Commit 957a0c9e6136cf567f4ce4d16e7b2de146db5f57

Authored by Igor Kulikov
2 parents d21752e3 188c3e5b

Merge with master

Showing 100 changed files with 896 additions and 614 deletions

Too many changes to show.

To preserve performance only 100 of 120 files are displayed.

@@ -14,33 +14,27 @@ @@ -14,33 +14,27 @@
14 -- limitations under the License. 14 -- limitations under the License.
15 -- 15 --
16 16
17 --- select check_version(); 17 +-- call check_version();
18 18
19 -CREATE OR REPLACE FUNCTION check_version() RETURNS boolean AS $$ 19 +CREATE OR REPLACE PROCEDURE check_version(INOUT valid_version boolean) LANGUAGE plpgsql AS $BODY$
20 DECLARE 20 DECLARE
21 current_version integer; 21 current_version integer;
22 - valid_version boolean;  
23 BEGIN 22 BEGIN
24 RAISE NOTICE 'Check the current installed PostgreSQL version...'; 23 RAISE NOTICE 'Check the current installed PostgreSQL version...';
25 SELECT current_setting('server_version_num') INTO current_version; 24 SELECT current_setting('server_version_num') INTO current_version;
26 - IF current_version < 100000 THEN  
27 - valid_version := FALSE;  
28 - ELSE  
29 - valid_version := TRUE;  
30 - END IF;  
31 - IF valid_version = FALSE THEN  
32 - RAISE NOTICE 'Postgres version should be at least more than 10!';  
33 - ELSE 25 + IF current_version > 110000 THEN
34 RAISE NOTICE 'PostgreSQL version is valid!'; 26 RAISE NOTICE 'PostgreSQL version is valid!';
35 RAISE NOTICE 'Schema update started...'; 27 RAISE NOTICE 'Schema update started...';
  28 + SELECT true INTO valid_version;
  29 + ELSE
  30 + RAISE NOTICE 'Postgres version should be at least more than 10!';
36 END IF; 31 END IF;
37 - RETURN valid_version;  
38 END; 32 END;
39 -$$ LANGUAGE 'plpgsql'; 33 +$BODY$;
40 34
41 --- select create_partition_ts_kv_table(); 35 +-- call create_partition_ts_kv_table();
42 36
43 -CREATE OR REPLACE FUNCTION create_partition_ts_kv_table() RETURNS VOID AS $$ 37 +CREATE OR REPLACE PROCEDURE create_partition_ts_kv_table() LANGUAGE plpgsql AS $$
44 38
45 BEGIN 39 BEGIN
46 ALTER TABLE ts_kv 40 ALTER TABLE ts_kv
@@ -57,11 +51,11 @@ BEGIN @@ -57,11 +51,11 @@ BEGIN
57 ALTER TABLE ts_kv 51 ALTER TABLE ts_kv
58 ALTER COLUMN key TYPE integer USING key::integer; 52 ALTER COLUMN key TYPE integer USING key::integer;
59 END; 53 END;
60 -$$ LANGUAGE 'plpgsql'; 54 +$$;
61 55
62 --- select create_new_ts_kv_latest_table(); 56 +-- call create_new_ts_kv_latest_table();
63 57
64 -CREATE OR REPLACE FUNCTION create_new_ts_kv_latest_table() RETURNS VOID AS $$ 58 +CREATE OR REPLACE PROCEDURE create_new_ts_kv_latest_table() LANGUAGE plpgsql AS $$
65 59
66 BEGIN 60 BEGIN
67 ALTER TABLE ts_kv_latest 61 ALTER TABLE ts_kv_latest
@@ -81,13 +75,13 @@ BEGIN @@ -81,13 +75,13 @@ BEGIN
81 ALTER TABLE ts_kv_latest 75 ALTER TABLE ts_kv_latest
82 ADD CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key); 76 ADD CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key);
83 END; 77 END;
84 -$$ LANGUAGE 'plpgsql'; 78 +$$;
85 79
86 80
87 --- select create_partitions(); 81 +-- call create_partitions();
  82 +
  83 +CREATE OR REPLACE PROCEDURE create_partitions() LANGUAGE plpgsql AS $$
88 84
89 -CREATE OR REPLACE FUNCTION create_partitions() RETURNS VOID AS  
90 -$$  
91 DECLARE 85 DECLARE
92 partition_date varchar; 86 partition_date varchar;
93 from_ts bigint; 87 from_ts bigint;
@@ -111,11 +105,11 @@ BEGIN @@ -111,11 +105,11 @@ BEGIN
111 105
112 CLOSE key_cursor; 106 CLOSE key_cursor;
113 END; 107 END;
114 -$$ language 'plpgsql'; 108 +$$;
115 109
116 --- select create_ts_kv_dictionary_table(); 110 +-- call create_ts_kv_dictionary_table();
117 111
118 -CREATE OR REPLACE FUNCTION create_ts_kv_dictionary_table() RETURNS VOID AS $$ 112 +CREATE OR REPLACE PROCEDURE create_ts_kv_dictionary_table() LANGUAGE plpgsql AS $$
119 113
120 BEGIN 114 BEGIN
121 CREATE TABLE IF NOT EXISTS ts_kv_dictionary 115 CREATE TABLE IF NOT EXISTS ts_kv_dictionary
@@ -125,12 +119,12 @@ BEGIN @@ -125,12 +119,12 @@ BEGIN
125 CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) 119 CONSTRAINT ts_key_id_pkey PRIMARY KEY (key)
126 ); 120 );
127 END; 121 END;
128 -$$ LANGUAGE 'plpgsql'; 122 +$$;
  123 +
  124 +-- call insert_into_dictionary();
129 125
130 --- select insert_into_dictionary(); 126 +CREATE OR REPLACE PROCEDURE insert_into_dictionary() LANGUAGE plpgsql AS $$
131 127
132 -CREATE OR REPLACE FUNCTION insert_into_dictionary() RETURNS VOID AS  
133 -$$  
134 DECLARE 128 DECLARE
135 insert_record RECORD; 129 insert_record RECORD;
136 key_cursor CURSOR FOR SELECT DISTINCT key 130 key_cursor CURSOR FOR SELECT DISTINCT key
@@ -150,28 +144,27 @@ BEGIN @@ -150,28 +144,27 @@ BEGIN
150 END LOOP; 144 END LOOP;
151 CLOSE key_cursor; 145 CLOSE key_cursor;
152 END; 146 END;
153 -$$ language 'plpgsql'; 147 +$$;
154 148
155 --- select insert_into_ts_kv(); 149 +-- call insert_into_ts_kv();
156 150
157 -CREATE OR REPLACE FUNCTION insert_into_ts_kv() RETURNS void AS  
158 -$$ 151 +CREATE OR REPLACE PROCEDURE insert_into_ts_kv() LANGUAGE plpgsql AS $$
159 DECLARE 152 DECLARE
160 insert_size CONSTANT integer := 10000; 153 insert_size CONSTANT integer := 10000;
161 insert_counter integer DEFAULT 0; 154 insert_counter integer DEFAULT 0;
162 insert_record RECORD; 155 insert_record RECORD;
163 - insert_cursor CURSOR FOR SELECT CONCAT(first_part_uuid, '-', second_part_uuid, '-1', third_part_uuid, '-', fourth_part_uuid, '-', fifth_part_uuid)::uuid AS entity_id, 156 + insert_cursor CURSOR FOR SELECT CONCAT(entity_id_uuid_first_part, '-', entity_id_uuid_second_part, '-1', entity_id_uuid_third_part, '-', entity_id_uuid_fourth_part, '-', entity_id_uuid_fifth_part)::uuid AS entity_id,
164 ts_kv_records.key AS key, 157 ts_kv_records.key AS key,
165 ts_kv_records.ts AS ts, 158 ts_kv_records.ts AS ts,
166 ts_kv_records.bool_v AS bool_v, 159 ts_kv_records.bool_v AS bool_v,
167 ts_kv_records.str_v AS str_v, 160 ts_kv_records.str_v AS str_v,
168 ts_kv_records.long_v AS long_v, 161 ts_kv_records.long_v AS long_v,
169 ts_kv_records.dbl_v AS dbl_v 162 ts_kv_records.dbl_v AS dbl_v
170 - FROM (SELECT SUBSTRING(entity_id, 8, 8) AS first_part_uuid,  
171 - SUBSTRING(entity_id, 4, 4) AS second_part_uuid,  
172 - SUBSTRING(entity_id, 1, 3) AS third_part_uuid,  
173 - SUBSTRING(entity_id, 16, 4) AS fourth_part_uuid,  
174 - SUBSTRING(entity_id, 20) AS fifth_part_uuid, 163 + FROM (SELECT SUBSTRING(entity_id, 8, 8) AS entity_id_uuid_first_part,
  164 + SUBSTRING(entity_id, 4, 4) AS entity_id_uuid_second_part,
  165 + SUBSTRING(entity_id, 1, 3) AS entity_id_uuid_third_part,
  166 + SUBSTRING(entity_id, 16, 4) AS entity_id_uuid_fourth_part,
  167 + SUBSTRING(entity_id, 20) AS entity_id_uuid_fifth_part,
175 key_id AS key, 168 key_id AS key,
176 ts, 169 ts,
177 bool_v, 170 bool_v,
@@ -198,28 +191,27 @@ BEGIN @@ -198,28 +191,27 @@ BEGIN
198 END LOOP; 191 END LOOP;
199 CLOSE insert_cursor; 192 CLOSE insert_cursor;
200 END; 193 END;
201 -$$ LANGUAGE 'plpgsql'; 194 +$$;
202 195
203 --- select insert_into_ts_kv_latest(); 196 +-- call insert_into_ts_kv_latest();
204 197
205 -CREATE OR REPLACE FUNCTION insert_into_ts_kv_latest() RETURNS void AS  
206 -$$ 198 +CREATE OR REPLACE PROCEDURE insert_into_ts_kv_latest() LANGUAGE plpgsql AS $$
207 DECLARE 199 DECLARE
208 insert_size CONSTANT integer := 10000; 200 insert_size CONSTANT integer := 10000;
209 insert_counter integer DEFAULT 0; 201 insert_counter integer DEFAULT 0;
210 insert_record RECORD; 202 insert_record RECORD;
211 - insert_cursor CURSOR FOR SELECT CONCAT(first_part_uuid, '-', second_part_uuid, '-1', third_part_uuid, '-', fourth_part_uuid, '-', fifth_part_uuid)::uuid AS entity_id, 203 + insert_cursor CURSOR FOR SELECT CONCAT(entity_id_uuid_first_part, '-', entity_id_uuid_second_part, '-1', entity_id_uuid_third_part, '-', entity_id_uuid_fourth_part, '-', entity_id_uuid_fifth_part)::uuid AS entity_id,
212 ts_kv_latest_records.key AS key, 204 ts_kv_latest_records.key AS key,
213 ts_kv_latest_records.ts AS ts, 205 ts_kv_latest_records.ts AS ts,
214 ts_kv_latest_records.bool_v AS bool_v, 206 ts_kv_latest_records.bool_v AS bool_v,
215 ts_kv_latest_records.str_v AS str_v, 207 ts_kv_latest_records.str_v AS str_v,
216 ts_kv_latest_records.long_v AS long_v, 208 ts_kv_latest_records.long_v AS long_v,
217 ts_kv_latest_records.dbl_v AS dbl_v 209 ts_kv_latest_records.dbl_v AS dbl_v
218 - FROM (SELECT SUBSTRING(entity_id, 8, 8) AS first_part_uuid,  
219 - SUBSTRING(entity_id, 4, 4) AS second_part_uuid,  
220 - SUBSTRING(entity_id, 1, 3) AS third_part_uuid,  
221 - SUBSTRING(entity_id, 16, 4) AS fourth_part_uuid,  
222 - SUBSTRING(entity_id, 20) AS fifth_part_uuid, 210 + FROM (SELECT SUBSTRING(entity_id, 8, 8) AS entity_id_uuid_first_part,
  211 + SUBSTRING(entity_id, 4, 4) AS entity_id_uuid_second_part,
  212 + SUBSTRING(entity_id, 1, 3) AS entity_id_uuid_third_part,
  213 + SUBSTRING(entity_id, 16, 4) AS entity_id_uuid_fourth_part,
  214 + SUBSTRING(entity_id, 20) AS entity_id_uuid_fifth_part,
223 key_id AS key, 215 key_id AS key,
224 ts, 216 ts,
225 bool_v, 217 bool_v,
@@ -246,6 +238,6 @@ BEGIN @@ -246,6 +238,6 @@ BEGIN
246 END LOOP; 238 END LOOP;
247 CLOSE insert_cursor; 239 CLOSE insert_cursor;
248 END; 240 END;
249 -$$ LANGUAGE 'plpgsql'; 241 +$$;
250 242
251 243
@@ -14,60 +14,51 @@ @@ -14,60 +14,51 @@
14 -- limitations under the License. 14 -- limitations under the License.
15 -- 15 --
16 16
17 --- select check_version(); 17 +-- call check_version();
  18 +
  19 +CREATE OR REPLACE PROCEDURE check_version(INOUT valid_version boolean) LANGUAGE plpgsql AS $BODY$
18 20
19 -CREATE OR REPLACE FUNCTION check_version() RETURNS boolean AS $$  
20 DECLARE 21 DECLARE
21 current_version integer; 22 current_version integer;
22 - valid_version boolean;  
23 BEGIN 23 BEGIN
24 RAISE NOTICE 'Check the current installed PostgreSQL version...'; 24 RAISE NOTICE 'Check the current installed PostgreSQL version...';
25 SELECT current_setting('server_version_num') INTO current_version; 25 SELECT current_setting('server_version_num') INTO current_version;
26 - IF current_version < 90600 THEN  
27 - valid_version := FALSE;  
28 - ELSE  
29 - valid_version := TRUE;  
30 - END IF;  
31 - IF valid_version = FALSE THEN  
32 - RAISE NOTICE 'Postgres version should be at least more than 9.6!';  
33 - ELSE 26 + IF current_version > 110000 THEN
34 RAISE NOTICE 'PostgreSQL version is valid!'; 27 RAISE NOTICE 'PostgreSQL version is valid!';
35 RAISE NOTICE 'Schema update started...'; 28 RAISE NOTICE 'Schema update started...';
  29 + SELECT true INTO valid_version;
  30 + ELSE
  31 + RAISE NOTICE 'Postgres version should be at least more than 10!';
36 END IF; 32 END IF;
37 - RETURN valid_version;  
38 END; 33 END;
39 -$$ LANGUAGE 'plpgsql'; 34 +$BODY$;
40 35
41 --- select create_new_tenant_ts_kv_table(); 36 +-- call create_new_ts_kv_table();
42 37
43 -CREATE OR REPLACE FUNCTION create_new_tenant_ts_kv_table() RETURNS VOID AS $$ 38 +CREATE OR REPLACE PROCEDURE create_new_ts_kv_table() LANGUAGE plpgsql AS $$
44 39
45 BEGIN 40 BEGIN
46 ALTER TABLE tenant_ts_kv 41 ALTER TABLE tenant_ts_kv
47 RENAME TO tenant_ts_kv_old; 42 RENAME TO tenant_ts_kv_old;
48 - CREATE TABLE IF NOT EXISTS tenant_ts_kv 43 + CREATE TABLE IF NOT EXISTS ts_kv
49 ( 44 (
50 LIKE tenant_ts_kv_old 45 LIKE tenant_ts_kv_old
51 ); 46 );
52 - ALTER TABLE tenant_ts_kv  
53 - ALTER COLUMN tenant_id TYPE uuid USING tenant_id::uuid;  
54 - ALTER TABLE tenant_ts_kv  
55 - ALTER COLUMN entity_id TYPE uuid USING entity_id::uuid;  
56 - ALTER TABLE tenant_ts_kv  
57 - ALTER COLUMN key TYPE integer USING key::integer;  
58 - ALTER TABLE tenant_ts_kv  
59 - ADD CONSTRAINT tenant_ts_kv_pkey PRIMARY KEY(tenant_id, entity_id, key, ts); 47 + ALTER TABLE ts_kv ALTER COLUMN entity_id TYPE uuid USING entity_id::uuid;
  48 + ALTER TABLE ts_kv ALTER COLUMN key TYPE integer USING key::integer;
  49 + ALTER INDEX ts_kv_pkey RENAME TO tenant_ts_kv_pkey_old;
60 ALTER INDEX idx_tenant_ts_kv RENAME TO idx_tenant_ts_kv_old; 50 ALTER INDEX idx_tenant_ts_kv RENAME TO idx_tenant_ts_kv_old;
61 ALTER INDEX tenant_ts_kv_ts_idx RENAME TO tenant_ts_kv_ts_idx_old; 51 ALTER INDEX tenant_ts_kv_ts_idx RENAME TO tenant_ts_kv_ts_idx_old;
62 --- PERFORM create_hypertable('tenant_ts_kv', 'ts', chunk_time_interval => 86400000, if_not_exists => true);  
63 - CREATE INDEX IF NOT EXISTS idx_tenant_ts_kv ON tenant_ts_kv(tenant_id, entity_id, key, ts); 52 + ALTER TABLE ts_kv ADD CONSTRAINT ts_kv_pkey PRIMARY KEY(entity_id, key, ts);
  53 +-- CREATE INDEX IF NOT EXISTS ts_kv_ts_idx ON ts_kv(ts DESC);
  54 + ALTER TABLE ts_kv DROP COLUMN IF EXISTS tenant_id;
64 END; 55 END;
65 -$$ LANGUAGE 'plpgsql'; 56 +$$;
66 57
67 58
68 --- select create_ts_kv_latest_table(); 59 +-- call create_ts_kv_latest_table();
69 60
70 -CREATE OR REPLACE FUNCTION create_ts_kv_latest_table() RETURNS VOID AS $$ 61 +CREATE OR REPLACE PROCEDURE create_ts_kv_latest_table() LANGUAGE plpgsql AS $$
71 62
72 BEGIN 63 BEGIN
73 CREATE TABLE IF NOT EXISTS ts_kv_latest 64 CREATE TABLE IF NOT EXISTS ts_kv_latest
@@ -82,12 +73,12 @@ BEGIN @@ -82,12 +73,12 @@ BEGIN
82 CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key) 73 CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key)
83 ); 74 );
84 END; 75 END;
85 -$$ LANGUAGE 'plpgsql'; 76 +$$;
86 77
87 78
88 --- select create_ts_kv_dictionary_table(); 79 +-- call create_ts_kv_dictionary_table();
89 80
90 -CREATE OR REPLACE FUNCTION create_ts_kv_dictionary_table() RETURNS VOID AS $$ 81 +CREATE OR REPLACE PROCEDURE create_ts_kv_dictionary_table() LANGUAGE plpgsql AS $$
91 82
92 BEGIN 83 BEGIN
93 CREATE TABLE IF NOT EXISTS ts_kv_dictionary 84 CREATE TABLE IF NOT EXISTS ts_kv_dictionary
@@ -97,12 +88,12 @@ BEGIN @@ -97,12 +88,12 @@ BEGIN
97 CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) 88 CONSTRAINT ts_key_id_pkey PRIMARY KEY (key)
98 ); 89 );
99 END; 90 END;
100 -$$ LANGUAGE 'plpgsql'; 91 +$$;
101 92
102 --- select insert_into_dictionary(); 93 +-- call insert_into_dictionary();
  94 +
  95 +CREATE OR REPLACE PROCEDURE insert_into_dictionary() LANGUAGE plpgsql AS $$
103 96
104 -CREATE OR REPLACE FUNCTION insert_into_dictionary() RETURNS VOID AS  
105 -$$  
106 DECLARE 97 DECLARE
107 insert_record RECORD; 98 insert_record RECORD;
108 key_cursor CURSOR FOR SELECT DISTINCT key 99 key_cursor CURSOR FOR SELECT DISTINCT key
@@ -122,34 +113,28 @@ BEGIN @@ -122,34 +113,28 @@ BEGIN
122 END LOOP; 113 END LOOP;
123 CLOSE key_cursor; 114 CLOSE key_cursor;
124 END; 115 END;
125 -$$ language 'plpgsql'; 116 +$$;
  117 +
  118 +-- call insert_into_ts_kv();
126 119
127 --- select insert_into_tenant_ts_kv(); 120 +CREATE OR REPLACE PROCEDURE insert_into_ts_kv() LANGUAGE plpgsql AS $$
128 121
129 -CREATE OR REPLACE FUNCTION insert_into_tenant_ts_kv() RETURNS void AS  
130 -$$  
131 DECLARE 122 DECLARE
132 insert_size CONSTANT integer := 10000; 123 insert_size CONSTANT integer := 10000;
133 insert_counter integer DEFAULT 0; 124 insert_counter integer DEFAULT 0;
134 insert_record RECORD; 125 insert_record RECORD;
135 - insert_cursor CURSOR FOR SELECT CONCAT(tenant_id_first_part_uuid, '-', tenant_id_second_part_uuid, '-1', tenant_id_third_part_uuid, '-', tenant_id_fourth_part_uuid, '-', tenant_id_fifth_part_uuid)::uuid AS tenant_id,  
136 - CONCAT(entity_id_first_part_uuid, '-', entity_id_second_part_uuid, '-1', entity_id_third_part_uuid, '-', entity_id_fourth_part_uuid, '-', entity_id_fifth_part_uuid)::uuid AS entity_id,  
137 - tenant_ts_kv_records.key AS key,  
138 - tenant_ts_kv_records.ts AS ts,  
139 - tenant_ts_kv_records.bool_v AS bool_v,  
140 - tenant_ts_kv_records.str_v AS str_v,  
141 - tenant_ts_kv_records.long_v AS long_v,  
142 - tenant_ts_kv_records.dbl_v AS dbl_v  
143 - FROM (SELECT SUBSTRING(tenant_id, 8, 8) AS tenant_id_first_part_uuid,  
144 - SUBSTRING(tenant_id, 4, 4) AS tenant_id_second_part_uuid,  
145 - SUBSTRING(tenant_id, 1, 3) AS tenant_id_third_part_uuid,  
146 - SUBSTRING(tenant_id, 16, 4) AS tenant_id_fourth_part_uuid,  
147 - SUBSTRING(tenant_id, 20) AS tenant_id_fifth_part_uuid,  
148 - SUBSTRING(entity_id, 8, 8) AS entity_id_first_part_uuid,  
149 - SUBSTRING(entity_id, 4, 4) AS entity_id_second_part_uuid,  
150 - SUBSTRING(entity_id, 1, 3) AS entity_id_third_part_uuid,  
151 - SUBSTRING(entity_id, 16, 4) AS entity_id_fourth_part_uuid,  
152 - SUBSTRING(entity_id, 20) AS entity_id_fifth_part_uuid, 126 + insert_cursor CURSOR FOR SELECT CONCAT(entity_id_uuid_first_part, '-', entity_id_uuid_second_part, '-1', entity_id_uuid_third_part, '-', entity_id_uuid_fourth_part, '-', entity_id_uuid_fifth_part)::uuid AS entity_id,
  127 + new_ts_kv_records.key AS key,
  128 + new_ts_kv_records.ts AS ts,
  129 + new_ts_kv_records.bool_v AS bool_v,
  130 + new_ts_kv_records.str_v AS str_v,
  131 + new_ts_kv_records.long_v AS long_v,
  132 + new_ts_kv_records.dbl_v AS dbl_v
  133 + FROM (SELECT SUBSTRING(entity_id, 8, 8) AS entity_id_uuid_first_part,
  134 + SUBSTRING(entity_id, 4, 4) AS entity_id_uuid_second_part,
  135 + SUBSTRING(entity_id, 1, 3) AS entity_id_uuid_third_part,
  136 + SUBSTRING(entity_id, 16, 4) AS entity_id_uuid_fourth_part,
  137 + SUBSTRING(entity_id, 20) AS entity_id_uuid_fifth_part,
153 key_id AS key, 138 key_id AS key,
154 ts, 139 ts,
155 bool_v, 140 bool_v,
@@ -157,31 +142,31 @@ DECLARE @@ -157,31 +142,31 @@ DECLARE
157 long_v, 142 long_v,
158 dbl_v 143 dbl_v
159 FROM tenant_ts_kv_old 144 FROM tenant_ts_kv_old
160 - INNER JOIN ts_kv_dictionary ON (tenant_ts_kv_old.key = ts_kv_dictionary.key)) AS tenant_ts_kv_records; 145 + INNER JOIN ts_kv_dictionary ON (tenant_ts_kv_old.key = ts_kv_dictionary.key)) AS new_ts_kv_records;
161 BEGIN 146 BEGIN
162 OPEN insert_cursor; 147 OPEN insert_cursor;
163 LOOP 148 LOOP
164 insert_counter := insert_counter + 1; 149 insert_counter := insert_counter + 1;
165 FETCH insert_cursor INTO insert_record; 150 FETCH insert_cursor INTO insert_record;
166 IF NOT FOUND THEN 151 IF NOT FOUND THEN
167 - RAISE NOTICE '% records have been inserted into the new tenant_ts_kv table!',insert_counter - 1; 152 + RAISE NOTICE '% records have been inserted into the new ts_kv table!',insert_counter - 1;
168 EXIT; 153 EXIT;
169 END IF; 154 END IF;
170 - INSERT INTO tenant_ts_kv(tenant_id, entity_id, key, ts, bool_v, str_v, long_v, dbl_v)  
171 - VALUES (insert_record.tenant_id, insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, 155 + INSERT INTO ts_kv(entity_id, key, ts, bool_v, str_v, long_v, dbl_v)
  156 + VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v,
172 insert_record.long_v, insert_record.dbl_v); 157 insert_record.long_v, insert_record.dbl_v);
173 IF MOD(insert_counter, insert_size) = 0 THEN 158 IF MOD(insert_counter, insert_size) = 0 THEN
174 - RAISE NOTICE '% records have been inserted into the new tenant_ts_kv table!',insert_counter; 159 + RAISE NOTICE '% records have been inserted into the new ts_kv table!',insert_counter;
175 END IF; 160 END IF;
176 END LOOP; 161 END LOOP;
177 CLOSE insert_cursor; 162 CLOSE insert_cursor;
178 END; 163 END;
179 -$$ LANGUAGE 'plpgsql'; 164 +$$;
  165 +
  166 +-- call insert_into_ts_kv_latest();
180 167
181 --- select insert_into_ts_kv_latest(); 168 +CREATE OR REPLACE PROCEDURE insert_into_ts_kv_latest() LANGUAGE plpgsql AS $$
182 169
183 -CREATE OR REPLACE FUNCTION insert_into_ts_kv_latest() RETURNS void AS  
184 -$$  
185 DECLARE 170 DECLARE
186 insert_size CONSTANT integer := 10000; 171 insert_size CONSTANT integer := 10000;
187 insert_counter integer DEFAULT 0; 172 insert_counter integer DEFAULT 0;
@@ -191,7 +176,7 @@ DECLARE @@ -191,7 +176,7 @@ DECLARE
191 latest_records.key AS key, 176 latest_records.key AS key,
192 latest_records.entity_id AS entity_id, 177 latest_records.entity_id AS entity_id,
193 latest_records.ts AS ts 178 latest_records.ts AS ts
194 - FROM (SELECT DISTINCT key AS key, entity_id AS entity_id, MAX(ts) AS ts FROM tenant_ts_kv GROUP BY key, entity_id) AS latest_records; 179 + FROM (SELECT DISTINCT key AS key, entity_id AS entity_id, MAX(ts) AS ts FROM ts_kv GROUP BY key, entity_id) AS latest_records;
195 BEGIN 180 BEGIN
196 OPEN insert_cursor; 181 OPEN insert_cursor;
197 LOOP 182 LOOP
@@ -201,7 +186,7 @@ BEGIN @@ -201,7 +186,7 @@ BEGIN
201 RAISE NOTICE '% records have been inserted into the ts_kv_latest table!',insert_counter - 1; 186 RAISE NOTICE '% records have been inserted into the ts_kv_latest table!',insert_counter - 1;
202 EXIT; 187 EXIT;
203 END IF; 188 END IF;
204 - SELECT entity_id AS entity_id, key AS key, ts AS ts, bool_v AS bool_v, str_v AS str_v, long_v AS long_v, dbl_v AS dbl_v INTO insert_record FROM tenant_ts_kv WHERE entity_id = latest_record.entity_id AND key = latest_record.key AND ts = latest_record.ts; 189 + SELECT entity_id AS entity_id, key AS key, ts AS ts, bool_v AS bool_v, str_v AS str_v, long_v AS long_v, dbl_v AS dbl_v INTO insert_record FROM ts_kv WHERE entity_id = latest_record.entity_id AND key = latest_record.key AND ts = latest_record.ts;
205 INSERT INTO ts_kv_latest(entity_id, key, ts, bool_v, str_v, long_v, dbl_v) 190 INSERT INTO ts_kv_latest(entity_id, key, ts, bool_v, str_v, long_v, dbl_v)
206 VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, insert_record.long_v, insert_record.dbl_v); 191 VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, insert_record.long_v, insert_record.dbl_v);
207 IF MOD(insert_counter, insert_size) = 0 THEN 192 IF MOD(insert_counter, insert_size) = 0 THEN
@@ -210,4 +195,4 @@ BEGIN @@ -210,4 +195,4 @@ BEGIN
210 END LOOP; 195 END LOOP;
211 CLOSE insert_cursor; 196 CLOSE insert_cursor;
212 END; 197 END;
213 -$$ LANGUAGE 'plpgsql'; 198 +$$;
@@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
24 import com.google.common.util.concurrent.FutureCallback; 24 import com.google.common.util.concurrent.FutureCallback;
25 import com.google.common.util.concurrent.Futures; 25 import com.google.common.util.concurrent.Futures;
26 import com.google.common.util.concurrent.ListenableFuture; 26 import com.google.common.util.concurrent.ListenableFuture;
  27 +import com.google.common.util.concurrent.MoreExecutors;
27 import com.typesafe.config.Config; 28 import com.typesafe.config.Config;
28 import com.typesafe.config.ConfigFactory; 29 import com.typesafe.config.ConfigFactory;
29 import lombok.Getter; 30 import lombok.Getter;
@@ -469,7 +470,7 @@ public class ActorSystemContext { @@ -469,7 +470,7 @@ public class ActorSystemContext {
469 public void onFailure(Throwable th) { 470 public void onFailure(Throwable th) {
470 log.error("Could not save debug Event for Node", th); 471 log.error("Could not save debug Event for Node", th);
471 } 472 }
472 - }); 473 + }, MoreExecutors.directExecutor());
473 } catch (IOException ex) { 474 } catch (IOException ex) {
474 log.warn("Failed to persist rule node debug message", ex); 475 log.warn("Failed to persist rule node debug message", ex);
475 } 476 }
@@ -522,7 +523,7 @@ public class ActorSystemContext { @@ -522,7 +523,7 @@ public class ActorSystemContext {
522 public void onFailure(Throwable th) { 523 public void onFailure(Throwable th) {
523 log.error("Could not save debug Event for Rule Chain", th); 524 log.error("Could not save debug Event for Rule Chain", th);
524 } 525 }
525 - }); 526 + }, MoreExecutors.directExecutor());
526 } 527 }
527 528
528 public static Exception toException(Throwable error) { 529 public static Exception toException(Throwable error) {
@@ -20,9 +20,9 @@ import com.datastax.driver.core.utils.UUIDs; @@ -20,9 +20,9 @@ import com.datastax.driver.core.utils.UUIDs;
20 import com.google.common.util.concurrent.FutureCallback; 20 import com.google.common.util.concurrent.FutureCallback;
21 import com.google.common.util.concurrent.Futures; 21 import com.google.common.util.concurrent.Futures;
22 import com.google.common.util.concurrent.ListenableFuture; 22 import com.google.common.util.concurrent.ListenableFuture;
  23 +import com.google.common.util.concurrent.MoreExecutors;
23 import com.google.gson.Gson; 24 import com.google.gson.Gson;
24 import com.google.gson.JsonObject; 25 import com.google.gson.JsonObject;
25 -import com.google.gson.JsonParser;  
26 import com.google.protobuf.InvalidProtocolBufferException; 26 import com.google.protobuf.InvalidProtocolBufferException;
27 import lombok.extern.slf4j.Slf4j; 27 import lombok.extern.slf4j.Slf4j;
28 import org.apache.commons.collections.CollectionUtils; 28 import org.apache.commons.collections.CollectionUtils;
@@ -292,7 +292,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -292,7 +292,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
292 .build(); 292 .build();
293 sendToTransport(responseMsg, sessionInfo); 293 sendToTransport(responseMsg, sessionInfo);
294 } 294 }
295 - }); 295 + }, MoreExecutors.directExecutor());
296 } 296 }
297 297
298 private ListenableFuture<List<List<AttributeKvEntry>>> getAttributesKvEntries(GetAttributeRequestMsg request) { 298 private ListenableFuture<List<List<AttributeKvEntry>>> getAttributesKvEntries(GetAttributeRequestMsg request) {
@@ -18,6 +18,7 @@ package org.thingsboard.server.controller; @@ -18,6 +18,7 @@ package org.thingsboard.server.controller;
18 import com.google.common.util.concurrent.FutureCallback; 18 import com.google.common.util.concurrent.FutureCallback;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 import org.springframework.http.HttpStatus; 22 import org.springframework.http.HttpStatus;
22 import org.springframework.http.ResponseEntity; 23 import org.springframework.http.ResponseEntity;
23 import org.springframework.security.access.prepost.PreAuthorize; 24 import org.springframework.security.access.prepost.PreAuthorize;
@@ -30,7 +31,13 @@ import org.springframework.web.bind.annotation.ResponseBody; @@ -30,7 +31,13 @@ import org.springframework.web.bind.annotation.ResponseBody;
30 import org.springframework.web.bind.annotation.ResponseStatus; 31 import org.springframework.web.bind.annotation.ResponseStatus;
31 import org.springframework.web.bind.annotation.RestController; 32 import org.springframework.web.bind.annotation.RestController;
32 import org.springframework.web.context.request.async.DeferredResult; 33 import org.springframework.web.context.request.async.DeferredResult;
33 -import org.thingsboard.server.common.data.*; 34 +import org.thingsboard.server.common.data.ClaimRequest;
  35 +import org.thingsboard.server.common.data.Customer;
  36 +import org.thingsboard.server.common.data.DataConstants;
  37 +import org.thingsboard.server.common.data.Device;
  38 +import org.thingsboard.server.common.data.DeviceInfo;
  39 +import org.thingsboard.server.common.data.EntitySubtype;
  40 +import org.thingsboard.server.common.data.EntityType;
34 import org.thingsboard.server.common.data.audit.ActionType; 41 import org.thingsboard.server.common.data.audit.ActionType;
35 import org.thingsboard.server.common.data.device.DeviceSearchQuery; 42 import org.thingsboard.server.common.data.device.DeviceSearchQuery;
36 import org.thingsboard.server.common.data.exception.ThingsboardException; 43 import org.thingsboard.server.common.data.exception.ThingsboardException;
@@ -40,7 +47,6 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -40,7 +47,6 @@ import org.thingsboard.server.common.data.id.TenantId;
40 import org.thingsboard.server.common.data.page.PageData; 47 import org.thingsboard.server.common.data.page.PageData;
41 import org.thingsboard.server.common.data.page.PageLink; 48 import org.thingsboard.server.common.data.page.PageLink;
42 import org.thingsboard.server.common.data.security.DeviceCredentials; 49 import org.thingsboard.server.common.data.security.DeviceCredentials;
43 -import org.thingsboard.server.common.data.ClaimRequest;  
44 import org.thingsboard.server.dao.device.claim.ClaimResponse; 50 import org.thingsboard.server.dao.device.claim.ClaimResponse;
45 import org.thingsboard.server.dao.device.claim.ClaimResult; 51 import org.thingsboard.server.dao.device.claim.ClaimResult;
46 import org.thingsboard.server.dao.exception.IncorrectParameterException; 52 import org.thingsboard.server.dao.exception.IncorrectParameterException;
@@ -486,11 +492,12 @@ public class DeviceController extends BaseController { @@ -486,11 +492,12 @@ public class DeviceController extends BaseController {
486 deferredResult.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST)); 492 deferredResult.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
487 } 493 }
488 } 494 }
  495 +
489 @Override 496 @Override
490 public void onFailure(Throwable t) { 497 public void onFailure(Throwable t) {
491 deferredResult.setErrorResult(t); 498 deferredResult.setErrorResult(t);
492 } 499 }
493 - }); 500 + }, MoreExecutors.directExecutor());
494 return deferredResult; 501 return deferredResult;
495 } catch (Exception e) { 502 } catch (Exception e) {
496 throw handleException(e); 503 throw handleException(e);
@@ -527,7 +534,7 @@ public class DeviceController extends BaseController { @@ -527,7 +534,7 @@ public class DeviceController extends BaseController {
527 public void onFailure(Throwable t) { 534 public void onFailure(Throwable t) {
528 deferredResult.setErrorResult(t); 535 deferredResult.setErrorResult(t);
529 } 536 }
530 - }); 537 + }, MoreExecutors.directExecutor());
531 return deferredResult; 538 return deferredResult;
532 } catch (Exception e) { 539 } catch (Exception e) {
533 throw handleException(e); 540 throw handleException(e);
@@ -18,6 +18,7 @@ package org.thingsboard.server.controller; @@ -18,6 +18,7 @@ package org.thingsboard.server.controller;
18 import com.google.common.util.concurrent.FutureCallback; 18 import com.google.common.util.concurrent.FutureCallback;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
22 import org.springframework.http.HttpStatus; 23 import org.springframework.http.HttpStatus;
23 import org.springframework.security.access.prepost.PreAuthorize; 24 import org.springframework.security.access.prepost.PreAuthorize;
@@ -167,7 +168,7 @@ public class EntityViewController extends BaseController { @@ -167,7 +168,7 @@ public class EntityViewController extends BaseController {
167 }); 168 });
168 } 169 }
169 return null; 170 return null;
170 - }); 171 + }, MoreExecutors.directExecutor());
171 } else { 172 } else {
172 return Futures.immediateFuture(null); 173 return Futures.immediateFuture(null);
173 } 174 }
@@ -22,6 +22,7 @@ import com.google.common.base.Function; @@ -22,6 +22,7 @@ import com.google.common.base.Function;
22 import com.google.common.util.concurrent.FutureCallback; 22 import com.google.common.util.concurrent.FutureCallback;
23 import com.google.common.util.concurrent.Futures; 23 import com.google.common.util.concurrent.Futures;
24 import com.google.common.util.concurrent.ListenableFuture; 24 import com.google.common.util.concurrent.ListenableFuture;
  25 +import com.google.common.util.concurrent.MoreExecutors;
25 import com.google.gson.JsonElement; 26 import com.google.gson.JsonElement;
26 import com.google.gson.JsonParseException; 27 import com.google.gson.JsonParseException;
27 import com.google.gson.JsonParser; 28 import com.google.gson.JsonParser;
@@ -174,7 +175,7 @@ public class TelemetryController extends BaseController { @@ -174,7 +175,7 @@ public class TelemetryController extends BaseController {
174 public DeferredResult<ResponseEntity> getTimeseriesKeys( 175 public DeferredResult<ResponseEntity> getTimeseriesKeys(
175 @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr) throws ThingsboardException { 176 @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr) throws ThingsboardException {
176 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, 177 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr,
177 - (result, tenantId, entityId) -> Futures.addCallback(tsService.findAllLatest(tenantId, entityId), getTsKeysToResponseCallback(result))); 178 + (result, tenantId, entityId) -> Futures.addCallback(tsService.findAllLatest(tenantId, entityId), getTsKeysToResponseCallback(result), MoreExecutors.directExecutor()));
178 } 179 }
179 180
180 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 181 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@@ -210,7 +211,7 @@ public class TelemetryController extends BaseController { @@ -210,7 +211,7 @@ public class TelemetryController extends BaseController {
210 List<ReadTsKvQuery> queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg)) 211 List<ReadTsKvQuery> queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg))
211 .collect(Collectors.toList()); 212 .collect(Collectors.toList());
212 213
213 - Futures.addCallback(tsService.findAll(tenantId, entityId, queries), getTsKvListCallback(result, useStrictDataTypes)); 214 + Futures.addCallback(tsService.findAll(tenantId, entityId, queries), getTsKvListCallback(result, useStrictDataTypes), MoreExecutors.directExecutor());
214 }); 215 });
215 } 216 }
216 217
@@ -462,7 +463,7 @@ public class TelemetryController extends BaseController { @@ -462,7 +463,7 @@ public class TelemetryController extends BaseController {
462 } else { 463 } else {
463 future = tsService.findLatest(user.getTenantId(), entityId, toKeysList(keys)); 464 future = tsService.findLatest(user.getTenantId(), entityId, toKeysList(keys));
464 } 465 }
465 - Futures.addCallback(future, getTsKvListCallback(result, useStrictDataTypes)); 466 + Futures.addCallback(future, getTsKvListCallback(result, useStrictDataTypes), MoreExecutors.directExecutor());
466 } 467 }
467 468
468 private void getAttributeValuesCallback(@Nullable DeferredResult<ResponseEntity> result, SecurityUser user, EntityId entityId, String scope, String keys) { 469 private void getAttributeValuesCallback(@Nullable DeferredResult<ResponseEntity> result, SecurityUser user, EntityId entityId, String scope, String keys) {
@@ -470,9 +471,9 @@ public class TelemetryController extends BaseController { @@ -470,9 +471,9 @@ public class TelemetryController extends BaseController {
470 FutureCallback<List<AttributeKvEntry>> callback = getAttributeValuesToResponseCallback(result, user, scope, entityId, keyList); 471 FutureCallback<List<AttributeKvEntry>> callback = getAttributeValuesToResponseCallback(result, user, scope, entityId, keyList);
471 if (!StringUtils.isEmpty(scope)) { 472 if (!StringUtils.isEmpty(scope)) {
472 if (keyList != null && !keyList.isEmpty()) { 473 if (keyList != null && !keyList.isEmpty()) {
473 - Futures.addCallback(attributesService.find(user.getTenantId(), entityId, scope, keyList), callback); 474 + Futures.addCallback(attributesService.find(user.getTenantId(), entityId, scope, keyList), callback, MoreExecutors.directExecutor());
474 } else { 475 } else {
475 - Futures.addCallback(attributesService.findAll(user.getTenantId(), entityId, scope), callback); 476 + Futures.addCallback(attributesService.findAll(user.getTenantId(), entityId, scope), callback, MoreExecutors.directExecutor());
476 } 477 }
477 } else { 478 } else {
478 List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>(); 479 List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>();
@@ -486,12 +487,12 @@ public class TelemetryController extends BaseController { @@ -486,12 +487,12 @@ public class TelemetryController extends BaseController {
486 487
487 ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures); 488 ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures);
488 489
489 - Futures.addCallback(future, callback); 490 + Futures.addCallback(future, callback, MoreExecutors.directExecutor());
490 } 491 }
491 } 492 }
492 493
493 private void getAttributeKeysCallback(@Nullable DeferredResult<ResponseEntity> result, TenantId tenantId, EntityId entityId, String scope) { 494 private void getAttributeKeysCallback(@Nullable DeferredResult<ResponseEntity> result, TenantId tenantId, EntityId entityId, String scope) {
494 - Futures.addCallback(attributesService.findAll(tenantId, entityId, scope), getAttributeKeysToResponseCallback(result)); 495 + Futures.addCallback(attributesService.findAll(tenantId, entityId, scope), getAttributeKeysToResponseCallback(result), MoreExecutors.directExecutor());
495 } 496 }
496 497
497 private void getAttributeKeysCallback(@Nullable DeferredResult<ResponseEntity> result, TenantId tenantId, EntityId entityId) { 498 private void getAttributeKeysCallback(@Nullable DeferredResult<ResponseEntity> result, TenantId tenantId, EntityId entityId) {
@@ -502,7 +503,7 @@ public class TelemetryController extends BaseController { @@ -502,7 +503,7 @@ public class TelemetryController extends BaseController {
502 503
503 ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures); 504 ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures);
504 505
505 - Futures.addCallback(future, getAttributeKeysToResponseCallback(result)); 506 + Futures.addCallback(future, getAttributeKeysToResponseCallback(result), MoreExecutors.directExecutor());
506 } 507 }
507 508
508 private FutureCallback<List<TsKvEntry>> getTsKeysToResponseCallback(final DeferredResult<ResponseEntity> response) { 509 private FutureCallback<List<TsKvEntry>> getTsKeysToResponseCallback(final DeferredResult<ResponseEntity> response) {
@@ -22,38 +22,21 @@ import org.springframework.beans.factory.annotation.Value; @@ -22,38 +22,21 @@ import org.springframework.beans.factory.annotation.Value;
22 import java.nio.charset.StandardCharsets; 22 import java.nio.charset.StandardCharsets;
23 import java.nio.file.Files; 23 import java.nio.file.Files;
24 import java.nio.file.Path; 24 import java.nio.file.Path;
25 -import java.sql.CallableStatement;  
26 import java.sql.Connection; 25 import java.sql.Connection;
  26 +import java.sql.ResultSet;
27 import java.sql.SQLException; 27 import java.sql.SQLException;
28 import java.sql.SQLWarning; 28 import java.sql.SQLWarning;
29 -import java.sql.Types; 29 +import java.sql.Statement;
30 30
31 @Slf4j 31 @Slf4j
32 public abstract class AbstractSqlTsDatabaseUpgradeService { 32 public abstract class AbstractSqlTsDatabaseUpgradeService {
33 33
34 protected static final String CALL_REGEX = "call "; 34 protected static final String CALL_REGEX = "call ";
35 - protected static final String CHECK_VERSION = "check_version()"; 35 + protected static final String CHECK_VERSION = "check_version(false)";
  36 + protected static final String CHECK_VERSION_TO_DELETE = "check_version(INOUT valid_version boolean)";
36 protected static final String DROP_TABLE = "DROP TABLE "; 37 protected static final String DROP_TABLE = "DROP TABLE ";
37 - protected static final String DROP_FUNCTION_IF_EXISTS = "DROP FUNCTION IF EXISTS ";  
38 -  
39 - private static final String CALL_CHECK_VERSION = CALL_REGEX + CHECK_VERSION;  
40 -  
41 -  
42 - private static final String FUNCTION = "function: {}";  
43 - private static final String DROP_STATEMENT = "drop statement: {}";  
44 - private static final String QUERY = "query: {}";  
45 - private static final String SUCCESSFULLY_EXECUTED = "Successfully executed ";  
46 - private static final String FAILED_TO_EXECUTE = "Failed to execute ";  
47 - private static final String FAILED_DUE_TO = " due to: {}";  
48 -  
49 - protected static final String SUCCESSFULLY_EXECUTED_FUNCTION = SUCCESSFULLY_EXECUTED + FUNCTION;  
50 - protected static final String FAILED_TO_EXECUTE_FUNCTION_DUE_TO = FAILED_TO_EXECUTE + FUNCTION + FAILED_DUE_TO;  
51 -  
52 - protected static final String SUCCESSFULLY_EXECUTED_DROP_STATEMENT = SUCCESSFULLY_EXECUTED + DROP_STATEMENT;  
53 - protected static final String FAILED_TO_EXECUTE_DROP_STATEMENT = FAILED_TO_EXECUTE + DROP_STATEMENT + FAILED_DUE_TO;  
54 -  
55 - protected static final String SUCCESSFULLY_EXECUTED_QUERY = SUCCESSFULLY_EXECUTED + QUERY;  
56 - protected static final String FAILED_TO_EXECUTE_QUERY = FAILED_TO_EXECUTE + QUERY + FAILED_DUE_TO; 38 + protected static final String DROP_PROCEDURE_IF_EXISTS = "DROP PROCEDURE IF EXISTS ";
  39 + protected static final String DROP_PROCEDURE_CHECK_VERSION = DROP_PROCEDURE_IF_EXISTS + CHECK_VERSION_TO_DELETE;
57 40
58 @Value("${spring.datasource.url}") 41 @Value("${spring.datasource.url}")
59 protected String dbUrl; 42 protected String dbUrl;
@@ -78,23 +61,22 @@ public abstract class AbstractSqlTsDatabaseUpgradeService { @@ -78,23 +61,22 @@ public abstract class AbstractSqlTsDatabaseUpgradeService {
78 log.info("Check the current PostgreSQL version..."); 61 log.info("Check the current PostgreSQL version...");
79 boolean versionValid = false; 62 boolean versionValid = false;
80 try { 63 try {
81 - CallableStatement callableStatement = conn.prepareCall("{? = " + CALL_CHECK_VERSION + " }");  
82 - callableStatement.registerOutParameter(1, Types.BOOLEAN);  
83 - callableStatement.execute();  
84 - versionValid = callableStatement.getBoolean(1);  
85 - callableStatement.close(); 64 + Statement statement = conn.createStatement();
  65 + ResultSet resultSet = statement.executeQuery(CALL_REGEX + CHECK_VERSION);
  66 + resultSet.next();
  67 + versionValid = resultSet.getBoolean(1);
  68 + statement.close();
86 } catch (Exception e) { 69 } catch (Exception e) {
87 log.info("Failed to check current PostgreSQL version due to: {}", e.getMessage()); 70 log.info("Failed to check current PostgreSQL version due to: {}", e.getMessage());
88 } 71 }
89 return versionValid; 72 return versionValid;
90 } 73 }
91 74
92 - protected void executeFunction(Connection conn, String query) {  
93 - log.info("{} ... ", query); 75 + protected void executeQuery(Connection conn, String query) {
94 try { 76 try {
95 - CallableStatement callableStatement = conn.prepareCall("{" + query + "}");  
96 - callableStatement.execute();  
97 - SQLWarning warnings = callableStatement.getWarnings(); 77 + Statement statement = conn.createStatement();
  78 + statement.execute(query); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
  79 + SQLWarning warnings = statement.getWarnings();
98 if (warnings != null) { 80 if (warnings != null) {
99 log.info("{}", warnings.getMessage()); 81 log.info("{}", warnings.getMessage());
100 SQLWarning nextWarning = warnings.getNextWarning(); 82 SQLWarning nextWarning = warnings.getNextWarning();
@@ -103,31 +85,10 @@ public abstract class AbstractSqlTsDatabaseUpgradeService { @@ -103,31 +85,10 @@ public abstract class AbstractSqlTsDatabaseUpgradeService {
103 nextWarning = nextWarning.getNextWarning(); 85 nextWarning = nextWarning.getNextWarning();
104 } 86 }
105 } 87 }
106 - callableStatement.close();  
107 - log.info(SUCCESSFULLY_EXECUTED_FUNCTION, query.replace(CALL_REGEX, ""));  
108 - Thread.sleep(2000);  
109 - } catch (Exception e) {  
110 - log.info(FAILED_TO_EXECUTE_FUNCTION_DUE_TO, query, e.getMessage());  
111 - }  
112 - }  
113 -  
114 - protected void executeDropStatement(Connection conn, String query) {  
115 - try {  
116 - conn.createStatement().execute(query); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script  
117 - log.info(SUCCESSFULLY_EXECUTED_DROP_STATEMENT, query);  
118 - Thread.sleep(5000);  
119 - } catch (InterruptedException | SQLException e) {  
120 - log.info(FAILED_TO_EXECUTE_DROP_STATEMENT, query, e.getMessage());  
121 - }  
122 - }  
123 -  
124 - protected void executeQuery(Connection conn, String query) {  
125 - try {  
126 - conn.createStatement().execute(query); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script  
127 - log.info(SUCCESSFULLY_EXECUTED_QUERY, query);  
128 Thread.sleep(5000); 88 Thread.sleep(5000);
  89 + log.info("Successfully executed query: {}", query);
129 } catch (InterruptedException | SQLException e) { 90 } catch (InterruptedException | SQLException e) {
130 - log.info(FAILED_TO_EXECUTE_QUERY, query, e.getMessage()); 91 + log.info("Failed to execute query: {} due to: {}", query, e.getMessage());
131 } 92 }
132 } 93 }
133 94
@@ -57,14 +57,13 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe @@ -57,14 +57,13 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe
57 private static final String DROP_TABLE_TS_KV_OLD = DROP_TABLE + TS_KV_OLD; 57 private static final String DROP_TABLE_TS_KV_OLD = DROP_TABLE + TS_KV_OLD;
58 private static final String DROP_TABLE_TS_KV_LATEST_OLD = DROP_TABLE + TS_KV_LATEST_OLD; 58 private static final String DROP_TABLE_TS_KV_LATEST_OLD = DROP_TABLE + TS_KV_LATEST_OLD;
59 59
60 - private static final String DROP_FUNCTION_CHECK_VERSION = DROP_FUNCTION_IF_EXISTS + CHECK_VERSION;  
61 - private static final String DROP_FUNCTION_CREATE_PARTITION_TS_KV_TABLE = DROP_FUNCTION_IF_EXISTS + CREATE_PARTITION_TS_KV_TABLE;  
62 - private static final String DROP_FUNCTION_CREATE_NEW_TS_KV_LATEST_TABLE = DROP_FUNCTION_IF_EXISTS + CREATE_NEW_TS_KV_LATEST_TABLE;  
63 - private static final String DROP_FUNCTION_CREATE_PARTITIONS = DROP_FUNCTION_IF_EXISTS + CREATE_PARTITIONS;  
64 - private static final String DROP_FUNCTION_CREATE_TS_KV_DICTIONARY_TABLE = DROP_FUNCTION_IF_EXISTS + CREATE_TS_KV_DICTIONARY_TABLE;  
65 - private static final String DROP_FUNCTION_INSERT_INTO_DICTIONARY = DROP_FUNCTION_IF_EXISTS + INSERT_INTO_DICTIONARY;  
66 - private static final String DROP_FUNCTION_INSERT_INTO_TS_KV = DROP_FUNCTION_IF_EXISTS + INSERT_INTO_TS_KV;  
67 - private static final String DROP_FUNCTION_INSERT_INTO_TS_KV_LATEST = DROP_FUNCTION_IF_EXISTS + INSERT_INTO_TS_KV_LATEST; 60 + private static final String DROP_PROCEDURE_CREATE_PARTITION_TS_KV_TABLE = DROP_PROCEDURE_IF_EXISTS + CREATE_PARTITION_TS_KV_TABLE;
  61 + private static final String DROP_PROCEDURE_CREATE_NEW_TS_KV_LATEST_TABLE = DROP_PROCEDURE_IF_EXISTS + CREATE_NEW_TS_KV_LATEST_TABLE;
  62 + private static final String DROP_PROCEDURE_CREATE_PARTITIONS = DROP_PROCEDURE_IF_EXISTS + CREATE_PARTITIONS;
  63 + private static final String DROP_PROCEDURE_CREATE_TS_KV_DICTIONARY_TABLE = DROP_PROCEDURE_IF_EXISTS + CREATE_TS_KV_DICTIONARY_TABLE;
  64 + private static final String DROP_PROCEDURE_INSERT_INTO_DICTIONARY = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_DICTIONARY;
  65 + private static final String DROP_PROCEDURE_INSERT_INTO_TS_KV = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_TS_KV;
  66 + private static final String DROP_PROCEDURE_INSERT_INTO_TS_KV_LATEST = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_TS_KV_LATEST;
68 67
69 @Override 68 @Override
70 public void upgradeDatabase(String fromVersion) throws Exception { 69 public void upgradeDatabase(String fromVersion) throws Exception {
@@ -76,30 +75,30 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe @@ -76,30 +75,30 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe
76 loadSql(conn); 75 loadSql(conn);
77 boolean versionValid = checkVersion(conn); 76 boolean versionValid = checkVersion(conn);
78 if (!versionValid) { 77 if (!versionValid) {
79 - log.info("PostgreSQL version should be at least more than 10!"); 78 + log.info("PostgreSQL version should be at least more than 11!");
80 log.info("Please upgrade your PostgreSQL and restart the script!"); 79 log.info("Please upgrade your PostgreSQL and restart the script!");
81 } else { 80 } else {
82 log.info("PostgreSQL version is valid!"); 81 log.info("PostgreSQL version is valid!");
83 log.info("Updating schema ..."); 82 log.info("Updating schema ...");
84 - executeFunction(conn, CALL_CREATE_PARTITION_TS_KV_TABLE);  
85 - executeFunction(conn, CALL_CREATE_PARTITIONS);  
86 - executeFunction(conn, CALL_CREATE_TS_KV_DICTIONARY_TABLE);  
87 - executeFunction(conn, CALL_INSERT_INTO_DICTIONARY);  
88 - executeFunction(conn, CALL_INSERT_INTO_TS_KV);  
89 - executeFunction(conn, CALL_CREATE_NEW_TS_KV_LATEST_TABLE);  
90 - executeFunction(conn, CALL_INSERT_INTO_TS_KV_LATEST); 83 + executeQuery(conn, CALL_CREATE_PARTITION_TS_KV_TABLE);
  84 + executeQuery(conn, CALL_CREATE_PARTITIONS);
  85 + executeQuery(conn, CALL_CREATE_TS_KV_DICTIONARY_TABLE);
  86 + executeQuery(conn, CALL_INSERT_INTO_DICTIONARY);
  87 + executeQuery(conn, CALL_INSERT_INTO_TS_KV);
  88 + executeQuery(conn, CALL_CREATE_NEW_TS_KV_LATEST_TABLE);
  89 + executeQuery(conn, CALL_INSERT_INTO_TS_KV_LATEST);
91 90
92 - executeDropStatement(conn, DROP_TABLE_TS_KV_OLD);  
93 - executeDropStatement(conn, DROP_TABLE_TS_KV_LATEST_OLD); 91 + executeQuery(conn, DROP_TABLE_TS_KV_OLD);
  92 + executeQuery(conn, DROP_TABLE_TS_KV_LATEST_OLD);
94 93
95 - executeDropStatement(conn, DROP_FUNCTION_CHECK_VERSION);  
96 - executeDropStatement(conn, DROP_FUNCTION_CREATE_PARTITION_TS_KV_TABLE);  
97 - executeDropStatement(conn, DROP_FUNCTION_CREATE_PARTITIONS);  
98 - executeDropStatement(conn, DROP_FUNCTION_CREATE_TS_KV_DICTIONARY_TABLE);  
99 - executeDropStatement(conn, DROP_FUNCTION_INSERT_INTO_DICTIONARY);  
100 - executeDropStatement(conn, DROP_FUNCTION_INSERT_INTO_TS_KV);  
101 - executeDropStatement(conn, DROP_FUNCTION_CREATE_NEW_TS_KV_LATEST_TABLE);  
102 - executeDropStatement(conn, DROP_FUNCTION_INSERT_INTO_TS_KV_LATEST); 94 + executeQuery(conn, DROP_PROCEDURE_CHECK_VERSION);
  95 + executeQuery(conn, DROP_PROCEDURE_CREATE_PARTITION_TS_KV_TABLE);
  96 + executeQuery(conn, DROP_PROCEDURE_CREATE_PARTITIONS);
  97 + executeQuery(conn, DROP_PROCEDURE_CREATE_TS_KV_DICTIONARY_TABLE);
  98 + executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_DICTIONARY);
  99 + executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_TS_KV);
  100 + executeQuery(conn, DROP_PROCEDURE_CREATE_NEW_TS_KV_LATEST_TABLE);
  101 + executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_TS_KV_LATEST);
103 102
104 executeQuery(conn, "ALTER TABLE ts_kv ADD COLUMN json_v json;"); 103 executeQuery(conn, "ALTER TABLE ts_kv ADD COLUMN json_v json;");
105 executeQuery(conn, "ALTER TABLE ts_kv_latest ADD COLUMN json_v json;"); 104 executeQuery(conn, "ALTER TABLE ts_kv_latest ADD COLUMN json_v json;");
@@ -45,13 +45,13 @@ public class TimescaleTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaS @@ -45,13 +45,13 @@ public class TimescaleTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaS
45 private long chunkTimeInterval; 45 private long chunkTimeInterval;
46 46
47 public TimescaleTsDatabaseSchemaService() { 47 public TimescaleTsDatabaseSchemaService() {
48 - super("schema-timescale.sql", "schema-timescale-idx.sql"); 48 + super("schema-timescale.sql", null);
49 } 49 }
50 50
51 @Override 51 @Override
52 public void createDatabaseSchema() throws Exception { 52 public void createDatabaseSchema() throws Exception {
53 super.createDatabaseSchema(); 53 super.createDatabaseSchema();
54 - executeQuery("SELECT create_hypertable('tenant_ts_kv', 'ts', chunk_time_interval => " + chunkTimeInterval + ", if_not_exists => true);"); 54 + executeQuery("SELECT create_hypertable('ts_kv', 'ts', chunk_time_interval => " + chunkTimeInterval + ", if_not_exists => true);");
55 } 55 }
56 56
57 private void executeQuery(String query) { 57 private void executeQuery(String query) {
@@ -43,27 +43,27 @@ public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgr @@ -43,27 +43,27 @@ public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgr
43 private static final String TENANT_TS_KV_OLD_TABLE = "tenant_ts_kv_old;"; 43 private static final String TENANT_TS_KV_OLD_TABLE = "tenant_ts_kv_old;";
44 44
45 private static final String CREATE_TS_KV_LATEST_TABLE = "create_ts_kv_latest_table()"; 45 private static final String CREATE_TS_KV_LATEST_TABLE = "create_ts_kv_latest_table()";
46 - private static final String CREATE_NEW_TENANT_TS_KV_TABLE = "create_new_tenant_ts_kv_table()"; 46 + private static final String CREATE_NEW_TS_KV_TABLE = "create_new_ts_kv_table()";
47 private static final String CREATE_TS_KV_DICTIONARY_TABLE = "create_ts_kv_dictionary_table()"; 47 private static final String CREATE_TS_KV_DICTIONARY_TABLE = "create_ts_kv_dictionary_table()";
48 private static final String INSERT_INTO_DICTIONARY = "insert_into_dictionary()"; 48 private static final String INSERT_INTO_DICTIONARY = "insert_into_dictionary()";
49 - private static final String INSERT_INTO_TENANT_TS_KV = "insert_into_tenant_ts_kv()"; 49 + private static final String INSERT_INTO_TS_KV = "insert_into_ts_kv()";
50 private static final String INSERT_INTO_TS_KV_LATEST = "insert_into_ts_kv_latest()"; 50 private static final String INSERT_INTO_TS_KV_LATEST = "insert_into_ts_kv_latest()";
51 51
52 private static final String CALL_CREATE_TS_KV_LATEST_TABLE = CALL_REGEX + CREATE_TS_KV_LATEST_TABLE; 52 private static final String CALL_CREATE_TS_KV_LATEST_TABLE = CALL_REGEX + CREATE_TS_KV_LATEST_TABLE;
53 - private static final String CALL_CREATE_NEW_TENANT_TS_KV_TABLE = CALL_REGEX + CREATE_NEW_TENANT_TS_KV_TABLE; 53 + private static final String CALL_CREATE_NEW_TENANT_TS_KV_TABLE = CALL_REGEX + CREATE_NEW_TS_KV_TABLE;
54 private static final String CALL_CREATE_TS_KV_DICTIONARY_TABLE = CALL_REGEX + CREATE_TS_KV_DICTIONARY_TABLE; 54 private static final String CALL_CREATE_TS_KV_DICTIONARY_TABLE = CALL_REGEX + CREATE_TS_KV_DICTIONARY_TABLE;
55 private static final String CALL_INSERT_INTO_DICTIONARY = CALL_REGEX + INSERT_INTO_DICTIONARY; 55 private static final String CALL_INSERT_INTO_DICTIONARY = CALL_REGEX + INSERT_INTO_DICTIONARY;
56 - private static final String CALL_INSERT_INTO_TS_KV = CALL_REGEX + INSERT_INTO_TENANT_TS_KV; 56 + private static final String CALL_INSERT_INTO_TS_KV = CALL_REGEX + INSERT_INTO_TS_KV;
57 private static final String CALL_INSERT_INTO_TS_KV_LATEST = CALL_REGEX + INSERT_INTO_TS_KV_LATEST; 57 private static final String CALL_INSERT_INTO_TS_KV_LATEST = CALL_REGEX + INSERT_INTO_TS_KV_LATEST;
58 58
59 private static final String DROP_OLD_TENANT_TS_KV_TABLE = DROP_TABLE + TENANT_TS_KV_OLD_TABLE; 59 private static final String DROP_OLD_TENANT_TS_KV_TABLE = DROP_TABLE + TENANT_TS_KV_OLD_TABLE;
60 60
61 - private static final String DROP_FUNCTION_CREATE_TS_KV_LATEST_TABLE = DROP_FUNCTION_IF_EXISTS + CREATE_TS_KV_LATEST_TABLE;  
62 - private static final String DROP_FUNCTION_CREATE_TENANT_TS_KV_TABLE_COPY = DROP_FUNCTION_IF_EXISTS + CREATE_NEW_TENANT_TS_KV_TABLE;  
63 - private static final String DROP_FUNCTION_CREATE_TS_KV_DICTIONARY_TABLE = DROP_FUNCTION_IF_EXISTS + CREATE_TS_KV_DICTIONARY_TABLE;  
64 - private static final String DROP_FUNCTION_INSERT_INTO_DICTIONARY = DROP_FUNCTION_IF_EXISTS + INSERT_INTO_DICTIONARY;  
65 - private static final String DROP_FUNCTION_INSERT_INTO_TENANT_TS_KV = DROP_FUNCTION_IF_EXISTS + INSERT_INTO_TENANT_TS_KV;  
66 - private static final String DROP_FUNCTION_INSERT_INTO_TS_KV_LATEST = DROP_FUNCTION_IF_EXISTS + INSERT_INTO_TS_KV_LATEST; 61 + private static final String DROP_PROCEDURE_CREATE_TS_KV_LATEST_TABLE = DROP_PROCEDURE_IF_EXISTS + CREATE_TS_KV_LATEST_TABLE;
  62 + private static final String DROP_PROCEDURE_CREATE_TENANT_TS_KV_TABLE_COPY = DROP_PROCEDURE_IF_EXISTS + CREATE_NEW_TS_KV_TABLE;
  63 + private static final String DROP_PROCEDURE_CREATE_TS_KV_DICTIONARY_TABLE = DROP_PROCEDURE_IF_EXISTS + CREATE_TS_KV_DICTIONARY_TABLE;
  64 + private static final String DROP_PROCEDURE_INSERT_INTO_DICTIONARY = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_DICTIONARY;
  65 + private static final String DROP_PROCEDURE_INSERT_INTO_TENANT_TS_KV = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_TS_KV;
  66 + private static final String DROP_PROCEDURE_INSERT_INTO_TS_KV_LATEST = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_TS_KV_LATEST;
67 67
68 @Autowired 68 @Autowired
69 private InstallScripts installScripts; 69 private InstallScripts installScripts;
@@ -78,33 +78,31 @@ public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgr @@ -78,33 +78,31 @@ public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgr
78 loadSql(conn); 78 loadSql(conn);
79 boolean versionValid = checkVersion(conn); 79 boolean versionValid = checkVersion(conn);
80 if (!versionValid) { 80 if (!versionValid) {
81 - log.info("PostgreSQL version should be at least more than 9.6!"); 81 + log.info("PostgreSQL version should be at least more than 11!");
82 log.info("Please upgrade your PostgreSQL and restart the script!"); 82 log.info("Please upgrade your PostgreSQL and restart the script!");
83 } else { 83 } else {
84 log.info("PostgreSQL version is valid!"); 84 log.info("PostgreSQL version is valid!");
85 log.info("Updating schema ..."); 85 log.info("Updating schema ...");
86 - executeFunction(conn, CALL_CREATE_TS_KV_LATEST_TABLE);  
87 - executeFunction(conn, CALL_CREATE_NEW_TENANT_TS_KV_TABLE); 86 + executeQuery(conn, CALL_CREATE_TS_KV_LATEST_TABLE);
  87 + executeQuery(conn, CALL_CREATE_NEW_TENANT_TS_KV_TABLE);
88 88
89 - executeQuery(conn, "SELECT create_hypertable('tenant_ts_kv', 'ts', chunk_time_interval => " + chunkTimeInterval + ", if_not_exists => true);"); 89 + executeQuery(conn, "SELECT create_hypertable('ts_kv', 'ts', chunk_time_interval => " + chunkTimeInterval + ", if_not_exists => true);");
90 90
91 - executeFunction(conn, CALL_CREATE_TS_KV_DICTIONARY_TABLE);  
92 - executeFunction(conn, CALL_INSERT_INTO_DICTIONARY);  
93 - executeFunction(conn, CALL_INSERT_INTO_TS_KV);  
94 - executeFunction(conn, CALL_INSERT_INTO_TS_KV_LATEST); 91 + executeQuery(conn, CALL_CREATE_TS_KV_DICTIONARY_TABLE);
  92 + executeQuery(conn, CALL_INSERT_INTO_DICTIONARY);
  93 + executeQuery(conn, CALL_INSERT_INTO_TS_KV);
  94 + executeQuery(conn, CALL_INSERT_INTO_TS_KV_LATEST);
95 95
96 - //executeQuery(conn, "SELECT set_chunk_time_interval('tenant_ts_kv', " + chunkTimeInterval +");"); 96 + executeQuery(conn, DROP_OLD_TENANT_TS_KV_TABLE);
97 97
98 - executeDropStatement(conn, DROP_OLD_TENANT_TS_KV_TABLE); 98 + executeQuery(conn, DROP_PROCEDURE_CREATE_TS_KV_LATEST_TABLE);
  99 + executeQuery(conn, DROP_PROCEDURE_CREATE_TENANT_TS_KV_TABLE_COPY);
  100 + executeQuery(conn, DROP_PROCEDURE_CREATE_TS_KV_DICTIONARY_TABLE);
  101 + executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_DICTIONARY);
  102 + executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_TENANT_TS_KV);
  103 + executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_TS_KV_LATEST);
99 104
100 - executeDropStatement(conn, DROP_FUNCTION_CREATE_TS_KV_LATEST_TABLE);  
101 - executeDropStatement(conn, DROP_FUNCTION_CREATE_TENANT_TS_KV_TABLE_COPY);  
102 - executeDropStatement(conn, DROP_FUNCTION_CREATE_TS_KV_DICTIONARY_TABLE);  
103 - executeDropStatement(conn, DROP_FUNCTION_INSERT_INTO_DICTIONARY);  
104 - executeDropStatement(conn, DROP_FUNCTION_INSERT_INTO_TENANT_TS_KV);  
105 - executeDropStatement(conn, DROP_FUNCTION_INSERT_INTO_TS_KV_LATEST);  
106 -  
107 - executeQuery(conn, "ALTER TABLE tenant_ts_kv ADD COLUMN json_v json;"); 105 + executeQuery(conn, "ALTER TABLE ts_kv ADD COLUMN json_v json;");
108 executeQuery(conn, "ALTER TABLE ts_kv_latest ADD COLUMN json_v json;"); 106 executeQuery(conn, "ALTER TABLE ts_kv_latest ADD COLUMN json_v json;");
109 107
110 log.info("schema timeseries updated!"); 108 log.info("schema timeseries updated!");
@@ -18,6 +18,7 @@ package org.thingsboard.server.service.script; @@ -18,6 +18,7 @@ package org.thingsboard.server.service.script;
18 import com.google.common.util.concurrent.FutureCallback; 18 import com.google.common.util.concurrent.FutureCallback;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 import delight.nashornsandbox.NashornSandbox; 22 import delight.nashornsandbox.NashornSandbox;
22 import delight.nashornsandbox.NashornSandboxes; 23 import delight.nashornsandbox.NashornSandboxes;
23 import jdk.nashorn.api.scripting.NashornScriptEngineFactory; 24 import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
@@ -28,20 +29,17 @@ import org.springframework.beans.factory.annotation.Value; @@ -28,20 +29,17 @@ import org.springframework.beans.factory.annotation.Value;
28 import org.springframework.scheduling.annotation.Scheduled; 29 import org.springframework.scheduling.annotation.Scheduled;
29 import org.thingsboard.common.util.ThingsBoardThreadFactory; 30 import org.thingsboard.common.util.ThingsBoardThreadFactory;
30 31
31 -import javax.annotation.Nullable;  
32 import javax.annotation.PostConstruct; 32 import javax.annotation.PostConstruct;
33 import javax.annotation.PreDestroy; 33 import javax.annotation.PreDestroy;
34 import javax.script.Invocable; 34 import javax.script.Invocable;
35 import javax.script.ScriptEngine; 35 import javax.script.ScriptEngine;
36 import javax.script.ScriptException; 36 import javax.script.ScriptException;
37 import java.util.UUID; 37 import java.util.UUID;
38 -import java.util.concurrent.Callable;  
39 import java.util.concurrent.ExecutionException; 38 import java.util.concurrent.ExecutionException;
40 import java.util.concurrent.ExecutorService; 39 import java.util.concurrent.ExecutorService;
41 import java.util.concurrent.Executors; 40 import java.util.concurrent.Executors;
42 import java.util.concurrent.ScheduledExecutorService; 41 import java.util.concurrent.ScheduledExecutorService;
43 import java.util.concurrent.TimeUnit; 42 import java.util.concurrent.TimeUnit;
44 -import java.util.concurrent.TimeoutException;  
45 import java.util.concurrent.atomic.AtomicInteger; 43 import java.util.concurrent.atomic.AtomicInteger;
46 44
47 @Slf4j 45 @Slf4j
@@ -140,7 +138,7 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer @@ -140,7 +138,7 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
140 if (maxRequestsTimeout > 0) { 138 if (maxRequestsTimeout > 0) {
141 result = Futures.withTimeout(result, maxRequestsTimeout, TimeUnit.MILLISECONDS, timeoutExecutorService); 139 result = Futures.withTimeout(result, maxRequestsTimeout, TimeUnit.MILLISECONDS, timeoutExecutorService);
142 } 140 }
143 - Futures.addCallback(result, evalCallback); 141 + Futures.addCallback(result, evalCallback, MoreExecutors.directExecutor());
144 return result; 142 return result;
145 } 143 }
146 144
@@ -163,7 +161,7 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer @@ -163,7 +161,7 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
163 if (maxRequestsTimeout > 0) { 161 if (maxRequestsTimeout > 0) {
164 result = Futures.withTimeout(result, maxRequestsTimeout, TimeUnit.MILLISECONDS, timeoutExecutorService); 162 result = Futures.withTimeout(result, maxRequestsTimeout, TimeUnit.MILLISECONDS, timeoutExecutorService);
165 } 163 }
166 - Futures.addCallback(result, invokeCallback); 164 + Futures.addCallback(result, invokeCallback, MoreExecutors.directExecutor());
167 return result; 165 return result;
168 } 166 }
169 167
@@ -18,6 +18,7 @@ package org.thingsboard.server.service.script; @@ -18,6 +18,7 @@ package org.thingsboard.server.service.script;
18 import com.google.common.util.concurrent.FutureCallback; 18 import com.google.common.util.concurrent.FutureCallback;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 import lombok.Getter; 22 import lombok.Getter;
22 import lombok.extern.slf4j.Slf4j; 23 import lombok.extern.slf4j.Slf4j;
23 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
@@ -40,7 +41,6 @@ import java.util.UUID; @@ -40,7 +41,6 @@ import java.util.UUID;
40 import java.util.concurrent.ConcurrentHashMap; 41 import java.util.concurrent.ConcurrentHashMap;
41 import java.util.concurrent.TimeoutException; 42 import java.util.concurrent.TimeoutException;
42 import java.util.concurrent.atomic.AtomicInteger; 43 import java.util.concurrent.atomic.AtomicInteger;
43 -import java.util.concurrent.atomic.AtomicLong;  
44 44
45 @Slf4j 45 @Slf4j
46 @ConditionalOnProperty(prefix = "js", value = "evaluator", havingValue = "remote", matchIfMissing = true) 46 @ConditionalOnProperty(prefix = "js", value = "evaluator", havingValue = "remote", matchIfMissing = true)
@@ -166,7 +166,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService { @@ -166,7 +166,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
166 } 166 }
167 kafkaFailedMsgs.incrementAndGet(); 167 kafkaFailedMsgs.incrementAndGet();
168 } 168 }
169 - }); 169 + }, MoreExecutors.directExecutor());
170 return Futures.transform(future, response -> { 170 return Futures.transform(future, response -> {
171 JsInvokeProtos.JsCompileResponse compilationResult = response.getCompileResponse(); 171 JsInvokeProtos.JsCompileResponse compilationResult = response.getCompileResponse();
172 UUID compiledScriptId = new UUID(compilationResult.getScriptIdMSB(), compilationResult.getScriptIdLSB()); 172 UUID compiledScriptId = new UUID(compilationResult.getScriptIdMSB(), compilationResult.getScriptIdLSB());
@@ -178,7 +178,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService { @@ -178,7 +178,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
178 log.debug("[{}] Failed to compile script due to [{}]: {}", compiledScriptId, compilationResult.getErrorCode().name(), compilationResult.getErrorDetails()); 178 log.debug("[{}] Failed to compile script due to [{}]: {}", compiledScriptId, compilationResult.getErrorCode().name(), compilationResult.getErrorDetails());
179 throw new RuntimeException(compilationResult.getErrorDetails()); 179 throw new RuntimeException(compilationResult.getErrorDetails());
180 } 180 }
181 - }); 181 + }, MoreExecutors.directExecutor());
182 } 182 }
183 183
184 @Override 184 @Override
@@ -217,7 +217,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService { @@ -217,7 +217,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
217 } 217 }
218 kafkaFailedMsgs.incrementAndGet(); 218 kafkaFailedMsgs.incrementAndGet();
219 } 219 }
220 - }); 220 + }, MoreExecutors.directExecutor());
221 return Futures.transform(future, response -> { 221 return Futures.transform(future, response -> {
222 JsInvokeProtos.JsInvokeResponse invokeResult = response.getInvokeResponse(); 222 JsInvokeProtos.JsInvokeResponse invokeResult = response.getInvokeResponse();
223 if (invokeResult.getSuccess()) { 223 if (invokeResult.getSuccess()) {
@@ -226,7 +226,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService { @@ -226,7 +226,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
226 log.debug("[{}] Failed to compile script due to [{}]: {}", scriptId, invokeResult.getErrorCode().name(), invokeResult.getErrorDetails()); 226 log.debug("[{}] Failed to compile script due to [{}]: {}", scriptId, invokeResult.getErrorCode().name(), invokeResult.getErrorDetails());
227 throw new RuntimeException(invokeResult.getErrorDetails()); 227 throw new RuntimeException(invokeResult.getErrorDetails());
228 } 228 }
229 - }); 229 + }, MoreExecutors.directExecutor());
230 } 230 }
231 231
232 @Override 232 @Override
@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
21 import com.google.common.collect.Sets; 21 import com.google.common.collect.Sets;
22 import com.google.common.util.concurrent.Futures; 22 import com.google.common.util.concurrent.Futures;
23 import com.google.common.util.concurrent.ListenableFuture; 23 import com.google.common.util.concurrent.ListenableFuture;
  24 +import com.google.common.util.concurrent.MoreExecutors;
24 import lombok.extern.slf4j.Slf4j; 25 import lombok.extern.slf4j.Slf4j;
25 import org.apache.commons.lang3.StringUtils; 26 import org.apache.commons.lang3.StringUtils;
26 import org.thingsboard.server.common.data.id.EntityId; 27 import org.thingsboard.server.common.data.id.EntityId;
@@ -121,7 +122,7 @@ public class RuleNodeJsScriptEngine implements org.thingsboard.rule.engine.api.S @@ -121,7 +122,7 @@ public class RuleNodeJsScriptEngine implements org.thingsboard.rule.engine.api.S
121 } else { 122 } else {
122 return Futures.immediateFuture(unbindMsg(json, msg)); 123 return Futures.immediateFuture(unbindMsg(json, msg));
123 } 124 }
124 - }); 125 + }, MoreExecutors.directExecutor());
125 } 126 }
126 127
127 @Override 128 @Override
@@ -174,7 +175,7 @@ public class RuleNodeJsScriptEngine implements org.thingsboard.rule.engine.api.S @@ -174,7 +175,7 @@ public class RuleNodeJsScriptEngine implements org.thingsboard.rule.engine.api.S
174 } else { 175 } else {
175 return Futures.immediateFuture(json.asBoolean()); 176 return Futures.immediateFuture(json.asBoolean());
176 } 177 }
177 - }); 178 + }, MoreExecutors.directExecutor());
178 } 179 }
179 180
180 @Override 181 @Override
@@ -232,7 +233,7 @@ public class RuleNodeJsScriptEngine implements org.thingsboard.rule.engine.api.S @@ -232,7 +233,7 @@ public class RuleNodeJsScriptEngine implements org.thingsboard.rule.engine.api.S
232 return Futures.immediateFailedFuture(new ScriptException(e)); 233 return Futures.immediateFailedFuture(new ScriptException(e));
233 } 234 }
234 } 235 }
235 - }); 236 + }, MoreExecutors.directExecutor());
236 } 237 }
237 238
238 public void destroy() { 239 public void destroy() {
@@ -64,14 +64,26 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; @@ -64,14 +64,26 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
64 import javax.annotation.Nullable; 64 import javax.annotation.Nullable;
65 import javax.annotation.PostConstruct; 65 import javax.annotation.PostConstruct;
66 import javax.annotation.PreDestroy; 66 import javax.annotation.PreDestroy;
67 -import java.util.*; 67 +import java.util.ArrayList;
  68 +import java.util.Arrays;
  69 +import java.util.Collections;
  70 +import java.util.HashSet;
  71 +import java.util.List;
  72 +import java.util.Optional;
  73 +import java.util.Random;
  74 +import java.util.Set;
  75 +import java.util.UUID;
68 import java.util.concurrent.ConcurrentHashMap; 76 import java.util.concurrent.ConcurrentHashMap;
69 import java.util.concurrent.ConcurrentMap; 77 import java.util.concurrent.ConcurrentMap;
70 import java.util.concurrent.ExecutionException; 78 import java.util.concurrent.ExecutionException;
71 import java.util.concurrent.Executors; 79 import java.util.concurrent.Executors;
72 import java.util.concurrent.TimeUnit; 80 import java.util.concurrent.TimeUnit;
73 81
74 -import static org.thingsboard.server.common.data.DataConstants.*; 82 +import static org.thingsboard.server.common.data.DataConstants.ACTIVITY_EVENT;
  83 +import static org.thingsboard.server.common.data.DataConstants.CONNECT_EVENT;
  84 +import static org.thingsboard.server.common.data.DataConstants.DISCONNECT_EVENT;
  85 +import static org.thingsboard.server.common.data.DataConstants.INACTIVITY_EVENT;
  86 +import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE;
75 87
76 /** 88 /**
77 * Created by ashvayka on 01.05.18. 89 * Created by ashvayka on 01.05.18.
@@ -401,7 +413,7 @@ public class DefaultDeviceStateService implements DeviceStateService { @@ -401,7 +413,7 @@ public class DefaultDeviceStateService implements DeviceStateService {
401 public void onFailure(Throwable t) { 413 public void onFailure(Throwable t) {
402 log.warn("Failed to register device to the state service", t); 414 log.warn("Failed to register device to the state service", t);
403 } 415 }
404 - }); 416 + }, MoreExecutors.directExecutor());
405 } else { 417 } else {
406 sendDeviceEvent(device.getTenantId(), device.getId(), address.get(), true, false, false); 418 sendDeviceEvent(device.getTenantId(), device.getId(), address.get(), true, false, false);
407 } 419 }
@@ -456,10 +468,10 @@ public class DefaultDeviceStateService implements DeviceStateService { @@ -456,10 +468,10 @@ public class DefaultDeviceStateService implements DeviceStateService {
456 private ListenableFuture<DeviceStateData> fetchDeviceState(Device device) { 468 private ListenableFuture<DeviceStateData> fetchDeviceState(Device device) {
457 if (persistToTelemetry) { 469 if (persistToTelemetry) {
458 ListenableFuture<List<TsKvEntry>> tsData = tsService.findLatest(TenantId.SYS_TENANT_ID, device.getId(), PERSISTENT_ATTRIBUTES); 470 ListenableFuture<List<TsKvEntry>> tsData = tsService.findLatest(TenantId.SYS_TENANT_ID, device.getId(), PERSISTENT_ATTRIBUTES);
459 - return Futures.transform(tsData, extractDeviceStateData(device)); 471 + return Futures.transform(tsData, extractDeviceStateData(device), MoreExecutors.directExecutor());
460 } else { 472 } else {
461 ListenableFuture<List<AttributeKvEntry>> attrData = attributesService.find(TenantId.SYS_TENANT_ID, device.getId(), DataConstants.SERVER_SCOPE, PERSISTENT_ATTRIBUTES); 473 ListenableFuture<List<AttributeKvEntry>> attrData = attributesService.find(TenantId.SYS_TENANT_ID, device.getId(), DataConstants.SERVER_SCOPE, PERSISTENT_ATTRIBUTES);
462 - return Futures.transform(attrData, extractDeviceStateData(device)); 474 + return Futures.transform(attrData, extractDeviceStateData(device), MoreExecutors.directExecutor());
463 } 475 }
464 } 476 }
465 477
@@ -21,6 +21,7 @@ import com.google.common.base.Function; @@ -21,6 +21,7 @@ import com.google.common.base.Function;
21 import com.google.common.util.concurrent.FutureCallback; 21 import com.google.common.util.concurrent.FutureCallback;
22 import com.google.common.util.concurrent.Futures; 22 import com.google.common.util.concurrent.Futures;
23 import com.google.common.util.concurrent.ListenableFuture; 23 import com.google.common.util.concurrent.ListenableFuture;
  24 +import com.google.common.util.concurrent.MoreExecutors;
24 import lombok.extern.slf4j.Slf4j; 25 import lombok.extern.slf4j.Slf4j;
25 import org.springframework.beans.factory.annotation.Autowired; 26 import org.springframework.beans.factory.annotation.Autowired;
26 import org.springframework.beans.factory.annotation.Value; 27 import org.springframework.beans.factory.annotation.Value;
@@ -54,9 +55,6 @@ import org.thingsboard.server.service.telemetry.cmd.SubscriptionCmd; @@ -54,9 +55,6 @@ import org.thingsboard.server.service.telemetry.cmd.SubscriptionCmd;
54 import org.thingsboard.server.service.telemetry.cmd.TelemetryPluginCmd; 55 import org.thingsboard.server.service.telemetry.cmd.TelemetryPluginCmd;
55 import org.thingsboard.server.service.telemetry.cmd.TelemetryPluginCmdsWrapper; 56 import org.thingsboard.server.service.telemetry.cmd.TelemetryPluginCmdsWrapper;
56 import org.thingsboard.server.service.telemetry.cmd.TimeseriesSubscriptionCmd; 57 import org.thingsboard.server.service.telemetry.cmd.TimeseriesSubscriptionCmd;
57 -import org.thingsboard.server.service.telemetry.exception.AccessDeniedException;  
58 -import org.thingsboard.server.service.telemetry.exception.EntityNotFoundException;  
59 -import org.thingsboard.server.service.telemetry.exception.InternalErrorException;  
60 import org.thingsboard.server.service.telemetry.exception.UnauthorizedException; 58 import org.thingsboard.server.service.telemetry.exception.UnauthorizedException;
61 import org.thingsboard.server.service.telemetry.sub.SubscriptionErrorCode; 59 import org.thingsboard.server.service.telemetry.sub.SubscriptionErrorCode;
62 import org.thingsboard.server.service.telemetry.sub.SubscriptionState; 60 import org.thingsboard.server.service.telemetry.sub.SubscriptionState;
@@ -70,12 +68,14 @@ import java.util.ArrayList; @@ -70,12 +68,14 @@ import java.util.ArrayList;
70 import java.util.Collections; 68 import java.util.Collections;
71 import java.util.HashMap; 69 import java.util.HashMap;
72 import java.util.HashSet; 70 import java.util.HashSet;
73 -import java.util.Iterator;  
74 import java.util.List; 71 import java.util.List;
75 import java.util.Map; 72 import java.util.Map;
76 import java.util.Optional; 73 import java.util.Optional;
77 import java.util.Set; 74 import java.util.Set;
78 -import java.util.concurrent.*; 75 +import java.util.concurrent.ConcurrentHashMap;
  76 +import java.util.concurrent.ConcurrentMap;
  77 +import java.util.concurrent.ExecutorService;
  78 +import java.util.concurrent.Executors;
79 import java.util.function.Consumer; 79 import java.util.function.Consumer;
80 import java.util.stream.Collectors; 80 import java.util.stream.Collectors;
81 81
@@ -616,7 +616,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi @@ -616,7 +616,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
616 } 616 }
617 617
618 ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures); 618 ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures);
619 - Futures.addCallback(future, callback); 619 + Futures.addCallback(future, callback, MoreExecutors.directExecutor());
620 } 620 }
621 621
622 @Override 622 @Override
@@ -630,7 +630,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi @@ -630,7 +630,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
630 return new FutureCallback<ValidationResult>() { 630 return new FutureCallback<ValidationResult>() {
631 @Override 631 @Override
632 public void onSuccess(@Nullable ValidationResult result) { 632 public void onSuccess(@Nullable ValidationResult result) {
633 - Futures.addCallback(attributesService.find(tenantId, entityId, scope, keys), callback); 633 + Futures.addCallback(attributesService.find(tenantId, entityId, scope, keys), callback, MoreExecutors.directExecutor());
634 } 634 }
635 635
636 @Override 636 @Override
@@ -650,7 +650,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi @@ -650,7 +650,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
650 } 650 }
651 651
652 ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures); 652 ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures);
653 - Futures.addCallback(future, callback); 653 + Futures.addCallback(future, callback, MoreExecutors.directExecutor());
654 } 654 }
655 655
656 @Override 656 @Override
@@ -664,7 +664,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi @@ -664,7 +664,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
664 return new FutureCallback<ValidationResult>() { 664 return new FutureCallback<ValidationResult>() {
665 @Override 665 @Override
666 public void onSuccess(@Nullable ValidationResult result) { 666 public void onSuccess(@Nullable ValidationResult result) {
667 - Futures.addCallback(attributesService.findAll(tenantId, entityId, scope), callback); 667 + Futures.addCallback(attributesService.findAll(tenantId, entityId, scope), callback, MoreExecutors.directExecutor());
668 } 668 }
669 669
670 @Override 670 @Override
@@ -19,10 +19,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; @@ -19,10 +19,9 @@ import com.fasterxml.jackson.core.JsonProcessingException;
19 import com.fasterxml.jackson.databind.ObjectMapper; 19 import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.google.common.util.concurrent.Futures; 20 import com.google.common.util.concurrent.Futures;
21 import com.google.common.util.concurrent.ListenableFuture; 21 import com.google.common.util.concurrent.ListenableFuture;
  22 +import com.google.common.util.concurrent.MoreExecutors;
22 import lombok.extern.slf4j.Slf4j; 23 import lombok.extern.slf4j.Slf4j;
23 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
24 -import org.springframework.beans.factory.annotation.Value;  
25 -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
26 import org.springframework.stereotype.Service; 25 import org.springframework.stereotype.Service;
27 import org.springframework.util.StringUtils; 26 import org.springframework.util.StringUtils;
28 import org.thingsboard.server.common.data.Device; 27 import org.thingsboard.server.common.data.Device;
@@ -42,19 +41,10 @@ import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponse @@ -42,19 +41,10 @@ import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponse
42 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; 41 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
43 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; 42 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg;
44 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; 43 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg;
45 -import org.thingsboard.server.kafka.TBKafkaConsumerTemplate;  
46 -import org.thingsboard.server.kafka.TBKafkaProducerTemplate;  
47 -import org.thingsboard.server.kafka.TbKafkaResponseTemplate;  
48 -import org.thingsboard.server.kafka.TbKafkaSettings;  
49 -import org.thingsboard.server.service.cluster.discovery.DiscoveryService;  
50 import org.thingsboard.server.service.executors.DbCallbackExecutorService; 44 import org.thingsboard.server.service.executors.DbCallbackExecutorService;
51 import org.thingsboard.server.service.state.DeviceStateService; 45 import org.thingsboard.server.service.state.DeviceStateService;
52 46
53 -import javax.annotation.PostConstruct;  
54 -import javax.annotation.PreDestroy;  
55 import java.util.UUID; 47 import java.util.UUID;
56 -import java.util.concurrent.ExecutorService;  
57 -import java.util.concurrent.Executors;  
58 import java.util.concurrent.locks.ReentrantLock; 48 import java.util.concurrent.locks.ReentrantLock;
59 49
60 /** 50 /**
@@ -145,7 +135,7 @@ public class LocalTransportApiService implements TransportApiService { @@ -145,7 +135,7 @@ public class LocalTransportApiService implements TransportApiService {
145 try { 135 try {
146 ValidateDeviceCredentialsResponseMsg.Builder builder = ValidateDeviceCredentialsResponseMsg.newBuilder(); 136 ValidateDeviceCredentialsResponseMsg.Builder builder = ValidateDeviceCredentialsResponseMsg.newBuilder();
147 builder.setDeviceInfo(getDeviceInfoProto(device)); 137 builder.setDeviceInfo(getDeviceInfoProto(device));
148 - if(!StringUtils.isEmpty(credentials.getCredentialsValue())){ 138 + if (!StringUtils.isEmpty(credentials.getCredentialsValue())) {
149 builder.setCredentialsBody(credentials.getCredentialsValue()); 139 builder.setCredentialsBody(credentials.getCredentialsValue());
150 } 140 }
151 return TransportApiResponseMsg.newBuilder() 141 return TransportApiResponseMsg.newBuilder()
@@ -154,7 +144,7 @@ public class LocalTransportApiService implements TransportApiService { @@ -154,7 +144,7 @@ public class LocalTransportApiService implements TransportApiService {
154 log.warn("[{}] Failed to lookup device by id", deviceId, e); 144 log.warn("[{}] Failed to lookup device by id", deviceId, e);
155 return getEmptyTransportApiResponse(); 145 return getEmptyTransportApiResponse();
156 } 146 }
157 - }); 147 + }, MoreExecutors.directExecutor());
158 } 148 }
159 149
160 private DeviceInfoProto getDeviceInfoProto(Device device) throws JsonProcessingException { 150 private DeviceInfoProto getDeviceInfoProto(Device device) throws JsonProcessingException {
@@ -298,7 +298,7 @@ caffeine: @@ -298,7 +298,7 @@ caffeine:
298 redis: 298 redis:
299 # standalone or cluster 299 # standalone or cluster
300 connection: 300 connection:
301 - type: standalone 301 + type: "${REDIS_CONNECTION_TYPE:standalone}"
302 standalone: 302 standalone:
303 host: "${REDIS_HOST:localhost}" 303 host: "${REDIS_HOST:localhost}"
304 port: "${REDIS_PORT:6379}" 304 port: "${REDIS_PORT:6379}"
@@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
2 2
3 set -e 3 set -e
4 4
5 -chown -R ${pkg.name}: ${pkg.logFolder}  
6 -chown -R ${pkg.name}: ${pkg.installFolder} 5 +chown -R ${pkg.user}: ${pkg.logFolder}
  6 +chown -R ${pkg.user}: ${pkg.installFolder}
7 systemctl --no-reload enable ${pkg.name}.service >/dev/null 2>&1 || : 7 systemctl --no-reload enable ${pkg.name}.service >/dev/null 2>&1 || :
8 8
9 exit 0 9 exit 0
@@ -2,21 +2,21 @@ @@ -2,21 +2,21 @@
2 2
3 set -e 3 set -e
4 4
5 -if ! getent group ${pkg.name} >/dev/null; then  
6 - addgroup --system ${pkg.name} 5 +if ! getent group ${pkg.user} >/dev/null; then
  6 + addgroup --system ${pkg.user}
7 fi 7 fi
8 8
9 -if ! getent passwd ${pkg.name} >/dev/null; then 9 +if ! getent passwd ${pkg.user} >/dev/null; then
10 adduser --quiet \ 10 adduser --quiet \
11 --system \ 11 --system \
12 - --ingroup ${pkg.name} \ 12 + --ingroup ${pkg.user} \
13 --quiet \ 13 --quiet \
14 --disabled-login \ 14 --disabled-login \
15 --disabled-password \ 15 --disabled-password \
16 --home ${pkg.installFolder} \ 16 --home ${pkg.installFolder} \
17 --no-create-home \ 17 --no-create-home \
18 -gecos "Thingsboard application" \ 18 -gecos "Thingsboard application" \
19 - ${pkg.name} 19 + ${pkg.user}
20 fi 20 fi
21 21
22 exit 0 22 exit 0
1 #!/bin/sh 1 #!/bin/sh
2 2
3 -chown -R ${pkg.name}: ${pkg.logFolder}  
4 -chown -R ${pkg.name}: ${pkg.installFolder} 3 +chown -R ${pkg.user}: ${pkg.logFolder}
  4 +chown -R ${pkg.user}: ${pkg.installFolder}
5 5
6 if [ $1 -eq 1 ] ; then 6 if [ $1 -eq 1 ] ; then
7 # Initial installation 7 # Initial installation
@@ -3,7 +3,7 @@ Description=${pkg.name} @@ -3,7 +3,7 @@ Description=${pkg.name}
3 After=syslog.target 3 After=syslog.target
4 4
5 [Service] 5 [Service]
6 -User=${pkg.name} 6 +User=${pkg.user}
7 ExecStart=${pkg.installFolder}/bin/${pkg.name}.jar 7 ExecStart=${pkg.installFolder}/bin/${pkg.name}.jar
8 SuccessExitStatus=143 8 SuccessExitStatus=143
9 9
@@ -44,7 +44,7 @@ installDir=${pkg.installFolder}/data @@ -44,7 +44,7 @@ installDir=${pkg.installFolder}/data
44 44
45 source "${CONF_FOLDER}/${configfile}" 45 source "${CONF_FOLDER}/${configfile}"
46 46
47 -run_user=${pkg.name} 47 +run_user=${pkg.user}
48 48
49 su -s /bin/sh -c "java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \ 49 su -s /bin/sh -c "java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \
50 -Dinstall.data_dir=${installDir} \ 50 -Dinstall.data_dir=${installDir} \
@@ -43,7 +43,7 @@ installDir=${pkg.installFolder}/data @@ -43,7 +43,7 @@ installDir=${pkg.installFolder}/data
43 43
44 source "${CONF_FOLDER}/${configfile}" 44 source "${CONF_FOLDER}/${configfile}"
45 45
46 -run_user=${pkg.name} 46 +run_user=${pkg.user}
47 47
48 su -s /bin/sh -c "java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \ 48 su -s /bin/sh -c "java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \
49 -Dinstall.data_dir=${installDir} \ 49 -Dinstall.data_dir=${installDir} \
@@ -18,6 +18,7 @@ package org.thingsboard.server.kafka; @@ -18,6 +18,7 @@ package org.thingsboard.server.kafka;
18 import com.google.common.util.concurrent.FutureCallback; 18 import com.google.common.util.concurrent.FutureCallback;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22
22 import java.util.concurrent.Executor; 23 import java.util.concurrent.Executor;
23 import java.util.concurrent.ScheduledExecutorService; 24 import java.util.concurrent.ScheduledExecutorService;
@@ -59,7 +60,7 @@ public class AsyncCallbackTemplate { @@ -59,7 +60,7 @@ public class AsyncCallbackTemplate {
59 if (executor != null) { 60 if (executor != null) {
60 Futures.addCallback(future, callback, executor); 61 Futures.addCallback(future, callback, executor);
61 } else { 62 } else {
62 - Futures.addCallback(future, callback); 63 + Futures.addCallback(future, callback, MoreExecutors.directExecutor());
63 } 64 }
64 } 65 }
65 66
@@ -18,19 +18,20 @@ package org.thingsboard.common.util; @@ -18,19 +18,20 @@ package org.thingsboard.common.util;
18 import com.google.common.util.concurrent.FutureCallback; 18 import com.google.common.util.concurrent.FutureCallback;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22
22 import java.util.concurrent.Executor; 23 import java.util.concurrent.Executor;
23 import java.util.function.Consumer; 24 import java.util.function.Consumer;
24 25
25 public class DonAsynchron { 26 public class DonAsynchron {
26 27
27 - public static <T> void withCallback(ListenableFuture<T> future, Consumer<T> onSuccess,  
28 - Consumer<Throwable> onFailure) { 28 + public static <T> void withCallback(ListenableFuture<T> future, Consumer<T> onSuccess,
  29 + Consumer<Throwable> onFailure) {
29 withCallback(future, onSuccess, onFailure, null); 30 withCallback(future, onSuccess, onFailure, null);
30 } 31 }
31 32
32 - public static <T> void withCallback(ListenableFuture<T> future, Consumer<T> onSuccess,  
33 - Consumer<Throwable> onFailure, Executor executor) { 33 + public static <T> void withCallback(ListenableFuture<T> future, Consumer<T> onSuccess,
  34 + Consumer<Throwable> onFailure, Executor executor) {
34 FutureCallback<T> callback = new FutureCallback<T>() { 35 FutureCallback<T> callback = new FutureCallback<T>() {
35 @Override 36 @Override
36 public void onSuccess(T result) { 37 public void onSuccess(T result) {
@@ -49,7 +50,7 @@ public class DonAsynchron { @@ -49,7 +50,7 @@ public class DonAsynchron {
49 if (executor != null) { 50 if (executor != null) {
50 Futures.addCallback(future, callback, executor); 51 Futures.addCallback(future, callback, executor);
51 } else { 52 } else {
52 - Futures.addCallback(future, callback); 53 + Futures.addCallback(future, callback, MoreExecutors.directExecutor());
53 } 54 }
54 } 55 }
55 } 56 }
@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode; @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode;
20 import com.google.common.base.Function; 20 import com.google.common.base.Function;
21 import com.google.common.util.concurrent.Futures; 21 import com.google.common.util.concurrent.Futures;
22 import com.google.common.util.concurrent.ListenableFuture; 22 import com.google.common.util.concurrent.ListenableFuture;
  23 +import com.google.common.util.concurrent.MoreExecutors;
23 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
24 import org.springframework.beans.factory.annotation.Autowired; 25 import org.springframework.beans.factory.annotation.Autowired;
25 import org.springframework.stereotype.Service; 26 import org.springframework.stereotype.Service;
@@ -53,7 +54,6 @@ import javax.annotation.Nullable; @@ -53,7 +54,6 @@ import javax.annotation.Nullable;
53 import javax.annotation.PostConstruct; 54 import javax.annotation.PostConstruct;
54 import javax.annotation.PreDestroy; 55 import javax.annotation.PreDestroy;
55 import java.util.ArrayList; 56 import java.util.ArrayList;
56 -import java.util.Collections;  
57 import java.util.Comparator; 57 import java.util.Comparator;
58 import java.util.List; 58 import java.util.List;
59 import java.util.Set; 59 import java.util.Set;
@@ -264,9 +264,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -264,9 +264,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
264 entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorName -> { 264 entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorName -> {
265 alarmInfo.setOriginatorName(originatorName); 265 alarmInfo.setOriginatorName(originatorName);
266 return alarmInfo; 266 return alarmInfo;
267 - }  
268 - );  
269 - }); 267 + }, MoreExecutors.directExecutor());
  268 + }, MoreExecutors.directExecutor());
270 } 269 }
271 270
272 @Override 271 @Override
@@ -282,12 +281,12 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -282,12 +281,12 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
282 } 281 }
283 alarmInfo.setOriginatorName(originatorName); 282 alarmInfo.setOriginatorName(originatorName);
284 return alarmInfo; 283 return alarmInfo;
285 - } 284 + }, MoreExecutors.directExecutor()
286 )); 285 ));
287 } 286 }
288 - return Futures.transform(Futures.successfulAsList(alarmFutures), alarmInfos -> {  
289 - return new PageData(alarmInfos, alarms.getTotalPages(), alarms.getTotalElements(), alarms.hasNext());  
290 - }); 287 + return Futures.transform(Futures.successfulAsList(alarmFutures),
  288 + alarmInfos -> new PageData(alarmInfos, alarms.getTotalPages(), alarms.getTotalElements(),
  289 + alarms.hasNext()), MoreExecutors.directExecutor());
291 } 290 }
292 return Futures.immediateFuture(alarms); 291 return Futures.immediateFuture(alarms);
293 } 292 }
@@ -16,9 +16,9 @@ @@ -16,9 +16,9 @@
16 package org.thingsboard.server.dao.asset; 16 package org.thingsboard.server.dao.asset;
17 17
18 18
19 -import com.google.common.base.Function;  
20 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
21 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
22 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
23 import org.hibernate.exception.ConstraintViolationException; 23 import org.hibernate.exception.ConstraintViolationException;
24 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
@@ -29,7 +29,6 @@ import org.springframework.cache.annotation.Cacheable; @@ -29,7 +29,6 @@ import org.springframework.cache.annotation.Cacheable;
29 import org.springframework.stereotype.Service; 29 import org.springframework.stereotype.Service;
30 import org.springframework.util.StringUtils; 30 import org.springframework.util.StringUtils;
31 import org.thingsboard.server.common.data.Customer; 31 import org.thingsboard.server.common.data.Customer;
32 -import org.thingsboard.server.common.data.Device;  
33 import org.thingsboard.server.common.data.EntitySubtype; 32 import org.thingsboard.server.common.data.EntitySubtype;
34 import org.thingsboard.server.common.data.EntityType; 33 import org.thingsboard.server.common.data.EntityType;
35 import org.thingsboard.server.common.data.EntityView; 34 import org.thingsboard.server.common.data.EntityView;
@@ -63,7 +62,10 @@ import java.util.stream.Collectors; @@ -63,7 +62,10 @@ import java.util.stream.Collectors;
63 import static org.thingsboard.server.common.data.CacheConstants.ASSET_CACHE; 62 import static org.thingsboard.server.common.data.CacheConstants.ASSET_CACHE;
64 import static org.thingsboard.server.dao.DaoUtil.toUUIDs; 63 import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
65 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; 64 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
66 -import static org.thingsboard.server.dao.service.Validator.*; 65 +import static org.thingsboard.server.dao.service.Validator.validateId;
  66 +import static org.thingsboard.server.dao.service.Validator.validateIds;
  67 +import static org.thingsboard.server.dao.service.Validator.validatePageLink;
  68 +import static org.thingsboard.server.dao.service.Validator.validateString;
67 69
68 @Service 70 @Service
69 @Slf4j 71 @Slf4j
@@ -298,9 +300,9 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -298,9 +300,9 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
298 } 300 }
299 } 301 }
300 return Futures.successfulAsList(futures); 302 return Futures.successfulAsList(futures);
301 - }); 303 + }, MoreExecutors.directExecutor());
302 assets = Futures.transform(assets, assetList -> 304 assets = Futures.transform(assets, assetList ->
303 - assetList == null ? Collections.emptyList() : assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList()) 305 + assetList == null ? Collections.emptyList() : assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList()), MoreExecutors.directExecutor()
304 ); 306 );
305 return assets; 307 return assets;
306 } 308 }
@@ -314,7 +316,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -314,7 +316,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
314 assetTypes -> { 316 assetTypes -> {
315 assetTypes.sort(Comparator.comparing(EntitySubtype::getType)); 317 assetTypes.sort(Comparator.comparing(EntitySubtype::getType));
316 return assetTypes; 318 return assetTypes;
317 - }); 319 + }, MoreExecutors.directExecutor());
318 } 320 }
319 321
320 private DataValidator<Asset> assetValidator = 322 private DataValidator<Asset> assetValidator =
@@ -375,18 +377,18 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -375,18 +377,18 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
375 }; 377 };
376 378
377 private PaginatedRemover<TenantId, Asset> tenantAssetsRemover = 379 private PaginatedRemover<TenantId, Asset> tenantAssetsRemover =
378 - new PaginatedRemover<TenantId, Asset>() { 380 + new PaginatedRemover<TenantId, Asset>() {
379 381
380 - @Override  
381 - protected PageData<Asset> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {  
382 - return assetDao.findAssetsByTenantId(id.getId(), pageLink);  
383 - } 382 + @Override
  383 + protected PageData<Asset> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
  384 + return assetDao.findAssetsByTenantId(id.getId(), pageLink);
  385 + }
384 386
385 - @Override  
386 - protected void removeEntity(TenantId tenantId, Asset entity) {  
387 - deleteAsset(tenantId, new AssetId(entity.getId().getId()));  
388 - }  
389 - }; 387 + @Override
  388 + protected void removeEntity(TenantId tenantId, Asset entity) {
  389 + deleteAsset(tenantId, new AssetId(entity.getId().getId()));
  390 + }
  391 + };
390 392
391 private PaginatedRemover<CustomerId, Asset> customerAssetsUnasigner = new PaginatedRemover<CustomerId, Asset>() { 393 private PaginatedRemover<CustomerId, Asset> customerAssetsUnasigner = new PaginatedRemover<CustomerId, Asset>() {
392 394
@@ -15,8 +15,6 @@ @@ -15,8 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.dao.dashboard; 16 package org.thingsboard.server.dao.dashboard;
17 17
18 -import com.google.common.base.Function;  
19 -import com.google.common.util.concurrent.Futures;  
20 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
21 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
22 import org.apache.commons.lang3.StringUtils; 20 import org.apache.commons.lang3.StringUtils;
@@ -31,7 +29,6 @@ import org.thingsboard.server.common.data.id.DashboardId; @@ -31,7 +29,6 @@ import org.thingsboard.server.common.data.id.DashboardId;
31 import org.thingsboard.server.common.data.id.TenantId; 29 import org.thingsboard.server.common.data.id.TenantId;
32 import org.thingsboard.server.common.data.page.PageData; 30 import org.thingsboard.server.common.data.page.PageData;
33 import org.thingsboard.server.common.data.page.PageLink; 31 import org.thingsboard.server.common.data.page.PageLink;
34 -import org.thingsboard.server.common.data.page.TimePageLink;  
35 import org.thingsboard.server.common.data.relation.EntityRelation; 32 import org.thingsboard.server.common.data.relation.EntityRelation;
36 import org.thingsboard.server.common.data.relation.RelationTypeGroup; 33 import org.thingsboard.server.common.data.relation.RelationTypeGroup;
37 import org.thingsboard.server.dao.customer.CustomerDao; 34 import org.thingsboard.server.dao.customer.CustomerDao;
@@ -39,12 +36,9 @@ import org.thingsboard.server.dao.entity.AbstractEntityService; @@ -39,12 +36,9 @@ import org.thingsboard.server.dao.entity.AbstractEntityService;
39 import org.thingsboard.server.dao.exception.DataValidationException; 36 import org.thingsboard.server.dao.exception.DataValidationException;
40 import org.thingsboard.server.dao.service.DataValidator; 37 import org.thingsboard.server.dao.service.DataValidator;
41 import org.thingsboard.server.dao.service.PaginatedRemover; 38 import org.thingsboard.server.dao.service.PaginatedRemover;
42 -import org.thingsboard.server.dao.service.TimePaginatedRemover;  
43 import org.thingsboard.server.dao.service.Validator; 39 import org.thingsboard.server.dao.service.Validator;
44 import org.thingsboard.server.dao.tenant.TenantDao; 40 import org.thingsboard.server.dao.tenant.TenantDao;
45 41
46 -import javax.annotation.Nullable;  
47 -import java.util.List;  
48 import java.util.concurrent.ExecutionException; 42 import java.util.concurrent.ExecutionException;
49 43
50 import static org.thingsboard.server.dao.service.Validator.validateId; 44 import static org.thingsboard.server.dao.service.Validator.validateId;
@@ -63,7 +57,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -63,7 +57,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
63 57
64 @Autowired 58 @Autowired
65 private TenantDao tenantDao; 59 private TenantDao tenantDao;
66 - 60 +
67 @Autowired 61 @Autowired
68 private CustomerDao customerDao; 62 private CustomerDao customerDao;
69 63
@@ -101,7 +95,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -101,7 +95,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
101 dashboardValidator.validate(dashboard, DashboardInfo::getTenantId); 95 dashboardValidator.validate(dashboard, DashboardInfo::getTenantId);
102 return dashboardDao.save(dashboard.getTenantId(), dashboard); 96 return dashboardDao.save(dashboard.getTenantId(), dashboard);
103 } 97 }
104 - 98 +
105 @Override 99 @Override
106 public Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, CustomerId customerId) { 100 public Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, CustomerId customerId) {
107 Dashboard dashboard = findDashboardById(tenantId, dashboardId); 101 Dashboard dashboard = findDashboardById(tenantId, dashboardId);
@@ -234,11 +228,11 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -234,11 +228,11 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
234 } 228 }
235 } 229 }
236 } 230 }
237 - };  
238 - 231 + };
  232 +
239 private PaginatedRemover<TenantId, DashboardInfo> tenantDashboardsRemover = 233 private PaginatedRemover<TenantId, DashboardInfo> tenantDashboardsRemover =
240 new PaginatedRemover<TenantId, DashboardInfo>() { 234 new PaginatedRemover<TenantId, DashboardInfo>() {
241 - 235 +
242 @Override 236 @Override
243 protected PageData<DashboardInfo> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) { 237 protected PageData<DashboardInfo> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
244 return dashboardInfoDao.findDashboardsByTenantId(id.getId(), pageLink); 238 return dashboardInfoDao.findDashboardsByTenantId(id.getId(), pageLink);
@@ -267,7 +261,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -267,7 +261,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
267 protected void removeEntity(TenantId tenantId, DashboardInfo entity) { 261 protected void removeEntity(TenantId tenantId, DashboardInfo entity) {
268 unassignDashboardFromCustomer(customer.getTenantId(), new DashboardId(entity.getUuidId()), this.customer.getId()); 262 unassignDashboardFromCustomer(customer.getTenantId(), new DashboardId(entity.getUuidId()), this.customer.getId());
269 } 263 }
270 - 264 +
271 } 265 }
272 266
273 private class CustomerDashboardsUpdater extends PaginatedRemover<Customer, DashboardInfo> { 267 private class CustomerDashboardsUpdater extends PaginatedRemover<Customer, DashboardInfo> {
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device; @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device;
18 import com.fasterxml.jackson.databind.ObjectMapper; 18 import com.fasterxml.jackson.databind.ObjectMapper;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
22 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.beans.factory.annotation.Value; 24 import org.springframework.beans.factory.annotation.Value;
@@ -97,9 +98,9 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { @@ -97,9 +98,9 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService {
97 } 98 }
98 log.warn("Failed to find claimingAllowed attribute for device or it is already claimed![{}]", device.getName()); 99 log.warn("Failed to find claimingAllowed attribute for device or it is already claimed![{}]", device.getName());
99 throw new IllegalArgumentException(); 100 throw new IllegalArgumentException();
100 - }); 101 + }, MoreExecutors.directExecutor());
101 } 102 }
102 - }); 103 + }, MoreExecutors.directExecutor());
103 } 104 }
104 105
105 private ClaimDataInfo getClaimData(Cache cache, Device device) throws ExecutionException, InterruptedException { 106 private ClaimDataInfo getClaimData(Cache cache, Device device) throws ExecutionException, InterruptedException {
@@ -138,9 +139,9 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { @@ -138,9 +139,9 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService {
138 if (device.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) { 139 if (device.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) {
139 device.setCustomerId(customerId); 140 device.setCustomerId(customerId);
140 Device savedDevice = deviceService.saveDevice(device); 141 Device savedDevice = deviceService.saveDevice(device);
141 - return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(savedDevice, ClaimResponse.SUCCESS)); 142 + return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(savedDevice, ClaimResponse.SUCCESS), MoreExecutors.directExecutor());
142 } 143 }
143 - return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(null, ClaimResponse.CLAIMED)); 144 + return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(null, ClaimResponse.CLAIMED), MoreExecutors.directExecutor());
144 } 145 }
145 } else { 146 } else {
146 log.warn("Failed to find the device's claiming message![{}]", device.getName()); 147 log.warn("Failed to find the device's claiming message![{}]", device.getName());
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device; @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device;
18 import com.google.common.base.Function; 18 import com.google.common.base.Function;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
22 import org.apache.commons.lang3.RandomStringUtils; 23 import org.apache.commons.lang3.RandomStringUtils;
23 import org.hibernate.exception.ConstraintViolationException; 24 import org.hibernate.exception.ConstraintViolationException;
@@ -28,7 +29,13 @@ import org.springframework.cache.annotation.CacheEvict; @@ -28,7 +29,13 @@ import org.springframework.cache.annotation.CacheEvict;
28 import org.springframework.cache.annotation.Cacheable; 29 import org.springframework.cache.annotation.Cacheable;
29 import org.springframework.stereotype.Service; 30 import org.springframework.stereotype.Service;
30 import org.springframework.util.StringUtils; 31 import org.springframework.util.StringUtils;
31 -import org.thingsboard.server.common.data.*; 32 +import org.thingsboard.server.common.data.Customer;
  33 +import org.thingsboard.server.common.data.Device;
  34 +import org.thingsboard.server.common.data.DeviceInfo;
  35 +import org.thingsboard.server.common.data.EntitySubtype;
  36 +import org.thingsboard.server.common.data.EntityType;
  37 +import org.thingsboard.server.common.data.EntityView;
  38 +import org.thingsboard.server.common.data.Tenant;
32 import org.thingsboard.server.common.data.device.DeviceSearchQuery; 39 import org.thingsboard.server.common.data.device.DeviceSearchQuery;
33 import org.thingsboard.server.common.data.id.CustomerId; 40 import org.thingsboard.server.common.data.id.CustomerId;
34 import org.thingsboard.server.common.data.id.DeviceId; 41 import org.thingsboard.server.common.data.id.DeviceId;
@@ -325,7 +332,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -325,7 +332,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
325 } 332 }
326 } 333 }
327 return Futures.successfulAsList(futures); 334 return Futures.successfulAsList(futures);
328 - }); 335 + }, MoreExecutors.directExecutor());
329 336
330 devices = Futures.transform(devices, new Function<List<Device>, List<Device>>() { 337 devices = Futures.transform(devices, new Function<List<Device>, List<Device>>() {
331 @Nullable 338 @Nullable
@@ -333,7 +340,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -333,7 +340,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
333 public List<Device> apply(@Nullable List<Device> deviceList) { 340 public List<Device> apply(@Nullable List<Device> deviceList) {
334 return deviceList == null ? Collections.emptyList() : deviceList.stream().filter(device -> query.getDeviceTypes().contains(device.getType())).collect(Collectors.toList()); 341 return deviceList == null ? Collections.emptyList() : deviceList.stream().filter(device -> query.getDeviceTypes().contains(device.getType())).collect(Collectors.toList());
335 } 342 }
336 - }); 343 + }, MoreExecutors.directExecutor());
337 344
338 return devices; 345 return devices;
339 } 346 }
@@ -347,7 +354,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -347,7 +354,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
347 deviceTypes -> { 354 deviceTypes -> {
348 deviceTypes.sort(Comparator.comparing(EntitySubtype::getType)); 355 deviceTypes.sort(Comparator.comparing(EntitySubtype::getType));
349 return deviceTypes; 356 return deviceTypes;
350 - }); 357 + }, MoreExecutors.directExecutor());
351 } 358 }
352 359
353 private DataValidator<Device> deviceValidator = 360 private DataValidator<Device> deviceValidator =
@@ -408,18 +415,18 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -408,18 +415,18 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
408 }; 415 };
409 416
410 private PaginatedRemover<TenantId, Device> tenantDevicesRemover = 417 private PaginatedRemover<TenantId, Device> tenantDevicesRemover =
411 - new PaginatedRemover<TenantId, Device>() { 418 + new PaginatedRemover<TenantId, Device>() {
412 419
413 - @Override  
414 - protected PageData<Device> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {  
415 - return deviceDao.findDevicesByTenantId(id.getId(), pageLink);  
416 - } 420 + @Override
  421 + protected PageData<Device> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
  422 + return deviceDao.findDevicesByTenantId(id.getId(), pageLink);
  423 + }
417 424
418 - @Override  
419 - protected void removeEntity(TenantId tenantId, Device entity) {  
420 - deleteDevice(tenantId, new DeviceId(entity.getUuidId()));  
421 - }  
422 - }; 425 + @Override
  426 + protected void removeEntity(TenantId tenantId, Device entity) {
  427 + deleteDevice(tenantId, new DeviceId(entity.getUuidId()));
  428 + }
  429 + };
423 430
424 private PaginatedRemover<CustomerId, Device> customerDeviceUnasigner = new PaginatedRemover<CustomerId, Device>() { 431 private PaginatedRemover<CustomerId, Device> customerDeviceUnasigner = new PaginatedRemover<CustomerId, Device>() {
425 432
@@ -18,12 +18,21 @@ package org.thingsboard.server.dao.entity; @@ -18,12 +18,21 @@ package org.thingsboard.server.dao.entity;
18 import com.google.common.base.Function; 18 import com.google.common.base.Function;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
22 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.stereotype.Service; 24 import org.springframework.stereotype.Service;
24 import org.thingsboard.server.common.data.HasName; 25 import org.thingsboard.server.common.data.HasName;
25 import org.thingsboard.server.common.data.alarm.AlarmId; 26 import org.thingsboard.server.common.data.alarm.AlarmId;
26 -import org.thingsboard.server.common.data.id.*; 27 +import org.thingsboard.server.common.data.id.AssetId;
  28 +import org.thingsboard.server.common.data.id.CustomerId;
  29 +import org.thingsboard.server.common.data.id.DashboardId;
  30 +import org.thingsboard.server.common.data.id.DeviceId;
  31 +import org.thingsboard.server.common.data.id.EntityId;
  32 +import org.thingsboard.server.common.data.id.EntityViewId;
  33 +import org.thingsboard.server.common.data.id.RuleChainId;
  34 +import org.thingsboard.server.common.data.id.TenantId;
  35 +import org.thingsboard.server.common.data.id.UserId;
27 import org.thingsboard.server.dao.alarm.AlarmService; 36 import org.thingsboard.server.dao.alarm.AlarmService;
28 import org.thingsboard.server.dao.asset.AssetService; 37 import org.thingsboard.server.dao.asset.AssetService;
29 import org.thingsboard.server.dao.customer.CustomerService; 38 import org.thingsboard.server.dao.customer.CustomerService;
@@ -109,7 +118,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe @@ -109,7 +118,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
109 default: 118 default:
110 throw new IllegalStateException("Not Implemented!"); 119 throw new IllegalStateException("Not Implemented!");
111 } 120 }
112 - entityName = Futures.transform(hasName, (Function<HasName, String>) hasName1 -> hasName1 != null ? hasName1.getName() : null ); 121 + entityName = Futures.transform(hasName, (Function<HasName, String>) hasName1 -> hasName1 != null ? hasName1.getName() : null, MoreExecutors.directExecutor());
113 return entityName; 122 return entityName;
114 } 123 }
115 124
@@ -19,6 +19,7 @@ import com.google.common.base.Function; @@ -19,6 +19,7 @@ import com.google.common.base.Function;
19 import com.google.common.util.concurrent.FutureCallback; 19 import com.google.common.util.concurrent.FutureCallback;
20 import com.google.common.util.concurrent.Futures; 20 import com.google.common.util.concurrent.Futures;
21 import com.google.common.util.concurrent.ListenableFuture; 21 import com.google.common.util.concurrent.ListenableFuture;
  22 +import com.google.common.util.concurrent.MoreExecutors;
22 import lombok.extern.slf4j.Slf4j; 23 import lombok.extern.slf4j.Slf4j;
23 import org.apache.commons.lang3.StringUtils; 24 import org.apache.commons.lang3.StringUtils;
24 import org.springframework.beans.factory.annotation.Autowired; 25 import org.springframework.beans.factory.annotation.Autowired;
@@ -238,7 +239,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -238,7 +239,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
238 } 239 }
239 } 240 }
240 return Futures.successfulAsList(futures); 241 return Futures.successfulAsList(futures);
241 - }); 242 + }, MoreExecutors.directExecutor());
242 243
243 entityViews = Futures.transform(entityViews, new Function<List<EntityView>, List<EntityView>>() { 244 entityViews = Futures.transform(entityViews, new Function<List<EntityView>, List<EntityView>>() {
244 @Nullable 245 @Nullable
@@ -246,7 +247,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -246,7 +247,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
246 public List<EntityView> apply(@Nullable List<EntityView> entityViewList) { 247 public List<EntityView> apply(@Nullable List<EntityView> entityViewList) {
247 return entityViewList == null ? Collections.emptyList() : entityViewList.stream().filter(entityView -> query.getEntityViewTypes().contains(entityView.getType())).collect(Collectors.toList()); 248 return entityViewList == null ? Collections.emptyList() : entityViewList.stream().filter(entityView -> query.getEntityViewTypes().contains(entityView.getType())).collect(Collectors.toList());
248 } 249 }
249 - }); 250 + }, MoreExecutors.directExecutor());
250 251
251 return entityViews; 252 return entityViews;
252 } 253 }
@@ -285,7 +286,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -285,7 +286,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
285 public void onFailure(Throwable t) { 286 public void onFailure(Throwable t) {
286 log.error("Error while finding entity views by tenantId and entityId", t); 287 log.error("Error while finding entity views by tenantId and entityId", t);
287 } 288 }
288 - }); 289 + }, MoreExecutors.directExecutor());
289 return entityViewsFuture; 290 return entityViewsFuture;
290 } 291 }
291 } 292 }
@@ -318,7 +319,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -318,7 +319,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
318 entityViewTypes -> { 319 entityViewTypes -> {
319 entityViewTypes.sort(Comparator.comparing(EntitySubtype::getType)); 320 entityViewTypes.sort(Comparator.comparing(EntitySubtype::getType));
320 return entityViewTypes; 321 return entityViewTypes;
321 - }); 322 + }, MoreExecutors.directExecutor());
322 } 323 }
323 324
324 private DataValidator<EntityView> entityViewValidator = 325 private DataValidator<EntityView> entityViewValidator =
@@ -36,6 +36,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.BOOLEAN_VALUE_COLU @@ -36,6 +36,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.BOOLEAN_VALUE_COLU
36 import static org.thingsboard.server.dao.model.ModelConstants.DOUBLE_VALUE_COLUMN; 36 import static org.thingsboard.server.dao.model.ModelConstants.DOUBLE_VALUE_COLUMN;
37 import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_ID_COLUMN; 37 import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_ID_COLUMN;
38 import static org.thingsboard.server.dao.model.ModelConstants.JSON_VALUE_COLUMN; 38 import static org.thingsboard.server.dao.model.ModelConstants.JSON_VALUE_COLUMN;
  39 +import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN;
39 import static org.thingsboard.server.dao.model.ModelConstants.LONG_VALUE_COLUMN; 40 import static org.thingsboard.server.dao.model.ModelConstants.LONG_VALUE_COLUMN;
40 import static org.thingsboard.server.dao.model.ModelConstants.STRING_VALUE_COLUMN; 41 import static org.thingsboard.server.dao.model.ModelConstants.STRING_VALUE_COLUMN;
41 import static org.thingsboard.server.dao.model.ModelConstants.TS_COLUMN; 42 import static org.thingsboard.server.dao.model.ModelConstants.TS_COLUMN;
@@ -54,6 +55,10 @@ public abstract class AbstractTsKvEntity implements ToData<TsKvEntry> { @@ -54,6 +55,10 @@ public abstract class AbstractTsKvEntity implements ToData<TsKvEntry> {
54 protected UUID entityId; 55 protected UUID entityId;
55 56
56 @Id 57 @Id
  58 + @Column(name = KEY_COLUMN)
  59 + protected int key;
  60 +
  61 + @Id
57 @Column(name = TS_COLUMN) 62 @Column(name = TS_COLUMN)
58 protected Long ts; 63 protected Long ts;
59 64
@@ -69,10 +69,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN; @@ -69,10 +69,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN;
69 }) 69 })
70 public final class TsKvLatestEntity extends AbstractTsKvEntity { 70 public final class TsKvLatestEntity extends AbstractTsKvEntity {
71 71
72 - @Id  
73 - @Column(name = KEY_COLUMN)  
74 - private int key;  
75 -  
76 @Override 72 @Override
77 public boolean isNotEmpty() { 73 public boolean isNotEmpty() {
78 return strValue != null || longValue != null || doubleValue != null || booleanValue != null || jsonValue != null; 74 return strValue != null || longValue != null || doubleValue != null || booleanValue != null || jsonValue != null;
@@ -31,7 +31,6 @@ public class TimescaleTsKvCompositeKey implements Serializable { @@ -31,7 +31,6 @@ public class TimescaleTsKvCompositeKey implements Serializable {
31 @Transient 31 @Transient
32 private static final long serialVersionUID = -4089175869616037523L; 32 private static final long serialVersionUID = -4089175869616037523L;
33 33
34 - private UUID tenantId;  
35 private UUID entityId; 34 private UUID entityId;
36 private int key; 35 private int key;
37 private long ts; 36 private long ts;
@@ -18,25 +18,18 @@ package org.thingsboard.server.dao.model.sqlts.timescale.ts; @@ -18,25 +18,18 @@ package org.thingsboard.server.dao.model.sqlts.timescale.ts;
18 import lombok.Data; 18 import lombok.Data;
19 import lombok.EqualsAndHashCode; 19 import lombok.EqualsAndHashCode;
20 import org.springframework.util.StringUtils; 20 import org.springframework.util.StringUtils;
21 -import org.thingsboard.server.common.data.kv.TsKvEntry;  
22 -import org.thingsboard.server.dao.model.ToData;  
23 import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; 21 import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity;
24 22
25 -import javax.persistence.Column;  
26 import javax.persistence.ColumnResult; 23 import javax.persistence.ColumnResult;
27 import javax.persistence.ConstructorResult; 24 import javax.persistence.ConstructorResult;
28 import javax.persistence.Entity; 25 import javax.persistence.Entity;
29 -import javax.persistence.Id;  
30 import javax.persistence.IdClass; 26 import javax.persistence.IdClass;
31 import javax.persistence.NamedNativeQueries; 27 import javax.persistence.NamedNativeQueries;
32 import javax.persistence.NamedNativeQuery; 28 import javax.persistence.NamedNativeQuery;
33 import javax.persistence.SqlResultSetMapping; 29 import javax.persistence.SqlResultSetMapping;
34 import javax.persistence.SqlResultSetMappings; 30 import javax.persistence.SqlResultSetMappings;
35 import javax.persistence.Table; 31 import javax.persistence.Table;
36 -import java.util.UUID;  
37 32
38 -import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN;  
39 -import static org.thingsboard.server.dao.model.ModelConstants.TENANT_ID_COLUMN;  
40 import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_AVG; 33 import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_AVG;
41 import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_AVG_QUERY; 34 import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_AVG_QUERY;
42 import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_COUNT; 35 import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_COUNT;
@@ -52,7 +45,7 @@ import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.F @@ -52,7 +45,7 @@ import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.F
52 @Data 45 @Data
53 @EqualsAndHashCode(callSuper = true) 46 @EqualsAndHashCode(callSuper = true)
54 @Entity 47 @Entity
55 -@Table(name = "tenant_ts_kv") 48 +@Table(name = "ts_kv")
56 @IdClass(TimescaleTsKvCompositeKey.class) 49 @IdClass(TimescaleTsKvCompositeKey.class)
57 @SqlResultSetMappings({ 50 @SqlResultSetMappings({
58 @SqlResultSetMapping( 51 @SqlResultSetMapping(
@@ -116,15 +109,7 @@ import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.F @@ -116,15 +109,7 @@ import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.F
116 resultSetMapping = "timescaleCountMapping" 109 resultSetMapping = "timescaleCountMapping"
117 ) 110 )
118 }) 111 })
119 -public final class TimescaleTsKvEntity extends AbstractTsKvEntity implements ToData<TsKvEntry> {  
120 -  
121 - @Id  
122 - @Column(name = TENANT_ID_COLUMN, columnDefinition = "uuid")  
123 - private UUID tenantId;  
124 -  
125 - @Id  
126 - @Column(name = KEY_COLUMN)  
127 - private int key; 112 +public final class TimescaleTsKvEntity extends AbstractTsKvEntity {
128 113
129 public TimescaleTsKvEntity() { 114 public TimescaleTsKvEntity() {
130 } 115 }
@@ -32,10 +32,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN; @@ -32,10 +32,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN;
32 @IdClass(TsKvCompositeKey.class) 32 @IdClass(TsKvCompositeKey.class)
33 public final class TsKvEntity extends AbstractTsKvEntity { 33 public final class TsKvEntity extends AbstractTsKvEntity {
34 34
35 - @Id  
36 - @Column(name = KEY_COLUMN)  
37 - private int key;  
38 -  
39 public TsKvEntity() { 35 public TsKvEntity() {
40 } 36 }
41 37
@@ -22,6 +22,7 @@ import com.datastax.driver.core.Statement; @@ -22,6 +22,7 @@ import com.datastax.driver.core.Statement;
22 import com.google.common.util.concurrent.FutureCallback; 22 import com.google.common.util.concurrent.FutureCallback;
23 import com.google.common.util.concurrent.Futures; 23 import com.google.common.util.concurrent.Futures;
24 import com.google.common.util.concurrent.ListenableFuture; 24 import com.google.common.util.concurrent.ListenableFuture;
  25 +import com.google.common.util.concurrent.MoreExecutors;
25 import com.google.common.util.concurrent.Uninterruptibles; 26 import com.google.common.util.concurrent.Uninterruptibles;
26 import org.thingsboard.server.dao.exception.BufferLimitException; 27 import org.thingsboard.server.dao.exception.BufferLimitException;
27 import org.thingsboard.server.dao.util.AsyncRateLimiter; 28 import org.thingsboard.server.dao.util.AsyncRateLimiter;
@@ -44,9 +45,9 @@ public class RateLimitedResultSetFuture implements ResultSetFuture { @@ -44,9 +45,9 @@ public class RateLimitedResultSetFuture implements ResultSetFuture {
44 rateLimiter.release(); 45 rateLimiter.release();
45 } 46 }
46 return Futures.immediateFailedFuture(t); 47 return Futures.immediateFailedFuture(t);
47 - }); 48 + }, MoreExecutors.directExecutor());
48 this.originalFuture = Futures.transform(rateLimitFuture, 49 this.originalFuture = Futures.transform(rateLimitFuture,
49 - i -> executeAsyncWithRelease(rateLimiter, session, statement)); 50 + i -> executeAsyncWithRelease(rateLimiter, session, statement), MoreExecutors.directExecutor());
50 51
51 } 52 }
52 53
@@ -145,7 +146,7 @@ public class RateLimitedResultSetFuture implements ResultSetFuture { @@ -145,7 +146,7 @@ public class RateLimitedResultSetFuture implements ResultSetFuture {
145 public void onFailure(Throwable t) { 146 public void onFailure(Throwable t) {
146 rateLimiter.release(); 147 rateLimiter.release();
147 } 148 }
148 - }); 149 + }, MoreExecutors.directExecutor());
149 return resultSetFuture; 150 return resultSetFuture;
150 } catch (RuntimeException re) { 151 } catch (RuntimeException re) {
151 rateLimiter.release(); 152 rateLimiter.release();
@@ -16,7 +16,10 @@ @@ -16,7 +16,10 @@
16 package org.thingsboard.server.dao.relation; 16 package org.thingsboard.server.dao.relation;
17 17
18 import com.google.common.base.Function; 18 import com.google.common.base.Function;
19 -import com.google.common.util.concurrent.*; 19 +import com.google.common.util.concurrent.FutureCallback;
  20 +import com.google.common.util.concurrent.Futures;
  21 +import com.google.common.util.concurrent.ListenableFuture;
  22 +import com.google.common.util.concurrent.MoreExecutors;
20 import lombok.extern.slf4j.Slf4j; 23 import lombok.extern.slf4j.Slf4j;
21 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.cache.Cache; 25 import org.springframework.cache.Cache;
@@ -206,17 +209,20 @@ public class BaseRelationService implements RelationService { @@ -206,17 +209,20 @@ public class BaseRelationService implements RelationService {
206 relations -> { 209 relations -> {
207 List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(tenantId, relations, cache, true); 210 List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(tenantId, relations, cache, true);
208 return Futures.allAsList(results); 211 return Futures.allAsList(results);
209 - }); 212 + }, MoreExecutors.directExecutor());
210 213
211 ListenableFuture<List<Boolean>> outboundDeletions = Futures.transformAsync(outboundRelations, 214 ListenableFuture<List<Boolean>> outboundDeletions = Futures.transformAsync(outboundRelations,
212 relations -> { 215 relations -> {
213 List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(tenantId, relations, cache, false); 216 List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(tenantId, relations, cache, false);
214 return Futures.allAsList(results); 217 return Futures.allAsList(results);
215 - }); 218 + }, MoreExecutors.directExecutor());
216 219
217 ListenableFuture<List<List<Boolean>>> deletionsFuture = Futures.allAsList(inboundDeletions, outboundDeletions); 220 ListenableFuture<List<List<Boolean>>> deletionsFuture = Futures.allAsList(inboundDeletions, outboundDeletions);
218 221
219 - return Futures.transform(Futures.transformAsync(deletionsFuture, (deletions) -> relationDao.deleteOutboundRelationsAsync(tenantId, entityId)), result -> null); 222 + return Futures.transform(Futures.transformAsync(deletionsFuture,
  223 + (deletions) -> relationDao.deleteOutboundRelationsAsync(tenantId, entityId),
  224 + MoreExecutors.directExecutor()),
  225 + result -> null, MoreExecutors.directExecutor());
220 } 226 }
221 227
222 private List<ListenableFuture<Boolean>> deleteRelationGroupsAsync(TenantId tenantId, List<List<EntityRelation>> relations, Cache cache, boolean deleteFromDb) { 228 private List<ListenableFuture<Boolean>> deleteRelationGroupsAsync(TenantId tenantId, List<List<EntityRelation>> relations, Cache cache, boolean deleteFromDb) {
@@ -306,9 +312,11 @@ public class BaseRelationService implements RelationService { @@ -306,9 +312,11 @@ public class BaseRelationService implements RelationService {
306 public void onSuccess(@Nullable List<EntityRelation> result) { 312 public void onSuccess(@Nullable List<EntityRelation> result) {
307 cache.putIfAbsent(fromAndTypeGroup, result); 313 cache.putIfAbsent(fromAndTypeGroup, result);
308 } 314 }
  315 +
309 @Override 316 @Override
310 - public void onFailure(Throwable t) {}  
311 - }); 317 + public void onFailure(Throwable t) {
  318 + }
  319 + }, MoreExecutors.directExecutor());
312 return relationsFuture; 320 return relationsFuture;
313 } 321 }
314 } 322 }
@@ -328,7 +336,7 @@ public class BaseRelationService implements RelationService { @@ -328,7 +336,7 @@ public class BaseRelationService implements RelationService {
328 EntityRelationInfo::setToName)) 336 EntityRelationInfo::setToName))
329 ); 337 );
330 return Futures.successfulAsList(futures); 338 return Futures.successfulAsList(futures);
331 - }); 339 + }, MoreExecutors.directExecutor());
332 } 340 }
333 341
334 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #relationType, #typeGroup, 'FROM'}") 342 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #relationType, #typeGroup, 'FROM'}")
@@ -385,9 +393,11 @@ public class BaseRelationService implements RelationService { @@ -385,9 +393,11 @@ public class BaseRelationService implements RelationService {
385 public void onSuccess(@Nullable List<EntityRelation> result) { 393 public void onSuccess(@Nullable List<EntityRelation> result) {
386 cache.putIfAbsent(toAndTypeGroup, result); 394 cache.putIfAbsent(toAndTypeGroup, result);
387 } 395 }
  396 +
388 @Override 397 @Override
389 - public void onFailure(Throwable t) {}  
390 - }); 398 + public void onFailure(Throwable t) {
  399 + }
  400 + }, MoreExecutors.directExecutor());
391 return relationsFuture; 401 return relationsFuture;
392 } 402 }
393 } 403 }
@@ -407,7 +417,7 @@ public class BaseRelationService implements RelationService { @@ -407,7 +417,7 @@ public class BaseRelationService implements RelationService {
407 EntityRelationInfo::setFromName)) 417 EntityRelationInfo::setFromName))
408 ); 418 );
409 return Futures.successfulAsList(futures); 419 return Futures.successfulAsList(futures);
410 - }); 420 + }, MoreExecutors.directExecutor());
411 } 421 }
412 422
413 private ListenableFuture<EntityRelationInfo> fetchRelationInfoAsync(TenantId tenantId, EntityRelation relation, 423 private ListenableFuture<EntityRelationInfo> fetchRelationInfoAsync(TenantId tenantId, EntityRelation relation,
@@ -418,7 +428,7 @@ public class BaseRelationService implements RelationService { @@ -418,7 +428,7 @@ public class BaseRelationService implements RelationService {
418 EntityRelationInfo entityRelationInfo1 = new EntityRelationInfo(relation); 428 EntityRelationInfo entityRelationInfo1 = new EntityRelationInfo(relation);
419 entityNameSetter.accept(entityRelationInfo1, entityName1); 429 entityNameSetter.accept(entityRelationInfo1, entityName1);
420 return entityRelationInfo1; 430 return entityRelationInfo1;
421 - }); 431 + }, MoreExecutors.directExecutor());
422 } 432 }
423 433
424 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#to, #relationType, #typeGroup, 'TO'}") 434 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#to, #relationType, #typeGroup, 'TO'}")
@@ -466,7 +476,7 @@ public class BaseRelationService implements RelationService { @@ -466,7 +476,7 @@ public class BaseRelationService implements RelationService {
466 } 476 }
467 } 477 }
468 return relations; 478 return relations;
469 - }); 479 + }, MoreExecutors.directExecutor());
470 } catch (Exception e) { 480 } catch (Exception e) {
471 log.warn("Failed to query relations: [{}]", query, e); 481 log.warn("Failed to query relations: [{}]", query, e);
472 throw new RuntimeException(e); 482 throw new RuntimeException(e);
@@ -493,7 +503,7 @@ public class BaseRelationService implements RelationService { @@ -493,7 +503,7 @@ public class BaseRelationService implements RelationService {
493 })) 503 }))
494 ); 504 );
495 return Futures.successfulAsList(futures); 505 return Futures.successfulAsList(futures);
496 - }); 506 + }, MoreExecutors.directExecutor());
497 } 507 }
498 508
499 protected void validate(EntityRelation relation) { 509 protected void validate(EntityRelation relation) {
@@ -600,7 +610,7 @@ public class BaseRelationService implements RelationService { @@ -600,7 +610,7 @@ public class BaseRelationService implements RelationService {
600 } 610 }
601 //TODO: try to remove this blocking operation 611 //TODO: try to remove this blocking operation
602 List<Set<EntityRelation>> relations = Futures.successfulAsList(futures).get(); 612 List<Set<EntityRelation>> relations = Futures.successfulAsList(futures).get();
603 - if (fetchLastLevelOnly && lvl > 0){ 613 + if (fetchLastLevelOnly && lvl > 0) {
604 children.clear(); 614 children.clear();
605 } 615 }
606 relations.forEach(r -> r.forEach(children::add)); 616 relations.forEach(r -> r.forEach(children::add));
@@ -15,14 +15,12 @@ @@ -15,14 +15,12 @@
15 */ 15 */
16 package org.thingsboard.server.dao.sql.alarm; 16 package org.thingsboard.server.dao.sql.alarm;
17 17
18 -import com.google.common.util.concurrent.Futures;  
19 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
20 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
21 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.data.domain.PageRequest; 21 import org.springframework.data.domain.PageRequest;
23 import org.springframework.data.repository.CrudRepository; 22 import org.springframework.data.repository.CrudRepository;
24 import org.springframework.stereotype.Component; 23 import org.springframework.stereotype.Component;
25 -import org.thingsboard.server.common.data.EntityType;  
26 import org.thingsboard.server.common.data.UUIDConverter; 24 import org.thingsboard.server.common.data.UUIDConverter;
27 import org.thingsboard.server.common.data.alarm.Alarm; 25 import org.thingsboard.server.common.data.alarm.Alarm;
28 import org.thingsboard.server.common.data.alarm.AlarmInfo; 26 import org.thingsboard.server.common.data.alarm.AlarmInfo;
@@ -31,8 +29,6 @@ import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; @@ -31,8 +29,6 @@ import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
31 import org.thingsboard.server.common.data.id.EntityId; 29 import org.thingsboard.server.common.data.id.EntityId;
32 import org.thingsboard.server.common.data.id.TenantId; 30 import org.thingsboard.server.common.data.id.TenantId;
33 import org.thingsboard.server.common.data.page.PageData; 31 import org.thingsboard.server.common.data.page.PageData;
34 -import org.thingsboard.server.common.data.relation.EntityRelation;  
35 -import org.thingsboard.server.common.data.relation.RelationTypeGroup;  
36 import org.thingsboard.server.dao.DaoUtil; 32 import org.thingsboard.server.dao.DaoUtil;
37 import org.thingsboard.server.dao.alarm.AlarmDao; 33 import org.thingsboard.server.dao.alarm.AlarmDao;
38 import org.thingsboard.server.dao.alarm.BaseAlarmService; 34 import org.thingsboard.server.dao.alarm.BaseAlarmService;
@@ -41,7 +37,6 @@ import org.thingsboard.server.dao.relation.RelationDao; @@ -41,7 +37,6 @@ import org.thingsboard.server.dao.relation.RelationDao;
41 import org.thingsboard.server.dao.sql.JpaAbstractDao; 37 import org.thingsboard.server.dao.sql.JpaAbstractDao;
42 import org.thingsboard.server.dao.util.SqlDao; 38 import org.thingsboard.server.dao.util.SqlDao;
43 39
44 -import java.util.ArrayList;  
45 import java.util.List; 40 import java.util.List;
46 import java.util.Objects; 41 import java.util.Objects;
47 import java.util.UUID; 42 import java.util.UUID;
@@ -15,23 +15,14 @@ @@ -15,23 +15,14 @@
15 */ 15 */
16 package org.thingsboard.server.dao.sql.dashboard; 16 package org.thingsboard.server.dao.sql.dashboard;
17 17
18 -import com.google.common.util.concurrent.Futures;  
19 -import com.google.common.util.concurrent.ListenableFuture;  
20 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
21 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
22 -import org.springframework.data.domain.PageRequest;  
23 import org.springframework.data.repository.CrudRepository; 20 import org.springframework.data.repository.CrudRepository;
24 import org.springframework.stereotype.Component; 21 import org.springframework.stereotype.Component;
25 import org.thingsboard.server.common.data.DashboardInfo; 22 import org.thingsboard.server.common.data.DashboardInfo;
26 -import org.thingsboard.server.common.data.EntityType;  
27 import org.thingsboard.server.common.data.UUIDConverter; 23 import org.thingsboard.server.common.data.UUIDConverter;
28 -import org.thingsboard.server.common.data.id.CustomerId;  
29 -import org.thingsboard.server.common.data.id.TenantId;  
30 import org.thingsboard.server.common.data.page.PageData; 24 import org.thingsboard.server.common.data.page.PageData;
31 import org.thingsboard.server.common.data.page.PageLink; 25 import org.thingsboard.server.common.data.page.PageLink;
32 -import org.thingsboard.server.common.data.page.TimePageLink;  
33 -import org.thingsboard.server.common.data.relation.EntityRelation;  
34 -import org.thingsboard.server.common.data.relation.RelationTypeGroup;  
35 import org.thingsboard.server.dao.DaoUtil; 26 import org.thingsboard.server.dao.DaoUtil;
36 import org.thingsboard.server.dao.dashboard.DashboardInfoDao; 27 import org.thingsboard.server.dao.dashboard.DashboardInfoDao;
37 import org.thingsboard.server.dao.model.sql.DashboardInfoEntity; 28 import org.thingsboard.server.dao.model.sql.DashboardInfoEntity;
@@ -39,13 +30,9 @@ import org.thingsboard.server.dao.relation.RelationDao; @@ -39,13 +30,9 @@ import org.thingsboard.server.dao.relation.RelationDao;
39 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 30 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
40 import org.thingsboard.server.dao.util.SqlDao; 31 import org.thingsboard.server.dao.util.SqlDao;
41 32
42 -import java.util.ArrayList;  
43 -import java.util.List;  
44 import java.util.Objects; 33 import java.util.Objects;
45 import java.util.UUID; 34 import java.util.UUID;
46 35
47 -import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR;  
48 -  
49 /** 36 /**
50 * Created by Valerii Sosliuk on 5/6/2017. 37 * Created by Valerii Sosliuk on 5/6/2017.
51 */ 38 */
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sql.relation;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.springframework.data.jpa.repository.Modifying;
  20 +import org.thingsboard.server.dao.model.sql.RelationEntity;
  21 +
  22 +import javax.persistence.EntityManager;
  23 +import javax.persistence.PersistenceContext;
  24 +import javax.persistence.Query;
  25 +
  26 +@Slf4j
  27 +public abstract class AbstractRelationInsertRepository implements RelationInsertRepository {
  28 +
  29 + @PersistenceContext
  30 + protected EntityManager entityManager;
  31 +
  32 + protected Query getQuery(RelationEntity entity, String query) {
  33 + Query nativeQuery = entityManager.createNativeQuery(query, RelationEntity.class);
  34 + if (entity.getAdditionalInfo() == null) {
  35 + nativeQuery.setParameter("additionalInfo", null);
  36 + } else {
  37 + nativeQuery.setParameter("additionalInfo", entity.getAdditionalInfo().toString());
  38 + }
  39 + return nativeQuery
  40 + .setParameter("fromId", entity.getFromId())
  41 + .setParameter("fromType", entity.getFromType())
  42 + .setParameter("toId", entity.getToId())
  43 + .setParameter("toType", entity.getToType())
  44 + .setParameter("relationTypeGroup", entity.getRelationTypeGroup())
  45 + .setParameter("relationType", entity.getRelationType());
  46 + }
  47 +
  48 + @Modifying
  49 + protected abstract RelationEntity processSaveOrUpdate(RelationEntity entity);
  50 +
  51 +}
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sql.relation;
  17 +
  18 +import org.springframework.stereotype.Repository;
  19 +import org.springframework.transaction.annotation.Transactional;
  20 +import org.thingsboard.server.dao.model.sql.RelationCompositeKey;
  21 +import org.thingsboard.server.dao.model.sql.RelationEntity;
  22 +import org.thingsboard.server.dao.util.HsqlDao;
  23 +import org.thingsboard.server.dao.util.SqlDao;
  24 +
  25 +@HsqlDao
  26 +@SqlDao
  27 +@Repository
  28 +@Transactional
  29 +public class HsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository {
  30 +
  31 + private static final String INSERT_ON_CONFLICT_DO_UPDATE = "MERGE INTO relation USING (VALUES :fromId, :fromType, :toId, :toType, :relationTypeGroup, :relationType, :additionalInfo) R " +
  32 + "(from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info) " +
  33 + "ON (relation.from_id = R.from_id AND relation.from_type = R.from_type AND relation.relation_type_group = R.relation_type_group AND relation.relation_type = R.relation_type AND relation.to_id = R.to_id AND relation.to_type = R.to_type) " +
  34 + "WHEN MATCHED THEN UPDATE SET relation.additional_info = R.additional_info " +
  35 + "WHEN NOT MATCHED THEN INSERT (from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info) VALUES (R.from_id, R.from_type, R.to_id, R.to_type, R.relation_type_group, R.relation_type, R.additional_info)";
  36 +
  37 + @Override
  38 + public RelationEntity saveOrUpdate(RelationEntity entity) {
  39 + return processSaveOrUpdate(entity);
  40 + }
  41 +
  42 + @Override
  43 + protected RelationEntity processSaveOrUpdate(RelationEntity entity) {
  44 + getQuery(entity, INSERT_ON_CONFLICT_DO_UPDATE).executeUpdate();
  45 + return entityManager.find(RelationEntity.class, new RelationCompositeKey(entity.toData()));
  46 + }
  47 +}
@@ -58,6 +58,9 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple @@ -58,6 +58,9 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple
58 @Autowired 58 @Autowired
59 private RelationRepository relationRepository; 59 private RelationRepository relationRepository;
60 60
  61 + @Autowired
  62 + private RelationInsertRepository relationInsertRepository;
  63 +
61 @Override 64 @Override
62 public ListenableFuture<List<EntityRelation>> findAllByFrom(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup) { 65 public ListenableFuture<List<EntityRelation>> findAllByFrom(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup) {
63 return service.submit(() -> DaoUtil.convertDataList( 66 return service.submit(() -> DaoUtil.convertDataList(
@@ -119,12 +122,12 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple @@ -119,12 +122,12 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple
119 122
120 @Override 123 @Override
121 public boolean saveRelation(TenantId tenantId, EntityRelation relation) { 124 public boolean saveRelation(TenantId tenantId, EntityRelation relation) {
122 - return relationRepository.save(new RelationEntity(relation)) != null; 125 + return relationInsertRepository.saveOrUpdate(new RelationEntity(relation)) != null;
123 } 126 }
124 127
125 @Override 128 @Override
126 public ListenableFuture<Boolean> saveRelationAsync(TenantId tenantId, EntityRelation relation) { 129 public ListenableFuture<Boolean> saveRelationAsync(TenantId tenantId, EntityRelation relation) {
127 - return service.submit(() -> relationRepository.save(new RelationEntity(relation)) != null); 130 + return service.submit(() -> relationInsertRepository.saveOrUpdate(new RelationEntity(relation)) != null);
128 } 131 }
129 132
130 @Override 133 @Override
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sql.relation;
  17 +
  18 +import org.springframework.stereotype.Repository;
  19 +import org.springframework.transaction.annotation.Transactional;
  20 +import org.thingsboard.server.dao.model.sql.RelationEntity;
  21 +import org.thingsboard.server.dao.util.PsqlDao;
  22 +import org.thingsboard.server.dao.util.SqlDao;
  23 +
  24 +@PsqlDao
  25 +@SqlDao
  26 +@Repository
  27 +@Transactional
  28 +public class PsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository {
  29 +
  30 + private static final String INSERT_ON_CONFLICT_DO_UPDATE = "INSERT INTO relation (from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info)" +
  31 + " VALUES (:fromId, :fromType, :toId, :toType, :relationTypeGroup, :relationType, :additionalInfo) " +
  32 + "ON CONFLICT (from_id, from_type, relation_type_group, relation_type, to_id, to_type) DO UPDATE SET additional_info = :additionalInfo returning *";
  33 +
  34 + @Override
  35 + public RelationEntity saveOrUpdate(RelationEntity entity) {
  36 + return processSaveOrUpdate(entity);
  37 + }
  38 +
  39 + @Override
  40 + protected RelationEntity processSaveOrUpdate(RelationEntity entity) {
  41 + return (RelationEntity) getQuery(entity, INSERT_ON_CONFLICT_DO_UPDATE).getSingleResult();
  42 + }
  43 +}
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sql.relation;
  17 +
  18 +import org.thingsboard.server.dao.model.sql.RelationEntity;
  19 +
  20 +public interface RelationInsertRepository {
  21 +
  22 + RelationEntity saveOrUpdate(RelationEntity entity);
  23 +
  24 +}
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.sqlts; @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.sqlts;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 import com.google.common.util.concurrent.SettableFuture; 21 import com.google.common.util.concurrent.SettableFuture;
21 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
22 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
@@ -95,7 +96,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -95,7 +96,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
95 96
96 @Override 97 @Override
97 public ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) { 98 public ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
98 - return getRemoveLatestFuture(tenantId, entityId, query); 99 + return getRemoveLatestFuture(entityId, query);
99 } 100 }
100 101
101 @Override 102 @Override
@@ -124,9 +125,9 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -124,9 +125,9 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
124 } 125 }
125 126
126 @Override 127 @Override
127 - protected ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { 128 + protected ListenableFuture<List<TsKvEntry>> findAllAsync(EntityId entityId, ReadTsKvQuery query) {
128 if (query.getAggregation() == Aggregation.NONE) { 129 if (query.getAggregation() == Aggregation.NONE) {
129 - return findAllAsyncWithLimit(tenantId, entityId, query); 130 + return findAllAsyncWithLimit(entityId, query);
130 } else { 131 } else {
131 long stepTs = query.getStartTs(); 132 long stepTs = query.getStartTs();
132 List<ListenableFuture<Optional<TsKvEntry>>> futures = new ArrayList<>(); 133 List<ListenableFuture<Optional<TsKvEntry>>> futures = new ArrayList<>();
@@ -134,7 +135,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -134,7 +135,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
134 long startTs = stepTs; 135 long startTs = stepTs;
135 long endTs = stepTs + query.getInterval(); 136 long endTs = stepTs + query.getInterval();
136 long ts = startTs + (endTs - startTs) / 2; 137 long ts = startTs + (endTs - startTs) / 2;
137 - futures.add(findAndAggregateAsync(tenantId, entityId, query.getKey(), startTs, endTs, ts, query.getAggregation())); 138 + futures.add(findAndAggregateAsync(entityId, query.getKey(), startTs, endTs, ts, query.getAggregation()));
138 stepTs = endTs; 139 stepTs = endTs;
139 } 140 }
140 return getTskvEntriesFuture(Futures.allAsList(futures)); 141 return getTskvEntriesFuture(Futures.allAsList(futures));
@@ -142,7 +143,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -142,7 +143,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
142 } 143 }
143 144
144 @Override 145 @Override
145 - protected ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { 146 + protected ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(EntityId entityId, ReadTsKvQuery query) {
146 Integer keyId = getOrSaveKeyId(query.getKey()); 147 Integer keyId = getOrSaveKeyId(query.getKey());
147 List<TsKvEntity> tsKvEntities = tsKvRepository.findAllWithLimit( 148 List<TsKvEntity> tsKvEntities = tsKvRepository.findAllWithLimit(
148 entityId.getId(), 149 entityId.getId(),
@@ -156,9 +157,9 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -156,9 +157,9 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
156 return Futures.immediateFuture(DaoUtil.convertDataList(tsKvEntities)); 157 return Futures.immediateFuture(DaoUtil.convertDataList(tsKvEntities));
157 } 158 }
158 159
159 - protected ListenableFuture<Optional<TsKvEntry>> findAndAggregateAsync(TenantId tenantId, EntityId entityId, String key, long startTs, long endTs, long ts, Aggregation aggregation) { 160 + private ListenableFuture<Optional<TsKvEntry>> findAndAggregateAsync(EntityId entityId, String key, long startTs, long endTs, long ts, Aggregation aggregation) {
160 List<CompletableFuture<TsKvEntity>> entitiesFutures = new ArrayList<>(); 161 List<CompletableFuture<TsKvEntity>> entitiesFutures = new ArrayList<>();
161 - switchAggregation(tenantId, entityId, key, startTs, endTs, aggregation, entitiesFutures); 162 + switchAggregation(entityId, key, startTs, endTs, aggregation, entitiesFutures);
162 return Futures.transform(setFutures(entitiesFutures), entity -> { 163 return Futures.transform(setFutures(entitiesFutures), entity -> {
163 if (entity != null && entity.isNotEmpty()) { 164 if (entity != null && entity.isNotEmpty()) {
164 entity.setEntityId(entityId.getId()); 165 entity.setEntityId(entityId.getId());
@@ -168,32 +169,32 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -168,32 +169,32 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
168 } else { 169 } else {
169 return Optional.empty(); 170 return Optional.empty();
170 } 171 }
171 - }); 172 + }, MoreExecutors.directExecutor());
172 } 173 }
173 174
174 - protected void switchAggregation(TenantId tenantId, EntityId entityId, String key, long startTs, long endTs, Aggregation aggregation, List<CompletableFuture<TsKvEntity>> entitiesFutures) { 175 + protected void switchAggregation(EntityId entityId, String key, long startTs, long endTs, Aggregation aggregation, List<CompletableFuture<TsKvEntity>> entitiesFutures) {
175 switch (aggregation) { 176 switch (aggregation) {
176 case AVG: 177 case AVG:
177 - findAvg(tenantId, entityId, key, startTs, endTs, entitiesFutures); 178 + findAvg(entityId, key, startTs, endTs, entitiesFutures);
178 break; 179 break;
179 case MAX: 180 case MAX:
180 - findMax(tenantId, entityId, key, startTs, endTs, entitiesFutures); 181 + findMax(entityId, key, startTs, endTs, entitiesFutures);
181 break; 182 break;
182 case MIN: 183 case MIN:
183 - findMin(tenantId, entityId, key, startTs, endTs, entitiesFutures); 184 + findMin(entityId, key, startTs, endTs, entitiesFutures);
184 break; 185 break;
185 case SUM: 186 case SUM:
186 - findSum(tenantId, entityId, key, startTs, endTs, entitiesFutures); 187 + findSum(entityId, key, startTs, endTs, entitiesFutures);
187 break; 188 break;
188 case COUNT: 189 case COUNT:
189 - findCount(tenantId, entityId, key, startTs, endTs, entitiesFutures); 190 + findCount(entityId, key, startTs, endTs, entitiesFutures);
190 break; 191 break;
191 default: 192 default:
192 throw new IllegalArgumentException("Not supported aggregation type: " + aggregation); 193 throw new IllegalArgumentException("Not supported aggregation type: " + aggregation);
193 } 194 }
194 } 195 }
195 196
196 - protected void findCount(TenantId tenantId, EntityId entityId, String key, long startTs, long endTs, List<CompletableFuture<TsKvEntity>> entitiesFutures) { 197 + protected void findCount(EntityId entityId, String key, long startTs, long endTs, List<CompletableFuture<TsKvEntity>> entitiesFutures) {
197 Integer keyId = getOrSaveKeyId(key); 198 Integer keyId = getOrSaveKeyId(key);
198 entitiesFutures.add(tsKvRepository.findCount( 199 entitiesFutures.add(tsKvRepository.findCount(
199 entityId.getId(), 200 entityId.getId(),
@@ -202,7 +203,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -202,7 +203,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
202 endTs)); 203 endTs));
203 } 204 }
204 205
205 - protected void findSum(TenantId tenantId, EntityId entityId, String key, long startTs, long endTs, List<CompletableFuture<TsKvEntity>> entitiesFutures) { 206 + protected void findSum(EntityId entityId, String key, long startTs, long endTs, List<CompletableFuture<TsKvEntity>> entitiesFutures) {
206 Integer keyId = getOrSaveKeyId(key); 207 Integer keyId = getOrSaveKeyId(key);
207 entitiesFutures.add(tsKvRepository.findSum( 208 entitiesFutures.add(tsKvRepository.findSum(
208 entityId.getId(), 209 entityId.getId(),
@@ -211,7 +212,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -211,7 +212,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
211 endTs)); 212 endTs));
212 } 213 }
213 214
214 - protected void findMin(TenantId tenantId, EntityId entityId, String key, long startTs, long endTs, List<CompletableFuture<TsKvEntity>> entitiesFutures) { 215 + protected void findMin(EntityId entityId, String key, long startTs, long endTs, List<CompletableFuture<TsKvEntity>> entitiesFutures) {
215 Integer keyId = getOrSaveKeyId(key); 216 Integer keyId = getOrSaveKeyId(key);
216 entitiesFutures.add(tsKvRepository.findStringMin( 217 entitiesFutures.add(tsKvRepository.findStringMin(
217 entityId.getId(), 218 entityId.getId(),
@@ -225,7 +226,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -225,7 +226,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
225 endTs)); 226 endTs));
226 } 227 }
227 228
228 - protected void findMax(TenantId tenantId, EntityId entityId, String key, long startTs, long endTs, List<CompletableFuture<TsKvEntity>> entitiesFutures) { 229 + protected void findMax(EntityId entityId, String key, long startTs, long endTs, List<CompletableFuture<TsKvEntity>> entitiesFutures) {
229 Integer keyId = getOrSaveKeyId(key); 230 Integer keyId = getOrSaveKeyId(key);
230 entitiesFutures.add(tsKvRepository.findStringMax( 231 entitiesFutures.add(tsKvRepository.findStringMax(
231 entityId.getId(), 232 entityId.getId(),
@@ -239,7 +240,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -239,7 +240,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
239 endTs)); 240 endTs));
240 } 241 }
241 242
242 - protected void findAvg(TenantId tenantId, EntityId entityId, String key, long startTs, long endTs, List<CompletableFuture<TsKvEntity>> entitiesFutures) { 243 + protected void findAvg(EntityId entityId, String key, long startTs, long endTs, List<CompletableFuture<TsKvEntity>> entitiesFutures) {
243 Integer keyId = getOrSaveKeyId(key); 244 Integer keyId = getOrSaveKeyId(key);
244 entitiesFutures.add(tsKvRepository.findAvg( 245 entitiesFutures.add(tsKvRepository.findAvg(
245 entityId.getId(), 246 entityId.getId(),
@@ -20,6 +20,7 @@ import com.google.common.collect.Lists; @@ -20,6 +20,7 @@ import com.google.common.collect.Lists;
20 import com.google.common.util.concurrent.FutureCallback; 20 import com.google.common.util.concurrent.FutureCallback;
21 import com.google.common.util.concurrent.Futures; 21 import com.google.common.util.concurrent.Futures;
22 import com.google.common.util.concurrent.ListenableFuture; 22 import com.google.common.util.concurrent.ListenableFuture;
  23 +import com.google.common.util.concurrent.MoreExecutors;
23 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
24 import org.hibernate.exception.ConstraintViolationException; 25 import org.hibernate.exception.ConstraintViolationException;
25 import org.springframework.beans.factory.annotation.Autowired; 26 import org.springframework.beans.factory.annotation.Autowired;
@@ -126,7 +127,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx @@ -126,7 +127,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
126 protected ListenableFuture<List<TsKvEntry>> processFindAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries) { 127 protected ListenableFuture<List<TsKvEntry>> processFindAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries) {
127 List<ListenableFuture<List<TsKvEntry>>> futures = queries 128 List<ListenableFuture<List<TsKvEntry>>> futures = queries
128 .stream() 129 .stream()
129 - .map(query -> findAllAsync(tenantId, entityId, query)) 130 + .map(query -> findAllAsync(entityId, query))
130 .collect(Collectors.toList()); 131 .collect(Collectors.toList());
131 return Futures.transform(Futures.allAsList(futures), new Function<List<List<TsKvEntry>>, List<TsKvEntry>>() { 132 return Futures.transform(Futures.allAsList(futures), new Function<List<List<TsKvEntry>>, List<TsKvEntry>>() {
132 @Nullable 133 @Nullable
@@ -143,9 +144,9 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx @@ -143,9 +144,9 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
143 }, service); 144 }, service);
144 } 145 }
145 146
146 - protected abstract ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query); 147 + protected abstract ListenableFuture<List<TsKvEntry>> findAllAsync(EntityId entityId, ReadTsKvQuery query);
147 148
148 - protected abstract ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(TenantId tenantId, EntityId entityId, ReadTsKvQuery query); 149 + protected abstract ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(EntityId entityId, ReadTsKvQuery query);
149 150
150 protected ListenableFuture<List<TsKvEntry>> getTskvEntriesFuture(ListenableFuture<List<Optional<TsKvEntry>>> future) { 151 protected ListenableFuture<List<TsKvEntry>> getTskvEntriesFuture(ListenableFuture<List<Optional<TsKvEntry>>> future) {
151 return Futures.transform(future, new Function<List<Optional<TsKvEntry>>, List<TsKvEntry>>() { 152 return Futures.transform(future, new Function<List<Optional<TsKvEntry>>, List<TsKvEntry>>() {
@@ -163,12 +164,12 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx @@ -163,12 +164,12 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
163 }, service); 164 }, service);
164 } 165 }
165 166
166 - protected ListenableFuture<List<TsKvEntry>> findNewLatestEntryFuture(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) { 167 + protected ListenableFuture<List<TsKvEntry>> findNewLatestEntryFuture(EntityId entityId, DeleteTsKvQuery query) {
167 long startTs = 0; 168 long startTs = 0;
168 long endTs = query.getStartTs() - 1; 169 long endTs = query.getStartTs() - 1;
169 ReadTsKvQuery findNewLatestQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, endTs - startTs, 1, 170 ReadTsKvQuery findNewLatestQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, endTs - startTs, 1,
170 Aggregation.NONE, DESC_ORDER); 171 Aggregation.NONE, DESC_ORDER);
171 - return findAllAsync(tenantId, entityId, findNewLatestQuery); 172 + return findAllAsync(entityId, findNewLatestQuery);
172 } 173 }
173 174
174 protected ListenableFuture<TsKvEntry> getFindLatestFuture(EntityId entityId, String key) { 175 protected ListenableFuture<TsKvEntry> getFindLatestFuture(EntityId entityId, String key) {
@@ -188,7 +189,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx @@ -188,7 +189,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
188 return Futures.immediateFuture(result); 189 return Futures.immediateFuture(result);
189 } 190 }
190 191
191 - protected ListenableFuture<Void> getRemoveLatestFuture(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) { 192 + protected ListenableFuture<Void> getRemoveLatestFuture(EntityId entityId, DeleteTsKvQuery query) {
192 ListenableFuture<TsKvEntry> latestFuture = getFindLatestFuture(entityId, query.getKey()); 193 ListenableFuture<TsKvEntry> latestFuture = getFindLatestFuture(entityId, query.getKey());
193 194
194 ListenableFuture<Boolean> booleanFuture = Futures.transform(latestFuture, tsKvEntry -> { 195 ListenableFuture<Boolean> booleanFuture = Futures.transform(latestFuture, tsKvEntry -> {
@@ -216,7 +217,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx @@ -216,7 +217,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
216 if (query.getRewriteLatestIfDeleted()) { 217 if (query.getRewriteLatestIfDeleted()) {
217 ListenableFuture<Void> savedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> { 218 ListenableFuture<Void> savedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> {
218 if (isRemove) { 219 if (isRemove) {
219 - return getNewLatestEntryFuture(tenantId, entityId, query); 220 + return getNewLatestEntryFuture(entityId, query);
220 } 221 }
221 return Futures.immediateFuture(null); 222 return Futures.immediateFuture(null);
222 }, service); 223 }, service);
@@ -235,7 +236,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx @@ -235,7 +236,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
235 public void onFailure(Throwable t) { 236 public void onFailure(Throwable t) {
236 log.warn("[{}] Failed to process remove of the latest value", entityId, t); 237 log.warn("[{}] Failed to process remove of the latest value", entityId, t);
237 } 238 }
238 - }); 239 + }, MoreExecutors.directExecutor());
239 return resultFuture; 240 return resultFuture;
240 } 241 }
241 242
@@ -295,8 +296,8 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx @@ -295,8 +296,8 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
295 return keyId; 296 return keyId;
296 } 297 }
297 298
298 - private ListenableFuture<Void> getNewLatestEntryFuture(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {  
299 - ListenableFuture<List<TsKvEntry>> future = findNewLatestEntryFuture(tenantId, entityId, query); 299 + private ListenableFuture<Void> getNewLatestEntryFuture(EntityId entityId, DeleteTsKvQuery query) {
  300 + ListenableFuture<List<TsKvEntry>> future = findNewLatestEntryFuture(entityId, query);
300 return Futures.transformAsync(future, entryList -> { 301 return Futures.transformAsync(future, entryList -> {
301 if (entryList.size() == 1) { 302 if (entryList.size() == 1) {
302 return getSaveLatestFuture(entityId, entryList.get(0)); 303 return getSaveLatestFuture(entityId, entryList.get(0));
@@ -37,8 +37,8 @@ import java.util.List; @@ -37,8 +37,8 @@ import java.util.List;
37 public class TimescaleInsertTsRepository extends AbstractInsertRepository implements InsertTsRepository<TimescaleTsKvEntity> { 37 public class TimescaleInsertTsRepository extends AbstractInsertRepository implements InsertTsRepository<TimescaleTsKvEntity> {
38 38
39 private static final String INSERT_OR_UPDATE = 39 private static final String INSERT_OR_UPDATE =
40 - "INSERT INTO tenant_ts_kv (tenant_id, entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) VALUES(?, ?, ?, ?, ?, ?, ?, ?, cast(? AS json)) " +  
41 - "ON CONFLICT (tenant_id, entity_id, key, ts) DO UPDATE SET bool_v = ?, str_v = ?, long_v = ?, dbl_v = ?, json_v = cast(? AS json);"; 40 + "INSERT INTO ts_kv (entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) VALUES(?, ?, ?, ?, ?, ?, ?, cast(? AS json)) " +
  41 + "ON CONFLICT (entity_id, key, ts) DO UPDATE SET bool_v = ?, str_v = ?, long_v = ?, dbl_v = ?, json_v = cast(? AS json);";
42 42
43 @Override 43 @Override
44 public void saveOrUpdate(List<EntityContainer<TimescaleTsKvEntity>> entities) { 44 public void saveOrUpdate(List<EntityContainer<TimescaleTsKvEntity>> entities) {
@@ -46,41 +46,40 @@ public class TimescaleInsertTsRepository extends AbstractInsertRepository implem @@ -46,41 +46,40 @@ public class TimescaleInsertTsRepository extends AbstractInsertRepository implem
46 @Override 46 @Override
47 public void setValues(PreparedStatement ps, int i) throws SQLException { 47 public void setValues(PreparedStatement ps, int i) throws SQLException {
48 TimescaleTsKvEntity tsKvEntity = entities.get(i).getEntity(); 48 TimescaleTsKvEntity tsKvEntity = entities.get(i).getEntity();
49 - ps.setObject(1, tsKvEntity.getTenantId());  
50 - ps.setObject(2, tsKvEntity.getEntityId());  
51 - ps.setInt(3, tsKvEntity.getKey());  
52 - ps.setLong(4, tsKvEntity.getTs()); 49 + ps.setObject(1, tsKvEntity.getEntityId());
  50 + ps.setInt(2, tsKvEntity.getKey());
  51 + ps.setLong(3, tsKvEntity.getTs());
53 52
54 if (tsKvEntity.getBooleanValue() != null) { 53 if (tsKvEntity.getBooleanValue() != null) {
55 - ps.setBoolean(5, tsKvEntity.getBooleanValue());  
56 - ps.setBoolean(10, tsKvEntity.getBooleanValue()); 54 + ps.setBoolean(4, tsKvEntity.getBooleanValue());
  55 + ps.setBoolean(9, tsKvEntity.getBooleanValue());
57 } else { 56 } else {
58 - ps.setNull(5, Types.BOOLEAN);  
59 - ps.setNull(10, Types.BOOLEAN); 57 + ps.setNull(4, Types.BOOLEAN);
  58 + ps.setNull(9, Types.BOOLEAN);
60 } 59 }
61 60
62 - ps.setString(6, replaceNullChars(tsKvEntity.getStrValue()));  
63 - ps.setString(11, replaceNullChars(tsKvEntity.getStrValue())); 61 + ps.setString(5, replaceNullChars(tsKvEntity.getStrValue()));
  62 + ps.setString(10, replaceNullChars(tsKvEntity.getStrValue()));
64 63
65 64
66 if (tsKvEntity.getLongValue() != null) { 65 if (tsKvEntity.getLongValue() != null) {
67 - ps.setLong(7, tsKvEntity.getLongValue());  
68 - ps.setLong(12, tsKvEntity.getLongValue()); 66 + ps.setLong(6, tsKvEntity.getLongValue());
  67 + ps.setLong(11, tsKvEntity.getLongValue());
69 } else { 68 } else {
70 - ps.setNull(7, Types.BIGINT);  
71 - ps.setNull(12, Types.BIGINT); 69 + ps.setNull(6, Types.BIGINT);
  70 + ps.setNull(11, Types.BIGINT);
72 } 71 }
73 72
74 if (tsKvEntity.getDoubleValue() != null) { 73 if (tsKvEntity.getDoubleValue() != null) {
75 - ps.setDouble(8, tsKvEntity.getDoubleValue());  
76 - ps.setDouble(13, tsKvEntity.getDoubleValue()); 74 + ps.setDouble(7, tsKvEntity.getDoubleValue());
  75 + ps.setDouble(12, tsKvEntity.getDoubleValue());
77 } else { 76 } else {
78 - ps.setNull(8, Types.DOUBLE);  
79 - ps.setNull(13, Types.DOUBLE); 77 + ps.setNull(7, Types.DOUBLE);
  78 + ps.setNull(12, Types.DOUBLE);
80 } 79 }
81 80
82 - ps.setString(9, replaceNullChars(tsKvEntity.getJsonValue()));  
83 - ps.setString(14, replaceNullChars(tsKvEntity.getJsonValue())); 81 + ps.setString(8, replaceNullChars(tsKvEntity.getJsonValue()));
  82 + ps.setString(13, replaceNullChars(tsKvEntity.getJsonValue()));
84 } 83 }
85 84
86 @Override 85 @Override
@@ -36,7 +36,7 @@ public class AggregationRepository { @@ -36,7 +36,7 @@ public class AggregationRepository {
36 public static final String FIND_SUM = "findSum"; 36 public static final String FIND_SUM = "findSum";
37 public static final String FIND_COUNT = "findCount"; 37 public static final String FIND_COUNT = "findCount";
38 38
39 - public static final String FROM_WHERE_CLAUSE = "FROM tenant_ts_kv tskv WHERE tskv.tenant_id = cast(:tenantId AS uuid) AND tskv.entity_id = cast(:entityId AS uuid) AND tskv.key= cast(:entityKey AS int) AND tskv.ts > :startTs AND tskv.ts <= :endTs GROUP BY tskv.tenant_id, tskv.entity_id, tskv.key, tsBucket ORDER BY tskv.tenant_id, tskv.entity_id, tskv.key, tsBucket"; 39 + public static final String FROM_WHERE_CLAUSE = "FROM ts_kv tskv WHERE tskv.entity_id = cast(:entityId AS uuid) AND tskv.key= cast(:entityKey AS int) AND tskv.ts > :startTs AND tskv.ts <= :endTs GROUP BY tskv.entity_id, tskv.key, tsBucket ORDER BY tskv.entity_id, tskv.key, tsBucket";
40 40
41 public static final String FIND_AVG_QUERY = "SELECT time_bucket(:timeBucket, tskv.ts) AS tsBucket, :timeBucket AS interval, SUM(COALESCE(tskv.long_v, 0)) AS longValue, SUM(COALESCE(tskv.dbl_v, 0.0)) AS doubleValue, SUM(CASE WHEN tskv.long_v IS NULL THEN 0 ELSE 1 END) AS longCountValue, SUM(CASE WHEN tskv.dbl_v IS NULL THEN 0 ELSE 1 END) AS doubleCountValue, null AS strValue, 'AVG' AS aggType "; 41 public static final String FIND_AVG_QUERY = "SELECT time_bucket(:timeBucket, tskv.ts) AS tsBucket, :timeBucket AS interval, SUM(COALESCE(tskv.long_v, 0)) AS longValue, SUM(COALESCE(tskv.dbl_v, 0.0)) AS doubleValue, SUM(CASE WHEN tskv.long_v IS NULL THEN 0 ELSE 1 END) AS longCountValue, SUM(CASE WHEN tskv.dbl_v IS NULL THEN 0 ELSE 1 END) AS doubleCountValue, null AS strValue, 'AVG' AS aggType ";
42 42
@@ -52,43 +52,42 @@ public class AggregationRepository { @@ -52,43 +52,42 @@ public class AggregationRepository {
52 private EntityManager entityManager; 52 private EntityManager entityManager;
53 53
54 @Async 54 @Async
55 - public CompletableFuture<List<TimescaleTsKvEntity>> findAvg(UUID tenantId, UUID entityId, int entityKey, long timeBucket, long startTs, long endTs) { 55 + public CompletableFuture<List<TimescaleTsKvEntity>> findAvg(UUID entityId, int entityKey, long timeBucket, long startTs, long endTs) {
56 @SuppressWarnings("unchecked") 56 @SuppressWarnings("unchecked")
57 - List<TimescaleTsKvEntity> resultList = getResultList(tenantId, entityId, entityKey, timeBucket, startTs, endTs, FIND_AVG); 57 + List<TimescaleTsKvEntity> resultList = getResultList(entityId, entityKey, timeBucket, startTs, endTs, FIND_AVG);
58 return CompletableFuture.supplyAsync(() -> resultList); 58 return CompletableFuture.supplyAsync(() -> resultList);
59 } 59 }
60 60
61 @Async 61 @Async
62 - public CompletableFuture<List<TimescaleTsKvEntity>> findMax(UUID tenantId, UUID entityId, int entityKey, long timeBucket, long startTs, long endTs) { 62 + public CompletableFuture<List<TimescaleTsKvEntity>> findMax(UUID entityId, int entityKey, long timeBucket, long startTs, long endTs) {
63 @SuppressWarnings("unchecked") 63 @SuppressWarnings("unchecked")
64 - List<TimescaleTsKvEntity> resultList = getResultList(tenantId, entityId, entityKey, timeBucket, startTs, endTs, FIND_MAX); 64 + List<TimescaleTsKvEntity> resultList = getResultList(entityId, entityKey, timeBucket, startTs, endTs, FIND_MAX);
65 return CompletableFuture.supplyAsync(() -> resultList); 65 return CompletableFuture.supplyAsync(() -> resultList);
66 } 66 }
67 67
68 @Async 68 @Async
69 - public CompletableFuture<List<TimescaleTsKvEntity>> findMin(UUID tenantId, UUID entityId, int entityKey, long timeBucket, long startTs, long endTs) { 69 + public CompletableFuture<List<TimescaleTsKvEntity>> findMin(UUID entityId, int entityKey, long timeBucket, long startTs, long endTs) {
70 @SuppressWarnings("unchecked") 70 @SuppressWarnings("unchecked")
71 - List<TimescaleTsKvEntity> resultList = getResultList(tenantId, entityId, entityKey, timeBucket, startTs, endTs, FIND_MIN); 71 + List<TimescaleTsKvEntity> resultList = getResultList(entityId, entityKey, timeBucket, startTs, endTs, FIND_MIN);
72 return CompletableFuture.supplyAsync(() -> resultList); 72 return CompletableFuture.supplyAsync(() -> resultList);
73 } 73 }
74 74
75 @Async 75 @Async
76 - public CompletableFuture<List<TimescaleTsKvEntity>> findSum(UUID tenantId, UUID entityId, int entityKey, long timeBucket, long startTs, long endTs) { 76 + public CompletableFuture<List<TimescaleTsKvEntity>> findSum(UUID entityId, int entityKey, long timeBucket, long startTs, long endTs) {
77 @SuppressWarnings("unchecked") 77 @SuppressWarnings("unchecked")
78 - List<TimescaleTsKvEntity> resultList = getResultList(tenantId, entityId, entityKey, timeBucket, startTs, endTs, FIND_SUM); 78 + List<TimescaleTsKvEntity> resultList = getResultList(entityId, entityKey, timeBucket, startTs, endTs, FIND_SUM);
79 return CompletableFuture.supplyAsync(() -> resultList); 79 return CompletableFuture.supplyAsync(() -> resultList);
80 } 80 }
81 81
82 @Async 82 @Async
83 - public CompletableFuture<List<TimescaleTsKvEntity>> findCount(UUID tenantId, UUID entityId, int entityKey, long timeBucket, long startTs, long endTs) { 83 + public CompletableFuture<List<TimescaleTsKvEntity>> findCount(UUID entityId, int entityKey, long timeBucket, long startTs, long endTs) {
84 @SuppressWarnings("unchecked") 84 @SuppressWarnings("unchecked")
85 - List<TimescaleTsKvEntity> resultList = getResultList(tenantId, entityId, entityKey, timeBucket, startTs, endTs, FIND_COUNT); 85 + List<TimescaleTsKvEntity> resultList = getResultList(entityId, entityKey, timeBucket, startTs, endTs, FIND_COUNT);
86 return CompletableFuture.supplyAsync(() -> resultList); 86 return CompletableFuture.supplyAsync(() -> resultList);
87 } 87 }
88 88
89 - private List getResultList(UUID tenantId, UUID entityId, int entityKey, long timeBucket, long startTs, long endTs, String query) { 89 + private List getResultList(UUID entityId, int entityKey, long timeBucket, long startTs, long endTs, String query) {
90 return entityManager.createNamedQuery(query) 90 return entityManager.createNamedQuery(query)
91 - .setParameter("tenantId", tenantId)  
92 .setParameter("entityId", entityId) 91 .setParameter("entityId", entityId)
93 .setParameter("entityKey", entityKey) 92 .setParameter("entityKey", entityKey)
94 .setParameter("timeBucket", timeBucket) 93 .setParameter("timeBucket", timeBucket)
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.sqlts.timescale; @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.sqlts.timescale;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 import com.google.common.util.concurrent.SettableFuture; 21 import com.google.common.util.concurrent.SettableFuture;
21 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
22 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
@@ -87,24 +88,23 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -87,24 +88,23 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
87 } 88 }
88 89
89 @Override 90 @Override
90 - protected ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { 91 + protected ListenableFuture<List<TsKvEntry>> findAllAsync(EntityId entityId, ReadTsKvQuery query) {
91 if (query.getAggregation() == Aggregation.NONE) { 92 if (query.getAggregation() == Aggregation.NONE) {
92 - return findAllAsyncWithLimit(tenantId, entityId, query); 93 + return findAllAsyncWithLimit(entityId, query);
93 } else { 94 } else {
94 long startTs = query.getStartTs(); 95 long startTs = query.getStartTs();
95 long endTs = query.getEndTs(); 96 long endTs = query.getEndTs();
96 long timeBucket = query.getInterval(); 97 long timeBucket = query.getInterval();
97 - ListenableFuture<List<Optional<TsKvEntry>>> future = findAllAndAggregateAsync(tenantId, entityId, query.getKey(), startTs, endTs, timeBucket, query.getAggregation()); 98 + ListenableFuture<List<Optional<TsKvEntry>>> future = findAllAndAggregateAsync(entityId, query.getKey(), startTs, endTs, timeBucket, query.getAggregation());
98 return getTskvEntriesFuture(future); 99 return getTskvEntriesFuture(future);
99 } 100 }
100 } 101 }
101 102
102 @Override 103 @Override
103 - protected ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { 104 + protected ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(EntityId entityId, ReadTsKvQuery query) {
104 String strKey = query.getKey(); 105 String strKey = query.getKey();
105 Integer keyId = getOrSaveKeyId(strKey); 106 Integer keyId = getOrSaveKeyId(strKey);
106 List<TimescaleTsKvEntity> timescaleTsKvEntities = tsKvRepository.findAllWithLimit( 107 List<TimescaleTsKvEntity> timescaleTsKvEntities = tsKvRepository.findAllWithLimit(
107 - tenantId.getId(),  
108 entityId.getId(), 108 entityId.getId(),
109 keyId, 109 keyId,
110 query.getStartTs(), 110 query.getStartTs(),
@@ -116,8 +116,8 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -116,8 +116,8 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
116 return Futures.immediateFuture(DaoUtil.convertDataList(timescaleTsKvEntities)); 116 return Futures.immediateFuture(DaoUtil.convertDataList(timescaleTsKvEntities));
117 } 117 }
118 118
119 - private ListenableFuture<List<Optional<TsKvEntry>>> findAllAndAggregateAsync(TenantId tenantId, EntityId entityId, String key, long startTs, long endTs, long timeBucket, Aggregation aggregation) {  
120 - CompletableFuture<List<TimescaleTsKvEntity>> listCompletableFuture = switchAggregation(key, startTs, endTs, timeBucket, aggregation, entityId.getId(), tenantId.getId()); 119 + private ListenableFuture<List<Optional<TsKvEntry>>> findAllAndAggregateAsync(EntityId entityId, String key, long startTs, long endTs, long timeBucket, Aggregation aggregation) {
  120 + CompletableFuture<List<TimescaleTsKvEntity>> listCompletableFuture = switchAggregation(key, startTs, endTs, timeBucket, aggregation, entityId.getId());
121 SettableFuture<List<TimescaleTsKvEntity>> listenableFuture = SettableFuture.create(); 121 SettableFuture<List<TimescaleTsKvEntity>> listenableFuture = SettableFuture.create();
122 listCompletableFuture.whenComplete((timescaleTsKvEntities, throwable) -> { 122 listCompletableFuture.whenComplete((timescaleTsKvEntities, throwable) -> {
123 if (throwable != null) { 123 if (throwable != null) {
@@ -132,7 +132,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -132,7 +132,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
132 timescaleTsKvEntities.forEach(entity -> { 132 timescaleTsKvEntities.forEach(entity -> {
133 if (entity != null && entity.isNotEmpty()) { 133 if (entity != null && entity.isNotEmpty()) {
134 entity.setEntityId(entityId.getId()); 134 entity.setEntityId(entityId.getId());
135 - entity.setTenantId(tenantId.getId());  
136 entity.setStrKey(key); 135 entity.setStrKey(key);
137 result.add(Optional.of(DaoUtil.getData(entity))); 136 result.add(Optional.of(DaoUtil.getData(entity)));
138 } else { 137 } else {
@@ -143,7 +142,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -143,7 +142,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
143 } else { 142 } else {
144 return Collections.emptyList(); 143 return Collections.emptyList();
145 } 144 }
146 - }); 145 + }, MoreExecutors.directExecutor());
147 } 146 }
148 147
149 @Override 148 @Override
@@ -166,7 +165,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -166,7 +165,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
166 String strKey = tsKvEntry.getKey(); 165 String strKey = tsKvEntry.getKey();
167 Integer keyId = getOrSaveKeyId(strKey); 166 Integer keyId = getOrSaveKeyId(strKey);
168 TimescaleTsKvEntity entity = new TimescaleTsKvEntity(); 167 TimescaleTsKvEntity entity = new TimescaleTsKvEntity();
169 - entity.setTenantId(tenantId.getId());  
170 entity.setEntityId(entityId.getId()); 168 entity.setEntityId(entityId.getId());
171 entity.setTs(tsKvEntry.getTs()); 169 entity.setTs(tsKvEntry.getTs());
172 entity.setKey(keyId); 170 entity.setKey(keyId);
@@ -196,7 +194,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -196,7 +194,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
196 Integer keyId = getOrSaveKeyId(strKey); 194 Integer keyId = getOrSaveKeyId(strKey);
197 return service.submit(() -> { 195 return service.submit(() -> {
198 tsKvRepository.delete( 196 tsKvRepository.delete(
199 - tenantId.getId(),  
200 entityId.getId(), 197 entityId.getId(),
201 keyId, 198 keyId,
202 query.getStartTs(), 199 query.getStartTs(),
@@ -207,7 +204,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -207,7 +204,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
207 204
208 @Override 205 @Override
209 public ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) { 206 public ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
210 - return getRemoveLatestFuture(tenantId, entityId, query); 207 + return getRemoveLatestFuture(entityId, query);
211 } 208 }
212 209
213 @Override 210 @Override
@@ -215,27 +212,26 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -215,27 +212,26 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
215 return service.submit(() -> null); 212 return service.submit(() -> null);
216 } 213 }
217 214
218 - private CompletableFuture<List<TimescaleTsKvEntity>> switchAggregation(String key, long startTs, long endTs, long timeBucket, Aggregation aggregation, UUID entityId, UUID tenantId) { 215 + private CompletableFuture<List<TimescaleTsKvEntity>> switchAggregation(String key, long startTs, long endTs, long timeBucket, Aggregation aggregation, UUID entityId) {
219 switch (aggregation) { 216 switch (aggregation) {
220 case AVG: 217 case AVG:
221 - return findAvg(key, startTs, endTs, timeBucket, entityId, tenantId); 218 + return findAvg(key, startTs, endTs, timeBucket, entityId);
222 case MAX: 219 case MAX:
223 - return findMax(key, startTs, endTs, timeBucket, entityId, tenantId); 220 + return findMax(key, startTs, endTs, timeBucket, entityId);
224 case MIN: 221 case MIN:
225 - return findMin(key, startTs, endTs, timeBucket, entityId, tenantId); 222 + return findMin(key, startTs, endTs, timeBucket, entityId);
226 case SUM: 223 case SUM:
227 - return findSum(key, startTs, endTs, timeBucket, entityId, tenantId); 224 + return findSum(key, startTs, endTs, timeBucket, entityId);
228 case COUNT: 225 case COUNT:
229 - return findCount(key, startTs, endTs, timeBucket, entityId, tenantId); 226 + return findCount(key, startTs, endTs, timeBucket, entityId);
230 default: 227 default:
231 throw new IllegalArgumentException("Not supported aggregation type: " + aggregation); 228 throw new IllegalArgumentException("Not supported aggregation type: " + aggregation);
232 } 229 }
233 } 230 }
234 231
235 - private CompletableFuture<List<TimescaleTsKvEntity>> findCount(String key, long startTs, long endTs, long timeBucket, UUID entityId, UUID tenantId) { 232 + private CompletableFuture<List<TimescaleTsKvEntity>> findCount(String key, long startTs, long endTs, long timeBucket, UUID entityId) {
236 Integer keyId = getOrSaveKeyId(key); 233 Integer keyId = getOrSaveKeyId(key);
237 return aggregationRepository.findCount( 234 return aggregationRepository.findCount(
238 - tenantId,  
239 entityId, 235 entityId,
240 keyId, 236 keyId,
241 timeBucket, 237 timeBucket,
@@ -243,10 +239,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -243,10 +239,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
243 endTs); 239 endTs);
244 } 240 }
245 241
246 - private CompletableFuture<List<TimescaleTsKvEntity>> findSum(String key, long startTs, long endTs, long timeBucket, UUID entityId, UUID tenantId) { 242 + private CompletableFuture<List<TimescaleTsKvEntity>> findSum(String key, long startTs, long endTs, long timeBucket, UUID entityId) {
247 Integer keyId = getOrSaveKeyId(key); 243 Integer keyId = getOrSaveKeyId(key);
248 return aggregationRepository.findSum( 244 return aggregationRepository.findSum(
249 - tenantId,  
250 entityId, 245 entityId,
251 keyId, 246 keyId,
252 timeBucket, 247 timeBucket,
@@ -254,10 +249,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -254,10 +249,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
254 endTs); 249 endTs);
255 } 250 }
256 251
257 - private CompletableFuture<List<TimescaleTsKvEntity>> findMin(String key, long startTs, long endTs, long timeBucket, UUID entityId, UUID tenantId) { 252 + private CompletableFuture<List<TimescaleTsKvEntity>> findMin(String key, long startTs, long endTs, long timeBucket, UUID entityId) {
258 Integer keyId = getOrSaveKeyId(key); 253 Integer keyId = getOrSaveKeyId(key);
259 return aggregationRepository.findMin( 254 return aggregationRepository.findMin(
260 - tenantId,  
261 entityId, 255 entityId,
262 keyId, 256 keyId,
263 timeBucket, 257 timeBucket,
@@ -265,10 +259,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -265,10 +259,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
265 endTs); 259 endTs);
266 } 260 }
267 261
268 - private CompletableFuture<List<TimescaleTsKvEntity>> findMax(String key, long startTs, long endTs, long timeBucket, UUID entityId, UUID tenantId) { 262 + private CompletableFuture<List<TimescaleTsKvEntity>> findMax(String key, long startTs, long endTs, long timeBucket, UUID entityId) {
269 Integer keyId = getOrSaveKeyId(key); 263 Integer keyId = getOrSaveKeyId(key);
270 return aggregationRepository.findMax( 264 return aggregationRepository.findMax(
271 - tenantId,  
272 entityId, 265 entityId,
273 keyId, 266 keyId,
274 timeBucket, 267 timeBucket,
@@ -276,10 +269,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -276,10 +269,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
276 endTs); 269 endTs);
277 } 270 }
278 271
279 - private CompletableFuture<List<TimescaleTsKvEntity>> findAvg(String key, long startTs, long endTs, long timeBucket, UUID entityId, UUID tenantId) { 272 + private CompletableFuture<List<TimescaleTsKvEntity>> findAvg(String key, long startTs, long endTs, long timeBucket, UUID entityId) {
280 Integer keyId = getOrSaveKeyId(key); 273 Integer keyId = getOrSaveKeyId(key);
281 return aggregationRepository.findAvg( 274 return aggregationRepository.findAvg(
282 - tenantId,  
283 entityId, 275 entityId,
284 keyId, 276 keyId,
285 timeBucket, 277 timeBucket,
@@ -31,12 +31,10 @@ import java.util.UUID; @@ -31,12 +31,10 @@ import java.util.UUID;
31 @TimescaleDBTsDao 31 @TimescaleDBTsDao
32 public interface TsKvTimescaleRepository extends CrudRepository<TimescaleTsKvEntity, TimescaleTsKvCompositeKey> { 32 public interface TsKvTimescaleRepository extends CrudRepository<TimescaleTsKvEntity, TimescaleTsKvCompositeKey> {
33 33
34 - @Query("SELECT tskv FROM TimescaleTsKvEntity tskv WHERE tskv.tenantId = :tenantId " +  
35 - "AND tskv.entityId = :entityId " + 34 + @Query("SELECT tskv FROM TimescaleTsKvEntity tskv WHERE tskv.entityId = :entityId " +
36 "AND tskv.key = :entityKey " + 35 "AND tskv.key = :entityKey " +
37 "AND tskv.ts > :startTs AND tskv.ts <= :endTs") 36 "AND tskv.ts > :startTs AND tskv.ts <= :endTs")
38 List<TimescaleTsKvEntity> findAllWithLimit( 37 List<TimescaleTsKvEntity> findAllWithLimit(
39 - @Param("tenantId") UUID tenantId,  
40 @Param("entityId") UUID entityId, 38 @Param("entityId") UUID entityId,
41 @Param("entityKey") int key, 39 @Param("entityKey") int key,
42 @Param("startTs") long startTs, 40 @Param("startTs") long startTs,
@@ -44,12 +42,10 @@ public interface TsKvTimescaleRepository extends CrudRepository<TimescaleTsKvEnt @@ -44,12 +42,10 @@ public interface TsKvTimescaleRepository extends CrudRepository<TimescaleTsKvEnt
44 42
45 @Transactional 43 @Transactional
46 @Modifying 44 @Modifying
47 - @Query("DELETE FROM TimescaleTsKvEntity tskv WHERE tskv.tenantId = :tenantId " +  
48 - "AND tskv.entityId = :entityId " + 45 + @Query("DELETE FROM TimescaleTsKvEntity tskv WHERE tskv.entityId = :entityId " +
49 "AND tskv.key = :entityKey " + 46 "AND tskv.key = :entityKey " +
50 "AND tskv.ts > :startTs AND tskv.ts <= :endTs") 47 "AND tskv.ts > :startTs AND tskv.ts <= :endTs")
51 - void delete(@Param("tenantId") UUID tenantId,  
52 - @Param("entityId") UUID entityId, 48 + void delete(@Param("entityId") UUID entityId,
53 @Param("entityKey") int key, 49 @Param("entityKey") int key,
54 @Param("startTs") long startTs, 50 @Param("startTs") long startTs,
55 @Param("endTs") long endTs); 51 @Param("endTs") long endTs);
@@ -28,6 +28,7 @@ import com.google.common.util.concurrent.AsyncFunction; @@ -28,6 +28,7 @@ import com.google.common.util.concurrent.AsyncFunction;
28 import com.google.common.util.concurrent.FutureCallback; 28 import com.google.common.util.concurrent.FutureCallback;
29 import com.google.common.util.concurrent.Futures; 29 import com.google.common.util.concurrent.Futures;
30 import com.google.common.util.concurrent.ListenableFuture; 30 import com.google.common.util.concurrent.ListenableFuture;
  31 +import com.google.common.util.concurrent.MoreExecutors;
31 import lombok.extern.slf4j.Slf4j; 32 import lombok.extern.slf4j.Slf4j;
32 import org.apache.commons.lang3.StringUtils; 33 import org.apache.commons.lang3.StringUtils;
33 import org.springframework.beans.factory.annotation.Autowired; 34 import org.springframework.beans.factory.annotation.Autowired;
@@ -330,7 +331,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -330,7 +331,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
330 stmt.setInt(6, (int) ttl); 331 stmt.setInt(6, (int) ttl);
331 } 332 }
332 futures.add(getFuture(executeAsyncWrite(tenantId, stmt), rs -> null)); 333 futures.add(getFuture(executeAsyncWrite(tenantId, stmt), rs -> null));
333 - return Futures.transform(Futures.allAsList(futures), result -> null); 334 + return Futures.transform(Futures.allAsList(futures), result -> null, MoreExecutors.directExecutor());
334 } 335 }
335 336
336 private void processSetNullValues(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl, List<ListenableFuture<Void>> futures, long partition, DataType type) { 337 private void processSetNullValues(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl, List<ListenableFuture<Void>> futures, long partition, DataType type) {
@@ -545,7 +546,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -545,7 +546,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
545 public void onFailure(Throwable t) { 546 public void onFailure(Throwable t) {
546 log.warn("[{}] Failed to process remove of the latest value", entityId, t); 547 log.warn("[{}] Failed to process remove of the latest value", entityId, t);
547 } 548 }
548 - }); 549 + }, MoreExecutors.directExecutor());
549 return resultFuture; 550 return resultFuture;
550 } 551 }
551 552
1 ---  
2 --- Copyright © 2016-2020 The Thingsboard Authors  
3 ---  
4 --- Licensed under the Apache License, Version 2.0 (the "License");  
5 --- you may not use this file except in compliance with the License.  
6 --- You may obtain a copy of the License at  
7 ---  
8 --- http://www.apache.org/licenses/LICENSE-2.0  
9 ---  
10 --- Unless required by applicable law or agreed to in writing, software  
11 --- distributed under the License is distributed on an "AS IS" BASIS,  
12 --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
13 --- See the License for the specific language governing permissions and  
14 --- limitations under the License.  
15 ---  
16 -  
17 -CREATE INDEX IF NOT EXISTS idx_tenant_ts_kv ON tenant_ts_kv(tenant_id, entity_id, key, ts);  
@@ -16,8 +16,7 @@ @@ -16,8 +16,7 @@
16 16
17 CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE; 17 CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;
18 18
19 -CREATE TABLE IF NOT EXISTS tenant_ts_kv (  
20 - tenant_id uuid NOT NULL, 19 +CREATE TABLE IF NOT EXISTS ts_kv (
21 entity_id uuid NOT NULL, 20 entity_id uuid NOT NULL,
22 key int NOT NULL, 21 key int NOT NULL,
23 ts bigint NOT NULL, 22 ts bigint NOT NULL,
@@ -26,7 +25,7 @@ CREATE TABLE IF NOT EXISTS tenant_ts_kv ( @@ -26,7 +25,7 @@ CREATE TABLE IF NOT EXISTS tenant_ts_kv (
26 long_v bigint, 25 long_v bigint,
27 dbl_v double precision, 26 dbl_v double precision,
28 json_v json, 27 json_v json,
29 - CONSTRAINT tenant_ts_kv_pkey PRIMARY KEY (tenant_id, entity_id, key, ts) 28 + CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts)
30 ); 29 );
31 30
32 CREATE TABLE IF NOT EXISTS ts_kv_dictionary ( 31 CREATE TABLE IF NOT EXISTS ts_kv_dictionary (
@@ -44,7 +44,7 @@ public class SqlDaoServiceTestSuite { @@ -44,7 +44,7 @@ public class SqlDaoServiceTestSuite {
44 44
45 // @ClassRule 45 // @ClassRule
46 // public static CustomSqlUnit sqlUnit = new CustomSqlUnit( 46 // public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
47 -// Arrays.asList("sql/schema-timescale.sql", "sql/schema-timescale-idx.sql", "sql/schema-entities.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql", "sql/system-test.sql"), 47 +// Arrays.asList("sql/schema-timescale.sql", "sql/schema-entities.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql", "sql/system-test.sql"),
48 // "sql/timescale/drop-all-tables.sql", 48 // "sql/timescale/drop-all-tables.sql",
49 // "sql-test.properties" 49 // "sql-test.properties"
50 // ); 50 // );
@@ -119,7 +119,7 @@ public class RateLimitedResultSetFutureTest { @@ -119,7 +119,7 @@ public class RateLimitedResultSetFutureTest {
119 119
120 resultSetFuture = new RateLimitedResultSetFuture(session, rateLimiter, statement); 120 resultSetFuture = new RateLimitedResultSetFuture(session, rateLimiter, statement);
121 121
122 - ListenableFuture<Row> transform = Futures.transform(resultSetFuture, ResultSet::one); 122 + ListenableFuture<Row> transform = Futures.transform(resultSetFuture, ResultSet::one, MoreExecutors.directExecutor());
123 Row actualRow = transform.get(); 123 Row actualRow = transform.get();
124 124
125 assertSame(row, actualRow); 125 assertSame(row, actualRow);
@@ -132,7 +132,7 @@ public class RateLimitedResultSetFutureTest { @@ -132,7 +132,7 @@ public class RateLimitedResultSetFutureTest {
132 when(rateLimiter.acquireAsync()).thenReturn(Futures.immediateFuture(null)); 132 when(rateLimiter.acquireAsync()).thenReturn(Futures.immediateFuture(null));
133 when(session.executeAsync(statement)).thenThrow(new UnsupportedFeatureException(ProtocolVersion.V3, "hjg")); 133 when(session.executeAsync(statement)).thenThrow(new UnsupportedFeatureException(ProtocolVersion.V3, "hjg"));
134 resultSetFuture = new RateLimitedResultSetFuture(session, rateLimiter, statement); 134 resultSetFuture = new RateLimitedResultSetFuture(session, rateLimiter, statement);
135 - ListenableFuture<Row> transform = Futures.transform(resultSetFuture, ResultSet::one); 135 + ListenableFuture<Row> transform = Futures.transform(resultSetFuture, ResultSet::one, MoreExecutors.directExecutor());
136 try { 136 try {
137 transform.get(); 137 transform.get();
138 fail(); 138 fail();
@@ -156,7 +156,7 @@ public class RateLimitedResultSetFutureTest { @@ -156,7 +156,7 @@ public class RateLimitedResultSetFutureTest {
156 156
157 when(realFuture.get()).thenThrow(new ExecutionException("Fail", new TimeoutException("timeout"))); 157 when(realFuture.get()).thenThrow(new ExecutionException("Fail", new TimeoutException("timeout")));
158 resultSetFuture = new RateLimitedResultSetFuture(session, rateLimiter, statement); 158 resultSetFuture = new RateLimitedResultSetFuture(session, rateLimiter, statement);
159 - ListenableFuture<Row> transform = Futures.transform(resultSetFuture, ResultSet::one); 159 + ListenableFuture<Row> transform = Futures.transform(resultSetFuture, ResultSet::one, MoreExecutors.directExecutor());
160 try { 160 try {
161 transform.get(); 161 transform.get();
162 fail(); 162 fail();
@@ -177,7 +177,7 @@ public class RateLimitedResultSetFutureTest { @@ -177,7 +177,7 @@ public class RateLimitedResultSetFutureTest {
177 when(rateLimiter.acquireAsync()).thenReturn(future); 177 when(rateLimiter.acquireAsync()).thenReturn(future);
178 resultSetFuture = new RateLimitedResultSetFuture(session, rateLimiter, statement); 178 resultSetFuture = new RateLimitedResultSetFuture(session, rateLimiter, statement);
179 179
180 - ListenableFuture<Row> transform = Futures.transform(resultSetFuture, ResultSet::one); 180 + ListenableFuture<Row> transform = Futures.transform(resultSetFuture, ResultSet::one, MoreExecutors.directExecutor());
181 // TimeUnit.MILLISECONDS.sleep(200); 181 // TimeUnit.MILLISECONDS.sleep(200);
182 future.cancel(false); 182 future.cancel(false);
183 latch.countDown(); 183 latch.countDown();
@@ -12,7 +12,7 @@ DROP TABLE IF EXISTS event; @@ -12,7 +12,7 @@ DROP TABLE IF EXISTS event;
12 DROP TABLE IF EXISTS relation; 12 DROP TABLE IF EXISTS relation;
13 DROP TABLE IF EXISTS tb_user; 13 DROP TABLE IF EXISTS tb_user;
14 DROP TABLE IF EXISTS tenant; 14 DROP TABLE IF EXISTS tenant;
15 -DROP TABLE IF EXISTS tenant_ts_kv; 15 +DROP TABLE IF EXISTS ts_kv;
16 DROP TABLE IF EXISTS ts_kv_latest; 16 DROP TABLE IF EXISTS ts_kv_latest;
17 DROP TABLE IF EXISTS user_credentials; 17 DROP TABLE IF EXISTS user_credentials;
18 DROP TABLE IF EXISTS widget_type; 18 DROP TABLE IF EXISTS widget_type;
@@ -17,6 +17,13 @@ In order to set database type change the value of `DATABASE` variable in `.env` @@ -17,6 +17,13 @@ In order to set database type change the value of `DATABASE` variable in `.env`
17 17
18 **NOTE**: According to the database type corresponding docker service will be deployed (see `docker-compose.postgres.yml`, `docker-compose.cassandra.yml` for details). 18 **NOTE**: According to the database type corresponding docker service will be deployed (see `docker-compose.postgres.yml`, `docker-compose.cassandra.yml` for details).
19 19
  20 +Execute the following command to create log folders for the services and chown of these folders to the docker container users.
  21 +To be able to change user, **chown** command is used, which requires sudo permissions (script will request password for a sudo access):
  22 +
  23 +`
  24 +$ ./docker-create-log-folders.sh
  25 +`
  26 +
20 Execute the following command to run installation: 27 Execute the following command to run installation:
21 28
22 ` 29 `
  1 +#!/bin/bash
  2 +#
  3 +# Copyright © 2016-2020 The Thingsboard Authors
  4 +#
  5 +# Licensed under the Apache License, Version 2.0 (the "License");
  6 +# you may not use this file except in compliance with the License.
  7 +# You may obtain a copy of the License at
  8 +#
  9 +# http://www.apache.org/licenses/LICENSE-2.0
  10 +#
  11 +# Unless required by applicable law or agreed to in writing, software
  12 +# distributed under the License is distributed on an "AS IS" BASIS,
  13 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 +# See the License for the specific language governing permissions and
  15 +# limitations under the License.
  16 +#
  17 +
  18 +mkdir -p tb-node/log/ && sudo chown -R 799:799 tb-node/log/
  19 +
  20 +mkdir -p tb-transports/coap/log && sudo chown -R 799:799 tb-transports/coap/log
  21 +
  22 +mkdir -p tb-transports/http/log && sudo chown -R 799:799 tb-transports/http/log
  23 +
  24 +mkdir -p tb-transports/mqtt/log && sudo chown -R 799:799 tb-transports/mqtt/log
@@ -39,5 +39,5 @@ spec: @@ -39,5 +39,5 @@ spec:
39 volumeMounts: 39 volumeMounts:
40 - mountPath: /config 40 - mountPath: /config
41 name: tb-node-config 41 name: tb-node-config
42 - command: ['sh', '-c', 'while [ ! -f /install-finished ]; do sleep 2; done;'] 42 + command: ['sh', '-c', 'while [ ! -f /tmp/install-finished ]; do sleep 2; done;']
43 restartPolicy: Never 43 restartPolicy: Never
@@ -15,4 +15,6 @@ @@ -15,4 +15,6 @@
15 # limitations under the License. 15 # limitations under the License.
16 # 16 #
17 17
18 -kubectl -n thingsboard delete svc,sts,deploy,pv,pvc,cm,po,ing --all 18 +kubectl -n thingsboard delete svc,sts,deploy,cm,po,ing --all
  19 +
  20 +kubectl -n thingsboard get pvc --no-headers=true | awk '//{print $1}' | xargs kubectl -n thingsboard delete --ignore-not-found=true pvc
@@ -22,7 +22,7 @@ function installTb() { @@ -22,7 +22,7 @@ function installTb() {
22 kubectl apply -f tb-node-configmap.yml 22 kubectl apply -f tb-node-configmap.yml
23 kubectl apply -f database-setup.yml && 23 kubectl apply -f database-setup.yml &&
24 kubectl wait --for=condition=Ready pod/tb-db-setup --timeout=120s && 24 kubectl wait --for=condition=Ready pod/tb-db-setup --timeout=120s &&
25 - kubectl exec tb-db-setup -- sh -c 'export INSTALL_TB=true; export LOAD_DEMO='"$loadDemo"'; start-tb-node.sh; touch /install-finished;' 25 + kubectl exec tb-db-setup -- sh -c 'export INSTALL_TB=true; export LOAD_DEMO='"$loadDemo"'; start-tb-node.sh; touch /tmp/install-finished;'
26 26
27 kubectl delete pod tb-db-setup 27 kubectl delete pod tb-db-setup
28 28
@@ -38,6 +38,6 @@ fi @@ -38,6 +38,6 @@ fi
38 38
39 kubectl apply -f database-setup.yml && 39 kubectl apply -f database-setup.yml &&
40 kubectl wait --for=condition=Ready pod/tb-db-setup --timeout=120s && 40 kubectl wait --for=condition=Ready pod/tb-db-setup --timeout=120s &&
41 -kubectl exec tb-db-setup -- sh -c 'export UPGRADE_TB=true; export FROM_VERSION='"$fromVersion"'; start-tb-node.sh; touch /install-finished;' 41 +kubectl exec tb-db-setup -- sh -c 'export UPGRADE_TB=true; export FROM_VERSION='"$fromVersion"'; start-tb-node.sh; touch /tmp/install-finished;'
42 42
43 kubectl delete pod tb-db-setup 43 kubectl delete pod tb-db-setup
@@ -58,6 +58,8 @@ spec: @@ -58,6 +58,8 @@ spec:
58 env: 58 env:
59 - name: POSTGRES_DB 59 - name: POSTGRES_DB
60 value: "thingsboard" 60 value: "thingsboard"
  61 + - name: POSTGRES_PASSWORD
  62 + value: "postgres"
61 - name: PGDATA 63 - name: PGDATA
62 value: /var/lib/postgresql/data/pgdata 64 value: /var/lib/postgresql/data/pgdata
63 volumeMounts: 65 volumeMounts:
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 # limitations under the License. 14 # limitations under the License.
15 # 15 #
16 16
17 -FROM debian:stretch 17 +FROM thingsboard/base
18 18
19 COPY start-js-executor.sh ${pkg.name}.deb /tmp/ 19 COPY start-js-executor.sh ${pkg.name}.deb /tmp/
20 20
@@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb @@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 RUN update-rc.d ${pkg.name} disable 26 RUN update-rc.d ${pkg.name} disable
27 27
  28 +USER ${pkg.user}
  29 +
28 CMD ["start-js-executor.sh"] 30 CMD ["start-js-executor.sh"]
@@ -26,4 +26,6 @@ identity=${pkg.name} @@ -26,4 +26,6 @@ identity=${pkg.name}
26 26
27 source "${CONF_FOLDER}/${configfile}" 27 source "${CONF_FOLDER}/${configfile}"
28 28
29 -su -s /bin/sh -c "$mainfile" 29 +cd ${pkg.installFolder}/bin
  30 +
  31 +exec /bin/sh -c "$mainfile"
@@ -36,7 +36,6 @@ @@ -36,7 +36,6 @@
36 <main.dir>${basedir}/../..</main.dir> 36 <main.dir>${basedir}/../..</main.dir>
37 <pkg.name>tb-js-executor</pkg.name> 37 <pkg.name>tb-js-executor</pkg.name>
38 <docker.name>tb-js-executor</docker.name> 38 <docker.name>tb-js-executor</docker.name>
39 - <pkg.user>thingsboard</pkg.user>  
40 <pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder> 39 <pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder>
41 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder> 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 <pkg.linux.dist>${project.build.directory}/package/linux</pkg.linux.dist> 41 <pkg.linux.dist>${project.build.directory}/package/linux</pkg.linux.dist>
@@ -25,4 +25,8 @@ RUN dpkg -i /tmp/${pkg.name}.deb @@ -25,4 +25,8 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 RUN systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || : 26 RUN systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || :
27 27
  28 +RUN chown -R ${pkg.user}:${pkg.user} /tmp
  29 +
  30 +USER ${pkg.user}
  31 +
28 CMD ["start-tb-node.sh"] 32 CMD ["start-tb-node.sh"]
@@ -18,12 +18,14 @@ @@ -18,12 +18,14 @@
18 CONF_FOLDER="/config" 18 CONF_FOLDER="/config"
19 jarfile=${pkg.installFolder}/bin/${pkg.name}.jar 19 jarfile=${pkg.installFolder}/bin/${pkg.name}.jar
20 configfile=${pkg.name}.conf 20 configfile=${pkg.name}.conf
21 -run_user=${pkg.name} 21 +run_user=${pkg.user}
22 22
23 source "${CONF_FOLDER}/${configfile}" 23 source "${CONF_FOLDER}/${configfile}"
24 24
25 export LOADER_PATH=/config,${LOADER_PATH} 25 export LOADER_PATH=/config,${LOADER_PATH}
26 26
  27 +cd ${pkg.installFolder}/bin
  28 +
27 if [ "$INSTALL_TB" == "true" ]; then 29 if [ "$INSTALL_TB" == "true" ]; then
28 30
29 if [ "$LOAD_DEMO" == "true" ]; then 31 if [ "$LOAD_DEMO" == "true" ]; then
@@ -36,7 +36,6 @@ @@ -36,7 +36,6 @@
36 <main.dir>${basedir}/../..</main.dir> 36 <main.dir>${basedir}/../..</main.dir>
37 <pkg.name>thingsboard</pkg.name> 37 <pkg.name>thingsboard</pkg.name>
38 <docker.name>tb-node</docker.name> 38 <docker.name>tb-node</docker.name>
39 - <pkg.user>thingsboard</pkg.user>  
40 <pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder> 39 <pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder>
41 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder> 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 </properties> 41 </properties>
@@ -38,7 +38,6 @@ @@ -38,7 +38,6 @@
38 <tb.docker.name>tb</tb.docker.name> 38 <tb.docker.name>tb</tb.docker.name>
39 <tb-postgres.docker.name>tb-postgres</tb-postgres.docker.name> 39 <tb-postgres.docker.name>tb-postgres</tb-postgres.docker.name>
40 <tb-cassandra.docker.name>tb-cassandra</tb-cassandra.docker.name> 40 <tb-cassandra.docker.name>tb-cassandra</tb-cassandra.docker.name>
41 - <pkg.user>thingsboard</pkg.user>  
42 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder> 41 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
43 <pkg.upgradeVersion>2.4.2</pkg.upgradeVersion> 42 <pkg.upgradeVersion>2.4.2</pkg.upgradeVersion>
44 </properties> 43 </properties>
@@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb @@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 RUN update-rc.d ${pkg.name} disable 26 RUN update-rc.d ${pkg.name} disable
27 27
  28 +USER ${pkg.user}
  29 +
28 CMD ["start-tb-coap-transport.sh"] 30 CMD ["start-tb-coap-transport.sh"]
@@ -25,6 +25,8 @@ export LOADER_PATH=/config,${LOADER_PATH} @@ -25,6 +25,8 @@ export LOADER_PATH=/config,${LOADER_PATH}
25 25
26 echo "Starting '${project.name}' ..." 26 echo "Starting '${project.name}' ..."
27 27
  28 +cd ${pkg.installFolder}/bin
  29 +
28 exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.coap.ThingsboardCoapTransportApplication \ 30 exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.coap.ThingsboardCoapTransportApplication \
29 -Dspring.jpa.hibernate.ddl-auto=none \ 31 -Dspring.jpa.hibernate.ddl-auto=none \
30 -Dlogging.config=/config/logback.xml \ 32 -Dlogging.config=/config/logback.xml \
@@ -36,7 +36,6 @@ @@ -36,7 +36,6 @@
36 <main.dir>${basedir}/../../..</main.dir> 36 <main.dir>${basedir}/../../..</main.dir>
37 <pkg.name>tb-coap-transport</pkg.name> 37 <pkg.name>tb-coap-transport</pkg.name>
38 <docker.name>tb-coap-transport</docker.name> 38 <docker.name>tb-coap-transport</docker.name>
39 - <pkg.user>thingsboard</pkg.user>  
40 <pkg.logFolder>/var/log/${pkg.name}</pkg.logFolder> 39 <pkg.logFolder>/var/log/${pkg.name}</pkg.logFolder>
41 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder> 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 </properties> 41 </properties>
@@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb @@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 RUN update-rc.d ${pkg.name} disable 26 RUN update-rc.d ${pkg.name} disable
27 27
  28 +USER ${pkg.user}
  29 +
28 CMD ["start-tb-http-transport.sh"] 30 CMD ["start-tb-http-transport.sh"]
@@ -25,6 +25,8 @@ export LOADER_PATH=/config,${LOADER_PATH} @@ -25,6 +25,8 @@ export LOADER_PATH=/config,${LOADER_PATH}
25 25
26 echo "Starting '${project.name}' ..." 26 echo "Starting '${project.name}' ..."
27 27
  28 +cd ${pkg.installFolder}/bin
  29 +
28 exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.http.ThingsboardHttpTransportApplication \ 30 exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.http.ThingsboardHttpTransportApplication \
29 -Dspring.jpa.hibernate.ddl-auto=none \ 31 -Dspring.jpa.hibernate.ddl-auto=none \
30 -Dlogging.config=/config/logback.xml \ 32 -Dlogging.config=/config/logback.xml \
@@ -36,7 +36,6 @@ @@ -36,7 +36,6 @@
36 <main.dir>${basedir}/../../..</main.dir> 36 <main.dir>${basedir}/../../..</main.dir>
37 <pkg.name>tb-http-transport</pkg.name> 37 <pkg.name>tb-http-transport</pkg.name>
38 <docker.name>tb-http-transport</docker.name> 38 <docker.name>tb-http-transport</docker.name>
39 - <pkg.user>thingsboard</pkg.user>  
40 <pkg.logFolder>/var/log/${pkg.name}</pkg.logFolder> 39 <pkg.logFolder>/var/log/${pkg.name}</pkg.logFolder>
41 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder> 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 </properties> 41 </properties>
@@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb @@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 RUN update-rc.d ${pkg.name} disable 26 RUN update-rc.d ${pkg.name} disable
27 27
  28 +USER ${pkg.user}
  29 +
28 CMD ["start-tb-mqtt-transport.sh"] 30 CMD ["start-tb-mqtt-transport.sh"]
@@ -25,6 +25,8 @@ export LOADER_PATH=/config,${LOADER_PATH} @@ -25,6 +25,8 @@ export LOADER_PATH=/config,${LOADER_PATH}
25 25
26 echo "Starting '${project.name}' ..." 26 echo "Starting '${project.name}' ..."
27 27
  28 +cd ${pkg.installFolder}/bin
  29 +
28 exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.mqtt.ThingsboardMqttTransportApplication \ 30 exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.mqtt.ThingsboardMqttTransportApplication \
29 -Dspring.jpa.hibernate.ddl-auto=none \ 31 -Dspring.jpa.hibernate.ddl-auto=none \
30 -Dlogging.config=/config/logback.xml \ 32 -Dlogging.config=/config/logback.xml \
@@ -36,7 +36,6 @@ @@ -36,7 +36,6 @@
36 <main.dir>${basedir}/../../..</main.dir> 36 <main.dir>${basedir}/../../..</main.dir>
37 <pkg.name>tb-mqtt-transport</pkg.name> 37 <pkg.name>tb-mqtt-transport</pkg.name>
38 <docker.name>tb-mqtt-transport</docker.name> 38 <docker.name>tb-mqtt-transport</docker.name>
39 - <pkg.user>thingsboard</pkg.user>  
40 <pkg.logFolder>/var/log/${pkg.name}</pkg.logFolder> 39 <pkg.logFolder>/var/log/${pkg.name}</pkg.logFolder>
41 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder> 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 </properties> 41 </properties>
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 # limitations under the License. 14 # limitations under the License.
15 # 15 #
16 16
17 -FROM debian:stretch 17 +FROM thingsboard/base
18 18
19 COPY start-web-ui.sh ${pkg.name}.deb /tmp/ 19 COPY start-web-ui.sh ${pkg.name}.deb /tmp/
20 20
@@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb @@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 RUN update-rc.d ${pkg.name} disable 26 RUN update-rc.d ${pkg.name} disable
27 27
  28 +USER ${pkg.user}
  29 +
28 CMD ["start-web-ui.sh"] 30 CMD ["start-web-ui.sh"]
@@ -26,4 +26,6 @@ identity=${pkg.name} @@ -26,4 +26,6 @@ identity=${pkg.name}
26 26
27 source "${CONF_FOLDER}/${configfile}" 27 source "${CONF_FOLDER}/${configfile}"
28 28
29 -su -s /bin/sh -c "$mainfile" 29 +cd ${pkg.installFolder}/bin
  30 +
  31 +exec /bin/sh -c "$mainfile"
@@ -36,7 +36,6 @@ @@ -36,7 +36,6 @@
36 <main.dir>${basedir}/../..</main.dir> 36 <main.dir>${basedir}/../..</main.dir>
37 <pkg.name>tb-web-ui</pkg.name> 37 <pkg.name>tb-web-ui</pkg.name>
38 <docker.name>tb-web-ui</docker.name> 38 <docker.name>tb-web-ui</docker.name>
39 - <pkg.user>thingsboard</pkg.user>  
40 <pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder> 39 <pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder>
41 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder> 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 <pkg.linux.dist>${project.build.directory}/package/linux</pkg.linux.dist> 41 <pkg.linux.dist>${project.build.directory}/package/linux</pkg.linux.dist>
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
29 29
30 <properties> 30 <properties>
31 <main.dir>${basedir}</main.dir> 31 <main.dir>${basedir}</main.dir>
  32 + <pkg.user>thingsboard</pkg.user>
32 <spring-boot.version>2.1.3.RELEASE</spring-boot.version> 33 <spring-boot.version>2.1.3.RELEASE</spring-boot.version>
33 <spring.version>5.1.5.RELEASE</spring.version> 34 <spring.version>5.1.5.RELEASE</spring.version>
34 <spring-security.version>5.1.4.RELEASE</spring-security.version> 35 <spring-security.version>5.1.4.RELEASE</spring-security.version>
@@ -44,7 +45,7 @@ @@ -44,7 +45,7 @@
44 <cassandra.version>3.6.0</cassandra.version> 45 <cassandra.version>3.6.0</cassandra.version>
45 <cassandra-unit.version>3.5.0.1</cassandra-unit.version> 46 <cassandra-unit.version>3.5.0.1</cassandra-unit.version>
46 <takari-cpsuite.version>1.2.7</takari-cpsuite.version> 47 <takari-cpsuite.version>1.2.7</takari-cpsuite.version>
47 - <guava.version>21.0</guava.version> 48 + <guava.version>28.2-jre</guava.version>
48 <caffeine.version>2.6.1</caffeine.version> 49 <caffeine.version>2.6.1</caffeine.version>
49 <commons-lang3.version>3.4</commons-lang3.version> 50 <commons-lang3.version>3.4</commons-lang3.version>
50 <commons-validator.version>1.6</commons-validator.version> 51 <commons-validator.version>1.6</commons-validator.version>
@@ -63,7 +64,7 @@ @@ -63,7 +64,7 @@
63 <mail.version>1.4.3</mail.version> 64 <mail.version>1.4.3</mail.version>
64 <curator.version>4.2.0</curator.version> 65 <curator.version>4.2.0</curator.version>
65 <zookeeper.version>3.5.5</zookeeper.version> 66 <zookeeper.version>3.5.5</zookeeper.version>
66 - <protobuf.version>3.6.1</protobuf.version> 67 + <protobuf.version>3.11.4</protobuf.version>
67 <grpc.version>1.22.1</grpc.version> 68 <grpc.version>1.22.1</grpc.version>
68 <lombok.version>1.16.18</lombok.version> 69 <lombok.version>1.16.18</lombok.version>
69 <paho.client.version>1.1.0</paho.client.version> 70 <paho.client.version>1.1.0</paho.client.version>
@@ -20,6 +20,7 @@ import com.google.common.cache.CacheLoader; @@ -20,6 +20,7 @@ import com.google.common.cache.CacheLoader;
20 import com.google.common.cache.LoadingCache; 20 import com.google.common.cache.LoadingCache;
21 import com.google.common.util.concurrent.Futures; 21 import com.google.common.util.concurrent.Futures;
22 import com.google.common.util.concurrent.ListenableFuture; 22 import com.google.common.util.concurrent.ListenableFuture;
  23 +import com.google.common.util.concurrent.MoreExecutors;
23 import lombok.AllArgsConstructor; 24 import lombok.AllArgsConstructor;
24 import lombok.Data; 25 import lombok.Data;
25 import lombok.NoArgsConstructor; 26 import lombok.NoArgsConstructor;
@@ -54,9 +55,9 @@ import java.util.List; @@ -54,9 +55,9 @@ import java.util.List;
54 import java.util.Optional; 55 import java.util.Optional;
55 import java.util.concurrent.TimeUnit; 56 import java.util.concurrent.TimeUnit;
56 57
  58 +import static org.thingsboard.common.util.DonAsynchron.withCallback;
57 import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE; 59 import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE;
58 import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; 60 import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
59 -import static org.thingsboard.common.util.DonAsynchron.withCallback;  
60 61
61 @Slf4j 62 @Slf4j
62 public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationActionNodeConfiguration> implements TbNode { 63 public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationActionNodeConfiguration> implements TbNode {
@@ -86,7 +87,7 @@ public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationA @@ -86,7 +87,7 @@ public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationA
86 } 87 }
87 88
88 protected ListenableFuture<RelationContainer> processEntityRelationAction(TbContext ctx, TbMsg msg) { 89 protected ListenableFuture<RelationContainer> processEntityRelationAction(TbContext ctx, TbMsg msg) {
89 - return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer)); 90 + return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer), MoreExecutors.directExecutor());
90 } 91 }
91 92
92 protected abstract boolean createEntityIfNotExists(); 93 protected abstract boolean createEntityIfNotExists();
@@ -18,12 +18,13 @@ package org.thingsboard.rule.engine.action; @@ -18,12 +18,13 @@ package org.thingsboard.rule.engine.action;
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
22 -import org.thingsboard.rule.engine.api.util.TbNodeUtils;  
23 import org.thingsboard.rule.engine.api.RuleNode; 23 import org.thingsboard.rule.engine.api.RuleNode;
24 import org.thingsboard.rule.engine.api.TbContext; 24 import org.thingsboard.rule.engine.api.TbContext;
25 import org.thingsboard.rule.engine.api.TbNodeConfiguration; 25 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
26 import org.thingsboard.rule.engine.api.TbNodeException; 26 import org.thingsboard.rule.engine.api.TbNodeException;
  27 +import org.thingsboard.rule.engine.api.util.TbNodeUtils;
27 import org.thingsboard.server.common.data.alarm.Alarm; 28 import org.thingsboard.server.common.data.alarm.Alarm;
28 import org.thingsboard.server.common.data.alarm.AlarmStatus; 29 import org.thingsboard.server.common.data.alarm.AlarmStatus;
29 import org.thingsboard.server.common.data.plugin.ComponentType; 30 import org.thingsboard.server.common.data.plugin.ComponentType;
@@ -80,8 +81,8 @@ public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfig @@ -80,8 +81,8 @@ public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfig
80 } 81 }
81 alarm.setStatus(alarm.getStatus().isAck() ? AlarmStatus.CLEARED_ACK : AlarmStatus.CLEARED_UNACK); 82 alarm.setStatus(alarm.getStatus().isAck() ? AlarmStatus.CLEARED_ACK : AlarmStatus.CLEARED_UNACK);
82 return Futures.immediateFuture(new AlarmResult(false, false, true, alarm)); 83 return Futures.immediateFuture(new AlarmResult(false, false, true, alarm));
83 - });  
84 - }); 84 + }, MoreExecutors.directExecutor());
  85 + }, MoreExecutors.directExecutor());
85 }, ctx.getDbCallbackExecutor()); 86 }, ctx.getDbCallbackExecutor());
86 } 87 }
87 } 88 }
@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.google.common.base.Function; 20 import com.google.common.base.Function;
21 import com.google.common.util.concurrent.Futures; 21 import com.google.common.util.concurrent.Futures;
22 import com.google.common.util.concurrent.ListenableFuture; 22 import com.google.common.util.concurrent.ListenableFuture;
  23 +import com.google.common.util.concurrent.MoreExecutors;
23 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
24 import org.thingsboard.rule.engine.api.RuleNode; 25 import org.thingsboard.rule.engine.api.RuleNode;
25 import org.thingsboard.rule.engine.api.TbContext; 26 import org.thingsboard.rule.engine.api.TbContext;
@@ -108,18 +109,18 @@ public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConf @@ -108,18 +109,18 @@ public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConf
108 private ListenableFuture<AlarmResult> createNewAlarm(TbContext ctx, TbMsg msg, Alarm msgAlarm) { 109 private ListenableFuture<AlarmResult> createNewAlarm(TbContext ctx, TbMsg msg, Alarm msgAlarm) {
109 ListenableFuture<Alarm> asyncAlarm; 110 ListenableFuture<Alarm> asyncAlarm;
110 if (msgAlarm != null) { 111 if (msgAlarm != null) {
111 - asyncAlarm = Futures.immediateCheckedFuture(msgAlarm); 112 + asyncAlarm = Futures.immediateFuture(msgAlarm);
112 } else { 113 } else {
113 ctx.logJsEvalRequest(); 114 ctx.logJsEvalRequest();
114 asyncAlarm = Futures.transform(buildAlarmDetails(ctx, msg, null), 115 asyncAlarm = Futures.transform(buildAlarmDetails(ctx, msg, null),
115 details -> { 116 details -> {
116 ctx.logJsEvalResponse(); 117 ctx.logJsEvalResponse();
117 return buildAlarm(msg, details, ctx.getTenantId()); 118 return buildAlarm(msg, details, ctx.getTenantId());
118 - }); 119 + }, MoreExecutors.directExecutor());
119 } 120 }
120 ListenableFuture<Alarm> asyncCreated = Futures.transform(asyncAlarm, 121 ListenableFuture<Alarm> asyncCreated = Futures.transform(asyncAlarm,
121 alarm -> ctx.getAlarmService().createOrUpdateAlarm(alarm), ctx.getDbCallbackExecutor()); 122 alarm -> ctx.getAlarmService().createOrUpdateAlarm(alarm), ctx.getDbCallbackExecutor());
122 - return Futures.transform(asyncCreated, alarm -> new AlarmResult(true, false, false, alarm)); 123 + return Futures.transform(asyncCreated, alarm -> new AlarmResult(true, false, false, alarm), MoreExecutors.directExecutor());
123 } 124 }
124 125
125 private ListenableFuture<AlarmResult> updateAlarm(TbContext ctx, TbMsg msg, Alarm existingAlarm, Alarm msgAlarm) { 126 private ListenableFuture<AlarmResult> updateAlarm(TbContext ctx, TbMsg msg, Alarm existingAlarm, Alarm msgAlarm) {
@@ -140,7 +141,7 @@ public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConf @@ -140,7 +141,7 @@ public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConf
140 return ctx.getAlarmService().createOrUpdateAlarm(existingAlarm); 141 return ctx.getAlarmService().createOrUpdateAlarm(existingAlarm);
141 }, ctx.getDbCallbackExecutor()); 142 }, ctx.getDbCallbackExecutor());
142 143
143 - return Futures.transform(asyncUpdated, a -> new AlarmResult(false, true, false, a)); 144 + return Futures.transform(asyncUpdated, a -> new AlarmResult(false, true, false, a), MoreExecutors.directExecutor());
144 } 145 }
145 146
146 private Alarm buildAlarm(TbMsg msg, JsonNode details, TenantId tenantId) { 147 private Alarm buildAlarm(TbMsg msg, JsonNode details, TenantId tenantId) {
@@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.action; @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.action;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
21 import org.thingsboard.rule.engine.api.RuleNode; 22 import org.thingsboard.rule.engine.api.RuleNode;
22 import org.thingsboard.rule.engine.api.TbContext; 23 import org.thingsboard.rule.engine.api.TbContext;
@@ -81,7 +82,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR @@ -81,7 +82,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR
81 } 82 }
82 container.setResult(result); 83 container.setResult(result);
83 return container; 84 return container;
84 - }); 85 + }, MoreExecutors.directExecutor());
85 } 86 }
86 87
87 private ListenableFuture<Boolean> createIfAbsent(TbContext ctx, TbMsg msg, EntityContainer entityContainer) { 88 private ListenableFuture<Boolean> createIfAbsent(TbContext ctx, TbMsg msg, EntityContainer entityContainer) {
@@ -120,7 +121,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR @@ -120,7 +121,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR
120 for (EntityRelation relation : entityRelations) { 121 for (EntityRelation relation : entityRelations) {
121 list.add(ctx.getRelationService().deleteRelationAsync(ctx.getTenantId(), relation)); 122 list.add(ctx.getRelationService().deleteRelationAsync(ctx.getTenantId(), relation));
122 } 123 }
123 - return Futures.transform(Futures.allAsList(list), result -> false); 124 + return Futures.transform(Futures.allAsList(list), result -> false, MoreExecutors.directExecutor());
124 } 125 }
125 return Futures.immediateFuture(false); 126 return Futures.immediateFuture(false);
126 }, ctx.getDbCallbackExecutor()); 127 }, ctx.getDbCallbackExecutor());
@@ -161,7 +162,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR @@ -161,7 +162,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR
161 } else { 162 } else {
162 return Futures.immediateFuture(true); 163 return Futures.immediateFuture(true);
163 } 164 }
164 - }); 165 + }, MoreExecutors.directExecutor());
165 } 166 }
166 167
167 private ListenableFuture<Boolean> processAsset(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) { 168 private ListenableFuture<Boolean> processAsset(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) {
@@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.action; @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.action;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
21 import org.thingsboard.rule.engine.api.RuleNode; 22 import org.thingsboard.rule.engine.api.RuleNode;
22 import org.thingsboard.rule.engine.api.TbContext; 23 import org.thingsboard.rule.engine.api.TbContext;
@@ -66,17 +67,18 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteR @@ -66,17 +67,18 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteR
66 67
67 @Override 68 @Override
68 protected ListenableFuture<RelationContainer> doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entityContainer) { 69 protected ListenableFuture<RelationContainer> doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entityContainer) {
69 - return Futures.transform(processSingle(ctx, msg, entityContainer), result -> new RelationContainer(msg, result)); 70 + return Futures.transform(processSingle(ctx, msg, entityContainer), result -> new RelationContainer(msg, result), MoreExecutors.directExecutor());
70 } 71 }
71 72
72 private ListenableFuture<RelationContainer> getRelationContainerListenableFuture(TbContext ctx, TbMsg msg) { 73 private ListenableFuture<RelationContainer> getRelationContainerListenableFuture(TbContext ctx, TbMsg msg) {
73 relationType = processPattern(msg, config.getRelationType()); 74 relationType = processPattern(msg, config.getRelationType());
74 if (config.isDeleteForSingleEntity()) { 75 if (config.isDeleteForSingleEntity()) {
75 - return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer)); 76 + return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer), MoreExecutors.directExecutor());
76 } else { 77 } else {
77 - return Futures.transform(processList(ctx, msg), result -> new RelationContainer(msg, result)); 78 + return Futures.transform(processList(ctx, msg), result -> new RelationContainer(msg, result), MoreExecutors.directExecutor());
78 } 79 }
79 } 80 }
  81 +
80 private ListenableFuture<Boolean> processList(TbContext ctx, TbMsg msg) { 82 private ListenableFuture<Boolean> processList(TbContext ctx, TbMsg msg) {
81 return Futures.transformAsync(processListSearchDirection(ctx, msg), entityRelations -> { 83 return Futures.transformAsync(processListSearchDirection(ctx, msg), entityRelations -> {
82 if (entityRelations.isEmpty()) { 84 if (entityRelations.isEmpty()) {
@@ -93,9 +95,9 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteR @@ -93,9 +95,9 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteR
93 } 95 }
94 } 96 }
95 return Futures.immediateFuture(true); 97 return Futures.immediateFuture(true);
96 - }); 98 + }, MoreExecutors.directExecutor());
97 } 99 }
98 - }); 100 + }, MoreExecutors.directExecutor());
99 } 101 }
100 102
101 private ListenableFuture<Boolean> processSingle(TbContext ctx, TbMsg msg, EntityContainer entityContainer) { 103 private ListenableFuture<Boolean> processSingle(TbContext ctx, TbMsg msg, EntityContainer entityContainer) {
@@ -106,7 +108,7 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteR @@ -106,7 +108,7 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteR
106 return processSingleDeleteRelation(ctx, sdId); 108 return processSingleDeleteRelation(ctx, sdId);
107 } 109 }
108 return Futures.immediateFuture(true); 110 return Futures.immediateFuture(true);
109 - }); 111 + }, MoreExecutors.directExecutor());
110 } 112 }
111 113
112 private ListenableFuture<Boolean> processSingleDeleteRelation(TbContext ctx, SearchDirectionIds sdId) { 114 private ListenableFuture<Boolean> processSingleDeleteRelation(TbContext ctx, SearchDirectionIds sdId) {
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.rule.engine.filter;
  17 +
  18 +import com.fasterxml.jackson.databind.ObjectMapper;
  19 +import com.google.common.util.concurrent.FutureCallback;
  20 +import com.google.common.util.concurrent.Futures;
  21 +import com.google.common.util.concurrent.ListenableFuture;
  22 +import com.google.common.util.concurrent.MoreExecutors;
  23 +import lombok.extern.slf4j.Slf4j;
  24 +import org.thingsboard.rule.engine.api.RuleNode;
  25 +import org.thingsboard.rule.engine.api.TbContext;
  26 +import org.thingsboard.rule.engine.api.TbNode;
  27 +import org.thingsboard.rule.engine.api.TbNodeConfiguration;
  28 +import org.thingsboard.rule.engine.api.TbNodeException;
  29 +import org.thingsboard.rule.engine.api.util.TbNodeUtils;
  30 +import org.thingsboard.server.common.data.alarm.Alarm;
  31 +import org.thingsboard.server.common.data.alarm.AlarmStatus;
  32 +import org.thingsboard.server.common.data.plugin.ComponentType;
  33 +import org.thingsboard.server.common.msg.TbMsg;
  34 +
  35 +import javax.annotation.Nullable;
  36 +import java.io.IOException;
  37 +
  38 +@Slf4j
  39 +@RuleNode(
  40 + type = ComponentType.FILTER,
  41 + name = "checks alarm status",
  42 + configClazz = TbCheckAlarmStatusNodeConfig.class,
  43 + relationTypes = {"True", "False"},
  44 + nodeDescription = "Checks alarm status.",
  45 + nodeDetails = "If the alarm status matches the specified one - msg is success if does not match - msg is failure.",
  46 + uiResources = {"static/rulenode/rulenode-core-config.js"},
  47 + configDirective = "tbFilterNodeCheckAlarmStatusConfig")
  48 +public class TbCheckAlarmStatusNode implements TbNode {
  49 + private TbCheckAlarmStatusNodeConfig config;
  50 + private final ObjectMapper mapper = new ObjectMapper();
  51 +
  52 + @Override
  53 + public void init(TbContext tbContext, TbNodeConfiguration configuration) throws TbNodeException {
  54 + this.config = TbNodeUtils.convert(configuration, TbCheckAlarmStatusNodeConfig.class);
  55 + }
  56 +
  57 + @Override
  58 + public void onMsg(TbContext ctx, TbMsg msg) throws TbNodeException {
  59 + try {
  60 + Alarm alarm = mapper.readValue(msg.getData(), Alarm.class);
  61 +
  62 + ListenableFuture<Alarm> latest = ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), alarm.getId());
  63 +
  64 + Futures.addCallback(latest, new FutureCallback<Alarm>() {
  65 + @Override
  66 + public void onSuccess(@Nullable Alarm result) {
  67 + if (result != null) {
  68 + boolean isPresent = false;
  69 + for (AlarmStatus alarmStatus : config.getAlarmStatusList()) {
  70 + if (alarm.getStatus() == alarmStatus) {
  71 + isPresent = true;
  72 + break;
  73 + }
  74 + }
  75 +
  76 + if (isPresent) {
  77 + ctx.tellNext(msg, "True");
  78 + } else {
  79 + ctx.tellNext(msg, "False");
  80 + }
  81 + } else {
  82 + ctx.tellFailure(msg, new TbNodeException("No such Alarm found."));
  83 + }
  84 + }
  85 +
  86 + @Override
  87 + public void onFailure(Throwable t) {
  88 + ctx.tellFailure(msg, t);
  89 + }
  90 + }, MoreExecutors.directExecutor());
  91 + } catch (IOException e) {
  92 + log.error("Failed to parse alarm: [{}]", msg.getData());
  93 + throw new TbNodeException(e);
  94 + }
  95 + }
  96 +
  97 + @Override
  98 + public void destroy() {
  99 + }
  100 +}
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.rule.engine.filter;
  17 +
  18 +import lombok.Data;
  19 +import org.thingsboard.rule.engine.api.NodeConfiguration;
  20 +import org.thingsboard.server.common.data.alarm.AlarmStatus;
  21 +
  22 +import java.util.Arrays;
  23 +import java.util.List;
  24 +
  25 +@Data
  26 +public class TbCheckAlarmStatusNodeConfig implements NodeConfiguration<TbCheckAlarmStatusNodeConfig> {
  27 + private List<AlarmStatus> alarmStatusList;
  28 +
  29 + @Override
  30 + public TbCheckAlarmStatusNodeConfig defaultConfiguration() {
  31 + TbCheckAlarmStatusNodeConfig config = new TbCheckAlarmStatusNodeConfig();
  32 + config.setAlarmStatusList(Arrays.asList(AlarmStatus.ACTIVE_ACK, AlarmStatus.ACTIVE_UNACK));
  33 + return config;
  34 + }
  35 +}
@@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.filter; @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.filter;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
21 import org.thingsboard.rule.engine.api.RuleNode; 22 import org.thingsboard.rule.engine.api.RuleNode;
22 import org.thingsboard.rule.engine.api.TbContext; 23 import org.thingsboard.rule.engine.api.TbContext;
@@ -87,10 +88,10 @@ public class TbCheckRelationNode implements TbNode { @@ -87,10 +88,10 @@ public class TbCheckRelationNode implements TbNode {
87 private ListenableFuture<Boolean> processList(TbContext ctx, TbMsg msg) { 88 private ListenableFuture<Boolean> processList(TbContext ctx, TbMsg msg) {
88 if (EntitySearchDirection.FROM.name().equals(config.getDirection())) { 89 if (EntitySearchDirection.FROM.name().equals(config.getDirection())) {
89 return Futures.transformAsync(ctx.getRelationService() 90 return Futures.transformAsync(ctx.getRelationService()
90 - .findByToAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), config.getRelationType(), RelationTypeGroup.COMMON), this::isEmptyList); 91 + .findByToAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), config.getRelationType(), RelationTypeGroup.COMMON), this::isEmptyList, MoreExecutors.directExecutor());
91 } else { 92 } else {
92 return Futures.transformAsync(ctx.getRelationService() 93 return Futures.transformAsync(ctx.getRelationService()
93 - .findByFromAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), config.getRelationType(), RelationTypeGroup.COMMON), this::isEmptyList); 94 + .findByFromAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), config.getRelationType(), RelationTypeGroup.COMMON), this::isEmptyList, MoreExecutors.directExecutor());
94 } 95 }
95 } 96 }
96 97
@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
21 import com.fasterxml.jackson.databind.node.ObjectNode; 21 import com.fasterxml.jackson.databind.node.ObjectNode;
22 import com.google.common.util.concurrent.Futures; 22 import com.google.common.util.concurrent.Futures;
23 import com.google.common.util.concurrent.ListenableFuture; 23 import com.google.common.util.concurrent.ListenableFuture;
  24 +import com.google.common.util.concurrent.MoreExecutors;
24 import com.google.gson.JsonParseException; 25 import com.google.gson.JsonParseException;
25 import org.apache.commons.collections.CollectionUtils; 26 import org.apache.commons.collections.CollectionUtils;
26 import org.apache.commons.lang3.BooleanUtils; 27 import org.apache.commons.lang3.BooleanUtils;
@@ -122,7 +123,7 @@ public abstract class TbAbstractGetAttributesNode<C extends TbGetAttributesNodeC @@ -122,7 +123,7 @@ public abstract class TbAbstractGetAttributesNode<C extends TbGetAttributesNodeC
122 } 123 }
123 } 124 }
124 return null; 125 return null;
125 - }); 126 + }, MoreExecutors.directExecutor());
126 } 127 }
127 128
128 private ListenableFuture<Void> putLatestTelemetry(TbContext ctx, EntityId entityId, TbMsg msg, String scope, List<String> keys, ConcurrentHashMap<String, List<String>> failuresMap) { 129 private ListenableFuture<Void> putLatestTelemetry(TbContext ctx, EntityId entityId, TbMsg msg, String scope, List<String> keys, ConcurrentHashMap<String, List<String>> failuresMap) {
@@ -152,7 +153,7 @@ public abstract class TbAbstractGetAttributesNode<C extends TbGetAttributesNodeC @@ -152,7 +153,7 @@ public abstract class TbAbstractGetAttributesNode<C extends TbGetAttributesNodeC
152 } 153 }
153 }); 154 });
154 return null; 155 return null;
155 - }); 156 + }, MoreExecutors.directExecutor());
156 } 157 }
157 158
158 private void putValueWithTs(TbMsg msg, TsKvEntry r) { 159 private void putValueWithTs(TbMsg msg, TsKvEntry r) {
@@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.metadata; @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.metadata;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 import com.google.gson.Gson; 21 import com.google.gson.Gson;
21 import com.google.gson.JsonElement; 22 import com.google.gson.JsonElement;
22 import com.google.gson.JsonObject; 23 import com.google.gson.JsonObject;
@@ -37,15 +38,16 @@ import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -37,15 +38,16 @@ import org.thingsboard.server.common.msg.TbMsgMetaData;
37 import java.lang.reflect.Type; 38 import java.lang.reflect.Type;
38 import java.util.Map; 39 import java.util.Map;
39 40
40 -import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;  
41 import static org.thingsboard.common.util.DonAsynchron.withCallback; 41 import static org.thingsboard.common.util.DonAsynchron.withCallback;
  42 +import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
42 43
43 @Slf4j 44 @Slf4j
44 public abstract class TbAbstractGetEntityDetailsNode<C extends TbAbstractGetEntityDetailsNodeConfiguration> implements TbNode { 45 public abstract class TbAbstractGetEntityDetailsNode<C extends TbAbstractGetEntityDetailsNodeConfiguration> implements TbNode {
45 46
46 private static final Gson gson = new Gson(); 47 private static final Gson gson = new Gson();
47 private static final JsonParser jsonParser = new JsonParser(); 48 private static final JsonParser jsonParser = new JsonParser();
48 - private static final Type TYPE = new TypeToken<Map<String, String>>() {}.getType(); 49 + private static final Type TYPE = new TypeToken<Map<String, String>>() {
  50 + }.getType();
49 51
50 protected C config; 52 protected C config;
51 53
@@ -104,7 +106,7 @@ public abstract class TbAbstractGetEntityDetailsNode<C extends TbAbstractGetEnti @@ -104,7 +106,7 @@ public abstract class TbAbstractGetEntityDetailsNode<C extends TbAbstractGetEnti
104 } else { 106 } else {
105 return Futures.immediateFuture(null); 107 return Futures.immediateFuture(null);
106 } 108 }
107 - }); 109 + }, MoreExecutors.directExecutor());
108 } 110 }
109 111
110 private ListenableFuture<JsonElement> addContactProperties(JsonElement data, ListenableFuture<ContactBased> entityFuture, EntityDetails entityDetails, String prefix) { 112 private ListenableFuture<JsonElement> addContactProperties(JsonElement data, ListenableFuture<ContactBased> entityFuture, EntityDetails entityDetails, String prefix) {
@@ -114,7 +116,7 @@ public abstract class TbAbstractGetEntityDetailsNode<C extends TbAbstractGetEnti @@ -114,7 +116,7 @@ public abstract class TbAbstractGetEntityDetailsNode<C extends TbAbstractGetEnti
114 } else { 116 } else {
115 return Futures.immediateFuture(null); 117 return Futures.immediateFuture(null);
116 } 118 }
117 - }); 119 + }, MoreExecutors.directExecutor());
118 } 120 }
119 121
120 private JsonElement setProperties(ContactBased entity, JsonElement data, EntityDetails entityDetails, String prefix) { 122 private JsonElement setProperties(ContactBased entity, JsonElement data, EntityDetails entityDetails, String prefix) {
@@ -17,12 +17,13 @@ package org.thingsboard.rule.engine.metadata; @@ -17,12 +17,13 @@ package org.thingsboard.rule.engine.metadata;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
21 -import org.thingsboard.rule.engine.api.util.TbNodeUtils;  
22 import org.thingsboard.rule.engine.api.TbContext; 22 import org.thingsboard.rule.engine.api.TbContext;
23 import org.thingsboard.rule.engine.api.TbNode; 23 import org.thingsboard.rule.engine.api.TbNode;
24 import org.thingsboard.rule.engine.api.TbNodeConfiguration; 24 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
25 import org.thingsboard.rule.engine.api.TbNodeException; 25 import org.thingsboard.rule.engine.api.TbNodeException;
  26 +import org.thingsboard.rule.engine.api.util.TbNodeUtils;
26 import org.thingsboard.server.common.data.id.EntityId; 27 import org.thingsboard.server.common.data.id.EntityId;
27 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 28 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
28 import org.thingsboard.server.common.data.kv.KvEntry; 29 import org.thingsboard.server.common.data.kv.KvEntry;
@@ -60,7 +61,7 @@ public abstract class TbEntityGetAttrNode<T extends EntityId> implements TbNode @@ -60,7 +61,7 @@ public abstract class TbEntityGetAttrNode<T extends EntityId> implements TbNode
60 } 61 }
61 62
62 private void safeGetAttributes(TbContext ctx, TbMsg msg, T entityId) { 63 private void safeGetAttributes(TbContext ctx, TbMsg msg, T entityId) {
63 - if(entityId == null || entityId.isNullUid()) { 64 + if (entityId == null || entityId.isNullUid()) {
64 ctx.tellNext(msg, FAILURE); 65 ctx.tellNext(msg, FAILURE);
65 return; 66 return;
66 } 67 }
@@ -73,13 +74,13 @@ public abstract class TbEntityGetAttrNode<T extends EntityId> implements TbNode @@ -73,13 +74,13 @@ public abstract class TbEntityGetAttrNode<T extends EntityId> implements TbNode
73 private ListenableFuture<List<KvEntry>> getAttributesAsync(TbContext ctx, EntityId entityId) { 74 private ListenableFuture<List<KvEntry>> getAttributesAsync(TbContext ctx, EntityId entityId) {
74 ListenableFuture<List<AttributeKvEntry>> latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, SERVER_SCOPE, config.getAttrMapping().keySet()); 75 ListenableFuture<List<AttributeKvEntry>> latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, SERVER_SCOPE, config.getAttrMapping().keySet());
75 return Futures.transform(latest, l -> 76 return Futures.transform(latest, l ->
76 - l.stream().map(i -> (KvEntry) i).collect(Collectors.toList())); 77 + l.stream().map(i -> (KvEntry) i).collect(Collectors.toList()), MoreExecutors.directExecutor());
77 } 78 }
78 79
79 private ListenableFuture<List<KvEntry>> getLatestTelemetry(TbContext ctx, EntityId entityId) { 80 private ListenableFuture<List<KvEntry>> getLatestTelemetry(TbContext ctx, EntityId entityId) {
80 ListenableFuture<List<TsKvEntry>> latest = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, config.getAttrMapping().keySet()); 81 ListenableFuture<List<TsKvEntry>> latest = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, config.getAttrMapping().keySet());
81 return Futures.transform(latest, l -> 82 return Futures.transform(latest, l ->
82 - l.stream().map(i -> (KvEntry) i).collect(Collectors.toList())); 83 + l.stream().map(i -> (KvEntry) i).collect(Collectors.toList()), MoreExecutors.directExecutor());
83 } 84 }
84 85
85 86
@@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.metadata; @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.metadata;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
21 import org.thingsboard.rule.engine.api.RuleNode; 22 import org.thingsboard.rule.engine.api.RuleNode;
22 import org.thingsboard.rule.engine.api.TbContext; 23 import org.thingsboard.rule.engine.api.TbContext;
@@ -63,7 +64,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG @@ -63,7 +64,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG
63 } else { 64 } else {
64 return Futures.immediateFuture(null); 65 return Futures.immediateFuture(null);
65 } 66 }
66 - }); 67 + }, MoreExecutors.directExecutor());
67 } 68 }
68 69
69 private ListenableFuture<Customer> getCustomer(TbContext ctx, TbMsg msg) { 70 private ListenableFuture<Customer> getCustomer(TbContext ctx, TbMsg msg) {
@@ -79,7 +80,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG @@ -79,7 +80,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG
79 } else { 80 } else {
80 return Futures.immediateFuture(null); 81 return Futures.immediateFuture(null);
81 } 82 }
82 - }); 83 + }, MoreExecutors.directExecutor());
83 case ASSET: 84 case ASSET:
84 return Futures.transformAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), new AssetId(msg.getOriginator().getId())), asset -> { 85 return Futures.transformAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), new AssetId(msg.getOriginator().getId())), asset -> {
85 if (asset != null) { 86 if (asset != null) {
@@ -91,7 +92,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG @@ -91,7 +92,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG
91 } else { 92 } else {
92 return Futures.immediateFuture(null); 93 return Futures.immediateFuture(null);
93 } 94 }
94 - }); 95 + }, MoreExecutors.directExecutor());
95 case ENTITY_VIEW: 96 case ENTITY_VIEW:
96 return Futures.transformAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), new EntityViewId(msg.getOriginator().getId())), entityView -> { 97 return Futures.transformAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), new EntityViewId(msg.getOriginator().getId())), entityView -> {
97 if (entityView != null) { 98 if (entityView != null) {
@@ -103,7 +104,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG @@ -103,7 +104,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG
103 } else { 104 } else {
104 return Futures.immediateFuture(null); 105 return Futures.immediateFuture(null);
105 } 106 }
106 - }); 107 + }, MoreExecutors.directExecutor());
107 default: 108 default:
108 throw new RuntimeException("Entity with entityType '" + msg.getOriginator().getEntityType() + "' is not supported."); 109 throw new RuntimeException("Entity with entityType '" + msg.getOriginator().getEntityType() + "' is not supported.");
109 } 110 }
@@ -17,16 +17,21 @@ package org.thingsboard.rule.engine.metadata; @@ -17,16 +17,21 @@ package org.thingsboard.rule.engine.metadata;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
21 -import org.thingsboard.rule.engine.api.*; 22 +import org.thingsboard.rule.engine.api.RuleNode;
  23 +import org.thingsboard.rule.engine.api.TbContext;
  24 +import org.thingsboard.rule.engine.api.TbNode;
  25 +import org.thingsboard.rule.engine.api.TbNodeConfiguration;
  26 +import org.thingsboard.rule.engine.api.TbNodeException;
22 import org.thingsboard.rule.engine.api.util.TbNodeUtils; 27 import org.thingsboard.rule.engine.api.util.TbNodeUtils;
23 import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader; 28 import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader;
24 import org.thingsboard.server.common.data.id.EntityId; 29 import org.thingsboard.server.common.data.id.EntityId;
25 import org.thingsboard.server.common.data.plugin.ComponentType; 30 import org.thingsboard.server.common.data.plugin.ComponentType;
26 import org.thingsboard.server.common.msg.TbMsg; 31 import org.thingsboard.server.common.msg.TbMsg;
27 32
28 -import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;  
29 import static org.thingsboard.common.util.DonAsynchron.withCallback; 33 import static org.thingsboard.common.util.DonAsynchron.withCallback;
  34 +import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
30 35
31 /** 36 /**
32 * Created by ashvayka on 19.01.18. 37 * Created by ashvayka on 19.01.18.
@@ -71,7 +76,7 @@ public class TbGetOriginatorFieldsNode implements TbNode { @@ -71,7 +76,7 @@ public class TbGetOriginatorFieldsNode implements TbNode {
71 } 76 }
72 }); 77 });
73 return null; 78 return null;
74 - } 79 + }, MoreExecutors.directExecutor()
75 ); 80 );
76 } 81 }
77 } 82 }
@@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.metadata; @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.metadata;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
21 import org.thingsboard.rule.engine.api.RuleNode; 22 import org.thingsboard.rule.engine.api.RuleNode;
22 import org.thingsboard.rule.engine.api.TbContext; 23 import org.thingsboard.rule.engine.api.TbContext;
@@ -59,6 +60,6 @@ public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode<TbGet @@ -59,6 +60,6 @@ public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode<TbGet
59 } else { 60 } else {
60 return Futures.immediateFuture(null); 61 return Futures.immediateFuture(null);
61 } 62 }
62 - }); 63 + }, MoreExecutors.directExecutor());
63 } 64 }
64 } 65 }