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 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 20 DECLARE
21 21 current_version integer;
22   - valid_version boolean;
23 22 BEGIN
24 23 RAISE NOTICE 'Check the current installed PostgreSQL version...';
25 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 26 RAISE NOTICE 'PostgreSQL version is valid!';
35 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 31 END IF;
37   - RETURN valid_version;
38 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 39 BEGIN
46 40 ALTER TABLE ts_kv
... ... @@ -57,11 +51,11 @@ BEGIN
57 51 ALTER TABLE ts_kv
58 52 ALTER COLUMN key TYPE integer USING key::integer;
59 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 60 BEGIN
67 61 ALTER TABLE ts_kv_latest
... ... @@ -81,13 +75,13 @@ BEGIN
81 75 ALTER TABLE ts_kv_latest
82 76 ADD CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key);
83 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 85 DECLARE
92 86 partition_date varchar;
93 87 from_ts bigint;
... ... @@ -111,11 +105,11 @@ BEGIN
111 105
112 106 CLOSE key_cursor;
113 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 114 BEGIN
121 115 CREATE TABLE IF NOT EXISTS ts_kv_dictionary
... ... @@ -125,12 +119,12 @@ BEGIN
125 119 CONSTRAINT ts_key_id_pkey PRIMARY KEY (key)
126 120 );
127 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 128 DECLARE
135 129 insert_record RECORD;
136 130 key_cursor CURSOR FOR SELECT DISTINCT key
... ... @@ -150,28 +144,27 @@ BEGIN
150 144 END LOOP;
151 145 CLOSE key_cursor;
152 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 152 DECLARE
160 153 insert_size CONSTANT integer := 10000;
161 154 insert_counter integer DEFAULT 0;
162 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 157 ts_kv_records.key AS key,
165 158 ts_kv_records.ts AS ts,
166 159 ts_kv_records.bool_v AS bool_v,
167 160 ts_kv_records.str_v AS str_v,
168 161 ts_kv_records.long_v AS long_v,
169 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 168 key_id AS key,
176 169 ts,
177 170 bool_v,
... ... @@ -198,28 +191,27 @@ BEGIN
198 191 END LOOP;
199 192 CLOSE insert_cursor;
200 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 199 DECLARE
208 200 insert_size CONSTANT integer := 10000;
209 201 insert_counter integer DEFAULT 0;
210 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 204 ts_kv_latest_records.key AS key,
213 205 ts_kv_latest_records.ts AS ts,
214 206 ts_kv_latest_records.bool_v AS bool_v,
215 207 ts_kv_latest_records.str_v AS str_v,
216 208 ts_kv_latest_records.long_v AS long_v,
217 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 215 key_id AS key,
224 216 ts,
225 217 bool_v,
... ... @@ -246,6 +238,6 @@ BEGIN
246 238 END LOOP;
247 239 CLOSE insert_cursor;
248 240 END;
249   -$$ LANGUAGE 'plpgsql';
  241 +$$;
250 242
251 243
... ...
... ... @@ -14,60 +14,51 @@
14 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 21 DECLARE
21 22 current_version integer;
22   - valid_version boolean;
23 23 BEGIN
24 24 RAISE NOTICE 'Check the current installed PostgreSQL version...';
25 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 27 RAISE NOTICE 'PostgreSQL version is valid!';
35 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 32 END IF;
37   - RETURN valid_version;
38 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 40 BEGIN
46 41 ALTER TABLE tenant_ts_kv
47 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 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 50 ALTER INDEX idx_tenant_ts_kv RENAME TO idx_tenant_ts_kv_old;
61 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 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 63 BEGIN
73 64 CREATE TABLE IF NOT EXISTS ts_kv_latest
... ... @@ -82,12 +73,12 @@ BEGIN
82 73 CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key)
83 74 );
84 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 83 BEGIN
93 84 CREATE TABLE IF NOT EXISTS ts_kv_dictionary
... ... @@ -97,12 +88,12 @@ BEGIN
97 88 CONSTRAINT ts_key_id_pkey PRIMARY KEY (key)
98 89 );
99 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 97 DECLARE
107 98 insert_record RECORD;
108 99 key_cursor CURSOR FOR SELECT DISTINCT key
... ... @@ -122,34 +113,28 @@ BEGIN
122 113 END LOOP;
123 114 CLOSE key_cursor;
124 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 122 DECLARE
132 123 insert_size CONSTANT integer := 10000;
133 124 insert_counter integer DEFAULT 0;
134 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 138 key_id AS key,
154 139 ts,
155 140 bool_v,
... ... @@ -157,31 +142,31 @@ DECLARE
157 142 long_v,
158 143 dbl_v
159 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 146 BEGIN
162 147 OPEN insert_cursor;
163 148 LOOP
164 149 insert_counter := insert_counter + 1;
165 150 FETCH insert_cursor INTO insert_record;
166 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 153 EXIT;
169 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 157 insert_record.long_v, insert_record.dbl_v);
173 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 160 END IF;
176 161 END LOOP;
177 162 CLOSE insert_cursor;
178 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 170 DECLARE
186 171 insert_size CONSTANT integer := 10000;
187 172 insert_counter integer DEFAULT 0;
... ... @@ -191,7 +176,7 @@ DECLARE
191 176 latest_records.key AS key,
192 177 latest_records.entity_id AS entity_id,
193 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 180 BEGIN
196 181 OPEN insert_cursor;
197 182 LOOP
... ... @@ -201,7 +186,7 @@ BEGIN
201 186 RAISE NOTICE '% records have been inserted into the ts_kv_latest table!',insert_counter - 1;
202 187 EXIT;
203 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 190 INSERT INTO ts_kv_latest(entity_id, key, ts, bool_v, str_v, long_v, dbl_v)
206 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 192 IF MOD(insert_counter, insert_size) = 0 THEN
... ... @@ -210,4 +195,4 @@ BEGIN
210 195 END LOOP;
211 196 CLOSE insert_cursor;
212 197 END;
213   -$$ LANGUAGE 'plpgsql';
  198 +$$;
... ...
... ... @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
24 24 import com.google.common.util.concurrent.FutureCallback;
25 25 import com.google.common.util.concurrent.Futures;
26 26 import com.google.common.util.concurrent.ListenableFuture;
  27 +import com.google.common.util.concurrent.MoreExecutors;
27 28 import com.typesafe.config.Config;
28 29 import com.typesafe.config.ConfigFactory;
29 30 import lombok.Getter;
... ... @@ -469,7 +470,7 @@ public class ActorSystemContext {
469 470 public void onFailure(Throwable th) {
470 471 log.error("Could not save debug Event for Node", th);
471 472 }
472   - });
  473 + }, MoreExecutors.directExecutor());
473 474 } catch (IOException ex) {
474 475 log.warn("Failed to persist rule node debug message", ex);
475 476 }
... ... @@ -522,7 +523,7 @@ public class ActorSystemContext {
522 523 public void onFailure(Throwable th) {
523 524 log.error("Could not save debug Event for Rule Chain", th);
524 525 }
525   - });
  526 + }, MoreExecutors.directExecutor());
526 527 }
527 528
528 529 public static Exception toException(Throwable error) {
... ...
... ... @@ -20,9 +20,9 @@ import com.datastax.driver.core.utils.UUIDs;
20 20 import com.google.common.util.concurrent.FutureCallback;
21 21 import com.google.common.util.concurrent.Futures;
22 22 import com.google.common.util.concurrent.ListenableFuture;
  23 +import com.google.common.util.concurrent.MoreExecutors;
23 24 import com.google.gson.Gson;
24 25 import com.google.gson.JsonObject;
25   -import com.google.gson.JsonParser;
26 26 import com.google.protobuf.InvalidProtocolBufferException;
27 27 import lombok.extern.slf4j.Slf4j;
28 28 import org.apache.commons.collections.CollectionUtils;
... ... @@ -292,7 +292,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
292 292 .build();
293 293 sendToTransport(responseMsg, sessionInfo);
294 294 }
295   - });
  295 + }, MoreExecutors.directExecutor());
296 296 }
297 297
298 298 private ListenableFuture<List<List<AttributeKvEntry>>> getAttributesKvEntries(GetAttributeRequestMsg request) {
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.controller;
18 18 import com.google.common.util.concurrent.FutureCallback;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22 import org.springframework.http.HttpStatus;
22 23 import org.springframework.http.ResponseEntity;
23 24 import org.springframework.security.access.prepost.PreAuthorize;
... ... @@ -30,7 +31,13 @@ import org.springframework.web.bind.annotation.ResponseBody;
30 31 import org.springframework.web.bind.annotation.ResponseStatus;
31 32 import org.springframework.web.bind.annotation.RestController;
32 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 41 import org.thingsboard.server.common.data.audit.ActionType;
35 42 import org.thingsboard.server.common.data.device.DeviceSearchQuery;
36 43 import org.thingsboard.server.common.data.exception.ThingsboardException;
... ... @@ -40,7 +47,6 @@ import org.thingsboard.server.common.data.id.TenantId;
40 47 import org.thingsboard.server.common.data.page.PageData;
41 48 import org.thingsboard.server.common.data.page.PageLink;
42 49 import org.thingsboard.server.common.data.security.DeviceCredentials;
43   -import org.thingsboard.server.common.data.ClaimRequest;
44 50 import org.thingsboard.server.dao.device.claim.ClaimResponse;
45 51 import org.thingsboard.server.dao.device.claim.ClaimResult;
46 52 import org.thingsboard.server.dao.exception.IncorrectParameterException;
... ... @@ -486,11 +492,12 @@ public class DeviceController extends BaseController {
486 492 deferredResult.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
487 493 }
488 494 }
  495 +
489 496 @Override
490 497 public void onFailure(Throwable t) {
491 498 deferredResult.setErrorResult(t);
492 499 }
493   - });
  500 + }, MoreExecutors.directExecutor());
494 501 return deferredResult;
495 502 } catch (Exception e) {
496 503 throw handleException(e);
... ... @@ -527,7 +534,7 @@ public class DeviceController extends BaseController {
527 534 public void onFailure(Throwable t) {
528 535 deferredResult.setErrorResult(t);
529 536 }
530   - });
  537 + }, MoreExecutors.directExecutor());
531 538 return deferredResult;
532 539 } catch (Exception e) {
533 540 throw handleException(e);
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.controller;
18 18 import com.google.common.util.concurrent.FutureCallback;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22 import lombok.extern.slf4j.Slf4j;
22 23 import org.springframework.http.HttpStatus;
23 24 import org.springframework.security.access.prepost.PreAuthorize;
... ... @@ -167,7 +168,7 @@ public class EntityViewController extends BaseController {
167 168 });
168 169 }
169 170 return null;
170   - });
  171 + }, MoreExecutors.directExecutor());
171 172 } else {
172 173 return Futures.immediateFuture(null);
173 174 }
... ...
... ... @@ -22,6 +22,7 @@ import com.google.common.base.Function;
22 22 import com.google.common.util.concurrent.FutureCallback;
23 23 import com.google.common.util.concurrent.Futures;
24 24 import com.google.common.util.concurrent.ListenableFuture;
  25 +import com.google.common.util.concurrent.MoreExecutors;
25 26 import com.google.gson.JsonElement;
26 27 import com.google.gson.JsonParseException;
27 28 import com.google.gson.JsonParser;
... ... @@ -174,7 +175,7 @@ public class TelemetryController extends BaseController {
174 175 public DeferredResult<ResponseEntity> getTimeseriesKeys(
175 176 @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr) throws ThingsboardException {
176 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 181 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
... ... @@ -210,7 +211,7 @@ public class TelemetryController extends BaseController {
210 211 List<ReadTsKvQuery> queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg))
211 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 463 } else {
463 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 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 471 FutureCallback<List<AttributeKvEntry>> callback = getAttributeValuesToResponseCallback(result, user, scope, entityId, keyList);
471 472 if (!StringUtils.isEmpty(scope)) {
472 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 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 478 } else {
478 479 List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>();
... ... @@ -486,12 +487,12 @@ public class TelemetryController extends BaseController {
486 487
487 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 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 498 private void getAttributeKeysCallback(@Nullable DeferredResult<ResponseEntity> result, TenantId tenantId, EntityId entityId) {
... ... @@ -502,7 +503,7 @@ public class TelemetryController extends BaseController {
502 503
503 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 509 private FutureCallback<List<TsKvEntry>> getTsKeysToResponseCallback(final DeferredResult<ResponseEntity> response) {
... ...
... ... @@ -22,38 +22,21 @@ import org.springframework.beans.factory.annotation.Value;
22 22 import java.nio.charset.StandardCharsets;
23 23 import java.nio.file.Files;
24 24 import java.nio.file.Path;
25   -import java.sql.CallableStatement;
26 25 import java.sql.Connection;
  26 +import java.sql.ResultSet;
27 27 import java.sql.SQLException;
28 28 import java.sql.SQLWarning;
29   -import java.sql.Types;
  29 +import java.sql.Statement;
30 30
31 31 @Slf4j
32 32 public abstract class AbstractSqlTsDatabaseUpgradeService {
33 33
34 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 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 41 @Value("${spring.datasource.url}")
59 42 protected String dbUrl;
... ... @@ -78,23 +61,22 @@ public abstract class AbstractSqlTsDatabaseUpgradeService {
78 61 log.info("Check the current PostgreSQL version...");
79 62 boolean versionValid = false;
80 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 69 } catch (Exception e) {
87 70 log.info("Failed to check current PostgreSQL version due to: {}", e.getMessage());
88 71 }
89 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 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 80 if (warnings != null) {
99 81 log.info("{}", warnings.getMessage());
100 82 SQLWarning nextWarning = warnings.getNextWarning();
... ... @@ -103,31 +85,10 @@ public abstract class AbstractSqlTsDatabaseUpgradeService {
103 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 88 Thread.sleep(5000);
  89 + log.info("Successfully executed query: {}", query);
129 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 57 private static final String DROP_TABLE_TS_KV_OLD = DROP_TABLE + TS_KV_OLD;
58 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 68 @Override
70 69 public void upgradeDatabase(String fromVersion) throws Exception {
... ... @@ -76,30 +75,30 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe
76 75 loadSql(conn);
77 76 boolean versionValid = checkVersion(conn);
78 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 79 log.info("Please upgrade your PostgreSQL and restart the script!");
81 80 } else {
82 81 log.info("PostgreSQL version is valid!");
83 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 103 executeQuery(conn, "ALTER TABLE ts_kv ADD COLUMN json_v json;");
105 104 executeQuery(conn, "ALTER TABLE ts_kv_latest ADD COLUMN json_v json;");
... ...
... ... @@ -45,13 +45,13 @@ public class TimescaleTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaS
45 45 private long chunkTimeInterval;
46 46
47 47 public TimescaleTsDatabaseSchemaService() {
48   - super("schema-timescale.sql", "schema-timescale-idx.sql");
  48 + super("schema-timescale.sql", null);
49 49 }
50 50
51 51 @Override
52 52 public void createDatabaseSchema() throws Exception {
53 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 57 private void executeQuery(String query) {
... ...
... ... @@ -43,27 +43,27 @@ public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgr
43 43 private static final String TENANT_TS_KV_OLD_TABLE = "tenant_ts_kv_old;";
44 44
45 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 47 private static final String CREATE_TS_KV_DICTIONARY_TABLE = "create_ts_kv_dictionary_table()";
48 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 50 private static final String INSERT_INTO_TS_KV_LATEST = "insert_into_ts_kv_latest()";
51 51
52 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 54 private static final String CALL_CREATE_TS_KV_DICTIONARY_TABLE = CALL_REGEX + CREATE_TS_KV_DICTIONARY_TABLE;
55 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 57 private static final String CALL_INSERT_INTO_TS_KV_LATEST = CALL_REGEX + INSERT_INTO_TS_KV_LATEST;
58 58
59 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 68 @Autowired
69 69 private InstallScripts installScripts;
... ... @@ -78,33 +78,31 @@ public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgr
78 78 loadSql(conn);
79 79 boolean versionValid = checkVersion(conn);
80 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 82 log.info("Please upgrade your PostgreSQL and restart the script!");
83 83 } else {
84 84 log.info("PostgreSQL version is valid!");
85 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 106 executeQuery(conn, "ALTER TABLE ts_kv_latest ADD COLUMN json_v json;");
109 107
110 108 log.info("schema timeseries updated!");
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.service.script;
18 18 import com.google.common.util.concurrent.FutureCallback;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22 import delight.nashornsandbox.NashornSandbox;
22 23 import delight.nashornsandbox.NashornSandboxes;
23 24 import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
... ... @@ -28,20 +29,17 @@ import org.springframework.beans.factory.annotation.Value;
28 29 import org.springframework.scheduling.annotation.Scheduled;
29 30 import org.thingsboard.common.util.ThingsBoardThreadFactory;
30 31
31   -import javax.annotation.Nullable;
32 32 import javax.annotation.PostConstruct;
33 33 import javax.annotation.PreDestroy;
34 34 import javax.script.Invocable;
35 35 import javax.script.ScriptEngine;
36 36 import javax.script.ScriptException;
37 37 import java.util.UUID;
38   -import java.util.concurrent.Callable;
39 38 import java.util.concurrent.ExecutionException;
40 39 import java.util.concurrent.ExecutorService;
41 40 import java.util.concurrent.Executors;
42 41 import java.util.concurrent.ScheduledExecutorService;
43 42 import java.util.concurrent.TimeUnit;
44   -import java.util.concurrent.TimeoutException;
45 43 import java.util.concurrent.atomic.AtomicInteger;
46 44
47 45 @Slf4j
... ... @@ -140,7 +138,7 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
140 138 if (maxRequestsTimeout > 0) {
141 139 result = Futures.withTimeout(result, maxRequestsTimeout, TimeUnit.MILLISECONDS, timeoutExecutorService);
142 140 }
143   - Futures.addCallback(result, evalCallback);
  141 + Futures.addCallback(result, evalCallback, MoreExecutors.directExecutor());
144 142 return result;
145 143 }
146 144
... ... @@ -163,7 +161,7 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
163 161 if (maxRequestsTimeout > 0) {
164 162 result = Futures.withTimeout(result, maxRequestsTimeout, TimeUnit.MILLISECONDS, timeoutExecutorService);
165 163 }
166   - Futures.addCallback(result, invokeCallback);
  164 + Futures.addCallback(result, invokeCallback, MoreExecutors.directExecutor());
167 165 return result;
168 166 }
169 167
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.service.script;
18 18 import com.google.common.util.concurrent.FutureCallback;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22 import lombok.Getter;
22 23 import lombok.extern.slf4j.Slf4j;
23 24 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -40,7 +41,6 @@ import java.util.UUID;
40 41 import java.util.concurrent.ConcurrentHashMap;
41 42 import java.util.concurrent.TimeoutException;
42 43 import java.util.concurrent.atomic.AtomicInteger;
43   -import java.util.concurrent.atomic.AtomicLong;
44 44
45 45 @Slf4j
46 46 @ConditionalOnProperty(prefix = "js", value = "evaluator", havingValue = "remote", matchIfMissing = true)
... ... @@ -166,7 +166,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
166 166 }
167 167 kafkaFailedMsgs.incrementAndGet();
168 168 }
169   - });
  169 + }, MoreExecutors.directExecutor());
170 170 return Futures.transform(future, response -> {
171 171 JsInvokeProtos.JsCompileResponse compilationResult = response.getCompileResponse();
172 172 UUID compiledScriptId = new UUID(compilationResult.getScriptIdMSB(), compilationResult.getScriptIdLSB());
... ... @@ -178,7 +178,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
178 178 log.debug("[{}] Failed to compile script due to [{}]: {}", compiledScriptId, compilationResult.getErrorCode().name(), compilationResult.getErrorDetails());
179 179 throw new RuntimeException(compilationResult.getErrorDetails());
180 180 }
181   - });
  181 + }, MoreExecutors.directExecutor());
182 182 }
183 183
184 184 @Override
... ... @@ -217,7 +217,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
217 217 }
218 218 kafkaFailedMsgs.incrementAndGet();
219 219 }
220   - });
  220 + }, MoreExecutors.directExecutor());
221 221 return Futures.transform(future, response -> {
222 222 JsInvokeProtos.JsInvokeResponse invokeResult = response.getInvokeResponse();
223 223 if (invokeResult.getSuccess()) {
... ... @@ -226,7 +226,7 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
226 226 log.debug("[{}] Failed to compile script due to [{}]: {}", scriptId, invokeResult.getErrorCode().name(), invokeResult.getErrorDetails());
227 227 throw new RuntimeException(invokeResult.getErrorDetails());
228 228 }
229   - });
  229 + }, MoreExecutors.directExecutor());
230 230 }
231 231
232 232 @Override
... ...
... ... @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
21 21 import com.google.common.collect.Sets;
22 22 import com.google.common.util.concurrent.Futures;
23 23 import com.google.common.util.concurrent.ListenableFuture;
  24 +import com.google.common.util.concurrent.MoreExecutors;
24 25 import lombok.extern.slf4j.Slf4j;
25 26 import org.apache.commons.lang3.StringUtils;
26 27 import org.thingsboard.server.common.data.id.EntityId;
... ... @@ -121,7 +122,7 @@ public class RuleNodeJsScriptEngine implements org.thingsboard.rule.engine.api.S
121 122 } else {
122 123 return Futures.immediateFuture(unbindMsg(json, msg));
123 124 }
124   - });
  125 + }, MoreExecutors.directExecutor());
125 126 }
126 127
127 128 @Override
... ... @@ -174,7 +175,7 @@ public class RuleNodeJsScriptEngine implements org.thingsboard.rule.engine.api.S
174 175 } else {
175 176 return Futures.immediateFuture(json.asBoolean());
176 177 }
177   - });
  178 + }, MoreExecutors.directExecutor());
178 179 }
179 180
180 181 @Override
... ... @@ -232,7 +233,7 @@ public class RuleNodeJsScriptEngine implements org.thingsboard.rule.engine.api.S
232 233 return Futures.immediateFailedFuture(new ScriptException(e));
233 234 }
234 235 }
235   - });
  236 + }, MoreExecutors.directExecutor());
236 237 }
237 238
238 239 public void destroy() {
... ...
... ... @@ -64,14 +64,26 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
64 64 import javax.annotation.Nullable;
65 65 import javax.annotation.PostConstruct;
66 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 76 import java.util.concurrent.ConcurrentHashMap;
69 77 import java.util.concurrent.ConcurrentMap;
70 78 import java.util.concurrent.ExecutionException;
71 79 import java.util.concurrent.Executors;
72 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 89 * Created by ashvayka on 01.05.18.
... ... @@ -401,7 +413,7 @@ public class DefaultDeviceStateService implements DeviceStateService {
401 413 public void onFailure(Throwable t) {
402 414 log.warn("Failed to register device to the state service", t);
403 415 }
404   - });
  416 + }, MoreExecutors.directExecutor());
405 417 } else {
406 418 sendDeviceEvent(device.getTenantId(), device.getId(), address.get(), true, false, false);
407 419 }
... ... @@ -456,10 +468,10 @@ public class DefaultDeviceStateService implements DeviceStateService {
456 468 private ListenableFuture<DeviceStateData> fetchDeviceState(Device device) {
457 469 if (persistToTelemetry) {
458 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 472 } else {
461 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 21 import com.google.common.util.concurrent.FutureCallback;
22 22 import com.google.common.util.concurrent.Futures;
23 23 import com.google.common.util.concurrent.ListenableFuture;
  24 +import com.google.common.util.concurrent.MoreExecutors;
24 25 import lombok.extern.slf4j.Slf4j;
25 26 import org.springframework.beans.factory.annotation.Autowired;
26 27 import org.springframework.beans.factory.annotation.Value;
... ... @@ -54,9 +55,6 @@ import org.thingsboard.server.service.telemetry.cmd.SubscriptionCmd;
54 55 import org.thingsboard.server.service.telemetry.cmd.TelemetryPluginCmd;
55 56 import org.thingsboard.server.service.telemetry.cmd.TelemetryPluginCmdsWrapper;
56 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 58 import org.thingsboard.server.service.telemetry.exception.UnauthorizedException;
61 59 import org.thingsboard.server.service.telemetry.sub.SubscriptionErrorCode;
62 60 import org.thingsboard.server.service.telemetry.sub.SubscriptionState;
... ... @@ -70,12 +68,14 @@ import java.util.ArrayList;
70 68 import java.util.Collections;
71 69 import java.util.HashMap;
72 70 import java.util.HashSet;
73   -import java.util.Iterator;
74 71 import java.util.List;
75 72 import java.util.Map;
76 73 import java.util.Optional;
77 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 79 import java.util.function.Consumer;
80 80 import java.util.stream.Collectors;
81 81
... ... @@ -616,7 +616,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
616 616 }
617 617
618 618 ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures);
619   - Futures.addCallback(future, callback);
  619 + Futures.addCallback(future, callback, MoreExecutors.directExecutor());
620 620 }
621 621
622 622 @Override
... ... @@ -630,7 +630,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
630 630 return new FutureCallback<ValidationResult>() {
631 631 @Override
632 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 636 @Override
... ... @@ -650,7 +650,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
650 650 }
651 651
652 652 ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures);
653   - Futures.addCallback(future, callback);
  653 + Futures.addCallback(future, callback, MoreExecutors.directExecutor());
654 654 }
655 655
656 656 @Override
... ... @@ -664,7 +664,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
664 664 return new FutureCallback<ValidationResult>() {
665 665 @Override
666 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 670 @Override
... ...
... ... @@ -19,10 +19,9 @@ import com.fasterxml.jackson.core.JsonProcessingException;
19 19 import com.fasterxml.jackson.databind.ObjectMapper;
20 20 import com.google.common.util.concurrent.Futures;
21 21 import com.google.common.util.concurrent.ListenableFuture;
  22 +import com.google.common.util.concurrent.MoreExecutors;
22 23 import lombok.extern.slf4j.Slf4j;
23 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 25 import org.springframework.stereotype.Service;
27 26 import org.springframework.util.StringUtils;
28 27 import org.thingsboard.server.common.data.Device;
... ... @@ -42,19 +41,10 @@ import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponse
42 41 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
43 42 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg;
44 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 44 import org.thingsboard.server.service.executors.DbCallbackExecutorService;
51 45 import org.thingsboard.server.service.state.DeviceStateService;
52 46
53   -import javax.annotation.PostConstruct;
54   -import javax.annotation.PreDestroy;
55 47 import java.util.UUID;
56   -import java.util.concurrent.ExecutorService;
57   -import java.util.concurrent.Executors;
58 48 import java.util.concurrent.locks.ReentrantLock;
59 49
60 50 /**
... ... @@ -145,7 +135,7 @@ public class LocalTransportApiService implements TransportApiService {
145 135 try {
146 136 ValidateDeviceCredentialsResponseMsg.Builder builder = ValidateDeviceCredentialsResponseMsg.newBuilder();
147 137 builder.setDeviceInfo(getDeviceInfoProto(device));
148   - if(!StringUtils.isEmpty(credentials.getCredentialsValue())){
  138 + if (!StringUtils.isEmpty(credentials.getCredentialsValue())) {
149 139 builder.setCredentialsBody(credentials.getCredentialsValue());
150 140 }
151 141 return TransportApiResponseMsg.newBuilder()
... ... @@ -154,7 +144,7 @@ public class LocalTransportApiService implements TransportApiService {
154 144 log.warn("[{}] Failed to lookup device by id", deviceId, e);
155 145 return getEmptyTransportApiResponse();
156 146 }
157   - });
  147 + }, MoreExecutors.directExecutor());
158 148 }
159 149
160 150 private DeviceInfoProto getDeviceInfoProto(Device device) throws JsonProcessingException {
... ...
... ... @@ -298,7 +298,7 @@ caffeine:
298 298 redis:
299 299 # standalone or cluster
300 300 connection:
301   - type: standalone
  301 + type: "${REDIS_CONNECTION_TYPE:standalone}"
302 302 standalone:
303 303 host: "${REDIS_HOST:localhost}"
304 304 port: "${REDIS_PORT:6379}"
... ...
... ... @@ -2,8 +2,8 @@
2 2
3 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 7 systemctl --no-reload enable ${pkg.name}.service >/dev/null 2>&1 || :
8 8
9 9 exit 0
... ...
... ... @@ -2,21 +2,21 @@
2 2
3 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 7 fi
8 8
9   -if ! getent passwd ${pkg.name} >/dev/null; then
  9 +if ! getent passwd ${pkg.user} >/dev/null; then
10 10 adduser --quiet \
11 11 --system \
12   - --ingroup ${pkg.name} \
  12 + --ingroup ${pkg.user} \
13 13 --quiet \
14 14 --disabled-login \
15 15 --disabled-password \
16 16 --home ${pkg.installFolder} \
17 17 --no-create-home \
18 18 -gecos "Thingsboard application" \
19   - ${pkg.name}
  19 + ${pkg.user}
20 20 fi
21 21
22 22 exit 0
\ No newline at end of file
... ...
1 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 6 if [ $1 -eq 1 ] ; then
7 7 # Initial installation
... ...
... ... @@ -3,7 +3,7 @@ Description=${pkg.name}
3 3 After=syslog.target
4 4
5 5 [Service]
6   -User=${pkg.name}
  6 +User=${pkg.user}
7 7 ExecStart=${pkg.installFolder}/bin/${pkg.name}.jar
8 8 SuccessExitStatus=143
9 9
... ...
... ... @@ -44,7 +44,7 @@ installDir=${pkg.installFolder}/data
44 44
45 45 source "${CONF_FOLDER}/${configfile}"
46 46
47   -run_user=${pkg.name}
  47 +run_user=${pkg.user}
48 48
49 49 su -s /bin/sh -c "java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \
50 50 -Dinstall.data_dir=${installDir} \
... ...
... ... @@ -43,7 +43,7 @@ installDir=${pkg.installFolder}/data
43 43
44 44 source "${CONF_FOLDER}/${configfile}"
45 45
46   -run_user=${pkg.name}
  46 +run_user=${pkg.user}
47 47
48 48 su -s /bin/sh -c "java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \
49 49 -Dinstall.data_dir=${installDir} \
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.kafka;
18 18 import com.google.common.util.concurrent.FutureCallback;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22
22 23 import java.util.concurrent.Executor;
23 24 import java.util.concurrent.ScheduledExecutorService;
... ... @@ -59,7 +60,7 @@ public class AsyncCallbackTemplate {
59 60 if (executor != null) {
60 61 Futures.addCallback(future, callback, executor);
61 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 18 import com.google.common.util.concurrent.FutureCallback;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22
22 23 import java.util.concurrent.Executor;
23 24 import java.util.function.Consumer;
24 25
25 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 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 35 FutureCallback<T> callback = new FutureCallback<T>() {
35 36 @Override
36 37 public void onSuccess(T result) {
... ... @@ -49,7 +50,7 @@ public class DonAsynchron {
49 50 if (executor != null) {
50 51 Futures.addCallback(future, callback, executor);
51 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 20 import com.google.common.base.Function;
21 21 import com.google.common.util.concurrent.Futures;
22 22 import com.google.common.util.concurrent.ListenableFuture;
  23 +import com.google.common.util.concurrent.MoreExecutors;
23 24 import lombok.extern.slf4j.Slf4j;
24 25 import org.springframework.beans.factory.annotation.Autowired;
25 26 import org.springframework.stereotype.Service;
... ... @@ -53,7 +54,6 @@ import javax.annotation.Nullable;
53 54 import javax.annotation.PostConstruct;
54 55 import javax.annotation.PreDestroy;
55 56 import java.util.ArrayList;
56   -import java.util.Collections;
57 57 import java.util.Comparator;
58 58 import java.util.List;
59 59 import java.util.Set;
... ... @@ -264,9 +264,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
264 264 entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorName -> {
265 265 alarmInfo.setOriginatorName(originatorName);
266 266 return alarmInfo;
267   - }
268   - );
269   - });
  267 + }, MoreExecutors.directExecutor());
  268 + }, MoreExecutors.directExecutor());
270 269 }
271 270
272 271 @Override
... ... @@ -282,12 +281,12 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
282 281 }
283 282 alarmInfo.setOriginatorName(originatorName);
284 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 291 return Futures.immediateFuture(alarms);
293 292 }
... ...
... ... @@ -16,9 +16,9 @@
16 16 package org.thingsboard.server.dao.asset;
17 17
18 18
19   -import com.google.common.base.Function;
20 19 import com.google.common.util.concurrent.Futures;
21 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
22 22 import lombok.extern.slf4j.Slf4j;
23 23 import org.hibernate.exception.ConstraintViolationException;
24 24 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -29,7 +29,6 @@ import org.springframework.cache.annotation.Cacheable;
29 29 import org.springframework.stereotype.Service;
30 30 import org.springframework.util.StringUtils;
31 31 import org.thingsboard.server.common.data.Customer;
32   -import org.thingsboard.server.common.data.Device;
33 32 import org.thingsboard.server.common.data.EntitySubtype;
34 33 import org.thingsboard.server.common.data.EntityType;
35 34 import org.thingsboard.server.common.data.EntityView;
... ... @@ -63,7 +62,10 @@ import java.util.stream.Collectors;
63 62 import static org.thingsboard.server.common.data.CacheConstants.ASSET_CACHE;
64 63 import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
65 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 70 @Service
69 71 @Slf4j
... ... @@ -298,9 +300,9 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
298 300 }
299 301 }
300 302 return Futures.successfulAsList(futures);
301   - });
  303 + }, MoreExecutors.directExecutor());
302 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 307 return assets;
306 308 }
... ... @@ -314,7 +316,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
314 316 assetTypes -> {
315 317 assetTypes.sort(Comparator.comparing(EntitySubtype::getType));
316 318 return assetTypes;
317   - });
  319 + }, MoreExecutors.directExecutor());
318 320 }
319 321
320 322 private DataValidator<Asset> assetValidator =
... ... @@ -375,18 +377,18 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
375 377 };
376 378
377 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 393 private PaginatedRemover<CustomerId, Asset> customerAssetsUnasigner = new PaginatedRemover<CustomerId, Asset>() {
392 394
... ...
... ... @@ -15,8 +15,6 @@
15 15 */
16 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 18 import com.google.common.util.concurrent.ListenableFuture;
21 19 import lombok.extern.slf4j.Slf4j;
22 20 import org.apache.commons.lang3.StringUtils;
... ... @@ -31,7 +29,6 @@ import org.thingsboard.server.common.data.id.DashboardId;
31 29 import org.thingsboard.server.common.data.id.TenantId;
32 30 import org.thingsboard.server.common.data.page.PageData;
33 31 import org.thingsboard.server.common.data.page.PageLink;
34   -import org.thingsboard.server.common.data.page.TimePageLink;
35 32 import org.thingsboard.server.common.data.relation.EntityRelation;
36 33 import org.thingsboard.server.common.data.relation.RelationTypeGroup;
37 34 import org.thingsboard.server.dao.customer.CustomerDao;
... ... @@ -39,12 +36,9 @@ import org.thingsboard.server.dao.entity.AbstractEntityService;
39 36 import org.thingsboard.server.dao.exception.DataValidationException;
40 37 import org.thingsboard.server.dao.service.DataValidator;
41 38 import org.thingsboard.server.dao.service.PaginatedRemover;
42   -import org.thingsboard.server.dao.service.TimePaginatedRemover;
43 39 import org.thingsboard.server.dao.service.Validator;
44 40 import org.thingsboard.server.dao.tenant.TenantDao;
45 41
46   -import javax.annotation.Nullable;
47   -import java.util.List;
48 42 import java.util.concurrent.ExecutionException;
49 43
50 44 import static org.thingsboard.server.dao.service.Validator.validateId;
... ... @@ -63,7 +57,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
63 57
64 58 @Autowired
65 59 private TenantDao tenantDao;
66   -
  60 +
67 61 @Autowired
68 62 private CustomerDao customerDao;
69 63
... ... @@ -101,7 +95,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
101 95 dashboardValidator.validate(dashboard, DashboardInfo::getTenantId);
102 96 return dashboardDao.save(dashboard.getTenantId(), dashboard);
103 97 }
104   -
  98 +
105 99 @Override
106 100 public Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, CustomerId customerId) {
107 101 Dashboard dashboard = findDashboardById(tenantId, dashboardId);
... ... @@ -234,11 +228,11 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
234 228 }
235 229 }
236 230 }
237   - };
238   -
  231 + };
  232 +
239 233 private PaginatedRemover<TenantId, DashboardInfo> tenantDashboardsRemover =
240 234 new PaginatedRemover<TenantId, DashboardInfo>() {
241   -
  235 +
242 236 @Override
243 237 protected PageData<DashboardInfo> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
244 238 return dashboardInfoDao.findDashboardsByTenantId(id.getId(), pageLink);
... ... @@ -267,7 +261,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
267 261 protected void removeEntity(TenantId tenantId, DashboardInfo entity) {
268 262 unassignDashboardFromCustomer(customer.getTenantId(), new DashboardId(entity.getUuidId()), this.customer.getId());
269 263 }
270   -
  264 +
271 265 }
272 266
273 267 private class CustomerDashboardsUpdater extends PaginatedRemover<Customer, DashboardInfo> {
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device;
18 18 import com.fasterxml.jackson.databind.ObjectMapper;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22 import lombok.extern.slf4j.Slf4j;
22 23 import org.springframework.beans.factory.annotation.Autowired;
23 24 import org.springframework.beans.factory.annotation.Value;
... ... @@ -97,9 +98,9 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService {
97 98 }
98 99 log.warn("Failed to find claimingAllowed attribute for device or it is already claimed![{}]", device.getName());
99 100 throw new IllegalArgumentException();
100   - });
  101 + }, MoreExecutors.directExecutor());
101 102 }
102   - });
  103 + }, MoreExecutors.directExecutor());
103 104 }
104 105
105 106 private ClaimDataInfo getClaimData(Cache cache, Device device) throws ExecutionException, InterruptedException {
... ... @@ -138,9 +139,9 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService {
138 139 if (device.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) {
139 140 device.setCustomerId(customerId);
140 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 146 } else {
146 147 log.warn("Failed to find the device's claiming message![{}]", device.getName());
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device;
18 18 import com.google.common.base.Function;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22 import lombok.extern.slf4j.Slf4j;
22 23 import org.apache.commons.lang3.RandomStringUtils;
23 24 import org.hibernate.exception.ConstraintViolationException;
... ... @@ -28,7 +29,13 @@ import org.springframework.cache.annotation.CacheEvict;
28 29 import org.springframework.cache.annotation.Cacheable;
29 30 import org.springframework.stereotype.Service;
30 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 39 import org.thingsboard.server.common.data.device.DeviceSearchQuery;
33 40 import org.thingsboard.server.common.data.id.CustomerId;
34 41 import org.thingsboard.server.common.data.id.DeviceId;
... ... @@ -325,7 +332,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
325 332 }
326 333 }
327 334 return Futures.successfulAsList(futures);
328   - });
  335 + }, MoreExecutors.directExecutor());
329 336
330 337 devices = Futures.transform(devices, new Function<List<Device>, List<Device>>() {
331 338 @Nullable
... ... @@ -333,7 +340,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
333 340 public List<Device> apply(@Nullable List<Device> deviceList) {
334 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 345 return devices;
339 346 }
... ... @@ -347,7 +354,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
347 354 deviceTypes -> {
348 355 deviceTypes.sort(Comparator.comparing(EntitySubtype::getType));
349 356 return deviceTypes;
350   - });
  357 + }, MoreExecutors.directExecutor());
351 358 }
352 359
353 360 private DataValidator<Device> deviceValidator =
... ... @@ -408,18 +415,18 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
408 415 };
409 416
410 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 431 private PaginatedRemover<CustomerId, Device> customerDeviceUnasigner = new PaginatedRemover<CustomerId, Device>() {
425 432
... ...
... ... @@ -18,12 +18,21 @@ package org.thingsboard.server.dao.entity;
18 18 import com.google.common.base.Function;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22 import lombok.extern.slf4j.Slf4j;
22 23 import org.springframework.beans.factory.annotation.Autowired;
23 24 import org.springframework.stereotype.Service;
24 25 import org.thingsboard.server.common.data.HasName;
25 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 36 import org.thingsboard.server.dao.alarm.AlarmService;
28 37 import org.thingsboard.server.dao.asset.AssetService;
29 38 import org.thingsboard.server.dao.customer.CustomerService;
... ... @@ -109,7 +118,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
109 118 default:
110 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 122 return entityName;
114 123 }
115 124
... ...
... ... @@ -19,6 +19,7 @@ import com.google.common.base.Function;
19 19 import com.google.common.util.concurrent.FutureCallback;
20 20 import com.google.common.util.concurrent.Futures;
21 21 import com.google.common.util.concurrent.ListenableFuture;
  22 +import com.google.common.util.concurrent.MoreExecutors;
22 23 import lombok.extern.slf4j.Slf4j;
23 24 import org.apache.commons.lang3.StringUtils;
24 25 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -238,7 +239,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
238 239 }
239 240 }
240 241 return Futures.successfulAsList(futures);
241   - });
  242 + }, MoreExecutors.directExecutor());
242 243
243 244 entityViews = Futures.transform(entityViews, new Function<List<EntityView>, List<EntityView>>() {
244 245 @Nullable
... ... @@ -246,7 +247,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
246 247 public List<EntityView> apply(@Nullable List<EntityView> entityViewList) {
247 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 252 return entityViews;
252 253 }
... ... @@ -285,7 +286,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
285 286 public void onFailure(Throwable t) {
286 287 log.error("Error while finding entity views by tenantId and entityId", t);
287 288 }
288   - });
  289 + }, MoreExecutors.directExecutor());
289 290 return entityViewsFuture;
290 291 }
291 292 }
... ... @@ -318,7 +319,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
318 319 entityViewTypes -> {
319 320 entityViewTypes.sort(Comparator.comparing(EntitySubtype::getType));
320 321 return entityViewTypes;
321   - });
  322 + }, MoreExecutors.directExecutor());
322 323 }
323 324
324 325 private DataValidator<EntityView> entityViewValidator =
... ...
... ... @@ -36,6 +36,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.BOOLEAN_VALUE_COLU
36 36 import static org.thingsboard.server.dao.model.ModelConstants.DOUBLE_VALUE_COLUMN;
37 37 import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_ID_COLUMN;
38 38 import static org.thingsboard.server.dao.model.ModelConstants.JSON_VALUE_COLUMN;
  39 +import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN;
39 40 import static org.thingsboard.server.dao.model.ModelConstants.LONG_VALUE_COLUMN;
40 41 import static org.thingsboard.server.dao.model.ModelConstants.STRING_VALUE_COLUMN;
41 42 import static org.thingsboard.server.dao.model.ModelConstants.TS_COLUMN;
... ... @@ -54,6 +55,10 @@ public abstract class AbstractTsKvEntity implements ToData<TsKvEntry> {
54 55 protected UUID entityId;
55 56
56 57 @Id
  58 + @Column(name = KEY_COLUMN)
  59 + protected int key;
  60 +
  61 + @Id
57 62 @Column(name = TS_COLUMN)
58 63 protected Long ts;
59 64
... ...
... ... @@ -69,10 +69,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN;
69 69 })
70 70 public final class TsKvLatestEntity extends AbstractTsKvEntity {
71 71
72   - @Id
73   - @Column(name = KEY_COLUMN)
74   - private int key;
75   -
76 72 @Override
77 73 public boolean isNotEmpty() {
78 74 return strValue != null || longValue != null || doubleValue != null || booleanValue != null || jsonValue != null;
... ...
... ... @@ -31,7 +31,6 @@ public class TimescaleTsKvCompositeKey implements Serializable {
31 31 @Transient
32 32 private static final long serialVersionUID = -4089175869616037523L;
33 33
34   - private UUID tenantId;
35 34 private UUID entityId;
36 35 private int key;
37 36 private long ts;
... ...
... ... @@ -18,25 +18,18 @@ package org.thingsboard.server.dao.model.sqlts.timescale.ts;
18 18 import lombok.Data;
19 19 import lombok.EqualsAndHashCode;
20 20 import org.springframework.util.StringUtils;
21   -import org.thingsboard.server.common.data.kv.TsKvEntry;
22   -import org.thingsboard.server.dao.model.ToData;
23 21 import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity;
24 22
25   -import javax.persistence.Column;
26 23 import javax.persistence.ColumnResult;
27 24 import javax.persistence.ConstructorResult;
28 25 import javax.persistence.Entity;
29   -import javax.persistence.Id;
30 26 import javax.persistence.IdClass;
31 27 import javax.persistence.NamedNativeQueries;
32 28 import javax.persistence.NamedNativeQuery;
33 29 import javax.persistence.SqlResultSetMapping;
34 30 import javax.persistence.SqlResultSetMappings;
35 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 33 import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_AVG;
41 34 import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_AVG_QUERY;
42 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 45 @Data
53 46 @EqualsAndHashCode(callSuper = true)
54 47 @Entity
55   -@Table(name = "tenant_ts_kv")
  48 +@Table(name = "ts_kv")
56 49 @IdClass(TimescaleTsKvCompositeKey.class)
57 50 @SqlResultSetMappings({
58 51 @SqlResultSetMapping(
... ... @@ -116,15 +109,7 @@ import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.F
116 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 114 public TimescaleTsKvEntity() {
130 115 }
... ...
... ... @@ -32,10 +32,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN;
32 32 @IdClass(TsKvCompositeKey.class)
33 33 public final class TsKvEntity extends AbstractTsKvEntity {
34 34
35   - @Id
36   - @Column(name = KEY_COLUMN)
37   - private int key;
38   -
39 35 public TsKvEntity() {
40 36 }
41 37
... ...
... ... @@ -22,6 +22,7 @@ import com.datastax.driver.core.Statement;
22 22 import com.google.common.util.concurrent.FutureCallback;
23 23 import com.google.common.util.concurrent.Futures;
24 24 import com.google.common.util.concurrent.ListenableFuture;
  25 +import com.google.common.util.concurrent.MoreExecutors;
25 26 import com.google.common.util.concurrent.Uninterruptibles;
26 27 import org.thingsboard.server.dao.exception.BufferLimitException;
27 28 import org.thingsboard.server.dao.util.AsyncRateLimiter;
... ... @@ -44,9 +45,9 @@ public class RateLimitedResultSetFuture implements ResultSetFuture {
44 45 rateLimiter.release();
45 46 }
46 47 return Futures.immediateFailedFuture(t);
47   - });
  48 + }, MoreExecutors.directExecutor());
48 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 146 public void onFailure(Throwable t) {
146 147 rateLimiter.release();
147 148 }
148   - });
  149 + }, MoreExecutors.directExecutor());
149 150 return resultSetFuture;
150 151 } catch (RuntimeException re) {
151 152 rateLimiter.release();
... ...
... ... @@ -16,7 +16,10 @@
16 16 package org.thingsboard.server.dao.relation;
17 17
18 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 23 import lombok.extern.slf4j.Slf4j;
21 24 import org.springframework.beans.factory.annotation.Autowired;
22 25 import org.springframework.cache.Cache;
... ... @@ -206,17 +209,20 @@ public class BaseRelationService implements RelationService {
206 209 relations -> {
207 210 List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(tenantId, relations, cache, true);
208 211 return Futures.allAsList(results);
209   - });
  212 + }, MoreExecutors.directExecutor());
210 213
211 214 ListenableFuture<List<Boolean>> outboundDeletions = Futures.transformAsync(outboundRelations,
212 215 relations -> {
213 216 List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(tenantId, relations, cache, false);
214 217 return Futures.allAsList(results);
215   - });
  218 + }, MoreExecutors.directExecutor());
216 219
217 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 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 312 public void onSuccess(@Nullable List<EntityRelation> result) {
307 313 cache.putIfAbsent(fromAndTypeGroup, result);
308 314 }
  315 +
309 316 @Override
310   - public void onFailure(Throwable t) {}
311   - });
  317 + public void onFailure(Throwable t) {
  318 + }
  319 + }, MoreExecutors.directExecutor());
312 320 return relationsFuture;
313 321 }
314 322 }
... ... @@ -328,7 +336,7 @@ public class BaseRelationService implements RelationService {
328 336 EntityRelationInfo::setToName))
329 337 );
330 338 return Futures.successfulAsList(futures);
331   - });
  339 + }, MoreExecutors.directExecutor());
332 340 }
333 341
334 342 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #relationType, #typeGroup, 'FROM'}")
... ... @@ -385,9 +393,11 @@ public class BaseRelationService implements RelationService {
385 393 public void onSuccess(@Nullable List<EntityRelation> result) {
386 394 cache.putIfAbsent(toAndTypeGroup, result);
387 395 }
  396 +
388 397 @Override
389   - public void onFailure(Throwable t) {}
390   - });
  398 + public void onFailure(Throwable t) {
  399 + }
  400 + }, MoreExecutors.directExecutor());
391 401 return relationsFuture;
392 402 }
393 403 }
... ... @@ -407,7 +417,7 @@ public class BaseRelationService implements RelationService {
407 417 EntityRelationInfo::setFromName))
408 418 );
409 419 return Futures.successfulAsList(futures);
410   - });
  420 + }, MoreExecutors.directExecutor());
411 421 }
412 422
413 423 private ListenableFuture<EntityRelationInfo> fetchRelationInfoAsync(TenantId tenantId, EntityRelation relation,
... ... @@ -418,7 +428,7 @@ public class BaseRelationService implements RelationService {
418 428 EntityRelationInfo entityRelationInfo1 = new EntityRelationInfo(relation);
419 429 entityNameSetter.accept(entityRelationInfo1, entityName1);
420 430 return entityRelationInfo1;
421   - });
  431 + }, MoreExecutors.directExecutor());
422 432 }
423 433
424 434 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#to, #relationType, #typeGroup, 'TO'}")
... ... @@ -466,7 +476,7 @@ public class BaseRelationService implements RelationService {
466 476 }
467 477 }
468 478 return relations;
469   - });
  479 + }, MoreExecutors.directExecutor());
470 480 } catch (Exception e) {
471 481 log.warn("Failed to query relations: [{}]", query, e);
472 482 throw new RuntimeException(e);
... ... @@ -493,7 +503,7 @@ public class BaseRelationService implements RelationService {
493 503 }))
494 504 );
495 505 return Futures.successfulAsList(futures);
496   - });
  506 + }, MoreExecutors.directExecutor());
497 507 }
498 508
499 509 protected void validate(EntityRelation relation) {
... ... @@ -600,7 +610,7 @@ public class BaseRelationService implements RelationService {
600 610 }
601 611 //TODO: try to remove this blocking operation
602 612 List<Set<EntityRelation>> relations = Futures.successfulAsList(futures).get();
603   - if (fetchLastLevelOnly && lvl > 0){
  613 + if (fetchLastLevelOnly && lvl > 0) {
604 614 children.clear();
605 615 }
606 616 relations.forEach(r -> r.forEach(children::add));
... ...
... ... @@ -15,14 +15,12 @@
15 15 */
16 16 package org.thingsboard.server.dao.sql.alarm;
17 17
18   -import com.google.common.util.concurrent.Futures;
19 18 import com.google.common.util.concurrent.ListenableFuture;
20 19 import lombok.extern.slf4j.Slf4j;
21 20 import org.springframework.beans.factory.annotation.Autowired;
22 21 import org.springframework.data.domain.PageRequest;
23 22 import org.springframework.data.repository.CrudRepository;
24 23 import org.springframework.stereotype.Component;
25   -import org.thingsboard.server.common.data.EntityType;
26 24 import org.thingsboard.server.common.data.UUIDConverter;
27 25 import org.thingsboard.server.common.data.alarm.Alarm;
28 26 import org.thingsboard.server.common.data.alarm.AlarmInfo;
... ... @@ -31,8 +29,6 @@ import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
31 29 import org.thingsboard.server.common.data.id.EntityId;
32 30 import org.thingsboard.server.common.data.id.TenantId;
33 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 32 import org.thingsboard.server.dao.DaoUtil;
37 33 import org.thingsboard.server.dao.alarm.AlarmDao;
38 34 import org.thingsboard.server.dao.alarm.BaseAlarmService;
... ... @@ -41,7 +37,6 @@ import org.thingsboard.server.dao.relation.RelationDao;
41 37 import org.thingsboard.server.dao.sql.JpaAbstractDao;
42 38 import org.thingsboard.server.dao.util.SqlDao;
43 39
44   -import java.util.ArrayList;
45 40 import java.util.List;
46 41 import java.util.Objects;
47 42 import java.util.UUID;
... ...
... ... @@ -15,23 +15,14 @@
15 15 */
16 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 18 import lombok.extern.slf4j.Slf4j;
21 19 import org.springframework.beans.factory.annotation.Autowired;
22   -import org.springframework.data.domain.PageRequest;
23 20 import org.springframework.data.repository.CrudRepository;
24 21 import org.springframework.stereotype.Component;
25 22 import org.thingsboard.server.common.data.DashboardInfo;
26   -import org.thingsboard.server.common.data.EntityType;
27 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 24 import org.thingsboard.server.common.data.page.PageData;
31 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 26 import org.thingsboard.server.dao.DaoUtil;
36 27 import org.thingsboard.server.dao.dashboard.DashboardInfoDao;
37 28 import org.thingsboard.server.dao.model.sql.DashboardInfoEntity;
... ... @@ -39,13 +30,9 @@ import org.thingsboard.server.dao.relation.RelationDao;
39 30 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
40 31 import org.thingsboard.server.dao.util.SqlDao;
41 32
42   -import java.util.ArrayList;
43   -import java.util.List;
44 33 import java.util.Objects;
45 34 import java.util.UUID;
46 35
47   -import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR;
48   -
49 36 /**
50 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 +}
\ No newline at end of file
... ...
  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 58 @Autowired
59 59 private RelationRepository relationRepository;
60 60
  61 + @Autowired
  62 + private RelationInsertRepository relationInsertRepository;
  63 +
61 64 @Override
62 65 public ListenableFuture<List<EntityRelation>> findAllByFrom(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup) {
63 66 return service.submit(() -> DaoUtil.convertDataList(
... ... @@ -119,12 +122,12 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple
119 122
120 123 @Override
121 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 128 @Override
126 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 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 +}
\ No newline at end of file
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.sqlts;
17 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 21 import com.google.common.util.concurrent.SettableFuture;
21 22 import lombok.extern.slf4j.Slf4j;
22 23 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -95,7 +96,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
95 96
96 97 @Override
97 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 102 @Override
... ... @@ -124,9 +125,9 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
124 125 }
125 126
126 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 129 if (query.getAggregation() == Aggregation.NONE) {
129   - return findAllAsyncWithLimit(tenantId, entityId, query);
  130 + return findAllAsyncWithLimit(entityId, query);
130 131 } else {
131 132 long stepTs = query.getStartTs();
132 133 List<ListenableFuture<Optional<TsKvEntry>>> futures = new ArrayList<>();
... ... @@ -134,7 +135,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
134 135 long startTs = stepTs;
135 136 long endTs = stepTs + query.getInterval();
136 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 139 stepTs = endTs;
139 140 }
140 141 return getTskvEntriesFuture(Futures.allAsList(futures));
... ... @@ -142,7 +143,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
142 143 }
143 144
144 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 147 Integer keyId = getOrSaveKeyId(query.getKey());
147 148 List<TsKvEntity> tsKvEntities = tsKvRepository.findAllWithLimit(
148 149 entityId.getId(),
... ... @@ -156,9 +157,9 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
156 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 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 163 return Futures.transform(setFutures(entitiesFutures), entity -> {
163 164 if (entity != null && entity.isNotEmpty()) {
164 165 entity.setEntityId(entityId.getId());
... ... @@ -168,32 +169,32 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
168 169 } else {
169 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 176 switch (aggregation) {
176 177 case AVG:
177   - findAvg(tenantId, entityId, key, startTs, endTs, entitiesFutures);
  178 + findAvg(entityId, key, startTs, endTs, entitiesFutures);
178 179 break;
179 180 case MAX:
180   - findMax(tenantId, entityId, key, startTs, endTs, entitiesFutures);
  181 + findMax(entityId, key, startTs, endTs, entitiesFutures);
181 182 break;
182 183 case MIN:
183   - findMin(tenantId, entityId, key, startTs, endTs, entitiesFutures);
  184 + findMin(entityId, key, startTs, endTs, entitiesFutures);
184 185 break;
185 186 case SUM:
186   - findSum(tenantId, entityId, key, startTs, endTs, entitiesFutures);
  187 + findSum(entityId, key, startTs, endTs, entitiesFutures);
187 188 break;
188 189 case COUNT:
189   - findCount(tenantId, entityId, key, startTs, endTs, entitiesFutures);
  190 + findCount(entityId, key, startTs, endTs, entitiesFutures);
190 191 break;
191 192 default:
192 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 198 Integer keyId = getOrSaveKeyId(key);
198 199 entitiesFutures.add(tsKvRepository.findCount(
199 200 entityId.getId(),
... ... @@ -202,7 +203,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
202 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 207 Integer keyId = getOrSaveKeyId(key);
207 208 entitiesFutures.add(tsKvRepository.findSum(
208 209 entityId.getId(),
... ... @@ -211,7 +212,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
211 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 216 Integer keyId = getOrSaveKeyId(key);
216 217 entitiesFutures.add(tsKvRepository.findStringMin(
217 218 entityId.getId(),
... ... @@ -225,7 +226,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
225 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 230 Integer keyId = getOrSaveKeyId(key);
230 231 entitiesFutures.add(tsKvRepository.findStringMax(
231 232 entityId.getId(),
... ... @@ -239,7 +240,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
239 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 244 Integer keyId = getOrSaveKeyId(key);
244 245 entitiesFutures.add(tsKvRepository.findAvg(
245 246 entityId.getId(),
... ...
... ... @@ -20,6 +20,7 @@ import com.google.common.collect.Lists;
20 20 import com.google.common.util.concurrent.FutureCallback;
21 21 import com.google.common.util.concurrent.Futures;
22 22 import com.google.common.util.concurrent.ListenableFuture;
  23 +import com.google.common.util.concurrent.MoreExecutors;
23 24 import lombok.extern.slf4j.Slf4j;
24 25 import org.hibernate.exception.ConstraintViolationException;
25 26 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -126,7 +127,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
126 127 protected ListenableFuture<List<TsKvEntry>> processFindAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries) {
127 128 List<ListenableFuture<List<TsKvEntry>>> futures = queries
128 129 .stream()
129   - .map(query -> findAllAsync(tenantId, entityId, query))
  130 + .map(query -> findAllAsync(entityId, query))
130 131 .collect(Collectors.toList());
131 132 return Futures.transform(Futures.allAsList(futures), new Function<List<List<TsKvEntry>>, List<TsKvEntry>>() {
132 133 @Nullable
... ... @@ -143,9 +144,9 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
143 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 151 protected ListenableFuture<List<TsKvEntry>> getTskvEntriesFuture(ListenableFuture<List<Optional<TsKvEntry>>> future) {
151 152 return Futures.transform(future, new Function<List<Optional<TsKvEntry>>, List<TsKvEntry>>() {
... ... @@ -163,12 +164,12 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
163 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 168 long startTs = 0;
168 169 long endTs = query.getStartTs() - 1;
169 170 ReadTsKvQuery findNewLatestQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, endTs - startTs, 1,
170 171 Aggregation.NONE, DESC_ORDER);
171   - return findAllAsync(tenantId, entityId, findNewLatestQuery);
  172 + return findAllAsync(entityId, findNewLatestQuery);
172 173 }
173 174
174 175 protected ListenableFuture<TsKvEntry> getFindLatestFuture(EntityId entityId, String key) {
... ... @@ -188,7 +189,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
188 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 193 ListenableFuture<TsKvEntry> latestFuture = getFindLatestFuture(entityId, query.getKey());
193 194
194 195 ListenableFuture<Boolean> booleanFuture = Futures.transform(latestFuture, tsKvEntry -> {
... ... @@ -216,7 +217,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
216 217 if (query.getRewriteLatestIfDeleted()) {
217 218 ListenableFuture<Void> savedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> {
218 219 if (isRemove) {
219   - return getNewLatestEntryFuture(tenantId, entityId, query);
  220 + return getNewLatestEntryFuture(entityId, query);
220 221 }
221 222 return Futures.immediateFuture(null);
222 223 }, service);
... ... @@ -235,7 +236,7 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
235 236 public void onFailure(Throwable t) {
236 237 log.warn("[{}] Failed to process remove of the latest value", entityId, t);
237 238 }
238   - });
  239 + }, MoreExecutors.directExecutor());
239 240 return resultFuture;
240 241 }
241 242
... ... @@ -295,8 +296,8 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
295 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 301 return Futures.transformAsync(future, entryList -> {
301 302 if (entryList.size() == 1) {
302 303 return getSaveLatestFuture(entityId, entryList.get(0));
... ...
... ... @@ -37,8 +37,8 @@ import java.util.List;
37 37 public class TimescaleInsertTsRepository extends AbstractInsertRepository implements InsertTsRepository<TimescaleTsKvEntity> {
38 38
39 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 43 @Override
44 44 public void saveOrUpdate(List<EntityContainer<TimescaleTsKvEntity>> entities) {
... ... @@ -46,41 +46,40 @@ public class TimescaleInsertTsRepository extends AbstractInsertRepository implem
46 46 @Override
47 47 public void setValues(PreparedStatement ps, int i) throws SQLException {
48 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 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 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 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 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 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 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 85 @Override
... ...
... ... @@ -36,7 +36,7 @@ public class AggregationRepository {
36 36 public static final String FIND_SUM = "findSum";
37 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 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 52 private EntityManager entityManager;
53 53
54 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 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 58 return CompletableFuture.supplyAsync(() -> resultList);
59 59 }
60 60
61 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 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 65 return CompletableFuture.supplyAsync(() -> resultList);
66 66 }
67 67
68 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 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 72 return CompletableFuture.supplyAsync(() -> resultList);
73 73 }
74 74
75 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 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 79 return CompletableFuture.supplyAsync(() -> resultList);
80 80 }
81 81
82 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 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 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 90 return entityManager.createNamedQuery(query)
91   - .setParameter("tenantId", tenantId)
92 91 .setParameter("entityId", entityId)
93 92 .setParameter("entityKey", entityKey)
94 93 .setParameter("timeBucket", timeBucket)
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.sqlts.timescale;
17 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 21 import com.google.common.util.concurrent.SettableFuture;
21 22 import lombok.extern.slf4j.Slf4j;
22 23 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -87,24 +88,23 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
87 88 }
88 89
89 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 92 if (query.getAggregation() == Aggregation.NONE) {
92   - return findAllAsyncWithLimit(tenantId, entityId, query);
  93 + return findAllAsyncWithLimit(entityId, query);
93 94 } else {
94 95 long startTs = query.getStartTs();
95 96 long endTs = query.getEndTs();
96 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 99 return getTskvEntriesFuture(future);
99 100 }
100 101 }
101 102
102 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 105 String strKey = query.getKey();
105 106 Integer keyId = getOrSaveKeyId(strKey);
106 107 List<TimescaleTsKvEntity> timescaleTsKvEntities = tsKvRepository.findAllWithLimit(
107   - tenantId.getId(),
108 108 entityId.getId(),
109 109 keyId,
110 110 query.getStartTs(),
... ... @@ -116,8 +116,8 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
116 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 121 SettableFuture<List<TimescaleTsKvEntity>> listenableFuture = SettableFuture.create();
122 122 listCompletableFuture.whenComplete((timescaleTsKvEntities, throwable) -> {
123 123 if (throwable != null) {
... ... @@ -132,7 +132,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
132 132 timescaleTsKvEntities.forEach(entity -> {
133 133 if (entity != null && entity.isNotEmpty()) {
134 134 entity.setEntityId(entityId.getId());
135   - entity.setTenantId(tenantId.getId());
136 135 entity.setStrKey(key);
137 136 result.add(Optional.of(DaoUtil.getData(entity)));
138 137 } else {
... ... @@ -143,7 +142,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
143 142 } else {
144 143 return Collections.emptyList();
145 144 }
146   - });
  145 + }, MoreExecutors.directExecutor());
147 146 }
148 147
149 148 @Override
... ... @@ -166,7 +165,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
166 165 String strKey = tsKvEntry.getKey();
167 166 Integer keyId = getOrSaveKeyId(strKey);
168 167 TimescaleTsKvEntity entity = new TimescaleTsKvEntity();
169   - entity.setTenantId(tenantId.getId());
170 168 entity.setEntityId(entityId.getId());
171 169 entity.setTs(tsKvEntry.getTs());
172 170 entity.setKey(keyId);
... ... @@ -196,7 +194,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
196 194 Integer keyId = getOrSaveKeyId(strKey);
197 195 return service.submit(() -> {
198 196 tsKvRepository.delete(
199   - tenantId.getId(),
200 197 entityId.getId(),
201 198 keyId,
202 199 query.getStartTs(),
... ... @@ -207,7 +204,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
207 204
208 205 @Override
209 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 210 @Override
... ... @@ -215,27 +212,26 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
215 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 216 switch (aggregation) {
220 217 case AVG:
221   - return findAvg(key, startTs, endTs, timeBucket, entityId, tenantId);
  218 + return findAvg(key, startTs, endTs, timeBucket, entityId);
222 219 case MAX:
223   - return findMax(key, startTs, endTs, timeBucket, entityId, tenantId);
  220 + return findMax(key, startTs, endTs, timeBucket, entityId);
224 221 case MIN:
225   - return findMin(key, startTs, endTs, timeBucket, entityId, tenantId);
  222 + return findMin(key, startTs, endTs, timeBucket, entityId);
226 223 case SUM:
227   - return findSum(key, startTs, endTs, timeBucket, entityId, tenantId);
  224 + return findSum(key, startTs, endTs, timeBucket, entityId);
228 225 case COUNT:
229   - return findCount(key, startTs, endTs, timeBucket, entityId, tenantId);
  226 + return findCount(key, startTs, endTs, timeBucket, entityId);
230 227 default:
231 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 233 Integer keyId = getOrSaveKeyId(key);
237 234 return aggregationRepository.findCount(
238   - tenantId,
239 235 entityId,
240 236 keyId,
241 237 timeBucket,
... ... @@ -243,10 +239,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
243 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 243 Integer keyId = getOrSaveKeyId(key);
248 244 return aggregationRepository.findSum(
249   - tenantId,
250 245 entityId,
251 246 keyId,
252 247 timeBucket,
... ... @@ -254,10 +249,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
254 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 253 Integer keyId = getOrSaveKeyId(key);
259 254 return aggregationRepository.findMin(
260   - tenantId,
261 255 entityId,
262 256 keyId,
263 257 timeBucket,
... ... @@ -265,10 +259,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
265 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 263 Integer keyId = getOrSaveKeyId(key);
270 264 return aggregationRepository.findMax(
271   - tenantId,
272 265 entityId,
273 266 keyId,
274 267 timeBucket,
... ... @@ -276,10 +269,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
276 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 273 Integer keyId = getOrSaveKeyId(key);
281 274 return aggregationRepository.findAvg(
282   - tenantId,
283 275 entityId,
284 276 keyId,
285 277 timeBucket,
... ...
... ... @@ -31,12 +31,10 @@ import java.util.UUID;
31 31 @TimescaleDBTsDao
32 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 35 "AND tskv.key = :entityKey " +
37 36 "AND tskv.ts > :startTs AND tskv.ts <= :endTs")
38 37 List<TimescaleTsKvEntity> findAllWithLimit(
39   - @Param("tenantId") UUID tenantId,
40 38 @Param("entityId") UUID entityId,
41 39 @Param("entityKey") int key,
42 40 @Param("startTs") long startTs,
... ... @@ -44,12 +42,10 @@ public interface TsKvTimescaleRepository extends CrudRepository<TimescaleTsKvEnt
44 42
45 43 @Transactional
46 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 46 "AND tskv.key = :entityKey " +
50 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 49 @Param("entityKey") int key,
54 50 @Param("startTs") long startTs,
55 51 @Param("endTs") long endTs);
... ...
... ... @@ -28,6 +28,7 @@ import com.google.common.util.concurrent.AsyncFunction;
28 28 import com.google.common.util.concurrent.FutureCallback;
29 29 import com.google.common.util.concurrent.Futures;
30 30 import com.google.common.util.concurrent.ListenableFuture;
  31 +import com.google.common.util.concurrent.MoreExecutors;
31 32 import lombok.extern.slf4j.Slf4j;
32 33 import org.apache.commons.lang3.StringUtils;
33 34 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -330,7 +331,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
330 331 stmt.setInt(6, (int) ttl);
331 332 }
332 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 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 546 public void onFailure(Throwable t) {
546 547 log.warn("[{}] Failed to process remove of the latest value", entityId, t);
547 548 }
548   - });
  549 + }, MoreExecutors.directExecutor());
549 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);
\ No newline at end of file
... ... @@ -16,8 +16,7 @@
16 16
17 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 20 entity_id uuid NOT NULL,
22 21 key int NOT NULL,
23 22 ts bigint NOT NULL,
... ... @@ -26,7 +25,7 @@ CREATE TABLE IF NOT EXISTS tenant_ts_kv (
26 25 long_v bigint,
27 26 dbl_v double precision,
28 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 31 CREATE TABLE IF NOT EXISTS ts_kv_dictionary (
... ...
... ... @@ -44,7 +44,7 @@ public class SqlDaoServiceTestSuite {
44 44
45 45 // @ClassRule
46 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 48 // "sql/timescale/drop-all-tables.sql",
49 49 // "sql-test.properties"
50 50 // );
... ...
... ... @@ -119,7 +119,7 @@ public class RateLimitedResultSetFutureTest {
119 119
120 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 123 Row actualRow = transform.get();
124 124
125 125 assertSame(row, actualRow);
... ... @@ -132,7 +132,7 @@ public class RateLimitedResultSetFutureTest {
132 132 when(rateLimiter.acquireAsync()).thenReturn(Futures.immediateFuture(null));
133 133 when(session.executeAsync(statement)).thenThrow(new UnsupportedFeatureException(ProtocolVersion.V3, "hjg"));
134 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 136 try {
137 137 transform.get();
138 138 fail();
... ... @@ -156,7 +156,7 @@ public class RateLimitedResultSetFutureTest {
156 156
157 157 when(realFuture.get()).thenThrow(new ExecutionException("Fail", new TimeoutException("timeout")));
158 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 160 try {
161 161 transform.get();
162 162 fail();
... ... @@ -177,7 +177,7 @@ public class RateLimitedResultSetFutureTest {
177 177 when(rateLimiter.acquireAsync()).thenReturn(future);
178 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 181 // TimeUnit.MILLISECONDS.sleep(200);
182 182 future.cancel(false);
183 183 latch.countDown();
... ...
... ... @@ -12,7 +12,7 @@ DROP TABLE IF EXISTS event;
12 12 DROP TABLE IF EXISTS relation;
13 13 DROP TABLE IF EXISTS tb_user;
14 14 DROP TABLE IF EXISTS tenant;
15   -DROP TABLE IF EXISTS tenant_ts_kv;
  15 +DROP TABLE IF EXISTS ts_kv;
16 16 DROP TABLE IF EXISTS ts_kv_latest;
17 17 DROP TABLE IF EXISTS user_credentials;
18 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 17
18 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 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
\ No newline at end of file
... ...
... ... @@ -39,5 +39,5 @@ spec:
39 39 volumeMounts:
40 40 - mountPath: /config
41 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 43 restartPolicy: Never
... ...
... ... @@ -15,4 +15,6 @@
15 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
\ No newline at end of file
... ...
... ... @@ -22,7 +22,7 @@ function installTb() {
22 22 kubectl apply -f tb-node-configmap.yml
23 23 kubectl apply -f database-setup.yml &&
24 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 27 kubectl delete pod tb-db-setup
28 28
... ...
... ... @@ -38,6 +38,6 @@ fi
38 38
39 39 kubectl apply -f database-setup.yml &&
40 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 43 kubectl delete pod tb-db-setup
... ...
... ... @@ -58,6 +58,8 @@ spec:
58 58 env:
59 59 - name: POSTGRES_DB
60 60 value: "thingsboard"
  61 + - name: POSTGRES_PASSWORD
  62 + value: "postgres"
61 63 - name: PGDATA
62 64 value: /var/lib/postgresql/data/pgdata
63 65 volumeMounts:
... ...
... ... @@ -14,7 +14,7 @@
14 14 # limitations under the License.
15 15 #
16 16
17   -FROM debian:stretch
  17 +FROM thingsboard/base
18 18
19 19 COPY start-js-executor.sh ${pkg.name}.deb /tmp/
20 20
... ... @@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 26 RUN update-rc.d ${pkg.name} disable
27 27
  28 +USER ${pkg.user}
  29 +
28 30 CMD ["start-js-executor.sh"]
... ...
... ... @@ -26,4 +26,6 @@ identity=${pkg.name}
26 26
27 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 36 <main.dir>${basedir}/../..</main.dir>
37 37 <pkg.name>tb-js-executor</pkg.name>
38 38 <docker.name>tb-js-executor</docker.name>
39   - <pkg.user>thingsboard</pkg.user>
40 39 <pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder>
41 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 41 <pkg.linux.dist>${project.build.directory}/package/linux</pkg.linux.dist>
... ...
... ... @@ -25,4 +25,8 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 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 32 CMD ["start-tb-node.sh"]
... ...
... ... @@ -18,12 +18,14 @@
18 18 CONF_FOLDER="/config"
19 19 jarfile=${pkg.installFolder}/bin/${pkg.name}.jar
20 20 configfile=${pkg.name}.conf
21   -run_user=${pkg.name}
  21 +run_user=${pkg.user}
22 22
23 23 source "${CONF_FOLDER}/${configfile}"
24 24
25 25 export LOADER_PATH=/config,${LOADER_PATH}
26 26
  27 +cd ${pkg.installFolder}/bin
  28 +
27 29 if [ "$INSTALL_TB" == "true" ]; then
28 30
29 31 if [ "$LOAD_DEMO" == "true" ]; then
... ...
... ... @@ -36,7 +36,6 @@
36 36 <main.dir>${basedir}/../..</main.dir>
37 37 <pkg.name>thingsboard</pkg.name>
38 38 <docker.name>tb-node</docker.name>
39   - <pkg.user>thingsboard</pkg.user>
40 39 <pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder>
41 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 41 </properties>
... ...
... ... @@ -38,7 +38,6 @@
38 38 <tb.docker.name>tb</tb.docker.name>
39 39 <tb-postgres.docker.name>tb-postgres</tb-postgres.docker.name>
40 40 <tb-cassandra.docker.name>tb-cassandra</tb-cassandra.docker.name>
41   - <pkg.user>thingsboard</pkg.user>
42 41 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
43 42 <pkg.upgradeVersion>2.4.2</pkg.upgradeVersion>
44 43 </properties>
... ...
... ... @@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 26 RUN update-rc.d ${pkg.name} disable
27 27
  28 +USER ${pkg.user}
  29 +
28 30 CMD ["start-tb-coap-transport.sh"]
... ...
... ... @@ -25,6 +25,8 @@ export LOADER_PATH=/config,${LOADER_PATH}
25 25
26 26 echo "Starting '${project.name}' ..."
27 27
  28 +cd ${pkg.installFolder}/bin
  29 +
28 30 exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.coap.ThingsboardCoapTransportApplication \
29 31 -Dspring.jpa.hibernate.ddl-auto=none \
30 32 -Dlogging.config=/config/logback.xml \
... ...
... ... @@ -36,7 +36,6 @@
36 36 <main.dir>${basedir}/../../..</main.dir>
37 37 <pkg.name>tb-coap-transport</pkg.name>
38 38 <docker.name>tb-coap-transport</docker.name>
39   - <pkg.user>thingsboard</pkg.user>
40 39 <pkg.logFolder>/var/log/${pkg.name}</pkg.logFolder>
41 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 41 </properties>
... ...
... ... @@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 26 RUN update-rc.d ${pkg.name} disable
27 27
  28 +USER ${pkg.user}
  29 +
28 30 CMD ["start-tb-http-transport.sh"]
... ...
... ... @@ -25,6 +25,8 @@ export LOADER_PATH=/config,${LOADER_PATH}
25 25
26 26 echo "Starting '${project.name}' ..."
27 27
  28 +cd ${pkg.installFolder}/bin
  29 +
28 30 exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.http.ThingsboardHttpTransportApplication \
29 31 -Dspring.jpa.hibernate.ddl-auto=none \
30 32 -Dlogging.config=/config/logback.xml \
... ...
... ... @@ -36,7 +36,6 @@
36 36 <main.dir>${basedir}/../../..</main.dir>
37 37 <pkg.name>tb-http-transport</pkg.name>
38 38 <docker.name>tb-http-transport</docker.name>
39   - <pkg.user>thingsboard</pkg.user>
40 39 <pkg.logFolder>/var/log/${pkg.name}</pkg.logFolder>
41 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 41 </properties>
... ...
... ... @@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 26 RUN update-rc.d ${pkg.name} disable
27 27
  28 +USER ${pkg.user}
  29 +
28 30 CMD ["start-tb-mqtt-transport.sh"]
... ...
... ... @@ -25,6 +25,8 @@ export LOADER_PATH=/config,${LOADER_PATH}
25 25
26 26 echo "Starting '${project.name}' ..."
27 27
  28 +cd ${pkg.installFolder}/bin
  29 +
28 30 exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.mqtt.ThingsboardMqttTransportApplication \
29 31 -Dspring.jpa.hibernate.ddl-auto=none \
30 32 -Dlogging.config=/config/logback.xml \
... ...
... ... @@ -36,7 +36,6 @@
36 36 <main.dir>${basedir}/../../..</main.dir>
37 37 <pkg.name>tb-mqtt-transport</pkg.name>
38 38 <docker.name>tb-mqtt-transport</docker.name>
39   - <pkg.user>thingsboard</pkg.user>
40 39 <pkg.logFolder>/var/log/${pkg.name}</pkg.logFolder>
41 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 41 </properties>
... ...
... ... @@ -14,7 +14,7 @@
14 14 # limitations under the License.
15 15 #
16 16
17   -FROM debian:stretch
  17 +FROM thingsboard/base
18 18
19 19 COPY start-web-ui.sh ${pkg.name}.deb /tmp/
20 20
... ... @@ -25,4 +25,6 @@ RUN dpkg -i /tmp/${pkg.name}.deb
25 25
26 26 RUN update-rc.d ${pkg.name} disable
27 27
  28 +USER ${pkg.user}
  29 +
28 30 CMD ["start-web-ui.sh"]
... ...
... ... @@ -26,4 +26,6 @@ identity=${pkg.name}
26 26
27 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 36 <main.dir>${basedir}/../..</main.dir>
37 37 <pkg.name>tb-web-ui</pkg.name>
38 38 <docker.name>tb-web-ui</docker.name>
39   - <pkg.user>thingsboard</pkg.user>
40 39 <pkg.unixLogFolder>/var/log/${pkg.name}</pkg.unixLogFolder>
41 40 <pkg.installFolder>/usr/share/${pkg.name}</pkg.installFolder>
42 41 <pkg.linux.dist>${project.build.directory}/package/linux</pkg.linux.dist>
... ...
... ... @@ -29,6 +29,7 @@
29 29
30 30 <properties>
31 31 <main.dir>${basedir}</main.dir>
  32 + <pkg.user>thingsboard</pkg.user>
32 33 <spring-boot.version>2.1.3.RELEASE</spring-boot.version>
33 34 <spring.version>5.1.5.RELEASE</spring.version>
34 35 <spring-security.version>5.1.4.RELEASE</spring-security.version>
... ... @@ -44,7 +45,7 @@
44 45 <cassandra.version>3.6.0</cassandra.version>
45 46 <cassandra-unit.version>3.5.0.1</cassandra-unit.version>
46 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 49 <caffeine.version>2.6.1</caffeine.version>
49 50 <commons-lang3.version>3.4</commons-lang3.version>
50 51 <commons-validator.version>1.6</commons-validator.version>
... ... @@ -63,7 +64,7 @@
63 64 <mail.version>1.4.3</mail.version>
64 65 <curator.version>4.2.0</curator.version>
65 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 68 <grpc.version>1.22.1</grpc.version>
68 69 <lombok.version>1.16.18</lombok.version>
69 70 <paho.client.version>1.1.0</paho.client.version>
... ...
... ... @@ -20,6 +20,7 @@ import com.google.common.cache.CacheLoader;
20 20 import com.google.common.cache.LoadingCache;
21 21 import com.google.common.util.concurrent.Futures;
22 22 import com.google.common.util.concurrent.ListenableFuture;
  23 +import com.google.common.util.concurrent.MoreExecutors;
23 24 import lombok.AllArgsConstructor;
24 25 import lombok.Data;
25 26 import lombok.NoArgsConstructor;
... ... @@ -54,9 +55,9 @@ import java.util.List;
54 55 import java.util.Optional;
55 56 import java.util.concurrent.TimeUnit;
56 57
  58 +import static org.thingsboard.common.util.DonAsynchron.withCallback;
57 59 import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE;
58 60 import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
59   -import static org.thingsboard.common.util.DonAsynchron.withCallback;
60 61
61 62 @Slf4j
62 63 public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationActionNodeConfiguration> implements TbNode {
... ... @@ -86,7 +87,7 @@ public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationA
86 87 }
87 88
88 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 93 protected abstract boolean createEntityIfNotExists();
... ...
... ... @@ -18,12 +18,13 @@ package org.thingsboard.rule.engine.action;
18 18 import com.fasterxml.jackson.databind.JsonNode;
19 19 import com.google.common.util.concurrent.Futures;
20 20 import com.google.common.util.concurrent.ListenableFuture;
  21 +import com.google.common.util.concurrent.MoreExecutors;
21 22 import lombok.extern.slf4j.Slf4j;
22   -import org.thingsboard.rule.engine.api.util.TbNodeUtils;
23 23 import org.thingsboard.rule.engine.api.RuleNode;
24 24 import org.thingsboard.rule.engine.api.TbContext;
25 25 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
26 26 import org.thingsboard.rule.engine.api.TbNodeException;
  27 +import org.thingsboard.rule.engine.api.util.TbNodeUtils;
27 28 import org.thingsboard.server.common.data.alarm.Alarm;
28 29 import org.thingsboard.server.common.data.alarm.AlarmStatus;
29 30 import org.thingsboard.server.common.data.plugin.ComponentType;
... ... @@ -80,8 +81,8 @@ public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfig
80 81 }
81 82 alarm.setStatus(alarm.getStatus().isAck() ? AlarmStatus.CLEARED_ACK : AlarmStatus.CLEARED_UNACK);
82 83 return Futures.immediateFuture(new AlarmResult(false, false, true, alarm));
83   - });
84   - });
  84 + }, MoreExecutors.directExecutor());
  85 + }, MoreExecutors.directExecutor());
85 86 }, ctx.getDbCallbackExecutor());
86 87 }
87 88 }
... ...
... ... @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
20 20 import com.google.common.base.Function;
21 21 import com.google.common.util.concurrent.Futures;
22 22 import com.google.common.util.concurrent.ListenableFuture;
  23 +import com.google.common.util.concurrent.MoreExecutors;
23 24 import lombok.extern.slf4j.Slf4j;
24 25 import org.thingsboard.rule.engine.api.RuleNode;
25 26 import org.thingsboard.rule.engine.api.TbContext;
... ... @@ -108,18 +109,18 @@ public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConf
108 109 private ListenableFuture<AlarmResult> createNewAlarm(TbContext ctx, TbMsg msg, Alarm msgAlarm) {
109 110 ListenableFuture<Alarm> asyncAlarm;
110 111 if (msgAlarm != null) {
111   - asyncAlarm = Futures.immediateCheckedFuture(msgAlarm);
  112 + asyncAlarm = Futures.immediateFuture(msgAlarm);
112 113 } else {
113 114 ctx.logJsEvalRequest();
114 115 asyncAlarm = Futures.transform(buildAlarmDetails(ctx, msg, null),
115 116 details -> {
116 117 ctx.logJsEvalResponse();
117 118 return buildAlarm(msg, details, ctx.getTenantId());
118   - });
  119 + }, MoreExecutors.directExecutor());
119 120 }
120 121 ListenableFuture<Alarm> asyncCreated = Futures.transform(asyncAlarm,
121 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 126 private ListenableFuture<AlarmResult> updateAlarm(TbContext ctx, TbMsg msg, Alarm existingAlarm, Alarm msgAlarm) {
... ... @@ -140,7 +141,7 @@ public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConf
140 141 return ctx.getAlarmService().createOrUpdateAlarm(existingAlarm);
141 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 147 private Alarm buildAlarm(TbMsg msg, JsonNode details, TenantId tenantId) {
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.action;
17 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 21 import lombok.extern.slf4j.Slf4j;
21 22 import org.thingsboard.rule.engine.api.RuleNode;
22 23 import org.thingsboard.rule.engine.api.TbContext;
... ... @@ -81,7 +82,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR
81 82 }
82 83 container.setResult(result);
83 84 return container;
84   - });
  85 + }, MoreExecutors.directExecutor());
85 86 }
86 87
87 88 private ListenableFuture<Boolean> createIfAbsent(TbContext ctx, TbMsg msg, EntityContainer entityContainer) {
... ... @@ -120,7 +121,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR
120 121 for (EntityRelation relation : entityRelations) {
121 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 126 return Futures.immediateFuture(false);
126 127 }, ctx.getDbCallbackExecutor());
... ... @@ -161,7 +162,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR
161 162 } else {
162 163 return Futures.immediateFuture(true);
163 164 }
164   - });
  165 + }, MoreExecutors.directExecutor());
165 166 }
166 167
167 168 private ListenableFuture<Boolean> processAsset(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) {
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.action;
17 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 21 import lombok.extern.slf4j.Slf4j;
21 22 import org.thingsboard.rule.engine.api.RuleNode;
22 23 import org.thingsboard.rule.engine.api.TbContext;
... ... @@ -66,17 +67,18 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteR
66 67
67 68 @Override
68 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 73 private ListenableFuture<RelationContainer> getRelationContainerListenableFuture(TbContext ctx, TbMsg msg) {
73 74 relationType = processPattern(msg, config.getRelationType());
74 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 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 82 private ListenableFuture<Boolean> processList(TbContext ctx, TbMsg msg) {
81 83 return Futures.transformAsync(processListSearchDirection(ctx, msg), entityRelations -> {
82 84 if (entityRelations.isEmpty()) {
... ... @@ -93,9 +95,9 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteR
93 95 }
94 96 }
95 97 return Futures.immediateFuture(true);
96   - });
  98 + }, MoreExecutors.directExecutor());
97 99 }
98   - });
  100 + }, MoreExecutors.directExecutor());
99 101 }
100 102
101 103 private ListenableFuture<Boolean> processSingle(TbContext ctx, TbMsg msg, EntityContainer entityContainer) {
... ... @@ -106,7 +108,7 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteR
106 108 return processSingleDeleteRelation(ctx, sdId);
107 109 }
108 110 return Futures.immediateFuture(true);
109   - });
  111 + }, MoreExecutors.directExecutor());
110 112 }
111 113
112 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 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 21 import lombok.extern.slf4j.Slf4j;
21 22 import org.thingsboard.rule.engine.api.RuleNode;
22 23 import org.thingsboard.rule.engine.api.TbContext;
... ... @@ -87,10 +88,10 @@ public class TbCheckRelationNode implements TbNode {
87 88 private ListenableFuture<Boolean> processList(TbContext ctx, TbMsg msg) {
88 89 if (EntitySearchDirection.FROM.name().equals(config.getDirection())) {
89 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 92 } else {
92 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 21 import com.fasterxml.jackson.databind.node.ObjectNode;
22 22 import com.google.common.util.concurrent.Futures;
23 23 import com.google.common.util.concurrent.ListenableFuture;
  24 +import com.google.common.util.concurrent.MoreExecutors;
24 25 import com.google.gson.JsonParseException;
25 26 import org.apache.commons.collections.CollectionUtils;
26 27 import org.apache.commons.lang3.BooleanUtils;
... ... @@ -122,7 +123,7 @@ public abstract class TbAbstractGetAttributesNode<C extends TbGetAttributesNodeC
122 123 }
123 124 }
124 125 return null;
125   - });
  126 + }, MoreExecutors.directExecutor());
126 127 }
127 128
128 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 153 }
153 154 });
154 155 return null;
155   - });
  156 + }, MoreExecutors.directExecutor());
156 157 }
157 158
158 159 private void putValueWithTs(TbMsg msg, TsKvEntry r) {
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.metadata;
17 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 21 import com.google.gson.Gson;
21 22 import com.google.gson.JsonElement;
22 23 import com.google.gson.JsonObject;
... ... @@ -37,15 +38,16 @@ import org.thingsboard.server.common.msg.TbMsgMetaData;
37 38 import java.lang.reflect.Type;
38 39 import java.util.Map;
39 40
40   -import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
41 41 import static org.thingsboard.common.util.DonAsynchron.withCallback;
  42 +import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
42 43
43 44 @Slf4j
44 45 public abstract class TbAbstractGetEntityDetailsNode<C extends TbAbstractGetEntityDetailsNodeConfiguration> implements TbNode {
45 46
46 47 private static final Gson gson = new Gson();
47 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 52 protected C config;
51 53
... ... @@ -104,7 +106,7 @@ public abstract class TbAbstractGetEntityDetailsNode<C extends TbAbstractGetEnti
104 106 } else {
105 107 return Futures.immediateFuture(null);
106 108 }
107   - });
  109 + }, MoreExecutors.directExecutor());
108 110 }
109 111
110 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 116 } else {
115 117 return Futures.immediateFuture(null);
116 118 }
117   - });
  119 + }, MoreExecutors.directExecutor());
118 120 }
119 121
120 122 private JsonElement setProperties(ContactBased entity, JsonElement data, EntityDetails entityDetails, String prefix) {
... ...
... ... @@ -17,12 +17,13 @@ package org.thingsboard.rule.engine.metadata;
17 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 21 import lombok.extern.slf4j.Slf4j;
21   -import org.thingsboard.rule.engine.api.util.TbNodeUtils;
22 22 import org.thingsboard.rule.engine.api.TbContext;
23 23 import org.thingsboard.rule.engine.api.TbNode;
24 24 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
25 25 import org.thingsboard.rule.engine.api.TbNodeException;
  26 +import org.thingsboard.rule.engine.api.util.TbNodeUtils;
26 27 import org.thingsboard.server.common.data.id.EntityId;
27 28 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
28 29 import org.thingsboard.server.common.data.kv.KvEntry;
... ... @@ -60,7 +61,7 @@ public abstract class TbEntityGetAttrNode<T extends EntityId> implements TbNode
60 61 }
61 62
62 63 private void safeGetAttributes(TbContext ctx, TbMsg msg, T entityId) {
63   - if(entityId == null || entityId.isNullUid()) {
  64 + if (entityId == null || entityId.isNullUid()) {
64 65 ctx.tellNext(msg, FAILURE);
65 66 return;
66 67 }
... ... @@ -73,13 +74,13 @@ public abstract class TbEntityGetAttrNode<T extends EntityId> implements TbNode
73 74 private ListenableFuture<List<KvEntry>> getAttributesAsync(TbContext ctx, EntityId entityId) {
74 75 ListenableFuture<List<AttributeKvEntry>> latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, SERVER_SCOPE, config.getAttrMapping().keySet());
75 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 80 private ListenableFuture<List<KvEntry>> getLatestTelemetry(TbContext ctx, EntityId entityId) {
80 81 ListenableFuture<List<TsKvEntry>> latest = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, config.getAttrMapping().keySet());
81 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 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 21 import lombok.extern.slf4j.Slf4j;
21 22 import org.thingsboard.rule.engine.api.RuleNode;
22 23 import org.thingsboard.rule.engine.api.TbContext;
... ... @@ -63,7 +64,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG
63 64 } else {
64 65 return Futures.immediateFuture(null);
65 66 }
66   - });
  67 + }, MoreExecutors.directExecutor());
67 68 }
68 69
69 70 private ListenableFuture<Customer> getCustomer(TbContext ctx, TbMsg msg) {
... ... @@ -79,7 +80,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG
79 80 } else {
80 81 return Futures.immediateFuture(null);
81 82 }
82   - });
  83 + }, MoreExecutors.directExecutor());
83 84 case ASSET:
84 85 return Futures.transformAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), new AssetId(msg.getOriginator().getId())), asset -> {
85 86 if (asset != null) {
... ... @@ -91,7 +92,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG
91 92 } else {
92 93 return Futures.immediateFuture(null);
93 94 }
94   - });
  95 + }, MoreExecutors.directExecutor());
95 96 case ENTITY_VIEW:
96 97 return Futures.transformAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), new EntityViewId(msg.getOriginator().getId())), entityView -> {
97 98 if (entityView != null) {
... ... @@ -103,7 +104,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbG
103 104 } else {
104 105 return Futures.immediateFuture(null);
105 106 }
106   - });
  107 + }, MoreExecutors.directExecutor());
107 108 default:
108 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 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 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 27 import org.thingsboard.rule.engine.api.util.TbNodeUtils;
23 28 import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader;
24 29 import org.thingsboard.server.common.data.id.EntityId;
25 30 import org.thingsboard.server.common.data.plugin.ComponentType;
26 31 import org.thingsboard.server.common.msg.TbMsg;
27 32
28   -import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
29 33 import static org.thingsboard.common.util.DonAsynchron.withCallback;
  34 +import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
30 35
31 36 /**
32 37 * Created by ashvayka on 19.01.18.
... ... @@ -71,7 +76,7 @@ public class TbGetOriginatorFieldsNode implements TbNode {
71 76 }
72 77 });
73 78 return null;
74   - }
  79 + }, MoreExecutors.directExecutor()
75 80 );
76 81 }
77 82 }
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.metadata;
17 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
20 21 import lombok.extern.slf4j.Slf4j;
21 22 import org.thingsboard.rule.engine.api.RuleNode;
22 23 import org.thingsboard.rule.engine.api.TbContext;
... ... @@ -59,6 +60,6 @@ public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode<TbGet
59 60 } else {
60 61 return Futures.immediateFuture(null);
61 62 }
62   - });
  63 + }, MoreExecutors.directExecutor());
63 64 }
64 65 }
... ...