diff --git a/.github/release.yml b/.github/release.yml
new file mode 100644
index 0000000000..1d760fe7bf
--- /dev/null
+++ b/.github/release.yml
@@ -0,0 +1,88 @@
+#
+# 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.
+#
+
+changelog:
+ exclude:
+ labels:
+ - Ignore for release
+ categories:
+ - title: 'Major Core & Rule Engine'
+ labels:
+ - 'Major Core'
+ - 'Major Rule Engine'
+ exclude:
+ labels:
+ - 'Bug'
+ - title: 'Major UI'
+ labels:
+ - 'Major UI'
+ exclude:
+ labels:
+ - 'Bug'
+ - title: 'Major Transport'
+ labels:
+ - 'Major Transport'
+ exclude:
+ labels:
+ - 'Bug'
+ - title: 'Major Edge'
+ labels:
+ - 'Major Edge'
+ exclude:
+ labels:
+ - 'Bug'
+ - title: 'Core & Rule Engine'
+ labels:
+ - 'Core'
+ - 'Rule Engine'
+ exclude:
+ labels:
+ - 'Bug'
+ - title: 'UI'
+ labels:
+ - 'UI'
+ exclude:
+ labels:
+ - 'Bug'
+ - title: 'Transport'
+ labels:
+ - 'Transport'
+ exclude:
+ labels:
+ - 'Bug'
+ - title: 'Edge'
+ labels:
+ - 'Edge'
+ exclude:
+ labels:
+ - 'Bug'
+ - title: 'Bug: Core & Rule Engine'
+ labels:
+ - 'Core'
+ - 'Rule Engine'
+ - 'Bug'
+ - title: 'Bug: UI'
+ labels:
+ - 'UI'
+ - 'Bug'
+ - title: 'Bug: Transport'
+ labels:
+ - 'Transport'
+ - 'Bug'
+ - title: 'Bug: Edge'
+ labels:
+ - 'Edge'
+ - 'Bug'
diff --git a/application/pom.xml b/application/pom.xml
index 61fa75cf49..8e7c3cd524 100644
--- a/application/pom.xml
+++ b/application/pom.xml
@@ -1,6 +1,6 @@
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/1.xml b/application/src/main/data/lwm2m-registry/1.xml
new file mode 100644
index 0000000000..ace9efcc6a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/1.xml
@@ -0,0 +1,360 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10.xml b/application/src/main/data/lwm2m-registry/10.xml
new file mode 100644
index 0000000000..af87413a94
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10.xml
@@ -0,0 +1,217 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10241.xml b/application/src/main/data/lwm2m-registry/10241.xml
new file mode 100644
index 0000000000..5a499100f3
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10241.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10242.xml b/application/src/main/data/lwm2m-registry/10242.xml
new file mode 100644
index 0000000000..09a62806d3
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10242.xml
@@ -0,0 +1,659 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10243.xml b/application/src/main/data/lwm2m-registry/10243.xml
new file mode 100644
index 0000000000..b73ce20021
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10243.xml
@@ -0,0 +1,263 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10244.xml b/application/src/main/data/lwm2m-registry/10244.xml
new file mode 100644
index 0000000000..9f55cd47de
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10244.xml
@@ -0,0 +1,303 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10245.xml b/application/src/main/data/lwm2m-registry/10245.xml
new file mode 100644
index 0000000000..b29349130d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10245.xml
@@ -0,0 +1,217 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10246.xml b/application/src/main/data/lwm2m-registry/10246.xml
new file mode 100644
index 0000000000..c3977d9538
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10246.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10247.xml b/application/src/main/data/lwm2m-registry/10247.xml
new file mode 100644
index 0000000000..eba05417e8
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10247.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10248.xml b/application/src/main/data/lwm2m-registry/10248.xml
new file mode 100644
index 0000000000..e9f69f7889
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10248.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10249.xml b/application/src/main/data/lwm2m-registry/10249.xml
new file mode 100644
index 0000000000..e1257c3dda
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10249.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10250.xml b/application/src/main/data/lwm2m-registry/10250.xml
new file mode 100644
index 0000000000..015149fae2
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10250.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10251.xml b/application/src/main/data/lwm2m-registry/10251.xml
new file mode 100644
index 0000000000..3fb1c00154
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10251.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10252.xml b/application/src/main/data/lwm2m-registry/10252.xml
new file mode 100644
index 0000000000..ddaf7cb1f2
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10252.xml
@@ -0,0 +1,229 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10253.xml b/application/src/main/data/lwm2m-registry/10253.xml
new file mode 100644
index 0000000000..27da37d16a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10253.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10254.xml b/application/src/main/data/lwm2m-registry/10254.xml
new file mode 100644
index 0000000000..ea37cf8cd8
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10254.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10255.xml b/application/src/main/data/lwm2m-registry/10255.xml
new file mode 100644
index 0000000000..fd63016952
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10255.xml
@@ -0,0 +1,165 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10256.xml b/application/src/main/data/lwm2m-registry/10256.xml
new file mode 100644
index 0000000000..dbcad740d0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10256.xml
@@ -0,0 +1,117 @@
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10257.xml b/application/src/main/data/lwm2m-registry/10257.xml
new file mode 100644
index 0000000000..75864d542b
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10257.xml
@@ -0,0 +1,275 @@
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10258.xml b/application/src/main/data/lwm2m-registry/10258.xml
new file mode 100644
index 0000000000..e2a9438170
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10258.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10259.xml b/application/src/main/data/lwm2m-registry/10259.xml
new file mode 100644
index 0000000000..d75869a122
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10259.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10260.xml b/application/src/main/data/lwm2m-registry/10260.xml
new file mode 100644
index 0000000000..5cd084af73
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10260.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10262.xml b/application/src/main/data/lwm2m-registry/10262.xml
new file mode 100644
index 0000000000..9fd47ac3af
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10262.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10263.xml b/application/src/main/data/lwm2m-registry/10263.xml
new file mode 100644
index 0000000000..07b9cde3ca
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10263.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10264.xml b/application/src/main/data/lwm2m-registry/10264.xml
new file mode 100644
index 0000000000..b11c42a21d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10264.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10265.xml b/application/src/main/data/lwm2m-registry/10265.xml
new file mode 100644
index 0000000000..2604ae86d7
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10265.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10266.xml b/application/src/main/data/lwm2m-registry/10266.xml
new file mode 100644
index 0000000000..48ee41319a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10266.xml
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10267.xml b/application/src/main/data/lwm2m-registry/10267.xml
new file mode 100644
index 0000000000..ffe70b5f2f
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10267.xml
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10268.xml b/application/src/main/data/lwm2m-registry/10268.xml
new file mode 100644
index 0000000000..a1ccd43888
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10268.xml
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10269.xml b/application/src/main/data/lwm2m-registry/10269.xml
new file mode 100644
index 0000000000..e4156e055e
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10269.xml
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10270.xml b/application/src/main/data/lwm2m-registry/10270.xml
new file mode 100644
index 0000000000..b7d171920c
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10270.xml
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10271.xml b/application/src/main/data/lwm2m-registry/10271.xml
new file mode 100644
index 0000000000..b4f8dfa6d5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10271.xml
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10272.xml b/application/src/main/data/lwm2m-registry/10272.xml
new file mode 100644
index 0000000000..0464c98a73
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10272.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10273.xml b/application/src/main/data/lwm2m-registry/10273.xml
new file mode 100644
index 0000000000..823adae0ed
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10273.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10274.xml b/application/src/main/data/lwm2m-registry/10274.xml
new file mode 100644
index 0000000000..f61554ca88
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10274.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10275.xml b/application/src/main/data/lwm2m-registry/10275.xml
new file mode 100644
index 0000000000..10248ea511
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10275.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10276.xml b/application/src/main/data/lwm2m-registry/10276.xml
new file mode 100644
index 0000000000..5863f0326b
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10276.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10277.xml b/application/src/main/data/lwm2m-registry/10277.xml
new file mode 100644
index 0000000000..83c6d4f0d5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10277.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10278.xml b/application/src/main/data/lwm2m-registry/10278.xml
new file mode 100644
index 0000000000..d004f89de6
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10278.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10279.xml b/application/src/main/data/lwm2m-registry/10279.xml
new file mode 100644
index 0000000000..38838e7c94
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10279.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10280.xml b/application/src/main/data/lwm2m-registry/10280.xml
new file mode 100644
index 0000000000..de2b7b6732
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10280.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10281.xml b/application/src/main/data/lwm2m-registry/10281.xml
new file mode 100644
index 0000000000..99eab667f2
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10281.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10282.xml b/application/src/main/data/lwm2m-registry/10282.xml
new file mode 100644
index 0000000000..e603de36b3
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10282.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10283.xml b/application/src/main/data/lwm2m-registry/10283.xml
new file mode 100644
index 0000000000..fd130fa713
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10283.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10284.xml b/application/src/main/data/lwm2m-registry/10284.xml
new file mode 100644
index 0000000000..1e889da48a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10284.xml
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10286.xml b/application/src/main/data/lwm2m-registry/10286.xml
new file mode 100644
index 0000000000..39e0809788
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10286.xml
@@ -0,0 +1,48 @@
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10290.xml b/application/src/main/data/lwm2m-registry/10290.xml
new file mode 100644
index 0000000000..7b89cc06c0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10290.xml
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10291.xml b/application/src/main/data/lwm2m-registry/10291.xml
new file mode 100644
index 0000000000..a232ed02f9
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10291.xml
@@ -0,0 +1,208 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10292.xml b/application/src/main/data/lwm2m-registry/10292.xml
new file mode 100644
index 0000000000..00fe33e320
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10292.xml
@@ -0,0 +1,208 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10299.xml b/application/src/main/data/lwm2m-registry/10299.xml
new file mode 100644
index 0000000000..a16a7c4fc2
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10299.xml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10300.xml b/application/src/main/data/lwm2m-registry/10300.xml
new file mode 100644
index 0000000000..234f0301a4
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10300.xml
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10308.xml b/application/src/main/data/lwm2m-registry/10308.xml
new file mode 100644
index 0000000000..0ed1a6ea30
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10308.xml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10309.xml b/application/src/main/data/lwm2m-registry/10309.xml
new file mode 100644
index 0000000000..b37b435724
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10309.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10311.xml b/application/src/main/data/lwm2m-registry/10311.xml
new file mode 100644
index 0000000000..6b6a78d21d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10311.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10313.xml b/application/src/main/data/lwm2m-registry/10313.xml
new file mode 100644
index 0000000000..4875e5d6b0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10313.xml
@@ -0,0 +1,253 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10314.xml b/application/src/main/data/lwm2m-registry/10314.xml
new file mode 100644
index 0000000000..f003fa03c2
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10314.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10315.xml b/application/src/main/data/lwm2m-registry/10315.xml
new file mode 100644
index 0000000000..da7ff8c67e
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10315.xml
@@ -0,0 +1,129 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10316.xml b/application/src/main/data/lwm2m-registry/10316.xml
new file mode 100644
index 0000000000..d10dabf99b
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10316.xml
@@ -0,0 +1,233 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10318.xml b/application/src/main/data/lwm2m-registry/10318.xml
new file mode 100644
index 0000000000..989db0de7e
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10318.xml
@@ -0,0 +1,189 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10319.xml b/application/src/main/data/lwm2m-registry/10319.xml
new file mode 100644
index 0000000000..b8ebcef6fb
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10319.xml
@@ -0,0 +1,130 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10320.xml b/application/src/main/data/lwm2m-registry/10320.xml
new file mode 100644
index 0000000000..fb48c814f0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10320.xml
@@ -0,0 +1,141 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10322.xml b/application/src/main/data/lwm2m-registry/10322.xml
new file mode 100644
index 0000000000..98822e0efe
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10322.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10323.xml b/application/src/main/data/lwm2m-registry/10323.xml
new file mode 100644
index 0000000000..dcbdaeb91d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10323.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10324.xml b/application/src/main/data/lwm2m-registry/10324.xml
new file mode 100644
index 0000000000..b3db2b4f06
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10324.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10326.xml b/application/src/main/data/lwm2m-registry/10326.xml
new file mode 100644
index 0000000000..cdc01a0e61
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10326.xml
@@ -0,0 +1,722 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10327.xml b/application/src/main/data/lwm2m-registry/10327.xml
new file mode 100644
index 0000000000..5f0e232a22
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10327.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10328.xml b/application/src/main/data/lwm2m-registry/10328.xml
new file mode 100644
index 0000000000..fdf39d5dc1
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10328.xml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10329.xml b/application/src/main/data/lwm2m-registry/10329.xml
new file mode 100644
index 0000000000..7470bec6e1
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10329.xml
@@ -0,0 +1,433 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10330.xml b/application/src/main/data/lwm2m-registry/10330.xml
new file mode 100644
index 0000000000..75c5a2ecdd
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10330.xml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10331.xml b/application/src/main/data/lwm2m-registry/10331.xml
new file mode 100644
index 0000000000..ca555cc0d9
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10331.xml
@@ -0,0 +1,221 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10332.xml b/application/src/main/data/lwm2m-registry/10332.xml
new file mode 100644
index 0000000000..f582373043
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10332.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10333.xml b/application/src/main/data/lwm2m-registry/10333.xml
new file mode 100644
index 0000000000..aaeb25487d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10333.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10334.xml b/application/src/main/data/lwm2m-registry/10334.xml
new file mode 100644
index 0000000000..479406630c
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10334.xml
@@ -0,0 +1,129 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10335.xml b/application/src/main/data/lwm2m-registry/10335.xml
new file mode 100644
index 0000000000..91fe8cd9c5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10335.xml
@@ -0,0 +1,97 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10336.xml b/application/src/main/data/lwm2m-registry/10336.xml
new file mode 100644
index 0000000000..5016e6ee13
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10336.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10337.xml b/application/src/main/data/lwm2m-registry/10337.xml
new file mode 100644
index 0000000000..6204020400
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10337.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10338.xml b/application/src/main/data/lwm2m-registry/10338.xml
new file mode 100644
index 0000000000..c66df8addf
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10338.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10339.xml b/application/src/main/data/lwm2m-registry/10339.xml
new file mode 100644
index 0000000000..5376de4a6c
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10339.xml
@@ -0,0 +1,114 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10340.xml b/application/src/main/data/lwm2m-registry/10340.xml
new file mode 100644
index 0000000000..679b46f150
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10340.xml
@@ -0,0 +1,218 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10341.xml b/application/src/main/data/lwm2m-registry/10341.xml
new file mode 100644
index 0000000000..c632fd5c57
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10341.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10342.xml b/application/src/main/data/lwm2m-registry/10342.xml
new file mode 100644
index 0000000000..644bcf9071
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10342.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10343.xml b/application/src/main/data/lwm2m-registry/10343.xml
new file mode 100644
index 0000000000..a34c80f3a6
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10343.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10344.xml b/application/src/main/data/lwm2m-registry/10344.xml
new file mode 100644
index 0000000000..d28d343ae3
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10344.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10345.xml b/application/src/main/data/lwm2m-registry/10345.xml
new file mode 100644
index 0000000000..ad489a7faa
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10345.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10346.xml b/application/src/main/data/lwm2m-registry/10346.xml
new file mode 100644
index 0000000000..4ee595e16a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10346.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10347.xml b/application/src/main/data/lwm2m-registry/10347.xml
new file mode 100644
index 0000000000..6c0808ed61
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10347.xml
@@ -0,0 +1,154 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10348.xml b/application/src/main/data/lwm2m-registry/10348.xml
new file mode 100644
index 0000000000..76451605f0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10348.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10349.xml b/application/src/main/data/lwm2m-registry/10349.xml
new file mode 100644
index 0000000000..a4212558c4
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10349.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10350.xml b/application/src/main/data/lwm2m-registry/10350.xml
new file mode 100644
index 0000000000..1942cabe0c
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10350.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10351.xml b/application/src/main/data/lwm2m-registry/10351.xml
new file mode 100644
index 0000000000..473b440b02
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10351.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10352.xml b/application/src/main/data/lwm2m-registry/10352.xml
new file mode 100644
index 0000000000..1e7503ef42
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10352.xml
@@ -0,0 +1,114 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10353.xml b/application/src/main/data/lwm2m-registry/10353.xml
new file mode 100644
index 0000000000..0b6bb56cc4
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10353.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10354.xml b/application/src/main/data/lwm2m-registry/10354.xml
new file mode 100644
index 0000000000..60d5fc0050
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10354.xml
@@ -0,0 +1,217 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10355.xml b/application/src/main/data/lwm2m-registry/10355.xml
new file mode 100644
index 0000000000..fb38ee2767
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10355.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10356.xml b/application/src/main/data/lwm2m-registry/10356.xml
new file mode 100644
index 0000000000..2e362ce052
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10356.xml
@@ -0,0 +1,203 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10357.xml b/application/src/main/data/lwm2m-registry/10357.xml
new file mode 100644
index 0000000000..9487b2813d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10357.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10358.xml b/application/src/main/data/lwm2m-registry/10358.xml
new file mode 100644
index 0000000000..27a3684b22
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10358.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10359.xml b/application/src/main/data/lwm2m-registry/10359.xml
new file mode 100644
index 0000000000..2fc8af9677
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10359.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10360.xml b/application/src/main/data/lwm2m-registry/10360.xml
new file mode 100644
index 0000000000..935fea848c
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10360.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10361.xml b/application/src/main/data/lwm2m-registry/10361.xml
new file mode 100644
index 0000000000..3525647afd
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10361.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10362.xml b/application/src/main/data/lwm2m-registry/10362.xml
new file mode 100644
index 0000000000..8a928e4425
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10362.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10363.xml b/application/src/main/data/lwm2m-registry/10363.xml
new file mode 100644
index 0000000000..ca9d064f2f
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10363.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10364.xml b/application/src/main/data/lwm2m-registry/10364.xml
new file mode 100644
index 0000000000..3519665e62
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10364.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10365.xml b/application/src/main/data/lwm2m-registry/10365.xml
new file mode 100644
index 0000000000..792844271e
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10365.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10366.xml b/application/src/main/data/lwm2m-registry/10366.xml
new file mode 100644
index 0000000000..44e94ae51d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10366.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10368.xml b/application/src/main/data/lwm2m-registry/10368.xml
new file mode 100644
index 0000000000..68d3dd3ee3
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10368.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10369.xml b/application/src/main/data/lwm2m-registry/10369.xml
new file mode 100644
index 0000000000..dcf8190bda
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10369.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10371.xml b/application/src/main/data/lwm2m-registry/10371.xml
new file mode 100644
index 0000000000..73a4476865
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10371.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10374.xml b/application/src/main/data/lwm2m-registry/10374.xml
new file mode 100644
index 0000000000..a51646b95f
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10374.xml
@@ -0,0 +1,161 @@
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10375.xml b/application/src/main/data/lwm2m-registry/10375.xml
new file mode 100644
index 0000000000..5818491c51
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10375.xml
@@ -0,0 +1,148 @@
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10376.xml b/application/src/main/data/lwm2m-registry/10376.xml
new file mode 100644
index 0000000000..faec95398e
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10376.xml
@@ -0,0 +1,211 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10377.xml b/application/src/main/data/lwm2m-registry/10377.xml
new file mode 100644
index 0000000000..f46ace72aa
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10377.xml
@@ -0,0 +1,251 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/10378.xml b/application/src/main/data/lwm2m-registry/10378.xml
new file mode 100644
index 0000000000..bbd45811d0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/10378.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/11.xml b/application/src/main/data/lwm2m-registry/11.xml
new file mode 100644
index 0000000000..438b2c3df2
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/11.xml
@@ -0,0 +1,408 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/12.xml b/application/src/main/data/lwm2m-registry/12.xml
new file mode 100644
index 0000000000..d4aad43dca
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/12.xml
@@ -0,0 +1,551 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/13.xml b/application/src/main/data/lwm2m-registry/13.xml
new file mode 100644
index 0000000000..9b30ecd225
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/13.xml
@@ -0,0 +1,209 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/14.xml b/application/src/main/data/lwm2m-registry/14.xml
new file mode 100644
index 0000000000..a1d7f7239f
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/14.xml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/15.xml b/application/src/main/data/lwm2m-registry/15.xml
new file mode 100644
index 0000000000..f4363e3f33
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/15.xml
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/16.xml b/application/src/main/data/lwm2m-registry/16.xml
new file mode 100644
index 0000000000..f8f2dc40df
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/16.xml
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/18830.xml b/application/src/main/data/lwm2m-registry/18830.xml
new file mode 100644
index 0000000000..87e0747d5c
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/18830.xml
@@ -0,0 +1,173 @@
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/18831.xml b/application/src/main/data/lwm2m-registry/18831.xml
new file mode 100644
index 0000000000..68dc873ed0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/18831.xml
@@ -0,0 +1,120 @@
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/19.xml b/application/src/main/data/lwm2m-registry/19.xml
new file mode 100644
index 0000000000..c4f5cbe6ab
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/19.xml
@@ -0,0 +1,144 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2.xml b/application/src/main/data/lwm2m-registry/2.xml
new file mode 100644
index 0000000000..4ea5805b36
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2.xml
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/20.xml b/application/src/main/data/lwm2m-registry/20.xml
new file mode 100644
index 0000000000..68aa96048c
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/20.xml
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2048.xml b/application/src/main/data/lwm2m-registry/2048.xml
new file mode 100644
index 0000000000..0bc99cffd1
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2048.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2049.xml b/application/src/main/data/lwm2m-registry/2049.xml
new file mode 100644
index 0000000000..7509b22160
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2049.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2050.xml b/application/src/main/data/lwm2m-registry/2050.xml
new file mode 100644
index 0000000000..da27a90de0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2050.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2051.xml b/application/src/main/data/lwm2m-registry/2051.xml
new file mode 100644
index 0000000000..1f4ecda5d1
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2051.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2052.xml b/application/src/main/data/lwm2m-registry/2052.xml
new file mode 100644
index 0000000000..abaae1b54e
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2052.xml
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2053.xml b/application/src/main/data/lwm2m-registry/2053.xml
new file mode 100644
index 0000000000..a765a7894a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2053.xml
@@ -0,0 +1,165 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2054.xml b/application/src/main/data/lwm2m-registry/2054.xml
new file mode 100644
index 0000000000..3935fb7253
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2054.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2055.xml b/application/src/main/data/lwm2m-registry/2055.xml
new file mode 100644
index 0000000000..cbd0dc5796
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2055.xml
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2056.xml b/application/src/main/data/lwm2m-registry/2056.xml
new file mode 100644
index 0000000000..ddd50e269a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2056.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/2057.xml b/application/src/main/data/lwm2m-registry/2057.xml
new file mode 100644
index 0000000000..68d4bcd135
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/2057.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/21.xml b/application/src/main/data/lwm2m-registry/21.xml
new file mode 100644
index 0000000000..5685648bad
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/21.xml
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/22.xml b/application/src/main/data/lwm2m-registry/22.xml
new file mode 100644
index 0000000000..02fed409ae
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/22.xml
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/23.xml b/application/src/main/data/lwm2m-registry/23.xml
new file mode 100644
index 0000000000..55db80cc77
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/23.xml
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/24.xml b/application/src/main/data/lwm2m-registry/24.xml
new file mode 100644
index 0000000000..7dd6942646
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/24.xml
@@ -0,0 +1,163 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/25.xml b/application/src/main/data/lwm2m-registry/25.xml
new file mode 100644
index 0000000000..5ab62b3c36
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/25.xml
@@ -0,0 +1,104 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/26.xml b/application/src/main/data/lwm2m-registry/26.xml
new file mode 100644
index 0000000000..0f77aad973
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/26.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/27.xml b/application/src/main/data/lwm2m-registry/27.xml
new file mode 100644
index 0000000000..9f30947997
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/27.xml
@@ -0,0 +1,322 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/28.xml b/application/src/main/data/lwm2m-registry/28.xml
new file mode 100644
index 0000000000..8edd51bcc5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/28.xml
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3.xml b/application/src/main/data/lwm2m-registry/3.xml
new file mode 100644
index 0000000000..cb360acd10
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3.xml
@@ -0,0 +1,331 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3200.xml b/application/src/main/data/lwm2m-registry/3200.xml
new file mode 100644
index 0000000000..6a6310b5bb
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3200.xml
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3201.xml b/application/src/main/data/lwm2m-registry/3201.xml
new file mode 100644
index 0000000000..b950077387
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3201.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3202.xml b/application/src/main/data/lwm2m-registry/3202.xml
new file mode 100644
index 0000000000..7814f6ccf9
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3202.xml
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3203.xml b/application/src/main/data/lwm2m-registry/3203.xml
new file mode 100644
index 0000000000..0316e920a5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3203.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3300.xml b/application/src/main/data/lwm2m-registry/3300.xml
new file mode 100644
index 0000000000..f7a5b8a3e2
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3300.xml
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3301.xml b/application/src/main/data/lwm2m-registry/3301.xml
new file mode 100644
index 0000000000..6604464f20
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3301.xml
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3302.xml b/application/src/main/data/lwm2m-registry/3302.xml
new file mode 100644
index 0000000000..fe9e886408
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3302.xml
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3303.xml b/application/src/main/data/lwm2m-registry/3303.xml
new file mode 100644
index 0000000000..2db5da74c8
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3303.xml
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3304.xml b/application/src/main/data/lwm2m-registry/3304.xml
new file mode 100644
index 0000000000..7331c5f83a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3304.xml
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3305.xml b/application/src/main/data/lwm2m-registry/3305.xml
new file mode 100644
index 0000000000..f927a44a59
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3305.xml
@@ -0,0 +1,278 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3306.xml b/application/src/main/data/lwm2m-registry/3306.xml
new file mode 100644
index 0000000000..748bc0f005
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3306.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3308.xml b/application/src/main/data/lwm2m-registry/3308.xml
new file mode 100644
index 0000000000..f1d5c18f12
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3308.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3310.xml b/application/src/main/data/lwm2m-registry/3310.xml
new file mode 100644
index 0000000000..6b4e04d6b6
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3310.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3311.xml b/application/src/main/data/lwm2m-registry/3311.xml
new file mode 100644
index 0000000000..4c98be2522
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3311.xml
@@ -0,0 +1,127 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3312.xml b/application/src/main/data/lwm2m-registry/3312.xml
new file mode 100644
index 0000000000..17bd0312db
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3312.xml
@@ -0,0 +1,127 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3313.xml b/application/src/main/data/lwm2m-registry/3313.xml
new file mode 100644
index 0000000000..43d0d63b88
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3313.xml
@@ -0,0 +1,157 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3314.xml b/application/src/main/data/lwm2m-registry/3314.xml
new file mode 100644
index 0000000000..96ebc5a537
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3314.xml
@@ -0,0 +1,147 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3315.xml b/application/src/main/data/lwm2m-registry/3315.xml
new file mode 100644
index 0000000000..d54a09edd8
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3315.xml
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3316.xml b/application/src/main/data/lwm2m-registry/3316.xml
new file mode 100644
index 0000000000..16a20a219a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3316.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3317.xml b/application/src/main/data/lwm2m-registry/3317.xml
new file mode 100644
index 0000000000..9d41da70de
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3317.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3318.xml b/application/src/main/data/lwm2m-registry/3318.xml
new file mode 100644
index 0000000000..957b593c89
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3318.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3319.xml b/application/src/main/data/lwm2m-registry/3319.xml
new file mode 100644
index 0000000000..e3a13ea3ef
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3319.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3320.xml b/application/src/main/data/lwm2m-registry/3320.xml
new file mode 100644
index 0000000000..9ec16fb671
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3320.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3321.xml b/application/src/main/data/lwm2m-registry/3321.xml
new file mode 100644
index 0000000000..e4a1f80bf1
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3321.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3322.xml b/application/src/main/data/lwm2m-registry/3322.xml
new file mode 100644
index 0000000000..838ed44995
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3322.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3323.xml b/application/src/main/data/lwm2m-registry/3323.xml
new file mode 100644
index 0000000000..e65c11c123
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3323.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3324.xml b/application/src/main/data/lwm2m-registry/3324.xml
new file mode 100644
index 0000000000..b80d427b91
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3324.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3325.xml b/application/src/main/data/lwm2m-registry/3325.xml
new file mode 100644
index 0000000000..c0577d64cd
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3325.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3326.xml b/application/src/main/data/lwm2m-registry/3326.xml
new file mode 100644
index 0000000000..e247637bcf
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3326.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3327.xml b/application/src/main/data/lwm2m-registry/3327.xml
new file mode 100644
index 0000000000..9cc689459f
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3327.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3328.xml b/application/src/main/data/lwm2m-registry/3328.xml
new file mode 100644
index 0000000000..752ebe0c53
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3328.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3329.xml b/application/src/main/data/lwm2m-registry/3329.xml
new file mode 100644
index 0000000000..fe221a1564
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3329.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3330.xml b/application/src/main/data/lwm2m-registry/3330.xml
new file mode 100644
index 0000000000..baec2dab14
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3330.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3331.xml b/application/src/main/data/lwm2m-registry/3331.xml
new file mode 100644
index 0000000000..1094d5bf31
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3331.xml
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3332.xml b/application/src/main/data/lwm2m-registry/3332.xml
new file mode 100644
index 0000000000..d4026e9558
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3332.xml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3333.xml b/application/src/main/data/lwm2m-registry/3333.xml
new file mode 100644
index 0000000000..1fc7117482
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3333.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3334.xml b/application/src/main/data/lwm2m-registry/3334.xml
new file mode 100644
index 0000000000..4ff3e6c6a6
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3334.xml
@@ -0,0 +1,229 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3335.xml b/application/src/main/data/lwm2m-registry/3335.xml
new file mode 100644
index 0000000000..9f608653f5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3335.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3336.xml b/application/src/main/data/lwm2m-registry/3336.xml
new file mode 100644
index 0000000000..68fea3b90e
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3336.xml
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3337.xml b/application/src/main/data/lwm2m-registry/3337.xml
new file mode 100644
index 0000000000..fa4eefbe81
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3337.xml
@@ -0,0 +1,159 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3338.xml b/application/src/main/data/lwm2m-registry/3338.xml
new file mode 100644
index 0000000000..fd1fba3332
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3338.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3339.xml b/application/src/main/data/lwm2m-registry/3339.xml
new file mode 100644
index 0000000000..194685474e
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3339.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3340.xml b/application/src/main/data/lwm2m-registry/3340.xml
new file mode 100644
index 0000000000..35de944f3a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3340.xml
@@ -0,0 +1,159 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3341.xml b/application/src/main/data/lwm2m-registry/3341.xml
new file mode 100644
index 0000000000..38e8fb8d9d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3341.xml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3342.xml b/application/src/main/data/lwm2m-registry/3342.xml
new file mode 100644
index 0000000000..cd27717ed4
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3342.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3343.xml b/application/src/main/data/lwm2m-registry/3343.xml
new file mode 100644
index 0000000000..3aa109923a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3343.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3344.xml b/application/src/main/data/lwm2m-registry/3344.xml
new file mode 100644
index 0000000000..2dd8648a19
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3344.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3345.xml b/application/src/main/data/lwm2m-registry/3345.xml
new file mode 100644
index 0000000000..bb234638a9
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3345.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3346.xml b/application/src/main/data/lwm2m-registry/3346.xml
new file mode 100644
index 0000000000..d49322f32a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3346.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3347.xml b/application/src/main/data/lwm2m-registry/3347.xml
new file mode 100644
index 0000000000..136e3445b9
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3347.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3348.xml b/application/src/main/data/lwm2m-registry/3348.xml
new file mode 100644
index 0000000000..9309b4b3dd
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3348.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3349.xml b/application/src/main/data/lwm2m-registry/3349.xml
new file mode 100644
index 0000000000..28029e7a6a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3349.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3350.xml b/application/src/main/data/lwm2m-registry/3350.xml
new file mode 100644
index 0000000000..f4f8477fdc
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3350.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3351.xml b/application/src/main/data/lwm2m-registry/3351.xml
new file mode 100644
index 0000000000..9219a765df
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3351.xml
@@ -0,0 +1,131 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3352.xml b/application/src/main/data/lwm2m-registry/3352.xml
new file mode 100644
index 0000000000..0e519c4951
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3352.xml
@@ -0,0 +1,124 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3353.xml b/application/src/main/data/lwm2m-registry/3353.xml
new file mode 100644
index 0000000000..1881a3b3bb
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3353.xml
@@ -0,0 +1,123 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3354.xml b/application/src/main/data/lwm2m-registry/3354.xml
new file mode 100644
index 0000000000..702be4cabc
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3354.xml
@@ -0,0 +1,134 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3355.xml b/application/src/main/data/lwm2m-registry/3355.xml
new file mode 100644
index 0000000000..fb56230fdf
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3355.xml
@@ -0,0 +1,156 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3356.xml b/application/src/main/data/lwm2m-registry/3356.xml
new file mode 100644
index 0000000000..95c7fc7835
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3356.xml
@@ -0,0 +1,120 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3357.xml b/application/src/main/data/lwm2m-registry/3357.xml
new file mode 100644
index 0000000000..935b7c4ba7
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3357.xml
@@ -0,0 +1,131 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3358.xml b/application/src/main/data/lwm2m-registry/3358.xml
new file mode 100644
index 0000000000..2784d6a990
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3358.xml
@@ -0,0 +1,106 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3359.xml b/application/src/main/data/lwm2m-registry/3359.xml
new file mode 100644
index 0000000000..91cb845e7a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3359.xml
@@ -0,0 +1,105 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3360.xml b/application/src/main/data/lwm2m-registry/3360.xml
new file mode 100644
index 0000000000..12b2302854
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3360.xml
@@ -0,0 +1,128 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3361.xml b/application/src/main/data/lwm2m-registry/3361.xml
new file mode 100644
index 0000000000..3d354bffac
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3361.xml
@@ -0,0 +1,130 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3362.xml b/application/src/main/data/lwm2m-registry/3362.xml
new file mode 100644
index 0000000000..3cb73eb79a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3362.xml
@@ -0,0 +1,97 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3363.xml b/application/src/main/data/lwm2m-registry/3363.xml
new file mode 100644
index 0000000000..3b44b91f26
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3363.xml
@@ -0,0 +1,100 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3364.xml b/application/src/main/data/lwm2m-registry/3364.xml
new file mode 100644
index 0000000000..0a042d12d2
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3364.xml
@@ -0,0 +1,97 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3365.xml b/application/src/main/data/lwm2m-registry/3365.xml
new file mode 100644
index 0000000000..83dbf0c807
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3365.xml
@@ -0,0 +1,123 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3366.xml b/application/src/main/data/lwm2m-registry/3366.xml
new file mode 100644
index 0000000000..5498af2a3d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3366.xml
@@ -0,0 +1,176 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3367.xml b/application/src/main/data/lwm2m-registry/3367.xml
new file mode 100644
index 0000000000..1f35cf4cc5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3367.xml
@@ -0,0 +1,138 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3368.xml b/application/src/main/data/lwm2m-registry/3368.xml
new file mode 100644
index 0000000000..40c17bfd37
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3368.xml
@@ -0,0 +1,100 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3369.xml b/application/src/main/data/lwm2m-registry/3369.xml
new file mode 100644
index 0000000000..b93bb86644
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3369.xml
@@ -0,0 +1,105 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3370.xml b/application/src/main/data/lwm2m-registry/3370.xml
new file mode 100644
index 0000000000..667ab0a281
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3370.xml
@@ -0,0 +1,141 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3371.xml b/application/src/main/data/lwm2m-registry/3371.xml
new file mode 100644
index 0000000000..fbc0860870
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3371.xml
@@ -0,0 +1,141 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3372.xml b/application/src/main/data/lwm2m-registry/3372.xml
new file mode 100644
index 0000000000..49d585a973
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3372.xml
@@ -0,0 +1,115 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3373.xml b/application/src/main/data/lwm2m-registry/3373.xml
new file mode 100644
index 0000000000..fb2af328b3
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3373.xml
@@ -0,0 +1,115 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3374.xml b/application/src/main/data/lwm2m-registry/3374.xml
new file mode 100644
index 0000000000..be7ecdc34e
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3374.xml
@@ -0,0 +1,132 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3375.xml b/application/src/main/data/lwm2m-registry/3375.xml
new file mode 100644
index 0000000000..75fb2a5a42
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3375.xml
@@ -0,0 +1,150 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3376.xml b/application/src/main/data/lwm2m-registry/3376.xml
new file mode 100644
index 0000000000..542f816da0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3376.xml
@@ -0,0 +1,97 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3377.xml b/application/src/main/data/lwm2m-registry/3377.xml
new file mode 100644
index 0000000000..515eb36439
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3377.xml
@@ -0,0 +1,168 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3378.xml b/application/src/main/data/lwm2m-registry/3378.xml
new file mode 100644
index 0000000000..970d245a90
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3378.xml
@@ -0,0 +1,115 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3379.xml b/application/src/main/data/lwm2m-registry/3379.xml
new file mode 100644
index 0000000000..87137da530
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3379.xml
@@ -0,0 +1,123 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3380.xml b/application/src/main/data/lwm2m-registry/3380.xml
new file mode 100644
index 0000000000..8290651569
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3380.xml
@@ -0,0 +1,204 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3381.xml b/application/src/main/data/lwm2m-registry/3381.xml
new file mode 100644
index 0000000000..db2e4d52e8
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3381.xml
@@ -0,0 +1,110 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3382.xml b/application/src/main/data/lwm2m-registry/3382.xml
new file mode 100644
index 0000000000..8f066837c8
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3382.xml
@@ -0,0 +1,108 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3383.xml b/application/src/main/data/lwm2m-registry/3383.xml
new file mode 100644
index 0000000000..663ac45faa
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3383.xml
@@ -0,0 +1,99 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3384.xml b/application/src/main/data/lwm2m-registry/3384.xml
new file mode 100644
index 0000000000..a18c6b910b
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3384.xml
@@ -0,0 +1,112 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3385.xml b/application/src/main/data/lwm2m-registry/3385.xml
new file mode 100644
index 0000000000..cc0a99182a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3385.xml
@@ -0,0 +1,110 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3386.xml b/application/src/main/data/lwm2m-registry/3386.xml
new file mode 100644
index 0000000000..43937efadb
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3386.xml
@@ -0,0 +1,105 @@
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3387.xml b/application/src/main/data/lwm2m-registry/3387.xml
new file mode 100644
index 0000000000..c50ecb47bc
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3387.xml
@@ -0,0 +1,224 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3388.xml b/application/src/main/data/lwm2m-registry/3388.xml
new file mode 100644
index 0000000000..c1b5e54206
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3388.xml
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3389.xml b/application/src/main/data/lwm2m-registry/3389.xml
new file mode 100644
index 0000000000..7e3d0c7cdb
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3389.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3390.xml b/application/src/main/data/lwm2m-registry/3390.xml
new file mode 100644
index 0000000000..0e56d0a19a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3390.xml
@@ -0,0 +1,298 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3391.xml b/application/src/main/data/lwm2m-registry/3391.xml
new file mode 100644
index 0000000000..0b4ce12cd0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3391.xml
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3392.xml b/application/src/main/data/lwm2m-registry/3392.xml
new file mode 100644
index 0000000000..07b1b154e4
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3392.xml
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3393.xml b/application/src/main/data/lwm2m-registry/3393.xml
new file mode 100644
index 0000000000..e3c883ac70
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3393.xml
@@ -0,0 +1,268 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3394.xml b/application/src/main/data/lwm2m-registry/3394.xml
new file mode 100644
index 0000000000..767100e145
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3394.xml
@@ -0,0 +1,177 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3395.xml b/application/src/main/data/lwm2m-registry/3395.xml
new file mode 100644
index 0000000000..29b4ce6b67
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3395.xml
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3396.xml b/application/src/main/data/lwm2m-registry/3396.xml
new file mode 100644
index 0000000000..c3183f8e29
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3396.xml
@@ -0,0 +1,270 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3397.xml b/application/src/main/data/lwm2m-registry/3397.xml
new file mode 100644
index 0000000000..b8a3bed8d0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3397.xml
@@ -0,0 +1,302 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3398.xml b/application/src/main/data/lwm2m-registry/3398.xml
new file mode 100644
index 0000000000..de3e24113d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3398.xml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3399.xml b/application/src/main/data/lwm2m-registry/3399.xml
new file mode 100644
index 0000000000..8c29c4af82
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3399.xml
@@ -0,0 +1,238 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3400.xml b/application/src/main/data/lwm2m-registry/3400.xml
new file mode 100644
index 0000000000..aea142daba
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3400.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3401.xml b/application/src/main/data/lwm2m-registry/3401.xml
new file mode 100644
index 0000000000..1b088f1737
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3401.xml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3402.xml b/application/src/main/data/lwm2m-registry/3402.xml
new file mode 100644
index 0000000000..5cf405a66a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3402.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3403.xml b/application/src/main/data/lwm2m-registry/3403.xml
new file mode 100644
index 0000000000..f3690e5df5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3403.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3404.xml b/application/src/main/data/lwm2m-registry/3404.xml
new file mode 100644
index 0000000000..24250ab608
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3404.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3405.xml b/application/src/main/data/lwm2m-registry/3405.xml
new file mode 100644
index 0000000000..f6939917ae
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3405.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3406.xml b/application/src/main/data/lwm2m-registry/3406.xml
new file mode 100644
index 0000000000..ccc7601eeb
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3406.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3407.xml b/application/src/main/data/lwm2m-registry/3407.xml
new file mode 100644
index 0000000000..7f29324566
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3407.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3408.xml b/application/src/main/data/lwm2m-registry/3408.xml
new file mode 100644
index 0000000000..4d5ff67eef
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3408.xml
@@ -0,0 +1,79 @@
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3410.xml b/application/src/main/data/lwm2m-registry/3410.xml
new file mode 100644
index 0000000000..63449e590b
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3410.xml
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3411.xml b/application/src/main/data/lwm2m-registry/3411.xml
new file mode 100644
index 0000000000..6339b847bd
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3411.xml
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3412.xml b/application/src/main/data/lwm2m-registry/3412.xml
new file mode 100644
index 0000000000..c3675639da
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3412.xml
@@ -0,0 +1,288 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3413.xml b/application/src/main/data/lwm2m-registry/3413.xml
new file mode 100644
index 0000000000..e699cb67dd
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3413.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3414.xml b/application/src/main/data/lwm2m-registry/3414.xml
new file mode 100644
index 0000000000..b3f7ad4567
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3414.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3415.xml b/application/src/main/data/lwm2m-registry/3415.xml
new file mode 100644
index 0000000000..5a76ca93a3
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3415.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3416.xml b/application/src/main/data/lwm2m-registry/3416.xml
new file mode 100644
index 0000000000..bf9f23b6ac
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3416.xml
@@ -0,0 +1,518 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3417.xml b/application/src/main/data/lwm2m-registry/3417.xml
new file mode 100644
index 0000000000..d22a318d84
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3417.xml
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3418.xml b/application/src/main/data/lwm2m-registry/3418.xml
new file mode 100644
index 0000000000..6ff07dfa94
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3418.xml
@@ -0,0 +1,348 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3419.xml b/application/src/main/data/lwm2m-registry/3419.xml
new file mode 100644
index 0000000000..88b66119a7
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3419.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3420.xml b/application/src/main/data/lwm2m-registry/3420.xml
new file mode 100644
index 0000000000..835f4ec8a5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3420.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3421.xml b/application/src/main/data/lwm2m-registry/3421.xml
new file mode 100644
index 0000000000..dadf8d8f47
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3421.xml
@@ -0,0 +1,618 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3423.xml b/application/src/main/data/lwm2m-registry/3423.xml
new file mode 100644
index 0000000000..6e0aaf3b21
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3423.xml
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3424.xml b/application/src/main/data/lwm2m-registry/3424.xml
new file mode 100644
index 0000000000..01df43cbaf
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3424.xml
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3425.xml b/application/src/main/data/lwm2m-registry/3425.xml
new file mode 100644
index 0000000000..dd94f14dfd
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3425.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3426.xml b/application/src/main/data/lwm2m-registry/3426.xml
new file mode 100644
index 0000000000..7f33c1bc1a
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3426.xml
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3427.xml b/application/src/main/data/lwm2m-registry/3427.xml
new file mode 100644
index 0000000000..4ffe60c2bc
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3427.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3428.xml b/application/src/main/data/lwm2m-registry/3428.xml
new file mode 100644
index 0000000000..68dab08269
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3428.xml
@@ -0,0 +1,268 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3429.xml b/application/src/main/data/lwm2m-registry/3429.xml
new file mode 100644
index 0000000000..e5f6f46b75
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3429.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3430.xml b/application/src/main/data/lwm2m-registry/3430.xml
new file mode 100644
index 0000000000..76a14c0656
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3430.xml
@@ -0,0 +1,371 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3431.xml b/application/src/main/data/lwm2m-registry/3431.xml
new file mode 100644
index 0000000000..8f0ec363d1
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3431.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3432.xml b/application/src/main/data/lwm2m-registry/3432.xml
new file mode 100644
index 0000000000..4816248320
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3432.xml
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3433.xml b/application/src/main/data/lwm2m-registry/3433.xml
new file mode 100644
index 0000000000..018f2af954
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3433.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3434.xml b/application/src/main/data/lwm2m-registry/3434.xml
new file mode 100644
index 0000000000..b06852cbe1
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3434.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3435.xml b/application/src/main/data/lwm2m-registry/3435.xml
new file mode 100644
index 0000000000..1694afc32b
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3435.xml
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3436.xml b/application/src/main/data/lwm2m-registry/3436.xml
new file mode 100644
index 0000000000..a450edf280
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3436.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3437.xml b/application/src/main/data/lwm2m-registry/3437.xml
new file mode 100644
index 0000000000..284911326e
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3437.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3438.xml b/application/src/main/data/lwm2m-registry/3438.xml
new file mode 100644
index 0000000000..2e2405c161
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3438.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3439.xml b/application/src/main/data/lwm2m-registry/3439.xml
new file mode 100644
index 0000000000..b702866ce0
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3439.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3441.xml b/application/src/main/data/lwm2m-registry/3441.xml
new file mode 100644
index 0000000000..bdd5efca6c
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3441.xml
@@ -0,0 +1,262 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/3442.xml b/application/src/main/data/lwm2m-registry/3442.xml
new file mode 100644
index 0000000000..b4607cead7
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/3442.xml
@@ -0,0 +1,332 @@
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/4.xml b/application/src/main/data/lwm2m-registry/4.xml
new file mode 100644
index 0000000000..dc3f100cc4
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/4.xml
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/5.xml b/application/src/main/data/lwm2m-registry/5.xml
new file mode 100644
index 0000000000..02188533b2
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/5.xml
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/500.xml b/application/src/main/data/lwm2m-registry/500.xml
new file mode 100644
index 0000000000..df21a5aa80
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/500.xml
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/501.xml b/application/src/main/data/lwm2m-registry/501.xml
new file mode 100644
index 0000000000..402cfc0b78
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/501.xml
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/502.xml b/application/src/main/data/lwm2m-registry/502.xml
new file mode 100644
index 0000000000..5b85aa4515
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/502.xml
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/503.xml b/application/src/main/data/lwm2m-registry/503.xml
new file mode 100644
index 0000000000..6c6e627a94
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/503.xml
@@ -0,0 +1,434 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/504.xml b/application/src/main/data/lwm2m-registry/504.xml
new file mode 100644
index 0000000000..25c033f59d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/504.xml
@@ -0,0 +1,341 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/505.xml b/application/src/main/data/lwm2m-registry/505.xml
new file mode 100644
index 0000000000..a89c59ca41
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/505.xml
@@ -0,0 +1,262 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/507.xml b/application/src/main/data/lwm2m-registry/507.xml
new file mode 100644
index 0000000000..650a0e8904
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/507.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/508.xml b/application/src/main/data/lwm2m-registry/508.xml
new file mode 100644
index 0000000000..7f45059dd5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/508.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/509.xml b/application/src/main/data/lwm2m-registry/509.xml
new file mode 100644
index 0000000000..17ff50250f
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/509.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/510.xml b/application/src/main/data/lwm2m-registry/510.xml
new file mode 100644
index 0000000000..302377bbff
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/510.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/6.xml b/application/src/main/data/lwm2m-registry/6.xml
new file mode 100644
index 0000000000..8b1b3da625
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/6.xml
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/7.xml b/application/src/main/data/lwm2m-registry/7.xml
new file mode 100644
index 0000000000..451780da1f
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/7.xml
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/8.xml b/application/src/main/data/lwm2m-registry/8.xml
new file mode 100644
index 0000000000..a9296999f5
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/8.xml
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/lwm2m-registry/9.xml b/application/src/main/data/lwm2m-registry/9.xml
new file mode 100644
index 0000000000..4186b1248d
--- /dev/null
+++ b/application/src/main/data/lwm2m-registry/9.xml
@@ -0,0 +1,321 @@
+
+
+
+
+
+
+
diff --git a/application/src/main/data/upgrade/1.3.0/schema_update.cql b/application/src/main/data/upgrade/1.3.0/schema_update.cql
index 88cb1dce81..da20e2b6d0 100644
--- a/application/src/main/data/upgrade/1.3.0/schema_update.cql
+++ b/application/src/main/data/upgrade/1.3.0/schema_update.cql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/1.3.1/schema_update.sql b/application/src/main/data/upgrade/1.3.1/schema_update.sql
index 1ca6590835..a0f1ef83b7 100644
--- a/application/src/main/data/upgrade/1.3.1/schema_update.sql
+++ b/application/src/main/data/upgrade/1.3.1/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/1.4.0/schema_update.cql b/application/src/main/data/upgrade/1.4.0/schema_update.cql
index 138c9f9086..b41f5b82d5 100644
--- a/application/src/main/data/upgrade/1.4.0/schema_update.cql
+++ b/application/src/main/data/upgrade/1.4.0/schema_update.cql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/1.4.0/schema_update.sql b/application/src/main/data/upgrade/1.4.0/schema_update.sql
index c999c6b3e9..435a3d05d0 100644
--- a/application/src/main/data/upgrade/1.4.0/schema_update.sql
+++ b/application/src/main/data/upgrade/1.4.0/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.0.0/schema_update.cql b/application/src/main/data/upgrade/2.0.0/schema_update.cql
index 5f7daa0ea8..279b21c489 100644
--- a/application/src/main/data/upgrade/2.0.0/schema_update.cql
+++ b/application/src/main/data/upgrade/2.0.0/schema_update.cql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.0.0/schema_update.sql b/application/src/main/data/upgrade/2.0.0/schema_update.sql
index 4a07d571e8..d110c2d232 100644
--- a/application/src/main/data/upgrade/2.0.0/schema_update.sql
+++ b/application/src/main/data/upgrade/2.0.0/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.1.1/schema_update.cql b/application/src/main/data/upgrade/2.1.1/schema_update.cql
index 49aa012d70..8fede09387 100644
--- a/application/src/main/data/upgrade/2.1.1/schema_update.cql
+++ b/application/src/main/data/upgrade/2.1.1/schema_update.cql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.1.1/schema_update.sql b/application/src/main/data/upgrade/2.1.1/schema_update.sql
index a840af7e4f..4589d405dd 100644
--- a/application/src/main/data/upgrade/2.1.1/schema_update.sql
+++ b/application/src/main/data/upgrade/2.1.1/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.1.2/schema_update.cql b/application/src/main/data/upgrade/2.1.2/schema_update.cql
index 0a27a912a0..a0b5ca5b90 100644
--- a/application/src/main/data/upgrade/2.1.2/schema_update.cql
+++ b/application/src/main/data/upgrade/2.1.2/schema_update.cql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.1.2/schema_update.sql b/application/src/main/data/upgrade/2.1.2/schema_update.sql
index d7baf2ec7e..5dcc63dc2f 100644
--- a/application/src/main/data/upgrade/2.1.2/schema_update.sql
+++ b/application/src/main/data/upgrade/2.1.2/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.2.0/schema_update.sql b/application/src/main/data/upgrade/2.2.0/schema_update.sql
index 9fc8d11189..568d0031fa 100644
--- a/application/src/main/data/upgrade/2.2.0/schema_update.sql
+++ b/application/src/main/data/upgrade/2.2.0/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.3.1/schema_update.sql b/application/src/main/data/upgrade/2.3.1/schema_update.sql
index 7fd717e253..33c3502ad7 100644
--- a/application/src/main/data/upgrade/2.3.1/schema_update.sql
+++ b/application/src/main/data/upgrade/2.3.1/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.4.0/schema_update.sql b/application/src/main/data/upgrade/2.4.0/schema_update.sql
index 835b1940ea..daf9f5f2b4 100644
--- a/application/src/main/data/upgrade/2.4.0/schema_update.sql
+++ b/application/src/main/data/upgrade/2.4.0/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.4.2/schema_update.sql b/application/src/main/data/upgrade/2.4.2/schema_update.sql
index d99aaa4d94..0923883a97 100644
--- a/application/src/main/data/upgrade/2.4.2/schema_update.sql
+++ b/application/src/main/data/upgrade/2.4.2/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.4.3/schema_update_psql_drop_partitions.sql b/application/src/main/data/upgrade/2.4.3/schema_update_psql_drop_partitions.sql
index 936911b6a1..9c05371d3a 100644
--- a/application/src/main/data/upgrade/2.4.3/schema_update_psql_drop_partitions.sql
+++ b/application/src/main/data/upgrade/2.4.3/schema_update_psql_drop_partitions.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.4.3/schema_update_psql_ts.sql b/application/src/main/data/upgrade/2.4.3/schema_update_psql_ts.sql
index 5cf51d13ed..0c9e250035 100644
--- a/application/src/main/data/upgrade/2.4.3/schema_update_psql_ts.sql
+++ b/application/src/main/data/upgrade/2.4.3/schema_update_psql_ts.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.4.3/schema_update_timescale_ts.sql b/application/src/main/data/upgrade/2.4.3/schema_update_timescale_ts.sql
index 58f69d034d..8d5bc061ad 100644
--- a/application/src/main/data/upgrade/2.4.3/schema_update_timescale_ts.sql
+++ b/application/src/main/data/upgrade/2.4.3/schema_update_timescale_ts.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/2.4.3/schema_update_ttl.sql b/application/src/main/data/upgrade/2.4.3/schema_update_ttl.sql
index 2a5ca58092..46f6e0f675 100644
--- a/application/src/main/data/upgrade/2.4.3/schema_update_ttl.sql
+++ b/application/src/main/data/upgrade/2.4.3/schema_update_ttl.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.0.1/schema_ts_latest.sql b/application/src/main/data/upgrade/3.0.1/schema_ts_latest.sql
index a270af1d53..67d5980da2 100644
--- a/application/src/main/data/upgrade/3.0.1/schema_ts_latest.sql
+++ b/application/src/main/data/upgrade/3.0.1/schema_ts_latest.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.0.1/schema_update_to_uuid.sql b/application/src/main/data/upgrade/3.0.1/schema_update_to_uuid.sql
index 01f443151d..ea382dc829 100644
--- a/application/src/main/data/upgrade/3.0.1/schema_update_to_uuid.sql
+++ b/application/src/main/data/upgrade/3.0.1/schema_update_to_uuid.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.1.0/schema_update.sql b/application/src/main/data/upgrade/3.1.0/schema_update.sql
index a23150cab9..3e666910c7 100644
--- a/application/src/main/data/upgrade/3.1.0/schema_update.sql
+++ b/application/src/main/data/upgrade/3.1.0/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.1.1/schema_update_after.sql b/application/src/main/data/upgrade/3.1.1/schema_update_after.sql
index 75cb865b69..97d767cdeb 100644
--- a/application/src/main/data/upgrade/3.1.1/schema_update_after.sql
+++ b/application/src/main/data/upgrade/3.1.1/schema_update_after.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.1.1/schema_update_before.sql b/application/src/main/data/upgrade/3.1.1/schema_update_before.sql
index 0d74063bb1..fc55cb18f3 100644
--- a/application/src/main/data/upgrade/3.1.1/schema_update_before.sql
+++ b/application/src/main/data/upgrade/3.1.1/schema_update_before.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.2.1/schema_update.sql b/application/src/main/data/upgrade/3.2.1/schema_update.sql
index 04dc38a28d..ea25872753 100644
--- a/application/src/main/data/upgrade/3.2.1/schema_update.sql
+++ b/application/src/main/data/upgrade/3.2.1/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.2.1/schema_update_ttl.sql b/application/src/main/data/upgrade/3.2.1/schema_update_ttl.sql
index cecbf5aff1..407a2e1727 100644
--- a/application/src/main/data/upgrade/3.2.1/schema_update_ttl.sql
+++ b/application/src/main/data/upgrade/3.2.1/schema_update_ttl.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.2.2/schema_update.sql b/application/src/main/data/upgrade/3.2.2/schema_update.sql
index 8685bf3ccf..c901dc8783 100644
--- a/application/src/main/data/upgrade/3.2.2/schema_update.sql
+++ b/application/src/main/data/upgrade/3.2.2/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.2.2/schema_update_event.sql b/application/src/main/data/upgrade/3.2.2/schema_update_event.sql
index 9e2e6cfd33..8f43d7e90e 100644
--- a/application/src/main/data/upgrade/3.2.2/schema_update_event.sql
+++ b/application/src/main/data/upgrade/3.2.2/schema_update_event.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.2.2/schema_update_ttl.sql b/application/src/main/data/upgrade/3.2.2/schema_update_ttl.sql
index 42a7e8b277..a765ce1957 100644
--- a/application/src/main/data/upgrade/3.2.2/schema_update_ttl.sql
+++ b/application/src/main/data/upgrade/3.2.2/schema_update_ttl.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.3.2/schema_update.sql b/application/src/main/data/upgrade/3.3.2/schema_update.sql
index 5501c359cb..fde6a83dc2 100644
--- a/application/src/main/data/upgrade/3.3.2/schema_update.sql
+++ b/application/src/main/data/upgrade/3.3.2/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.3.2/schema_update_lwm2m_bootstrap.sql b/application/src/main/data/upgrade/3.3.2/schema_update_lwm2m_bootstrap.sql
index dec4f269f3..fe31a67d55 100644
--- a/application/src/main/data/upgrade/3.3.2/schema_update_lwm2m_bootstrap.sql
+++ b/application/src/main/data/upgrade/3.3.2/schema_update_lwm2m_bootstrap.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.3.3/schema_event_ttl_procedure.sql b/application/src/main/data/upgrade/3.3.3/schema_event_ttl_procedure.sql
index 432fca8786..79862cdee7 100644
--- a/application/src/main/data/upgrade/3.3.3/schema_event_ttl_procedure.sql
+++ b/application/src/main/data/upgrade/3.3.3/schema_event_ttl_procedure.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.3.3/schema_update.sql b/application/src/main/data/upgrade/3.3.3/schema_update.sql
index eed1cab1ea..5d67f09baf 100644
--- a/application/src/main/data/upgrade/3.3.3/schema_update.sql
+++ b/application/src/main/data/upgrade/3.3.3/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.3.4/schema_update.sql b/application/src/main/data/upgrade/3.3.4/schema_update.sql
index c86a4fe1f4..566ef25aeb 100644
--- a/application/src/main/data/upgrade/3.3.4/schema_update.sql
+++ b/application/src/main/data/upgrade/3.3.4/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.4.0/schema_update.sql b/application/src/main/data/upgrade/3.4.0/schema_update.sql
index 71588d88ac..38f4e6d283 100644
--- a/application/src/main/data/upgrade/3.4.0/schema_update.sql
+++ b/application/src/main/data/upgrade/3.4.0/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.4.1/schema_update.sql b/application/src/main/data/upgrade/3.4.1/schema_update.sql
index a3d7bfb78f..fe012f8453 100644
--- a/application/src/main/data/upgrade/3.4.1/schema_update.sql
+++ b/application/src/main/data/upgrade/3.4.1/schema_update.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
@@ -22,6 +22,8 @@ $$
-- in case of running the upgrade script a second time:
IF NOT (SELECT exists(SELECT FROM pg_tables WHERE tablename = 'old_audit_log')) THEN
ALTER TABLE audit_log RENAME TO old_audit_log;
+ CREATE INDEX IF NOT EXISTS idx_old_audit_log_created_time ON old_audit_log(created_time);
+
ALTER INDEX IF EXISTS idx_audit_log_tenant_id_and_created_time RENAME TO idx_old_audit_log_tenant_id_and_created_time;
FOR table_partition IN SELECT tablename AS name, split_part(tablename, '_', 3) AS partition_ts
@@ -86,6 +88,7 @@ $$
-- in case of running the upgrade script a second time:
IF NOT (SELECT exists(SELECT FROM pg_tables WHERE tablename = 'old_edge_event')) THEN
ALTER TABLE edge_event RENAME TO old_edge_event;
+ CREATE INDEX IF NOT EXISTS idx_old_edge_event_created_time_tmp ON old_edge_event(created_time);
ALTER INDEX IF EXISTS idx_edge_event_tenant_id_and_created_time RENAME TO idx_old_edge_event_tenant_id_and_created_time;
FOR table_partition IN SELECT tablename AS name, split_part(tablename, '_', 3) AS partition_ts
diff --git a/application/src/main/data/upgrade/3.4.1/schema_update_after.sql b/application/src/main/data/upgrade/3.4.1/schema_update_after.sql
index 78df4d2fd2..d1d8ae4dbe 100644
--- a/application/src/main/data/upgrade/3.4.1/schema_update_after.sql
+++ b/application/src/main/data/upgrade/3.4.1/schema_update_after.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.4.1/schema_update_before.sql b/application/src/main/data/upgrade/3.4.1/schema_update_before.sql
index 27f772aba3..0820fde769 100644
--- a/application/src/main/data/upgrade/3.4.1/schema_update_before.sql
+++ b/application/src/main/data/upgrade/3.4.1/schema_update_before.sql
@@ -1,5 +1,5 @@
--
--- Copyright © 2016-2022 The Thingsboard Authors
+-- 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.
diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql
new file mode 100644
index 0000000000..aa53f98b74
--- /dev/null
+++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql
@@ -0,0 +1,379 @@
+--
+-- 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.
+--
+
+-- USER CREDENTIALS START
+
+ALTER TABLE user_credentials
+ ADD COLUMN IF NOT EXISTS additional_info varchar NOT NULL DEFAULT '{}';
+
+UPDATE user_credentials
+ SET additional_info = json_build_object('userPasswordHistory', (u.additional_info::json -> 'userPasswordHistory'))
+ FROM tb_user u WHERE user_credentials.user_id = u.id AND u.additional_info::jsonb ? 'userPasswordHistory';
+
+UPDATE tb_user SET additional_info = tb_user.additional_info::jsonb - 'userPasswordHistory' WHERE additional_info::jsonb ? 'userPasswordHistory';
+
+-- USER CREDENTIALS END
+
+-- ALARM ASSIGN TO USER START
+
+ALTER TABLE alarm ADD COLUMN IF NOT EXISTS assign_ts BIGINT DEFAULT 0;
+ALTER TABLE alarm ADD COLUMN IF NOT EXISTS assignee_id UUID;
+
+CREATE INDEX IF NOT EXISTS idx_alarm_tenant_assignee_created_time ON alarm(tenant_id, assignee_id, created_time DESC);
+
+-- ALARM ASSIGN TO USER END
+
+-- ALARM STATUS REFACTORING START
+
+ALTER TABLE alarm ADD COLUMN IF NOT EXISTS acknowledged boolean;
+ALTER TABLE alarm ADD COLUMN IF NOT EXISTS cleared boolean;
+
+ALTER TABLE alarm ADD COLUMN IF NOT EXISTS status varchar; -- to avoid failure of the subsequent upgrade.
+UPDATE alarm SET acknowledged = true, cleared = true WHERE status = 'CLEARED_ACK';
+UPDATE alarm SET acknowledged = true, cleared = false WHERE status = 'ACTIVE_ACK';
+UPDATE alarm SET acknowledged = false, cleared = true WHERE status = 'CLEARED_UNACK';
+UPDATE alarm SET acknowledged = false, cleared = false WHERE status = 'ACTIVE_UNACK';
+
+-- Drop index by 'status' column and replace with new indexes that has only active alarms;
+DROP INDEX IF EXISTS idx_alarm_originator_alarm_type_active;
+CREATE INDEX IF NOT EXISTS idx_alarm_originator_alarm_type_active
+ ON alarm USING btree (originator_id, type) WHERE cleared = false;
+
+DROP INDEX IF EXISTS idx_alarm_tenant_alarm_type_active;
+CREATE INDEX IF NOT EXISTS idx_alarm_tenant_alarm_type_active
+ ON alarm USING btree (tenant_id, type) WHERE cleared = false;
+
+-- Cover index by alarm type to optimize propagated alarm queries;
+DROP INDEX IF EXISTS idx_entity_alarm_entity_id_alarm_type_created_time_alarm_id;
+CREATE INDEX IF NOT EXISTS idx_entity_alarm_entity_id_alarm_type_created_time_alarm_id ON entity_alarm
+USING btree (tenant_id, entity_id, alarm_type, created_time DESC) INCLUDE(alarm_id);
+
+DROP INDEX IF EXISTS idx_alarm_tenant_status_created_time;
+ALTER TABLE alarm DROP COLUMN IF EXISTS status;
+
+-- Update old alarms and set their state to clear, if there are newer alarms.
+UPDATE alarm a
+SET cleared = TRUE
+WHERE cleared = FALSE
+ AND id != (SELECT l.id
+ FROM alarm l
+ WHERE l.tenant_id = a.tenant_id
+ AND l.originator_id = a.originator_id
+ AND l.type = a.type
+ ORDER BY l.created_time DESC, l.id
+ LIMIT 1);
+
+-- ALARM STATUS REFACTORING END
+
+-- ALARM COMMENTS START
+
+CREATE TABLE IF NOT EXISTS alarm_comment (
+ id uuid NOT NULL,
+ created_time bigint NOT NULL,
+ alarm_id uuid NOT NULL,
+ user_id uuid,
+ type varchar(255) NOT NULL,
+ comment varchar(10000),
+ CONSTRAINT fk_alarm_comment_alarm_id FOREIGN KEY (alarm_id) REFERENCES alarm(id) ON DELETE CASCADE
+) PARTITION BY RANGE (created_time);
+CREATE INDEX IF NOT EXISTS idx_alarm_comment_alarm_id ON alarm_comment(alarm_id);
+
+-- ALARM COMMENTS END
+
+-- NOTIFICATIONS START
+
+CREATE TABLE IF NOT EXISTS notification_target (
+ id UUID NOT NULL CONSTRAINT notification_target_pkey PRIMARY KEY,
+ created_time BIGINT NOT NULL,
+ tenant_id UUID NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ configuration VARCHAR(10000) NOT NULL,
+ CONSTRAINT uq_notification_target_name UNIQUE (tenant_id, name)
+);
+CREATE INDEX IF NOT EXISTS idx_notification_target_tenant_id_created_time ON notification_target(tenant_id, created_time DESC);
+
+CREATE TABLE IF NOT EXISTS notification_template (
+ id UUID NOT NULL CONSTRAINT notification_template_pkey PRIMARY KEY,
+ created_time BIGINT NOT NULL,
+ tenant_id UUID NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ notification_type VARCHAR(50) NOT NULL,
+ configuration VARCHAR(10000000) NOT NULL,
+ CONSTRAINT uq_notification_template_name UNIQUE (tenant_id, name)
+);
+CREATE INDEX IF NOT EXISTS idx_notification_template_tenant_id_created_time ON notification_template(tenant_id, created_time DESC);
+
+CREATE TABLE IF NOT EXISTS notification_rule (
+ id UUID NOT NULL CONSTRAINT notification_rule_pkey PRIMARY KEY,
+ created_time BIGINT NOT NULL,
+ tenant_id UUID NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ template_id UUID NOT NULL CONSTRAINT fk_notification_rule_template_id REFERENCES notification_template(id),
+ trigger_type VARCHAR(50) NOT NULL,
+ trigger_config VARCHAR(1000) NOT NULL,
+ recipients_config VARCHAR(10000) NOT NULL,
+ additional_config VARCHAR(255),
+ CONSTRAINT uq_notification_rule_name UNIQUE (tenant_id, name)
+);
+CREATE INDEX IF NOT EXISTS idx_notification_rule_tenant_id_trigger_type_created_time ON notification_rule(tenant_id, trigger_type, created_time DESC);
+
+CREATE TABLE IF NOT EXISTS notification_request (
+ id UUID NOT NULL CONSTRAINT notification_request_pkey PRIMARY KEY,
+ created_time BIGINT NOT NULL,
+ tenant_id UUID NOT NULL,
+ targets VARCHAR(10000) NOT NULL,
+ template_id UUID,
+ template VARCHAR(10000000),
+ info VARCHAR(1000),
+ additional_config VARCHAR(1000),
+ originator_entity_id UUID,
+ originator_entity_type VARCHAR(32),
+ rule_id UUID NULL,
+ status VARCHAR(32),
+ stats VARCHAR(10000)
+);
+CREATE INDEX IF NOT EXISTS idx_notification_request_tenant_id_user_created_time ON notification_request(tenant_id, created_time DESC)
+ WHERE originator_entity_type = 'USER';
+CREATE INDEX IF NOT EXISTS idx_notification_request_rule_id_originator_entity_id ON notification_request(rule_id, originator_entity_id)
+ WHERE originator_entity_type = 'ALARM';
+CREATE INDEX IF NOT EXISTS idx_notification_request_status ON notification_request(status)
+ WHERE status = 'SCHEDULED';
+
+CREATE TABLE IF NOT EXISTS notification (
+ id UUID NOT NULL,
+ created_time BIGINT NOT NULL,
+ request_id UUID NULL CONSTRAINT fk_notification_request_id REFERENCES notification_request(id) ON DELETE CASCADE,
+ recipient_id UUID NOT NULL CONSTRAINT fk_notification_recipient_id REFERENCES tb_user(id) ON DELETE CASCADE,
+ type VARCHAR(50) NOT NULL,
+ subject VARCHAR(255),
+ body VARCHAR(1000) NOT NULL,
+ additional_config VARCHAR(1000),
+ status VARCHAR(32)
+) PARTITION BY RANGE (created_time);
+CREATE INDEX IF NOT EXISTS idx_notification_id ON notification(id);
+CREATE INDEX IF NOT EXISTS idx_notification_recipient_id_created_time ON notification(recipient_id, created_time DESC);
+
+-- NOTIFICATIONS END
+
+ALTER TABLE tb_user ADD COLUMN IF NOT EXISTS phone VARCHAR(255);
+
+CREATE TABLE IF NOT EXISTS user_settings (
+ user_id uuid NOT NULL,
+ type VARCHAR(50) NOT NULL,
+ settings varchar(10000),
+ CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES tb_user(id) ON DELETE CASCADE,
+ CONSTRAINT user_settings_pkey PRIMARY KEY (user_id, type)
+);
+
+-- TTL DROP PARTITIONS FUNCTIONS UPDATE START
+
+DROP PROCEDURE IF EXISTS drop_partitions_by_max_ttl(character varying, bigint, bigint);
+DROP FUNCTION IF EXISTS get_partition_by_max_ttl_date;
+
+CREATE OR REPLACE FUNCTION get_partition_by_system_ttl_date(IN partition_type varchar, IN date timestamp, OUT partition varchar) AS
+$$
+BEGIN
+ CASE
+ WHEN partition_type = 'DAYS' THEN
+ partition := 'ts_kv_' || to_char(date, 'yyyy') || '_' || to_char(date, 'MM') || '_' || to_char(date, 'dd');
+ WHEN partition_type = 'MONTHS' THEN
+ partition := 'ts_kv_' || to_char(date, 'yyyy') || '_' || to_char(date, 'MM');
+ WHEN partition_type = 'YEARS' THEN
+ partition := 'ts_kv_' || to_char(date, 'yyyy');
+ ELSE
+ partition := NULL;
+ END CASE;
+ IF partition IS NOT NULL THEN
+ IF NOT EXISTS(SELECT
+ FROM pg_tables
+ WHERE schemaname = 'public'
+ AND tablename = partition) THEN
+ partition := NULL;
+ RAISE NOTICE 'Failed to found partition by ttl';
+ END IF;
+ END IF;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE PROCEDURE drop_partitions_by_system_ttl(IN partition_type varchar, IN system_ttl bigint, INOUT deleted bigint)
+ LANGUAGE plpgsql AS
+$$
+DECLARE
+ date timestamp;
+ partition_by_max_ttl_date varchar;
+ partition_by_max_ttl_month varchar;
+ partition_by_max_ttl_day varchar;
+ partition_by_max_ttl_year varchar;
+ partition varchar;
+ partition_year integer;
+ partition_month integer;
+ partition_day integer;
+
+BEGIN
+ if system_ttl IS NOT NULL AND system_ttl > 0 THEN
+ date := to_timestamp(EXTRACT(EPOCH FROM current_timestamp) - system_ttl);
+ partition_by_max_ttl_date := get_partition_by_system_ttl_date(partition_type, date);
+ RAISE NOTICE 'Date by max ttl: %', date;
+ RAISE NOTICE 'Partition by max ttl: %', partition_by_max_ttl_date;
+ IF partition_by_max_ttl_date IS NOT NULL THEN
+ CASE
+ WHEN partition_type = 'DAYS' THEN
+ partition_by_max_ttl_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3);
+ partition_by_max_ttl_month := SPLIT_PART(partition_by_max_ttl_date, '_', 4);
+ partition_by_max_ttl_day := SPLIT_PART(partition_by_max_ttl_date, '_', 5);
+ WHEN partition_type = 'MONTHS' THEN
+ partition_by_max_ttl_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3);
+ partition_by_max_ttl_month := SPLIT_PART(partition_by_max_ttl_date, '_', 4);
+ ELSE
+ partition_by_max_ttl_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3);
+ END CASE;
+ IF partition_by_max_ttl_year IS NULL THEN
+ RAISE NOTICE 'Failed to remove partitions by max ttl date due to partition_by_max_ttl_year is null!';
+ ELSE
+ IF partition_type = 'YEARS' THEN
+ FOR partition IN SELECT tablename
+ FROM pg_tables
+ WHERE schemaname = 'public'
+ AND tablename like 'ts_kv_' || '%'
+ AND tablename != 'ts_kv_latest'
+ AND tablename != 'ts_kv_dictionary'
+ AND tablename != 'ts_kv_indefinite'
+ AND tablename != partition_by_max_ttl_date
+ LOOP
+ partition_year := SPLIT_PART(partition, '_', 3)::integer;
+ IF partition_year < partition_by_max_ttl_year::integer THEN
+ RAISE NOTICE 'Partition to delete by max ttl: %', partition;
+ EXECUTE format('DROP TABLE IF EXISTS %I', partition);
+ deleted := deleted + 1;
+ END IF;
+ END LOOP;
+ ELSE
+ IF partition_type = 'MONTHS' THEN
+ IF partition_by_max_ttl_month IS NULL THEN
+ RAISE NOTICE 'Failed to remove months partitions by max ttl date due to partition_by_max_ttl_month is null!';
+ ELSE
+ FOR partition IN SELECT tablename
+ FROM pg_tables
+ WHERE schemaname = 'public'
+ AND tablename like 'ts_kv_' || '%'
+ AND tablename != 'ts_kv_latest'
+ AND tablename != 'ts_kv_dictionary'
+ AND tablename != 'ts_kv_indefinite'
+ AND tablename != partition_by_max_ttl_date
+ LOOP
+ partition_year := SPLIT_PART(partition, '_', 3)::integer;
+ IF partition_year > partition_by_max_ttl_year::integer THEN
+ RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition;
+ CONTINUE;
+ ELSE
+ IF partition_year < partition_by_max_ttl_year::integer THEN
+ RAISE NOTICE 'Partition to delete by max ttl: %', partition;
+ EXECUTE format('DROP TABLE IF EXISTS %I', partition);
+ deleted := deleted + 1;
+ ELSE
+ partition_month := SPLIT_PART(partition, '_', 4)::integer;
+ IF partition_year = partition_by_max_ttl_year::integer THEN
+ IF partition_month >= partition_by_max_ttl_month::integer THEN
+ RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition;
+ CONTINUE;
+ ELSE
+ RAISE NOTICE 'Partition to delete by max ttl: %', partition;
+ EXECUTE format('DROP TABLE IF EXISTS %I', partition);
+ deleted := deleted + 1;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+ END IF;
+ ELSE
+ IF partition_type = 'DAYS' THEN
+ IF partition_by_max_ttl_month IS NULL THEN
+ RAISE NOTICE 'Failed to remove days partitions by max ttl date due to partition_by_max_ttl_month is null!';
+ ELSE
+ IF partition_by_max_ttl_day IS NULL THEN
+ RAISE NOTICE 'Failed to remove days partitions by max ttl date due to partition_by_max_ttl_day is null!';
+ ELSE
+ FOR partition IN SELECT tablename
+ FROM pg_tables
+ WHERE schemaname = 'public'
+ AND tablename like 'ts_kv_' || '%'
+ AND tablename != 'ts_kv_latest'
+ AND tablename != 'ts_kv_dictionary'
+ AND tablename != 'ts_kv_indefinite'
+ AND tablename != partition_by_max_ttl_date
+ LOOP
+ partition_year := SPLIT_PART(partition, '_', 3)::integer;
+ IF partition_year > partition_by_max_ttl_year::integer THEN
+ RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition;
+ CONTINUE;
+ ELSE
+ IF partition_year < partition_by_max_ttl_year::integer THEN
+ RAISE NOTICE 'Partition to delete by max ttl: %', partition;
+ EXECUTE format('DROP TABLE IF EXISTS %I', partition);
+ deleted := deleted + 1;
+ ELSE
+ partition_month := SPLIT_PART(partition, '_', 4)::integer;
+ IF partition_month > partition_by_max_ttl_month::integer THEN
+ RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition;
+ CONTINUE;
+ ELSE
+ IF partition_month < partition_by_max_ttl_month::integer THEN
+ RAISE NOTICE 'Partition to delete by max ttl: %', partition;
+ EXECUTE format('DROP TABLE IF EXISTS %I', partition);
+ deleted := deleted + 1;
+ ELSE
+ partition_day := SPLIT_PART(partition, '_', 5)::integer;
+ IF partition_day >= partition_by_max_ttl_day::integer THEN
+ RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition;
+ CONTINUE;
+ ELSE
+ IF partition_day < partition_by_max_ttl_day::integer THEN
+ RAISE NOTICE 'Partition to delete by max ttl: %', partition;
+ EXECUTE format('DROP TABLE IF EXISTS %I', partition);
+ deleted := deleted + 1;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+END
+$$;
+
+-- TTL DROP PARTITIONS FUNCTIONS UPDATE END
+
+-- RULE NODE SINGLETON MODE SUPPORT
+
+ALTER TABLE rule_node ADD COLUMN IF NOT EXISTS singleton_mode bool DEFAULT false;
+
+UPDATE rule_node SET singleton_mode = true WHERE type IN ('org.thingsboard.rule.engine.mqtt.azure.TbAzureIotHubNode', 'org.thingsboard.rule.engine.mqtt.TbMqttNode');
+
+ALTER TABLE component_descriptor ADD COLUMN IF NOT EXISTS clustering_mode varchar(255) DEFAULT 'ENABLED';
+
+UPDATE component_descriptor SET clustering_mode = 'USER_PREFERENCE' WHERE clazz = 'org.thingsboard.rule.engine.mqtt.TbMqttNode';
+
+UPDATE component_descriptor SET clustering_mode = 'SINGLETON' WHERE clazz = 'org.thingsboard.rule.engine.mqtt.azure.TbAzureIotHubNode';
+
diff --git a/application/src/main/data/upgrade/3.5.0/schema_update.sql b/application/src/main/data/upgrade/3.5.0/schema_update.sql
new file mode 100644
index 0000000000..321112c4eb
--- /dev/null
+++ b/application/src/main/data/upgrade/3.5.0/schema_update.sql
@@ -0,0 +1,23 @@
+--
+-- 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.
+--
+
+-- FIX DASHBOARD TEMPLATES AFTER ANGULAR MIGRATION TO VER.15
+
+UPDATE dashboard SET configuration = REPLACE(configuration, 'mat-button mat-icon-button', 'mat-icon-button')
+ WHERE configuration like '%mat-button mat-icon-button%';
+
+UPDATE widget_type SET descriptor = REPLACE(descriptor, 'mat-button mat-icon-button', 'mat-icon-button')
+ WHERE descriptor like '%mat-button mat-icon-button%';
diff --git a/application/src/main/data/upgrade/3.5.1/schema_update.sql b/application/src/main/data/upgrade/3.5.1/schema_update.sql
new file mode 100644
index 0000000000..3bc2c99168
--- /dev/null
+++ b/application/src/main/data/upgrade/3.5.1/schema_update.sql
@@ -0,0 +1,54 @@
+--
+-- 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.
+--
+
+ALTER TABLE notification_rule ADD COLUMN IF NOT EXISTS enabled BOOLEAN NOT NULL DEFAULT true;
+
+-- NOTIFICATION CONFIGS VERSION CONTROL START
+
+ALTER TABLE notification_template
+ ADD COLUMN IF NOT EXISTS external_id UUID;
+DO
+$$
+ BEGIN
+ IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'uq_notification_template_external_id') THEN
+ ALTER TABLE notification_template ADD CONSTRAINT uq_notification_template_external_id UNIQUE (tenant_id, external_id);
+ END IF;
+ END;
+$$;
+
+ALTER TABLE notification_target
+ ADD COLUMN IF NOT EXISTS external_id UUID;
+DO
+$$
+ BEGIN
+ IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'uq_notification_target_external_id') THEN
+ ALTER TABLE notification_target ADD CONSTRAINT uq_notification_target_external_id UNIQUE (tenant_id, external_id);
+ END IF;
+ END;
+$$;
+
+ALTER TABLE notification_rule
+ ADD COLUMN IF NOT EXISTS external_id UUID;
+DO
+$$
+ BEGIN
+ IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'uq_notification_rule_external_id') THEN
+ ALTER TABLE notification_rule ADD CONSTRAINT uq_notification_rule_external_id UNIQUE (tenant_id, external_id);
+ END IF;
+ END;
+$$;
+
+-- NOTIFICATION CONFIGS VERSION CONTROL END
diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java
index b4a0e019b6..b780f0e8cd 100644
--- a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java
+++ b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java
index a9c462ee05..0fe6915877 100644
--- a/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java
+++ b/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
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 e1a41fe401..e0190bb388 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -15,7 +15,6 @@
*/
package org.thingsboard.server.actors;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
@@ -29,8 +28,11 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
+import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.api.MailService;
+import org.thingsboard.rule.engine.api.NotificationCenter;
import org.thingsboard.rule.engine.api.SmsService;
+import org.thingsboard.rule.engine.api.slack.SlackService;
import org.thingsboard.rule.engine.api.sms.SmsSenderFactory;
import org.thingsboard.script.api.js.JsInvokeService;
import org.thingsboard.script.api.tbel.TbelInvokeService;
@@ -50,6 +52,8 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.common.msg.tools.TbRateLimits;
import org.thingsboard.server.common.stats.TbApiUsageReportClient;
+import org.thingsboard.server.dao.alarm.AlarmCommentService;
+import org.thingsboard.server.dao.asset.AssetProfileService;
import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.audit.AuditLogService;
@@ -58,6 +62,7 @@ import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.device.ClaimDevicesService;
import org.thingsboard.server.dao.device.DeviceCredentialsService;
+import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.edge.EdgeEventService;
import org.thingsboard.server.dao.edge.EdgeService;
@@ -65,6 +70,10 @@ import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.dao.nosql.CassandraBufferedRateReadExecutor;
import org.thingsboard.server.dao.nosql.CassandraBufferedRateWriteExecutor;
+import org.thingsboard.server.dao.notification.NotificationRequestService;
+import org.thingsboard.server.dao.notification.NotificationRuleService;
+import org.thingsboard.server.dao.notification.NotificationTargetService;
+import org.thingsboard.server.dao.notification.NotificationTemplateService;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
import org.thingsboard.server.dao.relation.RelationService;
@@ -78,8 +87,10 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.dao.widget.WidgetTypeService;
import org.thingsboard.server.dao.widget.WidgetsBundleService;
+import org.thingsboard.server.queue.discovery.DiscoveryService;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
+import org.thingsboard.server.queue.notification.NotificationRuleProcessor;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
@@ -87,6 +98,7 @@ import org.thingsboard.server.service.edge.rpc.EdgeRpcService;
import org.thingsboard.server.service.entitiy.entityview.TbEntityViewService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.executors.ExternalCallExecutorService;
+import org.thingsboard.server.service.executors.NotificationExecutorService;
import org.thingsboard.server.service.executors.SharedEventLoopGroupService;
import org.thingsboard.server.service.mail.MailExecutorService;
import org.thingsboard.server.service.profile.TbAssetProfileCache;
@@ -138,8 +150,6 @@ public class ActorSystemContext {
}
};
- protected final ObjectMapper mapper = new ObjectMapper();
-
private final ConcurrentMap debugPerTenantLimits = new ConcurrentHashMap<>();
public ConcurrentMap getDebugPerTenantLimits() {
@@ -168,6 +178,10 @@ public class ActorSystemContext {
@Setter
private ComponentDiscoveryService componentService;
+ @Autowired
+ @Getter
+ private DiscoveryService discoveryService;
+
@Autowired
@Getter
private DataDecodingEncodingService encodingService;
@@ -176,6 +190,14 @@ public class ActorSystemContext {
@Getter
private DeviceService deviceService;
+ @Autowired
+ @Getter
+ private DeviceProfileService deviceProfileService;
+
+ @Autowired
+ @Getter
+ private AssetProfileService assetProfileService;
+
@Autowired
@Getter
private DeviceCredentialsService deviceCredentialsService;
@@ -268,6 +290,10 @@ public class ActorSystemContext {
@Getter
private AlarmSubscriptionService alarmService;
+ @Autowired
+ @Getter
+ private AlarmCommentService alarmCommentService;
+
@Autowired
@Getter
private JsInvokeService jsInvokeService;
@@ -292,6 +318,10 @@ public class ActorSystemContext {
@Getter
private ExternalCallExecutorService externalCallExecutorService;
+ @Autowired
+ @Getter
+ private NotificationExecutorService notificationExecutor;
+
@Autowired
@Getter
private SharedEventLoopGroupService sharedEventLoopGroupService;
@@ -308,6 +338,34 @@ public class ActorSystemContext {
@Getter
private SmsSenderFactory smsSenderFactory;
+ @Autowired
+ @Getter
+ private NotificationCenter notificationCenter;
+
+ @Autowired
+ @Getter
+ private NotificationRuleProcessor notificationRuleProcessor;
+
+ @Autowired
+ @Getter
+ private NotificationTargetService notificationTargetService;
+
+ @Autowired
+ @Getter
+ private NotificationTemplateService notificationTemplateService;
+
+ @Autowired
+ @Getter
+ private NotificationRequestService notificationRequestService;
+
+ @Autowired
+ @Getter
+ private NotificationRuleService notificationRuleService;
+
+ @Autowired
+ @Getter
+ private SlackService slackService;
+
@Lazy
@Autowired(required = false)
@Getter
@@ -586,7 +644,7 @@ public class ActorSystemContext {
.dataType(tbMsg.getDataType().name())
.relationType(relationType)
.data(tbMsg.getData())
- .metadata(mapper.writeValueAsString(tbMsg.getMetaData().getData()));
+ .metadata(JacksonUtil.toString(tbMsg.getMetaData().getData()));
if (error != null) {
event.error(toString(error));
@@ -596,7 +654,7 @@ public class ActorSystemContext {
ListenableFuture future = eventService.saveAsync(event.build());
Futures.addCallback(future, RULE_NODE_DEBUG_EVENT_ERROR_CALLBACK, MoreExecutors.directExecutor());
- } catch (IOException ex) {
+ } catch (IllegalArgumentException ex) {
log.warn("Failed to persist rule node debug message", ex);
}
}
diff --git a/application/src/main/java/org/thingsboard/server/actors/TbEntityTypeActorIdPredicate.java b/application/src/main/java/org/thingsboard/server/actors/TbEntityTypeActorIdPredicate.java
index 9a8232ebdb..ce2c239b41 100644
--- a/application/src/main/java/org/thingsboard/server/actors/TbEntityTypeActorIdPredicate.java
+++ b/application/src/main/java/org/thingsboard/server/actors/TbEntityTypeActorIdPredicate.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
diff --git a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java
index eeb6d8e82e..fb6fbbdff2 100644
--- a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
diff --git a/application/src/main/java/org/thingsboard/server/actors/app/AppInitMsg.java b/application/src/main/java/org/thingsboard/server/actors/app/AppInitMsg.java
index 772c9ae5b5..14bb93898e 100644
--- a/application/src/main/java/org/thingsboard/server/actors/app/AppInitMsg.java
+++ b/application/src/main/java/org/thingsboard/server/actors/app/AppInitMsg.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java
index a0f49ba62f..d5833e0c07 100644
--- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorCreator.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorCreator.java
index 7a369a57e9..c5563dfaa8 100644
--- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorCreator.java
+++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorCreator.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
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 8a365b4e56..934f309480 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
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -21,7 +21,6 @@ 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 com.google.protobuf.InvalidProtocolBufferException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.thingsboard.common.util.JacksonUtil;
@@ -116,7 +115,7 @@ import java.util.stream.Collectors;
* @author Andrew Shvayka
*/
@Slf4j
-class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
+public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
static final String SESSION_TIMEOUT_MESSAGE = "session timeout!";
final TenantId tenantId;
@@ -816,7 +815,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
}
private ListenableFuture saveRpcRequestToEdgeQueue(ToDeviceRpcRequest msg, Integer requestId) {
- ObjectNode body = mapper.createObjectNode();
+ ObjectNode body = JacksonUtil.newObjectNode();
body.put("requestId", requestId);
body.put("requestUUID", msg.getId().toString());
body.put("oneway", msg.isOneway());
diff --git a/application/src/main/java/org/thingsboard/server/actors/device/SessionInfo.java b/application/src/main/java/org/thingsboard/server/actors/device/SessionInfo.java
index 01e4765190..07fe24b272 100644
--- a/application/src/main/java/org/thingsboard/server/actors/device/SessionInfo.java
+++ b/application/src/main/java/org/thingsboard/server/actors/device/SessionInfo.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
diff --git a/application/src/main/java/org/thingsboard/server/actors/device/SessionInfoMetaData.java b/application/src/main/java/org/thingsboard/server/actors/device/SessionInfoMetaData.java
index a26fe90d65..7dd7525561 100644
--- a/application/src/main/java/org/thingsboard/server/actors/device/SessionInfoMetaData.java
+++ b/application/src/main/java/org/thingsboard/server/actors/device/SessionInfoMetaData.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -16,7 +16,6 @@
package org.thingsboard.server.actors.device;
import lombok.Data;
-import org.thingsboard.server.gen.transport.TransportProtos.SessionType;
/**
* @author Andrew Shvayka
diff --git a/application/src/main/java/org/thingsboard/server/actors/device/SessionTimeoutCheckMsg.java b/application/src/main/java/org/thingsboard/server/actors/device/SessionTimeoutCheckMsg.java
index 6815aee675..e74baf8b3d 100644
--- a/application/src/main/java/org/thingsboard/server/actors/device/SessionTimeoutCheckMsg.java
+++ b/application/src/main/java/org/thingsboard/server/actors/device/SessionTimeoutCheckMsg.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
diff --git a/application/src/main/java/org/thingsboard/server/actors/device/ToDeviceRpcRequestMetadata.java b/application/src/main/java/org/thingsboard/server/actors/device/ToDeviceRpcRequestMetadata.java
index d003656874..f876408d24 100644
--- a/application/src/main/java/org/thingsboard/server/actors/device/ToDeviceRpcRequestMetadata.java
+++ b/application/src/main/java/org/thingsboard/server/actors/device/ToDeviceRpcRequestMetadata.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
diff --git a/application/src/main/java/org/thingsboard/server/actors/device/ToServerRpcRequestMetadata.java b/application/src/main/java/org/thingsboard/server/actors/device/ToServerRpcRequestMetadata.java
index c0a68c178d..f5d9e0595c 100644
--- a/application/src/main/java/org/thingsboard/server/actors/device/ToServerRpcRequestMetadata.java
+++ b/application/src/main/java/org/thingsboard/server/actors/device/ToServerRpcRequestMetadata.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
index ef2de35912..8b76924d96 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -16,7 +16,6 @@
package org.thingsboard.server.actors.ruleChain;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.netty.channel.EventLoopGroup;
@@ -25,6 +24,7 @@ import org.bouncycastle.util.Arrays;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ListeningExecutor;
import org.thingsboard.rule.engine.api.MailService;
+import org.thingsboard.rule.engine.api.NotificationCenter;
import org.thingsboard.rule.engine.api.RuleEngineAlarmService;
import org.thingsboard.rule.engine.api.RuleEngineApiUsageStateService;
import org.thingsboard.rule.engine.api.RuleEngineAssetProfileCache;
@@ -35,6 +35,7 @@ import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.rule.engine.api.SmsService;
import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbRelationTypes;
+import org.thingsboard.rule.engine.api.slack.SlackService;
import org.thingsboard.rule.engine.api.sms.SmsSenderFactory;
import org.thingsboard.rule.engine.util.TenantIdLoader;
import org.thingsboard.server.actors.ActorSystemContext;
@@ -71,18 +72,25 @@ import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.TbMsgProcessingStackItem;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
+import org.thingsboard.server.dao.alarm.AlarmCommentService;
+import org.thingsboard.server.dao.asset.AssetProfileService;
import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.cassandra.CassandraCluster;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.device.DeviceCredentialsService;
+import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.edge.EdgeEventService;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.nosql.CassandraStatementTask;
import org.thingsboard.server.dao.nosql.TbResultSetFuture;
+import org.thingsboard.server.dao.notification.NotificationRequestService;
+import org.thingsboard.server.dao.notification.NotificationRuleService;
+import org.thingsboard.server.dao.notification.NotificationTargetService;
+import org.thingsboard.server.dao.notification.NotificationTemplateService;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
import org.thingsboard.server.dao.relation.RelationService;
@@ -102,6 +110,7 @@ import org.thingsboard.server.service.script.RuleNodeTbelScriptEngine;
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -111,8 +120,6 @@ import java.util.function.Consumer;
@Slf4j
class DefaultTbContext implements TbContext {
- public final static ObjectMapper mapper = new ObjectMapper();
-
private final ActorSystemContext mainCtx;
private final String ruleChainName;
private final RuleNodeCtx nodeCtx;
@@ -412,8 +419,8 @@ class DefaultTbContext implements TbContext {
public TbMsg entityActionMsg(E entity, I id, RuleNodeId ruleNodeId, String action, K profile) {
try {
- return entityActionMsg(id, getActionMetaData(ruleNodeId), mapper.writeValueAsString(mapper.valueToTree(entity)), action, profile);
- } catch (JsonProcessingException | IllegalArgumentException e) {
+ return entityActionMsg(id, getActionMetaData(ruleNodeId), JacksonUtil.toString(JacksonUtil.valueToTree(entity)), action, profile);
+ } catch (IllegalArgumentException e) {
throw new RuntimeException("Failed to process " + id.getEntityType().name().toLowerCase() + " " + action + " msg: " + e);
}
}
@@ -468,6 +475,11 @@ class DefaultTbContext implements TbContext {
return mainCtx.getExternalCallExecutorService();
}
+ @Override
+ public ListeningExecutor getNotificationExecutor() {
+ return mainCtx.getNotificationExecutor();
+ }
+
@Override
@Deprecated
public ScriptEngine createJsScriptEngine(String script, String... argNames) {
@@ -559,6 +571,16 @@ class DefaultTbContext implements TbContext {
return mainCtx.getDeviceService();
}
+ @Override
+ public DeviceProfileService getDeviceProfileService() {
+ return mainCtx.getDeviceProfileService();
+ }
+
+ @Override
+ public AssetProfileService getAssetProfileService() {
+ return mainCtx.getAssetProfileService();
+ }
+
@Override
public DeviceCredentialsService getDeviceCredentialsService() {
return mainCtx.getDeviceCredentialsService();
@@ -579,6 +601,11 @@ class DefaultTbContext implements TbContext {
return mainCtx.getAlarmService();
}
+ @Override
+ public AlarmCommentService getAlarmCommentService() {
+ return mainCtx.getAlarmCommentService();
+ }
+
@Override
public RuleChainService getRuleChainService() {
return mainCtx.getRuleChainService();
@@ -667,6 +694,36 @@ class DefaultTbContext implements TbContext {
return mainCtx.getSmsSenderFactory();
}
+ @Override
+ public NotificationCenter getNotificationCenter() {
+ return mainCtx.getNotificationCenter();
+ }
+
+ @Override
+ public NotificationTargetService getNotificationTargetService() {
+ return mainCtx.getNotificationTargetService();
+ }
+
+ @Override
+ public NotificationTemplateService getNotificationTemplateService() {
+ return mainCtx.getNotificationTemplateService();
+ }
+
+ @Override
+ public NotificationRequestService getNotificationRequestService() {
+ return mainCtx.getNotificationRequestService();
+ }
+
+ @Override
+ public NotificationRuleService getNotificationRuleService() {
+ return mainCtx.getNotificationRuleService();
+ }
+
+ @Override
+ public SlackService getSlackService() {
+ return mainCtx.getSlackService();
+ }
+
@Override
public RuleEngineRpcService getRpcService() {
return mainCtx.getTbRuleEngineDeviceRpcService();
@@ -776,6 +833,12 @@ class DefaultTbContext implements TbContext {
return metaData;
}
+
+ @Override
+ public void schedule(Runnable runnable, long delay, TimeUnit timeUnit) {
+ mainCtx.getScheduler().schedule(runnable, delay, timeUnit);
+ }
+
@Override
public void checkTenantEntity(EntityId entityId) {
if (!this.getTenantId().equals(TenantIdLoader.findTenantId(this, entityId))) {
diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java
index ff9e21dedd..da45f0f53d 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -20,7 +20,6 @@ import org.thingsboard.server.actors.TbActor;
import org.thingsboard.server.actors.TbActorCtx;
import org.thingsboard.server.actors.TbActorId;
import org.thingsboard.server.actors.TbEntityActorId;
-import org.thingsboard.server.actors.service.ComponentActor;
import org.thingsboard.server.actors.service.ContextBasedCreator;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
@@ -30,7 +29,7 @@ import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
-public class RuleChainActor extends ComponentActor {
+public class RuleChainActor extends RuleEngineComponentActor {
private final RuleChain ruleChain;
@@ -101,6 +100,16 @@ public class RuleChainActor extends ComponentActor> extends ComponentActor {
+
+ public RuleEngineComponentActor(ActorSystemContext systemContext, TenantId tenantId, T id) {
+ super(systemContext, tenantId, id);
+ }
+
+ @Override
+ protected void logLifecycleEvent(ComponentLifecycleEvent event, Exception e) {
+ super.logLifecycleEvent(event, e);
+ if (e instanceof TbRuleNodeUpdateException || (event == ComponentLifecycleEvent.STARTED && e != null)) {
+ return;
+ }
+ processNotificationRule(event, e);
+ }
+
+ @Override
+ public void destroy(TbActorStopReason stopReason, Throwable cause) {
+ super.destroy(stopReason, cause);
+ if (stopReason == TbActorStopReason.INIT_FAILED && cause != null) {
+ processNotificationRule(ComponentLifecycleEvent.STARTED, cause);
+ }
+ }
+
+ private void processNotificationRule(ComponentLifecycleEvent event, Throwable e) {
+ systemContext.getNotificationRuleProcessor().process(RuleEngineComponentLifecycleEventTrigger.builder()
+ .tenantId(tenantId)
+ .ruleChainId(getRuleChainId())
+ .ruleChainName(getRuleChainName())
+ .componentId(id)
+ .componentName(processor.getComponentName())
+ .eventType(event)
+ .error(e)
+ .build());
+ }
+
+ protected abstract RuleChainId getRuleChainId();
+
+ protected abstract String getRuleChainName();
+
+}
diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActor.java
index f5847f764b..e8dec535f6 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActor.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -21,7 +21,6 @@ import org.thingsboard.server.actors.TbActor;
import org.thingsboard.server.actors.TbActorCtx;
import org.thingsboard.server.actors.TbActorId;
import org.thingsboard.server.actors.TbEntityActorId;
-import org.thingsboard.server.actors.service.ComponentActor;
import org.thingsboard.server.actors.service.ContextBasedCreator;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
@@ -32,7 +31,7 @@ import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
@Slf4j
-public class RuleNodeActor extends ComponentActor {
+public class RuleNodeActor extends RuleEngineComponentActor {
private final String ruleChainName;
private final RuleChainId ruleChainId;
@@ -133,6 +132,16 @@ public class RuleNodeActor extends ComponentActor {
private final String ruleChainName;
- private final TbActorRef self;
private final TbApiUsageReportClient apiUsageClient;
+ private final DefaultTbContext defaultCtx;
private RuleNode ruleNode;
private TbNode tbNode;
- private DefaultTbContext defaultCtx;
private RuleNodeInfo info;
RuleNodeActorMessageProcessor(TenantId tenantId, String ruleChainName, RuleNodeId ruleNodeId, ActorSystemContext systemContext
@@ -51,7 +53,6 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor perTenantLimits = new ConcurrentHashMap<>();
- private final ConcurrentMap perCustomerLimits = new ConcurrentHashMap<>();
+ private final ThingsboardErrorResponseHandler errorResponseHandler;
+ private final RateLimitService rateLimitService;
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
SecurityUser user = getCurrentUser();
if (user != null && !user.isSystemAdmin()) {
- var profile = tenantProfileCache.get(user.getTenantId());
- if (profile == null) {
+ try {
+ if (!rateLimitService.checkRateLimit(LimitedApi.REST_REQUESTS, user.getTenantId())) {
+ rateLimitExceeded(EntityType.TENANT, response);
+ return;
+ }
+ } catch (TenantProfileNotFoundException e) {
log.debug("[{}] Failed to lookup tenant profile", user.getTenantId());
errorResponseHandler.handle(new BadCredentialsException("Failed to lookup tenant profile"), response);
return;
}
- var profileConfiguration = profile.getDefaultProfileConfiguration();
- if (!checkRateLimits(user.getTenantId(), profileConfiguration.getTenantServerRestLimitsConfiguration(), perTenantLimits, response)) {
- return;
- }
+
if (user.isCustomerUser()) {
- if (!checkRateLimits(user.getCustomerId(), profileConfiguration.getCustomerServerRestLimitsConfiguration(), perCustomerLimits, response)) {
+ if (!rateLimitService.checkRateLimit(LimitedApi.REST_REQUESTS, user.getTenantId(), user.getCustomerId())) {
+ rateLimitExceeded(EntityType.CUSTOMER, response);
return;
}
}
@@ -90,23 +79,8 @@ public class RateLimitProcessingFilter extends OncePerRequestFilter {
return false;
}
- private boolean checkRateLimits(I ownerId, String rateLimitConfig, Map rateLimitsMap, ServletResponse response) {
- if (StringUtils.isNotEmpty(rateLimitConfig)) {
- TbRateLimits rateLimits = rateLimitsMap.get(ownerId);
- if (rateLimits == null || !rateLimits.getConfiguration().equals(rateLimitConfig)) {
- rateLimits = new TbRateLimits(rateLimitConfig);
- rateLimitsMap.put(ownerId, rateLimits);
- }
-
- if (!rateLimits.tryConsume()) {
- errorResponseHandler.handle(new TbRateLimitsException(ownerId.getEntityType()), (HttpServletResponse) response);
- return false;
- }
- } else {
- rateLimitsMap.remove(ownerId);
- }
-
- return true;
+ private void rateLimitExceeded(EntityType type, HttpServletResponse response) {
+ errorResponseHandler.handle(new TbRateLimitsException(type), response);
}
protected SecurityUser getCurrentUser() {
diff --git a/application/src/main/java/org/thingsboard/server/config/SchedulingConfiguration.java b/application/src/main/java/org/thingsboard/server/config/SchedulingConfiguration.java
index e23b629fed..1b9ee9f71d 100644
--- a/application/src/main/java/org/thingsboard/server/config/SchedulingConfiguration.java
+++ b/application/src/main/java/org/thingsboard/server/config/SchedulingConfiguration.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
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 c53cf1b504..4415f1a0bf 100644
--- a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java
+++ b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -25,6 +25,7 @@ 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;
@@ -86,6 +87,8 @@ import static springfox.documentation.builders.PathSelectors.regex;
@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}")
@@ -115,6 +118,7 @@ public class SwaggerConfiguration {
public Docket thingsboardApi() {
TypeResolver typeResolver = new TypeResolver();
return new Docket(DocumentationType.OAS_30)
+ .enable(enabled)
.groupName("thingsboard")
.apiInfo(apiInfo())
.additionalModels(
@@ -138,6 +142,7 @@ public class SwaggerConfiguration {
)
.securitySchemes(newArrayList(httpLogin()))
.securityContexts(newArrayList(securityContext()))
+ .ignoredParameterTypes(AuthenticationPrincipal.class)
.enableUrlTemplating(true);
}
diff --git a/application/src/main/java/org/thingsboard/server/config/ThingsboardMessageConfiguration.java b/application/src/main/java/org/thingsboard/server/config/ThingsboardMessageConfiguration.java
index 112fa5c122..1d0437d56a 100644
--- a/application/src/main/java/org/thingsboard/server/config/ThingsboardMessageConfiguration.java
+++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardMessageConfiguration.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
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 a6540f007a..a418dc268b 100644
--- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
+++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -15,7 +15,6 @@
*/
package org.thingsboard.server.config;
-import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -30,6 +29,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
@@ -115,20 +115,18 @@ public class ThingsboardSecurityConfiguration {
@Autowired private AuthenticationManager authenticationManager;
- @Autowired private ObjectMapper objectMapper;
-
@Autowired private RateLimitProcessingFilter rateLimitProcessingFilter;
@Bean
protected RestLoginProcessingFilter buildRestLoginProcessingFilter() throws Exception {
- RestLoginProcessingFilter filter = new RestLoginProcessingFilter(FORM_BASED_LOGIN_ENTRY_POINT, successHandler, failureHandler, objectMapper);
+ RestLoginProcessingFilter filter = new RestLoginProcessingFilter(FORM_BASED_LOGIN_ENTRY_POINT, successHandler, failureHandler);
filter.setAuthenticationManager(this.authenticationManager);
return filter;
}
@Bean
protected RestPublicLoginProcessingFilter buildRestPublicLoginProcessingFilter() throws Exception {
- RestPublicLoginProcessingFilter filter = new RestPublicLoginProcessingFilter(PUBLIC_LOGIN_ENTRY_POINT, successHandler, failureHandler, objectMapper);
+ RestPublicLoginProcessingFilter filter = new RestPublicLoginProcessingFilter(PUBLIC_LOGIN_ENTRY_POINT, successHandler, failureHandler);
filter.setAuthenticationManager(this.authenticationManager);
return filter;
}
@@ -146,7 +144,7 @@ public class ThingsboardSecurityConfiguration {
@Bean
protected RefreshTokenProcessingFilter buildRefreshTokenProcessingFilter() throws Exception {
- RefreshTokenProcessingFilter filter = new RefreshTokenProcessingFilter(TOKEN_REFRESH_ENTRY_POINT, successHandler, failureHandler, objectMapper);
+ RefreshTokenProcessingFilter filter = new RefreshTokenProcessingFilter(TOKEN_REFRESH_ENTRY_POINT, successHandler, failureHandler);
filter.setAuthenticationManager(this.authenticationManager);
return filter;
}
@@ -181,15 +179,8 @@ public class ThingsboardSecurityConfiguration {
private OAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver;
@Bean
- @Order(0)
- SecurityFilterChain resources(HttpSecurity http) throws Exception {
- http
- .requestMatchers((matchers) -> matchers.antMatchers("/*.js","/*.css","/*.ico","/assets/**","/static/**"))
- .authorizeHttpRequests((authorize) -> authorize.anyRequest().permitAll())
- .requestCache().disable()
- .securityContext().disable()
- .sessionManagement().disable();
- return http.build();
+ public WebSecurityCustomizer webSecurityCustomizer() {
+ return (web) -> web.ignoring().antMatchers("/*.js","/*.css","/*.ico","/assets/**","/static/**");
}
@Bean
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 012d57f3bd..65396576c1 100644
--- a/application/src/main/java/org/thingsboard/server/config/WebConfig.java
+++ b/application/src/main/java/org/thingsboard/server/config/WebConfig.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
diff --git a/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java b/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java
index 13b13123e6..9a6ffb0e32 100644
--- a/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java
+++ b/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -15,6 +15,8 @@
*/
package org.thingsboard.server.config;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
@@ -40,11 +42,15 @@ import java.util.Map;
@Configuration
@TbCoreComponent
@EnableWebSocket
+@RequiredArgsConstructor
+@Slf4j
public class WebSocketConfiguration implements WebSocketConfigurer {
public static final String WS_PLUGIN_PREFIX = "/api/ws/plugins/";
private static final String WS_PLUGIN_MAPPING = WS_PLUGIN_PREFIX + "**";
+ private final WebSocketHandler wsHandler;
+
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
@@ -55,7 +61,11 @@ public class WebSocketConfiguration implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
- registry.addHandler(wsHandler(), WS_PLUGIN_MAPPING).setAllowedOriginPatterns("*")
+ if (!(wsHandler instanceof TbWebSocketHandler)) {
+ log.error("TbWebSocketHandler expected but [{}] provided", wsHandler);
+ throw new RuntimeException("TbWebSocketHandler expected but " + wsHandler + " provided");
+ }
+ registry.addHandler(wsHandler, WS_PLUGIN_MAPPING).setAllowedOriginPatterns("*")
.addInterceptors(new HttpSessionHandshakeInterceptor(), new HandshakeInterceptor() {
@Override
@@ -82,11 +92,6 @@ public class WebSocketConfiguration implements WebSocketConfigurer {
});
}
- @Bean
- public WebSocketHandler wsHandler() {
- return new TbWebSocketHandler();
- }
-
protected SecurityUser getCurrentUser() throws ThingsboardException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.getPrincipal() instanceof SecurityUser) {
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 e5a217893e..32797801c0 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -37,13 +37,13 @@ import org.thingsboard.server.common.data.rpc.RpcError;
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
+import org.thingsboard.server.exception.ToErrorResponseEntity;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.rpc.LocalRequestMetaData;
import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
import org.thingsboard.server.service.security.AccessValidator;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
-import org.thingsboard.server.service.telemetry.exception.ToErrorResponseEntity;
import javax.annotation.Nullable;
import java.util.Optional;
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 29f32b8ac9..5cf97a7cda 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AdminController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AdminController.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -21,29 +21,42 @@ 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 org.springframework.beans.factory.annotation.Autowired;
+import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.rule.engine.api.SmsService;
import org.thingsboard.server.common.data.AdminSettings;
+import org.thingsboard.server.common.data.FeaturesInfo;
+import org.thingsboard.server.common.data.SystemInfo;
import org.thingsboard.server.common.data.UpdateMessage;
+import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.security.model.JwtPair;
+import org.thingsboard.server.common.data.security.model.JwtSettings;
import org.thingsboard.server.common.data.security.model.SecuritySettings;
import org.thingsboard.server.common.data.sms.config.TestSmsRequest;
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.security.model.JwtSettings;
-import org.thingsboard.server.service.security.auth.jwt.settings.JwtSettingsService;
+import org.thingsboard.server.common.data.sync.vc.VcUtils;
+import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.queue.util.TbCoreComponent;
-import org.thingsboard.server.common.data.security.model.JwtPair;
+import org.thingsboard.server.service.security.auth.jwt.settings.JwtSettingsService;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
import org.thingsboard.server.service.security.permission.Operation;
@@ -51,43 +64,31 @@ import org.thingsboard.server.service.security.permission.Resource;
import org.thingsboard.server.service.security.system.SystemSecurityService;
import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService;
import org.thingsboard.server.service.sync.vc.autocommit.TbAutoCommitSettingsService;
+import org.thingsboard.server.service.system.SystemInfoService;
import org.thingsboard.server.service.update.UpdateService;
-import static org.thingsboard.server.controller.ControllerConstants.*;
+import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH;
+import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
@RestController
@TbCoreComponent
@RequestMapping("/api/admin")
+@RequiredArgsConstructor
public class AdminController extends BaseController {
- @Autowired
- private MailService mailService;
-
- @Autowired
- private SmsService smsService;
-
- @Autowired
- private AdminSettingsService adminSettingsService;
-
- @Autowired
- private SystemSecurityService systemSecurityService;
-
+ private final MailService mailService;
+ private final SmsService smsService;
+ private final AdminSettingsService adminSettingsService;
+ private final SystemSecurityService systemSecurityService;
@Lazy
- @Autowired
- private JwtSettingsService jwtSettingsService;
-
+ private final JwtSettingsService jwtSettingsService;
@Lazy
- @Autowired
- private JwtTokenFactory tokenFactory;
-
- @Autowired
- private EntitiesVersionControlService versionControlService;
-
- @Autowired
- private TbAutoCommitSettingsService autoCommitSettingsService;
-
- @Autowired
- private UpdateService updateService;
+ private final JwtTokenFactory tokenFactory;
+ private final EntitiesVersionControlService versionControlService;
+ private final TbAutoCommitSettingsService autoCommitSettingsService;
+ private final UpdateService updateService;
+ private final SystemInfoService systemInfoService;
+ private final AuditLogService auditLogService;
@ApiOperation(value = "Get the Administration Settings object using key (getAdminSettings)",
notes = "Get the Administration Settings object using specified string key. Referencing non-existing key will cause an error." + SYSTEM_AUTHORITY_PARAGRAPH)
@@ -97,19 +98,14 @@ public class AdminController extends BaseController {
public AdminSettings getAdminSettings(
@ApiParam(value = "A string value of the key (e.g. 'general' or 'mail').")
@PathVariable("key") String key) throws ThingsboardException {
- try {
- 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);
- if (adminSettings.getKey().equals("mail")) {
- ((ObjectNode) adminSettings.getJsonValue()).remove("password");
- }
- return adminSettings;
- } catch (Exception e) {
- throw handleException(e);
+ 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);
+ if (adminSettings.getKey().equals("mail")) {
+ ((ObjectNode) adminSettings.getJsonValue()).remove("password");
}
+ return adminSettings;
}
-
@ApiOperation(value = "Get the Administration Settings object using key (getAdminSettings)",
notes = "Creates or Updates the Administration Settings. Platform generates random Administration Settings Id during settings creation. " +
"The Administration Settings Id will be present in the response. Specify the Administration Settings Id when you would like to update the Administration Settings. " +
@@ -120,20 +116,16 @@ public class AdminController extends BaseController {
public AdminSettings saveAdminSettings(
@ApiParam(value = "A JSON value representing the Administration Settings.")
@RequestBody AdminSettings adminSettings) throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE);
- adminSettings.setTenantId(getTenantId());
- adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings));
- if (adminSettings.getKey().equals("mail")) {
- mailService.updateMailConfiguration();
- ((ObjectNode) adminSettings.getJsonValue()).remove("password");
- } else if (adminSettings.getKey().equals("sms")) {
- smsService.updateSmsConfiguration();
- }
- return adminSettings;
- } catch (Exception e) {
- throw handleException(e);
+ accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE);
+ adminSettings.setTenantId(getTenantId());
+ adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings));
+ if (adminSettings.getKey().equals("mail")) {
+ mailService.updateMailConfiguration();
+ ((ObjectNode) adminSettings.getJsonValue()).remove("password");
+ } else if (adminSettings.getKey().equals("sms")) {
+ smsService.updateSmsConfiguration();
}
+ return adminSettings;
}
@ApiOperation(value = "Get the Security Settings object",
@@ -142,12 +134,8 @@ public class AdminController extends BaseController {
@RequestMapping(value = "/securitySettings", method = RequestMethod.GET)
@ResponseBody
public SecuritySettings getSecuritySettings() throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
- return checkNotNull(systemSecurityService.getSecuritySettings(TenantId.SYS_TENANT_ID));
- } catch (Exception e) {
- throw handleException(e);
- }
+ accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
+ return checkNotNull(systemSecurityService.getSecuritySettings(TenantId.SYS_TENANT_ID));
}
@ApiOperation(value = "Update Security Settings (saveSecuritySettings)",
@@ -158,13 +146,9 @@ public class AdminController extends BaseController {
public SecuritySettings saveSecuritySettings(
@ApiParam(value = "A JSON value representing the Security Settings.")
@RequestBody SecuritySettings securitySettings) throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE);
- securitySettings = checkNotNull(systemSecurityService.saveSecuritySettings(TenantId.SYS_TENANT_ID, securitySettings));
- return securitySettings;
- } catch (Exception e) {
- throw handleException(e);
- }
+ accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE);
+ securitySettings = checkNotNull(systemSecurityService.saveSecuritySettings(TenantId.SYS_TENANT_ID, securitySettings));
+ return securitySettings;
}
@ApiOperation(value = "Get the JWT Settings object (getJwtSettings)",
@@ -174,12 +158,8 @@ public class AdminController extends BaseController {
@RequestMapping(value = "/jwtSettings", method = RequestMethod.GET)
@ResponseBody
public JwtSettings getJwtSettings() throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
- return checkNotNull(jwtSettingsService.getJwtSettings());
- } catch (Exception e) {
- throw handleException(e);
- }
+ accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
+ return checkNotNull(jwtSettingsService.getJwtSettings());
}
@ApiOperation(value = "Update JWT Settings (saveJwtSettings)",
@@ -191,14 +171,10 @@ public class AdminController extends BaseController {
public JwtPair saveJwtSettings(
@ApiParam(value = "A JSON value representing the JWT Settings.")
@RequestBody JwtSettings jwtSettings) throws ThingsboardException {
- try {
- SecurityUser securityUser = getCurrentUser();
- accessControlService.checkPermission(securityUser, Resource.ADMIN_SETTINGS, Operation.WRITE);
- checkNotNull(jwtSettingsService.saveJwtSettings(jwtSettings));
- return tokenFactory.createTokenPair(securityUser);
- } catch (Exception e) {
- throw handleException(e);
- }
+ SecurityUser securityUser = getCurrentUser();
+ accessControlService.checkPermission(securityUser, Resource.ADMIN_SETTINGS, Operation.WRITE);
+ checkNotNull(jwtSettingsService.saveJwtSettings(jwtSettings));
+ return tokenFactory.createTokenPair(securityUser);
}
@ApiOperation(value = "Send test email (sendTestMail)",
@@ -209,19 +185,15 @@ public class AdminController extends BaseController {
public void sendTestMail(
@ApiParam(value = "A JSON value representing the Mail Settings.")
@RequestBody AdminSettings adminSettings) throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
- adminSettings = checkNotNull(adminSettings);
- if (adminSettings.getKey().equals("mail")) {
- if (!adminSettings.getJsonValue().has("password")) {
- AdminSettings mailSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"));
- ((ObjectNode) adminSettings.getJsonValue()).put("password", mailSettings.getJsonValue().get("password").asText());
- }
- String email = getCurrentUser().getEmail();
- mailService.sendTestMail(adminSettings.getJsonValue(), email);
+ accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
+ adminSettings = checkNotNull(adminSettings);
+ if (adminSettings.getKey().equals("mail")) {
+ if (!adminSettings.getJsonValue().has("password")) {
+ AdminSettings mailSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"));
+ ((ObjectNode) adminSettings.getJsonValue()).put("password", mailSettings.getJsonValue().get("password").asText());
}
- } catch (Exception e) {
- throw handleException(e);
+ String email = getCurrentUser().getEmail();
+ mailService.sendTestMail(adminSettings.getJsonValue(), email);
}
}
@@ -233,11 +205,14 @@ public class AdminController extends BaseController {
public void sendTestSms(
@ApiParam(value = "A JSON value representing the Test SMS request.")
@RequestBody TestSmsRequest testSmsRequest) throws ThingsboardException {
+ SecurityUser user = getCurrentUser();
+ accessControlService.checkPermission(user, Resource.ADMIN_SETTINGS, Operation.READ);
try {
- accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
smsService.sendTestSms(testSmsRequest);
- } catch (Exception e) {
- throw handleException(e);
+ auditLogService.logEntityAction(user.getTenantId(), user.getCustomerId(), user.getId(), user.getName(), user.getId(), user, ActionType.SMS_SENT, null, testSmsRequest.getNumberTo());
+ } catch (ThingsboardException e) {
+ auditLogService.logEntityAction(user.getTenantId(), user.getCustomerId(), user.getId(), user.getName(), user.getId(), user, ActionType.SMS_SENT, e, testSmsRequest.getNumberTo());
+ throw e;
}
}
@@ -246,16 +221,12 @@ public class AdminController extends BaseController {
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping("/repositorySettings")
public RepositorySettings getRepositorySettings() throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ);
- RepositorySettings versionControlSettings = checkNotNull(versionControlService.getVersionControlSettings(getTenantId()));
- versionControlSettings.setPassword(null);
- versionControlSettings.setPrivateKey(null);
- versionControlSettings.setPrivateKeyPassword(null);
- return versionControlSettings;
- } catch (Exception e) {
- throw handleException(e);
- }
+ accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ);
+ RepositorySettings versionControlSettings = checkNotNull(versionControlService.getVersionControlSettings(getTenantId()));
+ versionControlSettings.setPassword(null);
+ versionControlSettings.setPrivateKey(null);
+ versionControlSettings.setPrivateKeyPassword(null);
+ return versionControlSettings;
}
@ApiOperation(value = "Check repository settings exists (repositorySettingsExists)",
@@ -263,12 +234,8 @@ public class AdminController extends BaseController {
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping("/repositorySettings/exists")
public Boolean repositorySettingsExists() throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ);
- return versionControlService.getVersionControlSettings(getTenantId()) != null;
- } catch (Exception e) {
- throw handleException(e);
- }
+ accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ);
+ return versionControlService.getVersionControlSettings(getTenantId()) != null;
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@@ -309,30 +276,21 @@ public class AdminController extends BaseController {
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/repositorySettings", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK)
- public DeferredResult deleteRepositorySettings() throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.DELETE);
- return wrapFuture(versionControlService.deleteVersionControlSettings(getTenantId()));
- } catch (Exception e) {
- throw handleException(e);
- }
+ public DeferredResult deleteRepositorySettings() throws Exception {
+ accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.DELETE);
+ return wrapFuture(versionControlService.deleteVersionControlSettings(getTenantId()));
}
-
@ApiOperation(value = "Check repository access (checkRepositoryAccess)",
notes = "Attempts to check repository access. " + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/repositorySettings/checkAccess", method = RequestMethod.POST)
public DeferredResult checkRepositoryAccess(
@ApiParam(value = "A JSON value representing the Repository Settings.")
- @RequestBody RepositorySettings settings) throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ);
- settings = checkNotNull(settings);
- return wrapFuture(versionControlService.checkVersionControlAccess(getTenantId(), settings));
- } catch (Exception e) {
- throw handleException(e);
- }
+ @RequestBody RepositorySettings settings) throws Exception {
+ accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ);
+ settings = checkNotNull(settings);
+ return wrapFuture(versionControlService.checkVersionControlAccess(getTenantId(), settings));
}
@ApiOperation(value = "Get auto commit settings (getAutoCommitSettings)",
@@ -340,12 +298,8 @@ public class AdminController extends BaseController {
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping("/autoCommitSettings")
public AutoCommitSettings getAutoCommitSettings() throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ);
- return checkNotNull(autoCommitSettingsService.get(getTenantId()));
- } catch (Exception e) {
- throw handleException(e);
- }
+ accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ);
+ return checkNotNull(autoCommitSettingsService.get(getTenantId()));
}
@ApiOperation(value = "Check auto commit settings exists (autoCommitSettingsExists)",
@@ -353,12 +307,8 @@ public class AdminController extends BaseController {
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping("/autoCommitSettings/exists")
public Boolean autoCommitSettingsExists() throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ);
- return autoCommitSettingsService.get(getTenantId()) != null;
- } catch (Exception e) {
- throw handleException(e);
- }
+ accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ);
+ return autoCommitSettingsService.get(getTenantId()) != null;
}
@ApiOperation(value = "Creates or Updates the auto commit settings (saveAutoCommitSettings)",
@@ -366,6 +316,7 @@ public class AdminController extends BaseController {
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@PostMapping("/autoCommitSettings")
public AutoCommitSettings saveAutoCommitSettings(@RequestBody AutoCommitSettings settings) throws ThingsboardException {
+ settings.values().forEach(config -> VcUtils.checkBranchName(config.getBranch()));
accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.WRITE);
return autoCommitSettingsService.save(getTenantId(), settings);
}
@@ -377,12 +328,8 @@ public class AdminController extends BaseController {
@RequestMapping(value = "/autoCommitSettings", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK)
public void deleteAutoCommitSettings() throws ThingsboardException {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.DELETE);
- autoCommitSettingsService.delete(getTenantId());
- } catch (Exception e) {
- throw handleException(e);
- }
+ accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.DELETE);
+ autoCommitSettingsService.delete(getTenantId());
}
@ApiOperation(value = "Check for new Platform Releases (checkUpdates)",
@@ -392,11 +339,27 @@ public class AdminController extends BaseController {
@RequestMapping(value = "/updates", method = RequestMethod.GET)
@ResponseBody
public UpdateMessage checkUpdates() throws ThingsboardException {
- try {
- return updateService.checkUpdates();
- } catch (Exception e) {
- throw handleException(e);
- }
+ return updateService.checkUpdates();
+ }
+
+ @ApiOperation(value = "Get system info (getSystemInfo)",
+ notes = "Get main information about system. "
+ + SYSTEM_AUTHORITY_PARAGRAPH)
+ @PreAuthorize("hasAuthority('SYS_ADMIN')")
+ @RequestMapping(value = "/systemInfo", method = RequestMethod.GET)
+ @ResponseBody
+ public SystemInfo getSystemInfo() throws ThingsboardException {
+ return systemInfoService.getSystemInfo();
+ }
+
+ @ApiOperation(value = "Get features info (getFeaturesInfo)",
+ notes = "Get information about enabled/disabled features. "
+ + SYSTEM_AUTHORITY_PARAGRAPH)
+ @PreAuthorize("hasAuthority('SYS_ADMIN')")
+ @RequestMapping(value = "/featuresInfo", method = RequestMethod.GET)
+ @ResponseBody
+ public FeaturesInfo getFeaturesInfo() {
+ return systemInfoService.getFeaturesInfo();
}
}
diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java
new file mode 100644
index 0000000000..92b2cb923f
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java
@@ -0,0 +1,124 @@
+/**
+ * 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.controller;
+
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+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;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.thingsboard.server.common.data.alarm.Alarm;
+import org.thingsboard.server.common.data.alarm.AlarmComment;
+import org.thingsboard.server.common.data.alarm.AlarmCommentInfo;
+import org.thingsboard.server.common.data.exception.ThingsboardException;
+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.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;
+import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK;
+
+@RestController
+@TbCoreComponent
+@RequiredArgsConstructor
+@RequestMapping("/api")
+public class AlarmCommentController extends BaseController {
+ public static final String ALARM_ID = "alarmId";
+ public static final String ALARM_COMMENT_ID = "commentId";
+
+ private final TbAlarmCommentService tbAlarmCommentService;
+
+ @ApiOperation(value = "Create or update Alarm Comment ",
+ notes = "Creates or Updates the Alarm Comment. " +
+ "When creating comment, platform generates Alarm Comment Id as " + UUID_WIKI_LINK +
+ "The newly created Alarm Comment id will be present in the response. Specify existing Alarm Comment id to update the alarm. " +
+ "Referencing non-existing Alarm Comment Id will cause 'Not Found' error. " +
+ "\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)
+ @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 {
+ checkParameter(ALARM_ID, strAlarmId);
+ AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
+ Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
+ alarmComment.setAlarmId(alarmId);
+ return tbAlarmCommentService.saveAlarmComment(alarm, alarmComment, getCurrentUser());
+ }
+
+ @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)
+ @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 {
+ checkParameter(ALARM_ID, strAlarmId);
+ AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
+ Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
+
+ AlarmCommentId alarmCommentId = new AlarmCommentId(toUUID(strCommentId));
+ AlarmComment alarmComment = checkAlarmCommentId(alarmCommentId, alarmId);
+ tbAlarmCommentService.deleteAlarmComment(alarm, alarmComment, getCurrentUser());
+ }
+
+ @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)
+ @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)
+ @PathVariable(ALARM_ID) String strAlarmId,
+ @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
+ @RequestParam int pageSize,
+ @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
+ @RequestParam int page,
+ @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_COMMENT_SORT_PROPERTY_ALLOWABLE_VALUES)
+ @RequestParam(required = false) String sortProperty,
+ @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
+ @RequestParam(required = false) String sortOrder
+ ) throws Exception {
+ checkParameter(ALARM_ID, strAlarmId);
+ AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
+ Alarm alarm = checkAlarmId(alarmId, Operation.READ);
+ PageLink pageLink = createPageLink(pageSize, page, null, sortProperty, sortOrder);
+ return checkNotNull(alarmCommentService.findAlarmComments(alarm.getTenantId(), alarmId, pageLink));
+ }
+}
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 858a7ee3c4..44263d19bd 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmQuery;
+import org.thingsboard.server.common.data.alarm.AlarmQueryV2;
import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
@@ -41,6 +42,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.EntityId;
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.queue.util.TbCoreComponent;
@@ -48,9 +50,18 @@ import org.thingsboard.server.service.entitiy.alarm.TbAlarmService;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+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;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE;
@@ -76,9 +87,16 @@ public class AlarmController extends BaseController {
private static final String ALARM_SECURITY_CHECK = "If the user has the authority of 'Tenant Administrator', the server checks that the originator of alarm is owned by the same tenant. " +
"If the user has the authority of 'Customer User', the server checks that the originator of alarm belongs to the customer. ";
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'";
private static final String ALARM_QUERY_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on of next alarm fields: type, severity or status";
private static final String ALARM_QUERY_START_TIME_DESCRIPTION = "The start timestamp in milliseconds of the search time range over the Alarm class field: 'createdTime'.";
private static final String ALARM_QUERY_END_TIME_DESCRIPTION = "The end timestamp in milliseconds of the search time range over the Alarm class field: 'createdTime'.";
@@ -93,12 +111,8 @@ public class AlarmController extends BaseController {
public Alarm getAlarmById(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION)
@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException {
checkParameter(ALARM_ID, strAlarmId);
- try {
- AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
- return checkAlarmId(alarmId, Operation.READ);
- } catch (Exception e) {
- throw handleException(e);
- }
+ AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
+ return checkAlarmId(alarmId, Operation.READ);
}
@ApiOperation(value = "Get Alarm Info (getAlarmInfoById)",
@@ -110,15 +124,11 @@ public class AlarmController extends BaseController {
public AlarmInfo getAlarmInfoById(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION)
@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException {
checkParameter(ALARM_ID, strAlarmId);
- try {
- AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
- return checkAlarmInfoId(alarmId, Operation.READ);
- } catch (Exception e) {
- throw handleException(e);
- }
+ AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
+ return checkAlarmInfoId(alarmId, Operation.READ);
}
- @ApiOperation(value = "Create or update Alarm (saveAlarm)",
+ @ApiOperation(value = "Create or Update Alarm (saveAlarm)",
notes = "Creates or Updates the Alarm. " +
"When creating alarm, platform generates Alarm Id as " + UUID_WIKI_LINK +
"The newly created Alarm id will be present in the response. Specify existing Alarm id to update the alarm. " +
@@ -135,7 +145,12 @@ public class AlarmController extends BaseController {
@ResponseBody
public Alarm saveAlarm(@ApiParam(value = "A JSON value representing the alarm.") @RequestBody Alarm alarm) throws ThingsboardException {
alarm.setTenantId(getTenantId());
+ checkNotNull(alarm.getOriginator());
checkEntity(alarm.getId(), alarm, Resource.ALARM);
+ checkEntityId(alarm.getOriginator(), Operation.READ);
+ if (alarm.getAssigneeId() != null) {
+ checkUserId(alarm.getAssigneeId(), Operation.READ);
+ }
return tbAlarmService.save(alarm, getCurrentUser());
}
@@ -158,11 +173,12 @@ public class AlarmController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
- public void ackAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws Exception {
+ public AlarmInfo ackAlarm(@ApiParam(value = 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);
- tbAlarmService.ack(alarm, getCurrentUser()).get();
+ //TODO: return correct error code if the alarm is not found or already cleared
+ return tbAlarmService.ack(alarm, getCurrentUser());
}
@ApiOperation(value = "Clear Alarm (clearAlarm)",
@@ -172,11 +188,50 @@ public class AlarmController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
- public void clearAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws Exception {
+ public AlarmInfo clearAlarm(@ApiParam(value = 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);
+ //TODO: return correct error code if the alarm is not found or already cleared
+ return tbAlarmService.clear(alarm, getCurrentUser());
+ }
+
+ @ApiOperation(value = "Assign/Reassign Alarm (assignAlarm)",
+ 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)
+ @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)
+ @PathVariable(ALARM_ID) String strAlarmId,
+ @ApiParam(value = ASSIGN_ID_PARAM_DESCRIPTION)
+ @PathVariable(ASSIGNEE_ID) String strAssigneeId
+ ) throws Exception {
+ checkParameter(ALARM_ID, strAlarmId);
+ checkParameter(ASSIGNEE_ID, strAssigneeId);
+ AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
+ Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
+ UserId assigneeId = new UserId(UUID.fromString(strAssigneeId));
+ checkUserId(assigneeId, Operation.READ);
+ return tbAlarmService.assign(alarm, assigneeId, System.currentTimeMillis(), getCurrentUser());
+ }
+
+ @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)
+ @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)
+ @PathVariable(ALARM_ID) String strAlarmId
+ ) throws Exception {
checkParameter(ALARM_ID, strAlarmId);
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
- tbAlarmService.clear(alarm, getCurrentUser()).get();
+ return tbAlarmService.unassign(alarm, System.currentTimeMillis(), getCurrentUser());
}
@ApiOperation(value = "Get Alarms (getAlarms)",
@@ -194,6 +249,8 @@ public class AlarmController extends BaseController {
@RequestParam(required = false) String searchStatus,
@ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)
@RequestParam(required = false) String status,
+ @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION)
+ @RequestParam(required = false) String assigneeId,
@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
@@ -210,7 +267,7 @@ public class AlarmController extends BaseController {
@RequestParam(required = false) Long endTime,
@ApiParam(value = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION)
@RequestParam(required = false) Boolean fetchOriginator
- ) throws ThingsboardException {
+ ) throws ThingsboardException, ExecutionException, InterruptedException {
checkParameter("EntityId", strEntityId);
checkParameter("EntityType", strEntityType);
EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
@@ -221,13 +278,13 @@ public class AlarmController extends BaseController {
"and 'status' can't be specified at the same time!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
}
checkEntityId(entityId, Operation.READ);
+ UserId assigneeUserId = null;
+ if (assigneeId != null) {
+ assigneeUserId = new UserId(UUID.fromString(assigneeId));
+ }
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
- try {
- return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, fetchOriginator)).get());
- } catch (Exception e) {
- throw handleException(e);
- }
+ return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, assigneeUserId, fetchOriginator)).get());
}
@ApiOperation(value = "Get All Alarms (getAllAlarms)",
@@ -244,6 +301,8 @@ public class AlarmController extends BaseController {
@RequestParam(required = false) String searchStatus,
@ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)
@RequestParam(required = false) String status,
+ @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION)
+ @RequestParam(required = false) String assigneeId,
@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
@@ -260,23 +319,149 @@ public class AlarmController extends BaseController {
@RequestParam(required = false) Long endTime,
@ApiParam(value = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION)
@RequestParam(required = false) Boolean fetchOriginator
- ) throws ThingsboardException {
+ ) throws ThingsboardException, ExecutionException, InterruptedException {
AlarmSearchStatus alarmSearchStatus = StringUtils.isEmpty(searchStatus) ? null : AlarmSearchStatus.valueOf(searchStatus);
AlarmStatus alarmStatus = StringUtils.isEmpty(status) ? null : AlarmStatus.valueOf(status);
if (alarmSearchStatus != null && alarmStatus != null) {
throw new ThingsboardException("Invalid alarms search query: Both parameters 'searchStatus' " +
"and 'status' can't be specified at the same time!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
}
+ UserId assigneeUserId = null;
+ if (assigneeId != null) {
+ assigneeUserId = new UserId(UUID.fromString(assigneeId));
+ }
+ TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
+
+ if (getCurrentUser().isCustomerUser()) {
+ return checkNotNull(alarmService.findCustomerAlarms(getCurrentUser().getTenantId(), getCurrentUser().getCustomerId(), new AlarmQuery(null, pageLink, alarmSearchStatus, alarmStatus, assigneeUserId, fetchOriginator)).get());
+ } else {
+ return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(null, pageLink, alarmSearchStatus, alarmStatus, assigneeUserId, fetchOriginator)).get());
+ }
+ }
+
+ @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)
+ @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")
+ @PathVariable(ENTITY_TYPE) String strEntityType,
+ @ApiParam(value = 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)
+ @RequestParam(required = false) String[] statusList,
+ @ApiParam(value = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES)
+ @RequestParam(required = false) String[] severityList,
+ @ApiParam(value = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION)
+ @RequestParam(required = false) String[] typeList,
+ @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION)
+ @RequestParam(required = false) String assigneeId,
+ @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
+ @RequestParam int pageSize,
+ @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
+ @RequestParam int page,
+ @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION)
+ @RequestParam(required = false) String textSearch,
+ @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES)
+ @RequestParam(required = false) String sortProperty,
+ @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
+ @RequestParam(required = false) String sortOrder,
+ @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION)
+ @RequestParam(required = false) Long startTime,
+ @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION)
+ @RequestParam(required = false) Long endTime
+ ) throws ThingsboardException, ExecutionException, InterruptedException {
+ checkParameter("EntityId", strEntityId);
+ checkParameter("EntityType", strEntityType);
+ EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
+ checkEntityId(entityId, Operation.READ);
+ List alarmStatusList = new ArrayList<>();
+ if (statusList != null) {
+ for (String strStatus : statusList) {
+ if (!StringUtils.isEmpty(strStatus)) {
+ alarmStatusList.add(AlarmSearchStatus.valueOf(strStatus));
+ }
+ }
+ }
+ List alarmSeverityList = new ArrayList<>();
+ if (severityList != null) {
+ for (String strSeverity : severityList) {
+ if (!StringUtils.isEmpty(strSeverity)) {
+ alarmSeverityList.add(AlarmSeverity.valueOf(strSeverity));
+ }
+ }
+ }
+ List alarmTypeList = typeList != null ? Arrays.asList(typeList) : Collections.emptyList();
+ UserId assigneeUserId = null;
+ if (assigneeId != null) {
+ assigneeUserId = new UserId(UUID.fromString(assigneeId));
+ }
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
- try {
- if (getCurrentUser().isCustomerUser()) {
- return checkNotNull(alarmService.findCustomerAlarms(getCurrentUser().getTenantId(), getCurrentUser().getCustomerId(), new AlarmQuery(null, pageLink, alarmSearchStatus, alarmStatus, fetchOriginator)).get());
- } else {
- return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(null, pageLink, alarmSearchStatus, alarmStatus, fetchOriginator)).get());
+ return checkNotNull(alarmService.findAlarmsV2(getCurrentUser().getTenantId(), new AlarmQueryV2(entityId, pageLink, alarmTypeList, alarmStatusList, alarmSeverityList, assigneeUserId)).get());
+ }
+
+ @ApiOperation(value = "Get All Alarms (getAllAlarmsV2)",
+ 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)
+ @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)
+ @RequestParam(required = false) String[] statusList,
+ @ApiParam(value = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES)
+ @RequestParam(required = false) String[] severityList,
+ @ApiParam(value = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION)
+ @RequestParam(required = false) String[] typeList,
+ @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION)
+ @RequestParam(required = false) String assigneeId,
+ @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
+ @RequestParam int pageSize,
+ @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
+ @RequestParam int page,
+ @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION)
+ @RequestParam(required = false) String textSearch,
+ @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES)
+ @RequestParam(required = false) String sortProperty,
+ @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
+ @RequestParam(required = false) String sortOrder,
+ @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION)
+ @RequestParam(required = false) Long startTime,
+ @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION)
+ @RequestParam(required = false) Long endTime
+ ) throws ThingsboardException, ExecutionException, InterruptedException {
+ List alarmStatusList = new ArrayList<>();
+ if (statusList != null) {
+ for (String strStatus : statusList) {
+ if (!StringUtils.isEmpty(strStatus)) {
+ alarmStatusList.add(AlarmSearchStatus.valueOf(strStatus));
+ }
}
- } catch (Exception e) {
- throw handleException(e);
+ }
+ List alarmSeverityList = new ArrayList<>();
+ if (severityList != null) {
+ for (String strSeverity : severityList) {
+ if (!StringUtils.isEmpty(strSeverity)) {
+ alarmSeverityList.add(AlarmSeverity.valueOf(strSeverity));
+ }
+ }
+ }
+ List alarmTypeList = typeList != null ? Arrays.asList(typeList) : Collections.emptyList();
+ UserId assigneeUserId = null;
+ if (assigneeId != null) {
+ assigneeUserId = new UserId(UUID.fromString(assigneeId));
+ }
+ TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
+
+ if (getCurrentUser().isCustomerUser()) {
+ return checkNotNull(alarmService.findCustomerAlarmsV2(getCurrentUser().getTenantId(), getCurrentUser().getCustomerId(), new AlarmQueryV2(null, pageLink, alarmTypeList, alarmStatusList, alarmSeverityList, assigneeUserId)).get());
+ } else {
+ return checkNotNull(alarmService.findAlarmsV2(getCurrentUser().getTenantId(), new AlarmQueryV2(null, pageLink, alarmTypeList, alarmStatusList, alarmSeverityList, assigneeUserId)).get());
}
}
@@ -295,7 +480,9 @@ public class AlarmController extends BaseController {
@ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)
@RequestParam(required = false) String searchStatus,
@ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)
- @RequestParam(required = false) String status
+ @RequestParam(required = false) String status,
+ @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION)
+ @RequestParam(required = false) String assigneeId
) throws ThingsboardException {
checkParameter("EntityId", strEntityId);
checkParameter("EntityType", strEntityType);
@@ -307,11 +494,8 @@ public class AlarmController extends BaseController {
"and 'status' can't be specified at the same time!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
}
checkEntityId(entityId, Operation.READ);
- try {
- return alarmService.findHighestAlarmSeverity(getCurrentUser().getTenantId(), entityId, alarmSearchStatus, alarmStatus);
- } catch (Exception e) {
- throw handleException(e);
- }
+ return alarmService.findHighestAlarmSeverity(getCurrentUser().getTenantId(), entityId, alarmSearchStatus,
+ alarmStatus, assigneeId);
}
}
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 968829b65a..510fefe305 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -60,6 +60,7 @@ import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import static org.thingsboard.server.controller.ControllerConstants.ASSET_ID_PARAM_DESCRIPTION;
@@ -108,12 +109,8 @@ public class AssetController extends BaseController {
public Asset getAssetById(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION)
@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
checkParameter(ASSET_ID, strAssetId);
- try {
- AssetId assetId = new AssetId(toUUID(strAssetId));
- return checkAssetId(assetId, Operation.READ);
- } catch (Exception e) {
- throw handleException(e);
- }
+ AssetId assetId = new AssetId(toUUID(strAssetId));
+ return checkAssetId(assetId, Operation.READ);
}
@ApiOperation(value = "Get Asset Info (getAssetInfoById)",
@@ -127,12 +124,8 @@ public class AssetController extends BaseController {
public AssetInfo getAssetInfoById(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION)
@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
checkParameter(ASSET_ID, strAssetId);
- try {
- AssetId assetId = new AssetId(toUUID(strAssetId));
- return checkAssetInfoId(assetId, Operation.READ);
- } catch (Exception e) {
- throw handleException(e);
- }
+ AssetId assetId = new AssetId(toUUID(strAssetId));
+ return checkAssetInfoId(assetId, Operation.READ);
}
@ApiOperation(value = "Create Or Update Asset (saveAsset)",
@@ -228,16 +221,12 @@ public class AssetController extends BaseController {
@RequestParam(required = false) String sortProperty,
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
- try {
- TenantId tenantId = getCurrentUser().getTenantId();
- PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
- if (type != null && type.trim().length() > 0) {
- return checkNotNull(assetService.findAssetsByTenantIdAndType(tenantId, type, pageLink));
- } else {
- return checkNotNull(assetService.findAssetsByTenantId(tenantId, pageLink));
- }
- } catch (Exception e) {
- throw handleException(e);
+ TenantId tenantId = getCurrentUser().getTenantId();
+ PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
+ if (type != null && type.trim().length() > 0) {
+ return checkNotNull(assetService.findAssetsByTenantIdAndType(tenantId, type, pageLink));
+ } else {
+ return checkNotNull(assetService.findAssetsByTenantId(tenantId, pageLink));
}
}
@@ -262,19 +251,15 @@ public class AssetController extends BaseController {
@RequestParam(required = false) String sortProperty,
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
- try {
- TenantId tenantId = getCurrentUser().getTenantId();
- PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
- if (type != null && type.trim().length() > 0) {
- return checkNotNull(assetService.findAssetInfosByTenantIdAndType(tenantId, type, pageLink));
- } else if (assetProfileId != null && assetProfileId.length() > 0) {
- AssetProfileId profileId = new AssetProfileId(toUUID(assetProfileId));
- return checkNotNull(assetService.findAssetInfosByTenantIdAndAssetProfileId(tenantId, profileId, pageLink));
- } else {
- return checkNotNull(assetService.findAssetInfosByTenantId(tenantId, pageLink));
- }
- } catch (Exception e) {
- throw handleException(e);
+ TenantId tenantId = getCurrentUser().getTenantId();
+ PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
+ if (type != null && type.trim().length() > 0) {
+ return checkNotNull(assetService.findAssetInfosByTenantIdAndType(tenantId, type, pageLink));
+ } else if (assetProfileId != null && assetProfileId.length() > 0) {
+ AssetProfileId profileId = new AssetProfileId(toUUID(assetProfileId));
+ return checkNotNull(assetService.findAssetInfosByTenantIdAndAssetProfileId(tenantId, profileId, pageLink));
+ } else {
+ return checkNotNull(assetService.findAssetInfosByTenantId(tenantId, pageLink));
}
}
@@ -287,12 +272,8 @@ public class AssetController extends BaseController {
public Asset getTenantAsset(
@ApiParam(value = ASSET_NAME_DESCRIPTION)
@RequestParam String assetName) throws ThingsboardException {
- try {
- TenantId tenantId = getCurrentUser().getTenantId();
- return checkNotNull(assetService.findAssetByTenantIdAndName(tenantId, assetName));
- } catch (Exception e) {
- throw handleException(e);
- }
+ TenantId tenantId = getCurrentUser().getTenantId();
+ return checkNotNull(assetService.findAssetByTenantIdAndName(tenantId, assetName));
}
@ApiOperation(value = "Get Customer Assets (getCustomerAssets)",
@@ -317,18 +298,14 @@ public class AssetController extends BaseController {
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
checkParameter("customerId", strCustomerId);
- try {
- TenantId tenantId = getCurrentUser().getTenantId();
- CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- checkCustomerId(customerId, Operation.READ);
- PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
- if (type != null && type.trim().length() > 0) {
- return checkNotNull(assetService.findAssetsByTenantIdAndCustomerIdAndType(tenantId, customerId, type, pageLink));
- } else {
- return checkNotNull(assetService.findAssetsByTenantIdAndCustomerId(tenantId, customerId, pageLink));
- }
- } catch (Exception e) {
- throw handleException(e);
+ TenantId tenantId = getCurrentUser().getTenantId();
+ CustomerId customerId = new CustomerId(toUUID(strCustomerId));
+ checkCustomerId(customerId, Operation.READ);
+ PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
+ if (type != null && type.trim().length() > 0) {
+ return checkNotNull(assetService.findAssetsByTenantIdAndCustomerIdAndType(tenantId, customerId, type, pageLink));
+ } else {
+ return checkNotNull(assetService.findAssetsByTenantIdAndCustomerId(tenantId, customerId, pageLink));
}
}
@@ -356,21 +333,17 @@ public class AssetController extends BaseController {
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
checkParameter("customerId", strCustomerId);
- try {
- TenantId tenantId = getCurrentUser().getTenantId();
- CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- checkCustomerId(customerId, Operation.READ);
- PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
- if (type != null && type.trim().length() > 0) {
- return checkNotNull(assetService.findAssetInfosByTenantIdAndCustomerIdAndType(tenantId, customerId, type, pageLink));
- } else if (assetProfileId != null && assetProfileId.length() > 0) {
- AssetProfileId profileId = new AssetProfileId(toUUID(assetProfileId));
- return checkNotNull(assetService.findAssetInfosByTenantIdAndCustomerIdAndAssetProfileId(tenantId, customerId, profileId, pageLink));
- } else {
- return checkNotNull(assetService.findAssetInfosByTenantIdAndCustomerId(tenantId, customerId, pageLink));
- }
- } catch (Exception e) {
- throw handleException(e);
+ TenantId tenantId = getCurrentUser().getTenantId();
+ CustomerId customerId = new CustomerId(toUUID(strCustomerId));
+ checkCustomerId(customerId, Operation.READ);
+ PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
+ if (type != null && type.trim().length() > 0) {
+ return checkNotNull(assetService.findAssetInfosByTenantIdAndCustomerIdAndType(tenantId, customerId, type, pageLink));
+ } else if (assetProfileId != null && assetProfileId.length() > 0) {
+ AssetProfileId profileId = new AssetProfileId(toUUID(assetProfileId));
+ return checkNotNull(assetService.findAssetInfosByTenantIdAndCustomerIdAndAssetProfileId(tenantId, customerId, profileId, pageLink));
+ } else {
+ return checkNotNull(assetService.findAssetInfosByTenantIdAndCustomerId(tenantId, customerId, pageLink));
}
}
@@ -381,26 +354,22 @@ public class AssetController extends BaseController {
@ResponseBody
public List getAssetsByIds(
@ApiParam(value = "A list of assets ids, separated by comma ','")
- @RequestParam("assetIds") String[] strAssetIds) throws ThingsboardException {
+ @RequestParam("assetIds") String[] strAssetIds) throws ThingsboardException, ExecutionException, InterruptedException {
checkArrayParameter("assetIds", strAssetIds);
- try {
- SecurityUser user = getCurrentUser();
- TenantId tenantId = user.getTenantId();
- CustomerId customerId = user.getCustomerId();
- List assetIds = new ArrayList<>();
- for (String strAssetId : strAssetIds) {
- assetIds.add(new AssetId(toUUID(strAssetId)));
- }
- ListenableFuture> assets;
- if (customerId == null || customerId.isNullUid()) {
- assets = assetService.findAssetsByTenantIdAndIdsAsync(tenantId, assetIds);
- } else {
- assets = assetService.findAssetsByTenantIdCustomerIdAndIdsAsync(tenantId, customerId, assetIds);
- }
- return checkNotNull(assets.get());
- } catch (Exception e) {
- throw handleException(e);
+ SecurityUser user = getCurrentUser();
+ TenantId tenantId = user.getTenantId();
+ CustomerId customerId = user.getCustomerId();
+ List assetIds = new ArrayList<>();
+ for (String strAssetId : strAssetIds) {
+ assetIds.add(new AssetId(toUUID(strAssetId)));
}
+ ListenableFuture> assets;
+ if (customerId == null || customerId.isNullUid()) {
+ assets = assetService.findAssetsByTenantIdAndIdsAsync(tenantId, assetIds);
+ } else {
+ assets = assetService.findAssetsByTenantIdCustomerIdAndIdsAsync(tenantId, customerId, assetIds);
+ }
+ return checkNotNull(assets.get());
}
@ApiOperation(value = "Find related assets (findByQuery)",
@@ -410,25 +379,21 @@ public class AssetController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/assets", method = RequestMethod.POST)
@ResponseBody
- public List findByQuery(@RequestBody AssetSearchQuery query) throws ThingsboardException {
+ public List findByQuery(@RequestBody AssetSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
checkNotNull(query);
checkNotNull(query.getParameters());
checkNotNull(query.getAssetTypes());
checkEntityId(query.getParameters().getEntityId(), Operation.READ);
- try {
- List assets = checkNotNull(assetService.findAssetsByQuery(getTenantId(), query).get());
- assets = assets.stream().filter(asset -> {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.ASSET, Operation.READ, asset.getId(), asset);
- return true;
- } catch (ThingsboardException e) {
- return false;
- }
- }).collect(Collectors.toList());
- return assets;
- } catch (Exception e) {
- throw handleException(e);
- }
+ List assets = checkNotNull(assetService.findAssetsByQuery(getTenantId(), query).get());
+ assets = assets.stream().filter(asset -> {
+ try {
+ accessControlService.checkPermission(getCurrentUser(), Resource.ASSET, Operation.READ, asset.getId(), asset);
+ return true;
+ } catch (ThingsboardException e) {
+ return false;
+ }
+ }).collect(Collectors.toList());
+ return assets;
}
@ApiOperation(value = "Get Asset Types (getAssetTypes)",
@@ -436,15 +401,11 @@ public class AssetController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/asset/types", method = RequestMethod.GET)
@ResponseBody
- public List getAssetTypes() throws ThingsboardException {
- try {
- SecurityUser user = getCurrentUser();
- TenantId tenantId = user.getTenantId();
- ListenableFuture> assetTypes = assetService.findAssetTypesByTenantId(tenantId);
- return checkNotNull(assetTypes.get());
- } catch (Exception e) {
- throw handleException(e);
- }
+ public List getAssetTypes() throws ThingsboardException, ExecutionException, InterruptedException {
+ SecurityUser user = getCurrentUser();
+ TenantId tenantId = user.getTenantId();
+ ListenableFuture> assetTypes = assetService.findAssetTypesByTenantId(tenantId);
+ return checkNotNull(assetTypes.get());
}
@ApiOperation(value = "Assign asset to edge (assignAssetToEdge)",
@@ -520,33 +481,29 @@ public class AssetController extends BaseController {
@ApiParam(value = "Timestamp. Assets with creation time after it won't be queried")
@RequestParam(required = false) Long endTime) throws ThingsboardException {
checkParameter(EDGE_ID, strEdgeId);
- try {
- TenantId tenantId = getCurrentUser().getTenantId();
- EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
- checkEdgeId(edgeId, Operation.READ);
- TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
- PageData nonFilteredResult;
- if (type != null && type.trim().length() > 0) {
- nonFilteredResult = assetService.findAssetsByTenantIdAndEdgeIdAndType(tenantId, edgeId, type, pageLink);
- } else {
- nonFilteredResult = assetService.findAssetsByTenantIdAndEdgeId(tenantId, edgeId, pageLink);
- }
- List filteredAssets = nonFilteredResult.getData().stream().filter(asset -> {
- try {
- accessControlService.checkPermission(getCurrentUser(), Resource.ASSET, Operation.READ, asset.getId(), asset);
- return true;
- } catch (ThingsboardException e) {
- return false;
- }
- }).collect(Collectors.toList());
- PageData filteredResult = new PageData<>(filteredAssets,
- nonFilteredResult.getTotalPages(),
- nonFilteredResult.getTotalElements(),
- nonFilteredResult.hasNext());
- return checkNotNull(filteredResult);
- } catch (Exception e) {
- throw handleException(e);
+ TenantId tenantId = getCurrentUser().getTenantId();
+ EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
+ checkEdgeId(edgeId, Operation.READ);
+ TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
+ PageData nonFilteredResult;
+ if (type != null && type.trim().length() > 0) {
+ nonFilteredResult = assetService.findAssetsByTenantIdAndEdgeIdAndType(tenantId, edgeId, type, pageLink);
+ } else {
+ nonFilteredResult = assetService.findAssetsByTenantIdAndEdgeId(tenantId, edgeId, pageLink);
}
+ List filteredAssets = nonFilteredResult.getData().stream().filter(asset -> {
+ try {
+ accessControlService.checkPermission(getCurrentUser(), Resource.ASSET, Operation.READ, asset.getId(), asset);
+ return true;
+ } catch (ThingsboardException e) {
+ return false;
+ }
+ }).collect(Collectors.toList());
+ PageData filteredResult = new PageData<>(filteredAssets,
+ nonFilteredResult.getTotalPages(),
+ nonFilteredResult.getTotalElements(),
+ nonFilteredResult.hasNext());
+ return checkNotNull(filteredResult);
}
@ApiOperation(value = "Import the bulk of assets (processAssetsBulkImport)",
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 2e84dd6634..47a7eede4b 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -19,7 +19,6 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
@@ -36,7 +35,6 @@ 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.dao.timeseries.TimeseriesService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.asset.profile.TbAssetProfileService;
import org.thingsboard.server.service.security.permission.Operation;
@@ -78,12 +76,8 @@ public class AssetProfileController extends BaseController {
@ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION)
@PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException {
checkParameter(ASSET_PROFILE_ID, strAssetProfileId);
- try {
- AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId));
- return checkAssetProfileId(assetProfileId, Operation.READ);
- } catch (Exception e) {
- throw handleException(e);
- }
+ AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId));
+ return checkAssetProfileId(assetProfileId, Operation.READ);
}
@ApiOperation(value = "Get Asset Profile Info (getAssetProfileInfoById)",
@@ -97,12 +91,8 @@ public class AssetProfileController extends BaseController {
@ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION)
@PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException {
checkParameter(ASSET_PROFILE_ID, strAssetProfileId);
- try {
- AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId));
- return new AssetProfileInfo(checkAssetProfileId(assetProfileId, Operation.READ));
- } catch (Exception e) {
- throw handleException(e);
- }
+ AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId));
+ return new AssetProfileInfo(checkAssetProfileId(assetProfileId, Operation.READ));
}
@ApiOperation(value = "Get Default Asset Profile (getDefaultAssetProfileInfo)",
@@ -113,11 +103,7 @@ public class AssetProfileController extends BaseController {
@RequestMapping(value = "/assetProfileInfo/default", method = RequestMethod.GET)
@ResponseBody
public AssetProfileInfo getDefaultAssetProfileInfo() throws ThingsboardException {
- try {
- return checkNotNull(assetProfileService.findDefaultAssetProfileInfo(getTenantId()));
- } catch (Exception e) {
- throw handleException(e);
- }
+ return checkNotNull(assetProfileService.findDefaultAssetProfileInfo(getTenantId()));
}
@ApiOperation(value = "Create Or Update Asset Profile (saveAssetProfile)",
@@ -191,12 +177,8 @@ public class AssetProfileController extends BaseController {
@RequestParam(required = false) String sortProperty,
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
- try {
- PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
- return checkNotNull(assetProfileService.findAssetProfiles(getTenantId(), pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
+ PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
+ return checkNotNull(assetProfileService.findAssetProfiles(getTenantId(), pageLink));
}
@ApiOperation(value = "Get Asset Profile infos (getAssetProfileInfos)",
@@ -217,11 +199,7 @@ public class AssetProfileController extends BaseController {
@RequestParam(required = false) String sortProperty,
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
- try {
- PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
- return checkNotNull(assetProfileService.findAssetProfileInfos(getTenantId(), pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
+ 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 33792a703f..387f0d014b 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -97,15 +97,11 @@ public class AuditLogController extends BaseController {
@RequestParam(required = false) Long endTime,
@ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION)
@RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException {
- try {
- checkParameter("CustomerId", strCustomerId);
- TenantId tenantId = getCurrentUser().getTenantId();
- TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
- List actionTypes = parseActionTypesStr(actionTypesStr);
- return checkNotNull(auditLogService.findAuditLogsByTenantIdAndCustomerId(tenantId, new CustomerId(UUID.fromString(strCustomerId)), actionTypes, pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
+ checkParameter("CustomerId", strCustomerId);
+ TenantId tenantId = getCurrentUser().getTenantId();
+ TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
+ List actionTypes = parseActionTypesStr(actionTypesStr);
+ return checkNotNull(auditLogService.findAuditLogsByTenantIdAndCustomerId(tenantId, new CustomerId(UUID.fromString(strCustomerId)), actionTypes, pageLink));
}
@ApiOperation(value = "Get audit logs by user id (getAuditLogsByUserId)",
@@ -135,15 +131,11 @@ public class AuditLogController extends BaseController {
@RequestParam(required = false) Long endTime,
@ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION)
@RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException {
- try {
- checkParameter("UserId", strUserId);
- TenantId tenantId = getCurrentUser().getTenantId();
- TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
- List actionTypes = parseActionTypesStr(actionTypesStr);
- return checkNotNull(auditLogService.findAuditLogsByTenantIdAndUserId(tenantId, new UserId(UUID.fromString(strUserId)), actionTypes, pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
+ checkParameter("UserId", strUserId);
+ TenantId tenantId = getCurrentUser().getTenantId();
+ TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
+ List actionTypes = parseActionTypesStr(actionTypesStr);
+ return checkNotNull(auditLogService.findAuditLogsByTenantIdAndUserId(tenantId, new UserId(UUID.fromString(strUserId)), actionTypes, pageLink));
}
@ApiOperation(value = "Get audit logs by entity id (getAuditLogsByEntityId)",
@@ -176,16 +168,12 @@ public class AuditLogController extends BaseController {
@RequestParam(required = false) Long endTime,
@ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION)
@RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException {
- try {
- checkParameter("EntityId", strEntityId);
- checkParameter("EntityType", strEntityType);
- TenantId tenantId = getCurrentUser().getTenantId();
- TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
- List actionTypes = parseActionTypesStr(actionTypesStr);
- return checkNotNull(auditLogService.findAuditLogsByTenantIdAndEntityId(tenantId, EntityIdFactory.getByTypeAndId(strEntityType, strEntityId), actionTypes, pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
+ checkParameter("EntityId", strEntityId);
+ checkParameter("EntityType", strEntityType);
+ TenantId tenantId = getCurrentUser().getTenantId();
+ TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
+ List actionTypes = parseActionTypesStr(actionTypesStr);
+ return checkNotNull(auditLogService.findAuditLogsByTenantIdAndEntityId(tenantId, EntityIdFactory.getByTypeAndId(strEntityType, strEntityId), actionTypes, pageLink));
}
@ApiOperation(value = "Get all audit logs (getAuditLogs)",
@@ -212,14 +200,10 @@ public class AuditLogController extends BaseController {
@RequestParam(required = false) Long endTime,
@ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION)
@RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException {
- try {
- TenantId tenantId = getCurrentUser().getTenantId();
- List actionTypes = parseActionTypesStr(actionTypesStr);
- TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
- return checkNotNull(auditLogService.findAuditLogsByTenantId(tenantId, actionTypes, pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
+ TenantId tenantId = getCurrentUser().getTenantId();
+ List actionTypes = parseActionTypesStr(actionTypesStr);
+ TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
+ return checkNotNull(auditLogService.findAuditLogsByTenantId(tenantId, actionTypes, pageLink));
}
private List parseActionTypesStr(String 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 0cb3a3fc92..566b6900a4 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -20,6 +20,7 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@@ -44,14 +45,15 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent;
import org.thingsboard.server.common.data.security.event.UserSessionInvalidationEvent;
+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.dao.audit.AuditLogService;
import org.thingsboard.server.queue.util.TbCoreComponent;
+import org.thingsboard.server.dao.util.limits.LimitedApi;
+import org.thingsboard.server.dao.util.limits.RateLimitService;
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;
-import org.thingsboard.server.common.data.security.model.JwtPair;
import org.thingsboard.server.service.security.model.ResetPasswordEmailRequest;
import org.thingsboard.server.service.security.model.ResetPasswordRequest;
import org.thingsboard.server.service.security.model.SecurityUser;
@@ -69,11 +71,14 @@ import java.net.URISyntaxException;
@Slf4j
@RequiredArgsConstructor
public class AuthController extends BaseController {
+
+ @Value("${server.rest.rate_limits.reset_password_per_user:5:3600}")
+ private String defaultLimitsConfiguration;
private final BCryptPasswordEncoder passwordEncoder;
private final JwtTokenFactory tokenFactory;
private final MailService mailService;
private final SystemSecurityService systemSecurityService;
- private final AuditLogService auditLogService;
+ private final RateLimitService rateLimitService;
private final ApplicationEventPublisher eventPublisher;
@@ -83,12 +88,8 @@ public class AuthController extends BaseController {
@RequestMapping(value = "/auth/user", method = RequestMethod.GET)
public @ResponseBody
User getUser() throws ThingsboardException {
- try {
- SecurityUser securityUser = getCurrentUser();
- return userService.findUserById(securityUser.getTenantId(), securityUser.getId());
- } catch (Exception e) {
- throw handleException(e);
- }
+ SecurityUser securityUser = getCurrentUser();
+ return userService.findUserById(securityUser.getTenantId(), securityUser.getId());
}
@ApiOperation(value = "Logout (logout)",
@@ -108,31 +109,27 @@ public class AuthController extends BaseController {
public ObjectNode changePassword(
@ApiParam(value = "Change Password Request")
@RequestBody ChangePasswordRequest changePasswordRequest) throws ThingsboardException {
- try {
- String currentPassword = changePasswordRequest.getCurrentPassword();
- String newPassword = changePasswordRequest.getNewPassword();
- SecurityUser securityUser = getCurrentUser();
- UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, securityUser.getId());
- if (!passwordEncoder.matches(currentPassword, userCredentials.getPassword())) {
- throw new ThingsboardException("Current password doesn't match!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
- }
- systemSecurityService.validatePassword(securityUser.getTenantId(), newPassword, userCredentials);
- if (passwordEncoder.matches(newPassword, userCredentials.getPassword())) {
- throw new ThingsboardException("New password should be different from existing!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
- }
- userCredentials.setPassword(passwordEncoder.encode(newPassword));
- userService.replaceUserCredentials(securityUser.getTenantId(), userCredentials);
+ String currentPassword = changePasswordRequest.getCurrentPassword();
+ String newPassword = changePasswordRequest.getNewPassword();
+ SecurityUser securityUser = getCurrentUser();
+ UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, securityUser.getId());
+ if (!passwordEncoder.matches(currentPassword, userCredentials.getPassword())) {
+ throw new ThingsboardException("Current password doesn't match!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
+ }
+ systemSecurityService.validatePassword(securityUser.getTenantId(), newPassword, userCredentials);
+ if (passwordEncoder.matches(newPassword, userCredentials.getPassword())) {
+ throw new ThingsboardException("New password should be different from existing!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
+ }
+ userCredentials.setPassword(passwordEncoder.encode(newPassword));
+ userService.replaceUserCredentials(securityUser.getTenantId(), userCredentials);
- sendEntityNotificationMsg(getTenantId(), userCredentials.getUserId(), EdgeEventActionType.CREDENTIALS_UPDATED);
+ sendEntityNotificationMsg(getTenantId(), userCredentials.getUserId(), EdgeEventActionType.CREDENTIALS_UPDATED);
- eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(securityUser.getId()));
- ObjectNode response = JacksonUtil.newObjectNode();
- response.put("token", tokenFactory.createAccessJwtToken(securityUser).getToken());
- response.put("refreshToken", tokenFactory.createRefreshToken(securityUser).getToken());
- return response;
- } catch (Exception e) {
- throw handleException(e);
- }
+ eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(securityUser.getId()));
+ ObjectNode response = JacksonUtil.newObjectNode();
+ response.put("token", tokenFactory.createAccessJwtToken(securityUser).getToken());
+ response.put("refreshToken", tokenFactory.createRefreshToken(securityUser).getToken());
+ return response;
}
@ApiOperation(value = "Get the current User password policy (getUserPasswordPolicy)",
@@ -140,13 +137,9 @@ public class AuthController extends BaseController {
@RequestMapping(value = "/noauth/userPasswordPolicy", method = RequestMethod.GET)
@ResponseBody
public UserPasswordPolicy getUserPasswordPolicy() throws ThingsboardException {
- try {
- SecuritySettings securitySettings =
- checkNotNull(systemSecurityService.getSecuritySettings(TenantId.SYS_TENANT_ID));
- return securitySettings.getPasswordPolicy();
- } catch (Exception e) {
- throw handleException(e);
- }
+ SecuritySettings securitySettings =
+ checkNotNull(systemSecurityService.getSecuritySettings(TenantId.SYS_TENANT_ID));
+ return securitySettings.getPasswordPolicy();
}
@ApiOperation(value = "Check Activate User Token (checkActivateToken)",
@@ -211,7 +204,11 @@ public class AuthController extends BaseController {
HttpStatus responseStatus;
String resetURI = "/login/resetPassword";
UserCredentials userCredentials = userService.findUserCredentialsByResetToken(TenantId.SYS_TENANT_ID, resetToken);
+
if (userCredentials != null) {
+ if (!rateLimitService.checkRateLimit(LimitedApi.PASSWORD_RESET, userCredentials.getUserId(), defaultLimitsConfiguration)) {
+ return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).build();
+ }
try {
URI location = new URI(resetURI + "?resetToken=" + resetToken);
headers.setLocation(location);
@@ -241,34 +238,30 @@ public class AuthController extends BaseController {
@RequestBody ActivateUserRequest activateRequest,
@RequestParam(required = false, defaultValue = "true") boolean sendActivationMail,
HttpServletRequest request) throws ThingsboardException {
- try {
- String activateToken = activateRequest.getActivateToken();
- String password = activateRequest.getPassword();
- systemSecurityService.validatePassword(TenantId.SYS_TENANT_ID, password, null);
- String encodedPassword = passwordEncoder.encode(password);
- UserCredentials credentials = userService.activateUserCredentials(TenantId.SYS_TENANT_ID, activateToken, encodedPassword);
- User user = userService.findUserById(TenantId.SYS_TENANT_ID, credentials.getUserId());
- UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail());
- SecurityUser securityUser = new SecurityUser(user, credentials.isEnabled(), principal);
- userService.setUserCredentialsEnabled(user.getTenantId(), user.getId(), true);
- String baseUrl = systemSecurityService.getBaseUrl(user.getTenantId(), user.getCustomerId(), request);
- String loginUrl = String.format("%s/login", baseUrl);
- String email = user.getEmail();
+ String activateToken = activateRequest.getActivateToken();
+ String password = activateRequest.getPassword();
+ systemSecurityService.validatePassword(TenantId.SYS_TENANT_ID, password, null);
+ String encodedPassword = passwordEncoder.encode(password);
+ UserCredentials credentials = userService.activateUserCredentials(TenantId.SYS_TENANT_ID, activateToken, encodedPassword);
+ User user = userService.findUserById(TenantId.SYS_TENANT_ID, credentials.getUserId());
+ UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail());
+ SecurityUser securityUser = new SecurityUser(user, credentials.isEnabled(), principal);
+ userService.setUserCredentialsEnabled(user.getTenantId(), user.getId(), true);
+ String baseUrl = systemSecurityService.getBaseUrl(user.getTenantId(), user.getCustomerId(), request);
+ String loginUrl = String.format("%s/login", baseUrl);
+ String email = user.getEmail();
- if (sendActivationMail) {
- try {
- mailService.sendAccountActivatedEmail(loginUrl, email);
- } catch (Exception e) {
- log.info("Unable to send account activation email [{}]", e.getMessage());
- }
+ if (sendActivationMail) {
+ try {
+ mailService.sendAccountActivatedEmail(loginUrl, email);
+ } catch (Exception e) {
+ log.info("Unable to send account activation email [{}]", e.getMessage());
}
+ }
- sendEntityNotificationMsg(user.getTenantId(), user.getId(), EdgeEventActionType.CREDENTIALS_UPDATED);
+ sendEntityNotificationMsg(user.getTenantId(), user.getId(), EdgeEventActionType.CREDENTIALS_UPDATED);
- return tokenFactory.createTokenPair(securityUser);
- } catch (Exception e) {
- throw handleException(e);
- }
+ return tokenFactory.createTokenPair(securityUser);
}
@ApiOperation(value = "Reset password (resetPassword)",
@@ -282,45 +275,38 @@ public class AuthController extends BaseController {
@ApiParam(value = "Reset password request.")
@RequestBody ResetPasswordRequest resetPasswordRequest,
HttpServletRequest request) throws ThingsboardException {
- try {
- String resetToken = resetPasswordRequest.getResetToken();
- String password = resetPasswordRequest.getPassword();
- UserCredentials userCredentials = userService.findUserCredentialsByResetToken(TenantId.SYS_TENANT_ID, resetToken);
- if (userCredentials != null) {
- systemSecurityService.validatePassword(TenantId.SYS_TENANT_ID, password, userCredentials);
- if (passwordEncoder.matches(password, userCredentials.getPassword())) {
- throw new ThingsboardException("New password should be different from existing!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
- }
- String encodedPassword = passwordEncoder.encode(password);
- userCredentials.setPassword(encodedPassword);
- userCredentials.setResetToken(null);
- userCredentials = userService.replaceUserCredentials(TenantId.SYS_TENANT_ID, userCredentials);
- User user = userService.findUserById(TenantId.SYS_TENANT_ID, userCredentials.getUserId());
- UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail());
- SecurityUser securityUser = new SecurityUser(user, userCredentials.isEnabled(), principal);
- String baseUrl = systemSecurityService.getBaseUrl(user.getTenantId(), user.getCustomerId(), request);
- String loginUrl = String.format("%s/login", baseUrl);
- String email = user.getEmail();
- mailService.sendPasswordWasResetEmail(loginUrl, email);
+ String resetToken = resetPasswordRequest.getResetToken();
+ String password = resetPasswordRequest.getPassword();
+ UserCredentials userCredentials = userService.findUserCredentialsByResetToken(TenantId.SYS_TENANT_ID, resetToken);
+ if (userCredentials != null) {
+ systemSecurityService.validatePassword(TenantId.SYS_TENANT_ID, password, userCredentials);
+ if (passwordEncoder.matches(password, userCredentials.getPassword())) {
+ throw new ThingsboardException("New password should be different from existing!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
+ }
+ String encodedPassword = passwordEncoder.encode(password);
+ userCredentials.setPassword(encodedPassword);
+ userCredentials.setResetToken(null);
+ userCredentials = userService.replaceUserCredentials(TenantId.SYS_TENANT_ID, userCredentials);
+ User user = userService.findUserById(TenantId.SYS_TENANT_ID, userCredentials.getUserId());
+ UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail());
+ SecurityUser securityUser = new SecurityUser(user, userCredentials.isEnabled(), principal);
+ String baseUrl = systemSecurityService.getBaseUrl(user.getTenantId(), user.getCustomerId(), request);
+ String loginUrl = String.format("%s/login", baseUrl);
+ String email = user.getEmail();
+ mailService.sendPasswordWasResetEmail(loginUrl, email);
- eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(securityUser.getId()));
+ eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(securityUser.getId()));
- return tokenFactory.createTokenPair(securityUser);
- } else {
- throw new ThingsboardException("Invalid reset token!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
- }
- } catch (Exception e) {
- throw handleException(e);
+ return tokenFactory.createTokenPair(securityUser);
+ } else {
+ throw new ThingsboardException("Invalid reset token!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
}
}
private void logLogoutAction(HttpServletRequest request) throws ThingsboardException {
- try {
- var user = getCurrentUser();
- systemSecurityService.logLoginAction(user, new RestAuthenticationDetails(request), ActionType.LOGOUT, null);
- eventPublisher.publishEvent(new UserSessionInvalidationEvent(user.getSessionId()));
- } catch (Exception e) {
- throw handleException(e);
- }
+ var user = getCurrentUser();
+ systemSecurityService.logLoginAction(user, new RestAuthenticationDetails(request), ActionType.LOGOUT, null);
+ eventPublisher.publishEvent(new UserSessionInvalidationEvent(user.getSessionId()));
}
+
}
diff --git a/application/src/main/java/org/thingsboard/server/controller/AutoCommitController.java b/application/src/main/java/org/thingsboard/server/controller/AutoCommitController.java
index 1a097e6817..1e7f3d66ce 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AutoCommitController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AutoCommitController.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
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 ffc3fcf3cd..68a987a0bc 100644
--- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java
@@ -1,5 +1,5 @@
/**
- * Copyright © 2016-2022 The Thingsboard Authors
+ * 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.
@@ -15,7 +15,6 @@
*/
package org.thingsboard.server.controller;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
@@ -25,7 +24,6 @@ import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -43,6 +41,7 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.EntityViewInfo;
+import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.OtaPackage;
import org.thingsboard.server.common.data.OtaPackageInfo;
@@ -54,16 +53,19 @@ import org.thingsboard.server.common.data.TenantInfo;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm;
+import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetInfo;
import org.thingsboard.server.common.data.asset.AssetProfile;
+import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
+import org.thingsboard.server.common.data.id.AlarmCommentId;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.AssetProfileId;
@@ -75,6 +77,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.EntityViewId;
+import org.thingsboard.server.common.data.id.HasId;
import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.QueueId;
import org.thingsboard.server.common.data.id.RpcId;
@@ -83,6 +86,7 @@ import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TbResourceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
+import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
@@ -91,13 +95,17 @@ import org.thingsboard.server.common.data.page.SortOrder;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
+import org.thingsboard.server.common.data.query.EntityDataSortOrder;
+import org.thingsboard.server.common.data.query.EntityKey;
import org.thingsboard.server.common.data.queue.Queue;
import org.thingsboard.server.common.data.rpc.Rpc;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.rule.RuleNode;
+import org.thingsboard.server.common.data.util.ThrowingBiFunction;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
+import org.thingsboard.server.dao.alarm.AlarmCommentService;
import org.thingsboard.server.dao.asset.AssetProfileService;
import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService;
@@ -120,6 +128,8 @@ import org.thingsboard.server.dao.queue.QueueService;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.rpc.RpcService;
import org.thingsboard.server.dao.rule.RuleChainService;
+import org.thingsboard.server.dao.service.ConstraintValidator;
+import org.thingsboard.server.dao.service.Validator;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.dao.tenant.TenantProfileService;
import org.thingsboard.server.dao.tenant.TenantService;
@@ -130,10 +140,12 @@ import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.TbCoreComponent;
+import org.thingsboard.server.service.action.EntityActionService;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
-import org.thingsboard.server.service.edge.EdgeNotificationService;
+import org.thingsboard.server.service.edge.instructions.EdgeInstallService;
import org.thingsboard.server.service.edge.rpc.EdgeRpcService;
import org.thingsboard.server.service.entitiy.TbNotificationEntityService;
+import org.thingsboard.server.service.entitiy.user.TbUserSettingsService;
import org.thingsboard.server.service.ota.OtaPackageStateService;
import org.thingsboard.server.service.profile.TbAssetProfileCache;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
@@ -143,19 +155,26 @@ 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 org.thingsboard.server.service.state.DeviceStateService;
+import org.thingsboard.server.service.sync.ie.exporting.ExportableEntitiesService;
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 java.util.List;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
import java.util.stream.Collectors;
-import static org.thingsboard.server.controller.ControllerConstants.INCORRECT_TENANT_ID;
+import static org.thingsboard.server.common.data.StringUtils.isNotEmpty;
+import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD;
import static org.thingsboard.server.controller.UserController.YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION;
import static org.thingsboard.server.dao.service.Validator.validateId;
@@ -165,8 +184,6 @@ public abstract class BaseController {
/*Swagger UI description*/
- private static final ObjectMapper json = new ObjectMapper();
-
@Autowired
private ThingsboardErrorResponseHandler errorResponseHandler;
@@ -185,6 +202,9 @@ public abstract class BaseController {
@Autowired
protected UserService userService;
+ @Autowired
+ protected TbUserSettingsService userSettingsService;
+
@Autowired
protected DeviceService deviceService;
@@ -200,6 +220,9 @@ public abstract class BaseController {
@Autowired
protected AlarmSubscriptionService alarmService;
+ @Autowired
+ protected AlarmCommentService alarmCommentService;
+
@Autowired
protected DeviceCredentialsService deviceCredentialsService;
@@ -281,15 +304,24 @@ public abstract class BaseController {
@Autowired(required = false)
protected EdgeRpcService edgeRpcService;
+ @Autowired(required = false)
+ protected EdgeInstallService edgeInstallService;
+
@Autowired
protected TbNotificationEntityService notificationEntityService;
+ @Autowired
+ protected EntityActionService entityActionService;
+
@Autowired
protected QueueService queueService;
@Autowired
protected EntitiesVersionControlService vcService;
+ @Autowired
+ protected ExportableEntitiesService entitiesService;
+
@Value("${server.log_controller_error_stack_trace}")
@Getter
private boolean logControllerErrorStackTrace;
@@ -361,12 +393,21 @@ public abstract class BaseController {
* Handles validation error for controller method arguments annotated with @{@link javax.validation.Valid}
* */
@ExceptionHandler(MethodArgumentNotValidException.class)
- public void handleValidationError(MethodArgumentNotValidException e, HttpServletResponse response) {
- String errorMessage = "Validation error: " + e.getBindingResult().getAllErrors().stream()
- .map(DefaultMessageSourceResolvable::getDefaultMessage)
- .collect(Collectors.joining(", "));
+ public void handleValidationError(MethodArgumentNotValidException validationError, HttpServletResponse response) {
+ List> constraintsViolations = validationError.getFieldErrors().stream()
+ .map(fieldError -> {
+ try {
+ return (ConstraintViolation