Commit 237c2880501db168bde86588ffc12132a88dd65b

Authored by YevhenBondarenko
2 parents 9ef3445b e39ccaa2

Merge branch 'master' of https://github.com/thingsboard/thingsboard into develop/2.5-js-executor

Showing 35 changed files with 218 additions and 152 deletions
@@ -21,6 +21,8 @@ CREATE OR REPLACE PROCEDURE create_partition_ts_kv_table() LANGUAGE plpgsql AS $ @@ -21,6 +21,8 @@ CREATE OR REPLACE PROCEDURE create_partition_ts_kv_table() LANGUAGE plpgsql AS $
21 BEGIN 21 BEGIN
22 ALTER TABLE ts_kv 22 ALTER TABLE ts_kv
23 RENAME TO ts_kv_old; 23 RENAME TO ts_kv_old;
  24 + ALTER TABLE ts_kv_old
  25 + RENAME CONSTRAINT ts_kv_pkey TO ts_kv_pkey_old;
24 CREATE TABLE IF NOT EXISTS ts_kv 26 CREATE TABLE IF NOT EXISTS ts_kv
25 ( 27 (
26 LIKE ts_kv_old 28 LIKE ts_kv_old
@@ -32,6 +34,8 @@ BEGIN @@ -32,6 +34,8 @@ BEGIN
32 ALTER COLUMN entity_id TYPE uuid USING entity_id::uuid; 34 ALTER COLUMN entity_id TYPE uuid USING entity_id::uuid;
33 ALTER TABLE ts_kv 35 ALTER TABLE ts_kv
34 ALTER COLUMN key TYPE integer USING key::integer; 36 ALTER COLUMN key TYPE integer USING key::integer;
  37 + ALTER TABLE ts_kv
  38 + ADD CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts);
35 END; 39 END;
36 $$; 40 $$;
37 41
@@ -59,33 +63,65 @@ BEGIN @@ -59,33 +63,65 @@ BEGIN
59 END; 63 END;
60 $$; 64 $$;
61 65
  66 +CREATE OR REPLACE FUNCTION get_partitions_data(IN partition_type varchar)
  67 + RETURNS
  68 + TABLE
  69 + (
  70 + partition_date text,
  71 + from_ts bigint,
  72 + to_ts bigint
  73 + )
  74 +AS
  75 +$$
  76 +BEGIN
  77 + CASE
  78 + WHEN partition_type = 'DAYS' THEN
  79 + RETURN QUERY SELECT day_date.day AS partition_date,
  80 + (extract(epoch from (day_date.day)::timestamp) * 1000)::bigint AS from_ts,
  81 + (extract(epoch from (day_date.day::date + INTERVAL '1 DAY')::timestamp) *
  82 + 1000)::bigint AS to_ts
  83 + FROM (SELECT DISTINCT TO_CHAR(TO_TIMESTAMP(ts / 1000), 'YYYY_MM_DD') AS day
  84 + FROM ts_kv_old) AS day_date;
  85 + WHEN partition_type = 'MONTHS' THEN
  86 + RETURN QUERY SELECT SUBSTRING(month_date.first_date, 1, 7) AS partition_date,
  87 + (extract(epoch from (month_date.first_date)::timestamp) * 1000)::bigint AS from_ts,
  88 + (extract(epoch from (month_date.first_date::date + INTERVAL '1 MONTH')::timestamp) *
  89 + 1000)::bigint AS to_ts
  90 + FROM (SELECT DISTINCT TO_CHAR(TO_TIMESTAMP(ts / 1000), 'YYYY_MM_01') AS first_date
  91 + FROM ts_kv_old) AS month_date;
  92 + WHEN partition_type = 'YEARS' THEN
  93 + RETURN QUERY SELECT SUBSTRING(year_date.year, 1, 4) AS partition_date,
  94 + (extract(epoch from (year_date.year)::timestamp) * 1000)::bigint AS from_ts,
  95 + (extract(epoch from (year_date.year::date + INTERVAL '1 YEAR')::timestamp) *
  96 + 1000)::bigint AS to_ts
  97 + FROM (SELECT DISTINCT TO_CHAR(TO_TIMESTAMP(ts / 1000), 'YYYY_01_01') AS year FROM ts_kv_old) AS year_date;
  98 + ELSE
  99 + RAISE EXCEPTION 'Failed to parse partitioning property: % !', partition_type;
  100 + END CASE;
  101 +END;
  102 +$$ LANGUAGE plpgsql;
62 103
63 -- call create_partitions(); 104 -- call create_partitions();
64 105
65 -CREATE OR REPLACE PROCEDURE create_partitions() LANGUAGE plpgsql AS $$ 106 +CREATE OR REPLACE PROCEDURE create_partitions(IN partition_type varchar) LANGUAGE plpgsql AS $$
66 107
67 DECLARE 108 DECLARE
68 partition_date varchar; 109 partition_date varchar;
69 from_ts bigint; 110 from_ts bigint;
70 to_ts bigint; 111 to_ts bigint;
71 - key_cursor CURSOR FOR select SUBSTRING(month_date.first_date, 1, 7) AS partition_date,  
72 - extract(epoch from (month_date.first_date)::timestamp) * 1000 as from_ts,  
73 - extract(epoch from (month_date.first_date::date + INTERVAL '1 MONTH')::timestamp) *  
74 - 1000 as to_ts  
75 - FROM (SELECT DISTINCT TO_CHAR(TO_TIMESTAMP(ts / 1000), 'YYYY_MM_01') AS first_date  
76 - FROM ts_kv_old) AS month_date; 112 + partitions_cursor CURSOR FOR SELECT * FROM get_partitions_data(partition_type);
77 BEGIN 113 BEGIN
78 - OPEN key_cursor; 114 + OPEN partitions_cursor;
79 LOOP 115 LOOP
80 - FETCH key_cursor INTO partition_date, from_ts, to_ts; 116 + FETCH partitions_cursor INTO partition_date, from_ts, to_ts;
81 EXIT WHEN NOT FOUND; 117 EXIT WHEN NOT FOUND;
82 EXECUTE 'CREATE TABLE IF NOT EXISTS ts_kv_' || partition_date || 118 EXECUTE 'CREATE TABLE IF NOT EXISTS ts_kv_' || partition_date ||
83 - ' PARTITION OF ts_kv(PRIMARY KEY (entity_id, key, ts)) FOR VALUES FROM (' || from_ts || 119 + ' PARTITION OF ts_kv FOR VALUES FROM (' || from_ts ||
84 ') TO (' || to_ts || ');'; 120 ') TO (' || to_ts || ');';
85 RAISE NOTICE 'A partition % has been created!',CONCAT('ts_kv_', partition_date); 121 RAISE NOTICE 'A partition % has been created!',CONCAT('ts_kv_', partition_date);
86 END LOOP; 122 END LOOP;
87 123
88 - CLOSE key_cursor; 124 + CLOSE partitions_cursor;
89 END; 125 END;
90 $$; 126 $$;
91 127
@@ -106,7 +106,8 @@ public abstract class AbstractSqlTsDatabaseUpgradeService { @@ -106,7 +106,8 @@ public abstract class AbstractSqlTsDatabaseUpgradeService {
106 Thread.sleep(2000); 106 Thread.sleep(2000);
107 log.info("Successfully executed query: {}", query); 107 log.info("Successfully executed query: {}", query);
108 } catch (InterruptedException | SQLException e) { 108 } catch (InterruptedException | SQLException e) {
109 - log.info("Failed to execute query: {} due to: {}", query, e.getMessage()); 109 + log.error("Failed to execute query: {} due to: {}", query, e.getMessage());
  110 + throw new RuntimeException("Failed to execute query:" + query + " due to: ", e);
110 } 111 }
111 } 112 }
112 113
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.service.install; 16 package org.thingsboard.server.service.install;
17 17
  18 +import org.springframework.beans.factory.annotation.Value;
18 import org.springframework.context.annotation.Profile; 19 import org.springframework.context.annotation.Profile;
19 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
20 import org.thingsboard.server.dao.util.PsqlDao; 21 import org.thingsboard.server.dao.util.PsqlDao;
@@ -24,9 +25,20 @@ import org.thingsboard.server.dao.util.SqlTsDao; @@ -24,9 +25,20 @@ import org.thingsboard.server.dao.util.SqlTsDao;
24 @SqlTsDao 25 @SqlTsDao
25 @PsqlDao 26 @PsqlDao
26 @Profile("install") 27 @Profile("install")
27 -public class PsqlTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaService  
28 - implements TsDatabaseSchemaService { 28 +public class PsqlTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaService implements TsDatabaseSchemaService {
  29 +
  30 + @Value("${sql.postgres.ts_key_value_partitioning:MONTHS}")
  31 + private String partitionType;
  32 +
29 public PsqlTsDatabaseSchemaService() { 33 public PsqlTsDatabaseSchemaService() {
30 super("schema-ts-psql.sql", null); 34 super("schema-ts-psql.sql", null);
31 } 35 }
  36 +
  37 + @Override
  38 + public void createDatabaseSchema() throws Exception {
  39 + super.createDatabaseSchema();
  40 + if (partitionType.equals("INDEFINITE")) {
  41 + executeQuery("CREATE TABLE ts_kv_indefinite PARTITION OF ts_kv DEFAULT;");
  42 + }
  43 + }
32 } 44 }
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.service.install; 16 package org.thingsboard.server.service.install;
17 17
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
  19 +import org.springframework.beans.factory.annotation.Value;
19 import org.springframework.context.annotation.Profile; 20 import org.springframework.context.annotation.Profile;
20 import org.springframework.stereotype.Service; 21 import org.springframework.stereotype.Service;
21 import org.thingsboard.server.dao.util.PsqlDao; 22 import org.thingsboard.server.dao.util.PsqlDao;
@@ -33,6 +34,9 @@ import java.sql.DriverManager; @@ -33,6 +34,9 @@ import java.sql.DriverManager;
33 @PsqlDao 34 @PsqlDao
34 public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeService implements DatabaseTsUpgradeService { 35 public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeService implements DatabaseTsUpgradeService {
35 36
  37 + @Value("${sql.postgres.ts_key_value_partitioning:MONTHS}")
  38 + private String partitionType;
  39 +
36 private static final String LOAD_FUNCTIONS_SQL = "schema_update_psql_ts.sql"; 40 private static final String LOAD_FUNCTIONS_SQL = "schema_update_psql_ts.sql";
37 private static final String LOAD_TTL_FUNCTIONS_SQL = "schema_update_ttl.sql"; 41 private static final String LOAD_TTL_FUNCTIONS_SQL = "schema_update_ttl.sql";
38 private static final String LOAD_DROP_PARTITIONS_FUNCTIONS_SQL = "schema_update_psql_drop_partitions.sql"; 42 private static final String LOAD_DROP_PARTITIONS_FUNCTIONS_SQL = "schema_update_psql_drop_partitions.sql";
@@ -50,7 +54,6 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe @@ -50,7 +54,6 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe
50 54
51 private static final String CALL_CREATE_PARTITION_TS_KV_TABLE = CALL_REGEX + CREATE_PARTITION_TS_KV_TABLE; 55 private static final String CALL_CREATE_PARTITION_TS_KV_TABLE = CALL_REGEX + CREATE_PARTITION_TS_KV_TABLE;
52 private static final String CALL_CREATE_NEW_TS_KV_LATEST_TABLE = CALL_REGEX + CREATE_NEW_TS_KV_LATEST_TABLE; 56 private static final String CALL_CREATE_NEW_TS_KV_LATEST_TABLE = CALL_REGEX + CREATE_NEW_TS_KV_LATEST_TABLE;
53 - private static final String CALL_CREATE_PARTITIONS = CALL_REGEX + CREATE_PARTITIONS;  
54 private static final String CALL_CREATE_TS_KV_DICTIONARY_TABLE = CALL_REGEX + CREATE_TS_KV_DICTIONARY_TABLE; 57 private static final String CALL_CREATE_TS_KV_DICTIONARY_TABLE = CALL_REGEX + CREATE_TS_KV_DICTIONARY_TABLE;
55 private static final String CALL_INSERT_INTO_DICTIONARY = CALL_REGEX + INSERT_INTO_DICTIONARY; 58 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_TS_KV; 59 private static final String CALL_INSERT_INTO_TS_KV = CALL_REGEX + INSERT_INTO_TS_KV;
@@ -66,6 +69,7 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe @@ -66,6 +69,7 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe
66 private static final String DROP_PROCEDURE_INSERT_INTO_DICTIONARY = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_DICTIONARY; 69 private static final String DROP_PROCEDURE_INSERT_INTO_DICTIONARY = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_DICTIONARY;
67 private static final String DROP_PROCEDURE_INSERT_INTO_TS_KV = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_TS_KV; 70 private static final String DROP_PROCEDURE_INSERT_INTO_TS_KV = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_TS_KV;
68 private static final String DROP_PROCEDURE_INSERT_INTO_TS_KV_LATEST = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_TS_KV_LATEST; 71 private static final String DROP_PROCEDURE_INSERT_INTO_TS_KV_LATEST = DROP_PROCEDURE_IF_EXISTS + INSERT_INTO_TS_KV_LATEST;
  72 + private static final String DROP_FUNCTION_GET_PARTITION_DATA = "DROP FUNCTION IF EXISTS get_partitions_data;";
69 73
70 @Override 74 @Override
71 public void upgradeDatabase(String fromVersion) throws Exception { 75 public void upgradeDatabase(String fromVersion) throws Exception {
@@ -83,7 +87,11 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe @@ -83,7 +87,11 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe
83 loadSql(conn, LOAD_FUNCTIONS_SQL); 87 loadSql(conn, LOAD_FUNCTIONS_SQL);
84 log.info("Updating timeseries schema ..."); 88 log.info("Updating timeseries schema ...");
85 executeQuery(conn, CALL_CREATE_PARTITION_TS_KV_TABLE); 89 executeQuery(conn, CALL_CREATE_PARTITION_TS_KV_TABLE);
86 - executeQuery(conn, CALL_CREATE_PARTITIONS); 90 + if (!partitionType.equals("INDEFINITE")) {
  91 + executeQuery(conn, "call create_partitions('" + partitionType + "')");
  92 + } else {
  93 + executeQuery(conn, "CREATE TABLE IF NOT EXISTS ts_kv_indefinite PARTITION OF ts_kv DEFAULT;");
  94 + }
87 executeQuery(conn, CALL_CREATE_TS_KV_DICTIONARY_TABLE); 95 executeQuery(conn, CALL_CREATE_TS_KV_DICTIONARY_TABLE);
88 executeQuery(conn, CALL_INSERT_INTO_DICTIONARY); 96 executeQuery(conn, CALL_INSERT_INTO_DICTIONARY);
89 executeQuery(conn, CALL_INSERT_INTO_TS_KV); 97 executeQuery(conn, CALL_INSERT_INTO_TS_KV);
@@ -100,9 +108,14 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe @@ -100,9 +108,14 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe
100 executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_TS_KV); 108 executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_TS_KV);
101 executeQuery(conn, DROP_PROCEDURE_CREATE_NEW_TS_KV_LATEST_TABLE); 109 executeQuery(conn, DROP_PROCEDURE_CREATE_NEW_TS_KV_LATEST_TABLE);
102 executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_TS_KV_LATEST); 110 executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_TS_KV_LATEST);
  111 + executeQuery(conn, DROP_PROCEDURE_INSERT_INTO_TS_KV_LATEST);
  112 + executeQuery(conn, DROP_FUNCTION_GET_PARTITION_DATA);
103 113
104 executeQuery(conn, "ALTER TABLE ts_kv ADD COLUMN IF NOT EXISTS json_v json;"); 114 executeQuery(conn, "ALTER TABLE ts_kv ADD COLUMN IF NOT EXISTS json_v json;");
105 executeQuery(conn, "ALTER TABLE ts_kv_latest ADD COLUMN IF NOT EXISTS json_v json;"); 115 executeQuery(conn, "ALTER TABLE ts_kv_latest ADD COLUMN IF NOT EXISTS json_v json;");
  116 + } else {
  117 + executeQuery(conn, "ALTER TABLE ts_kv DROP CONSTRAINT IF EXISTS ts_kv_pkey;");
  118 + executeQuery(conn, "ALTER TABLE ts_kv ADD CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts);");
106 } 119 }
107 120
108 log.info("Load TTL functions ..."); 121 log.info("Load TTL functions ...");
@@ -25,6 +25,7 @@ import java.nio.file.Path; @@ -25,6 +25,7 @@ import java.nio.file.Path;
25 import java.nio.file.Paths; 25 import java.nio.file.Paths;
26 import java.sql.Connection; 26 import java.sql.Connection;
27 import java.sql.DriverManager; 27 import java.sql.DriverManager;
  28 +import java.sql.SQLException;
28 29
29 @Slf4j 30 @Slf4j
30 public abstract class SqlAbstractDatabaseSchemaService implements DatabaseSchemaService { 31 public abstract class SqlAbstractDatabaseSchemaService implements DatabaseSchemaService {
@@ -73,4 +74,14 @@ public abstract class SqlAbstractDatabaseSchemaService implements DatabaseSchema @@ -73,4 +74,14 @@ public abstract class SqlAbstractDatabaseSchemaService implements DatabaseSchema
73 } 74 }
74 } 75 }
75 76
  77 + protected void executeQuery(String query) {
  78 + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
  79 + conn.createStatement().execute(query); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
  80 + log.info("Successfully executed query: {}", query);
  81 + Thread.sleep(5000);
  82 + } catch (InterruptedException | SQLException e) {
  83 + log.info("Failed to execute query: {} due to: {}", query, e.getMessage());
  84 + }
  85 + }
  86 +
76 } 87 }
@@ -33,14 +33,6 @@ import java.sql.SQLException; @@ -33,14 +33,6 @@ import java.sql.SQLException;
33 @Slf4j 33 @Slf4j
34 public class TimescaleTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaService implements TsDatabaseSchemaService { 34 public class TimescaleTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaService implements TsDatabaseSchemaService {
35 35
36 - private static final String QUERY = "query: {}";  
37 - private static final String SUCCESSFULLY_EXECUTED = "Successfully executed ";  
38 - private static final String FAILED_TO_EXECUTE = "Failed to execute ";  
39 - private static final String FAILED_DUE_TO = " due to: {}";  
40 -  
41 - private static final String SUCCESSFULLY_EXECUTED_QUERY = SUCCESSFULLY_EXECUTED + QUERY;  
42 - private static final String FAILED_TO_EXECUTE_QUERY = FAILED_TO_EXECUTE + QUERY + FAILED_DUE_TO;  
43 -  
44 @Value("${sql.timescale.chunk_time_interval:86400000}") 36 @Value("${sql.timescale.chunk_time_interval:86400000}")
45 private long chunkTimeInterval; 37 private long chunkTimeInterval;
46 38
@@ -54,15 +46,4 @@ public class TimescaleTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaS @@ -54,15 +46,4 @@ public class TimescaleTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaS
54 executeQuery("SELECT create_hypertable('ts_kv', 'ts', chunk_time_interval => " + chunkTimeInterval + ", if_not_exists => true);"); 46 executeQuery("SELECT create_hypertable('ts_kv', 'ts', chunk_time_interval => " + chunkTimeInterval + ", if_not_exists => true);");
55 } 47 }
56 48
57 - private void executeQuery(String query) {  
58 - try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {  
59 - conn.createStatement().execute(query); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script  
60 - log.info(SUCCESSFULLY_EXECUTED_QUERY, query);  
61 - Thread.sleep(5000);  
62 - } catch (InterruptedException | SQLException e) {  
63 - log.info(FAILED_TO_EXECUTE_QUERY, query, e.getMessage());  
64 - }  
65 - }  
66 -  
67 -  
68 } 49 }
@@ -18,10 +18,13 @@ package org.thingsboard.server.service.script; @@ -18,10 +18,13 @@ package org.thingsboard.server.service.script;
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
20 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
  21 +import org.thingsboard.common.util.ThingsBoardThreadFactory;
21 22
22 import java.util.Map; 23 import java.util.Map;
23 import java.util.UUID; 24 import java.util.UUID;
24 import java.util.concurrent.ConcurrentHashMap; 25 import java.util.concurrent.ConcurrentHashMap;
  26 +import java.util.concurrent.Executors;
  27 +import java.util.concurrent.ScheduledExecutorService;
25 import java.util.concurrent.atomic.AtomicInteger; 28 import java.util.concurrent.atomic.AtomicInteger;
26 29
27 /** 30 /**
@@ -30,9 +33,22 @@ import java.util.concurrent.atomic.AtomicInteger; @@ -30,9 +33,22 @@ import java.util.concurrent.atomic.AtomicInteger;
30 @Slf4j 33 @Slf4j
31 public abstract class AbstractJsInvokeService implements JsInvokeService { 34 public abstract class AbstractJsInvokeService implements JsInvokeService {
32 35
  36 + protected ScheduledExecutorService timeoutExecutorService;
33 protected Map<UUID, String> scriptIdToNameMap = new ConcurrentHashMap<>(); 37 protected Map<UUID, String> scriptIdToNameMap = new ConcurrentHashMap<>();
34 protected Map<UUID, BlackListInfo> blackListedFunctions = new ConcurrentHashMap<>(); 38 protected Map<UUID, BlackListInfo> blackListedFunctions = new ConcurrentHashMap<>();
35 39
  40 + public void init(long maxRequestsTimeout) {
  41 + if (maxRequestsTimeout > 0) {
  42 + timeoutExecutorService = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName("nashorn-js-timeout"));
  43 + }
  44 + }
  45 +
  46 + public void stop() {
  47 + if (timeoutExecutorService != null) {
  48 + timeoutExecutorService.shutdownNow();
  49 + }
  50 + }
  51 +
36 @Override 52 @Override
37 public ListenableFuture<UUID> eval(JsScriptType scriptType, String scriptBody, String... argNames) { 53 public ListenableFuture<UUID> eval(JsScriptType scriptType, String scriptBody, String... argNames) {
38 UUID scriptId = UUID.randomUUID(); 54 UUID scriptId = UUID.randomUUID();
@@ -48,7 +48,6 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer @@ -48,7 +48,6 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
48 private NashornSandbox sandbox; 48 private NashornSandbox sandbox;
49 private ScriptEngine engine; 49 private ScriptEngine engine;
50 private ExecutorService monitorExecutorService; 50 private ExecutorService monitorExecutorService;
51 - private ScheduledExecutorService timeoutExecutorService;  
52 51
53 private final AtomicInteger jsPushedMsgs = new AtomicInteger(0); 52 private final AtomicInteger jsPushedMsgs = new AtomicInteger(0);
54 private final AtomicInteger jsInvokeMsgs = new AtomicInteger(0); 53 private final AtomicInteger jsInvokeMsgs = new AtomicInteger(0);
@@ -85,9 +84,7 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer @@ -85,9 +84,7 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
85 84
86 @PostConstruct 85 @PostConstruct
87 public void init() { 86 public void init() {
88 - if (maxRequestsTimeout > 0) {  
89 - timeoutExecutorService = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName("nashorn-js-timeout"));  
90 - } 87 + super.init(maxRequestsTimeout);
91 if (useJsSandbox()) { 88 if (useJsSandbox()) {
92 sandbox = NashornSandboxes.create(); 89 sandbox = NashornSandboxes.create();
93 monitorExecutorService = Executors.newWorkStealingPool(getMonitorThreadPoolSize()); 90 monitorExecutorService = Executors.newWorkStealingPool(getMonitorThreadPoolSize());
@@ -104,12 +101,10 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer @@ -104,12 +101,10 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
104 101
105 @PreDestroy 102 @PreDestroy
106 public void stop() { 103 public void stop() {
  104 + super.stop();
107 if (monitorExecutorService != null) { 105 if (monitorExecutorService != null) {
108 monitorExecutorService.shutdownNow(); 106 monitorExecutorService.shutdownNow();
109 } 107 }
110 - if (timeoutExecutorService != null) {  
111 - timeoutExecutorService.shutdownNow();  
112 - }  
113 } 108 }
114 109
115 protected abstract boolean useJsSandbox(); 110 protected abstract boolean useJsSandbox();
@@ -87,11 +87,13 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService { @@ -87,11 +87,13 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
87 87
88 @PostConstruct 88 @PostConstruct
89 public void init() { 89 public void init() {
  90 + super.init(maxRequestsTimeout);
90 requestTemplate.init(); 91 requestTemplate.init();
91 } 92 }
92 93
93 @PreDestroy 94 @PreDestroy
94 public void destroy() { 95 public void destroy() {
  96 + super.stop();
95 if (requestTemplate != null) { 97 if (requestTemplate != null) {
96 requestTemplate.stop(); 98 requestTemplate.stop();
97 } 99 }
@@ -111,7 +113,9 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService { @@ -111,7 +113,9 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
111 113
112 log.trace("Post compile request for scriptId [{}]", scriptId); 114 log.trace("Post compile request for scriptId [{}]", scriptId);
113 ListenableFuture<TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>> future = requestTemplate.send(new TbProtoJsQueueMsg<>(UUID.randomUUID(), jsRequestWrapper)); 115 ListenableFuture<TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>> future = requestTemplate.send(new TbProtoJsQueueMsg<>(UUID.randomUUID(), jsRequestWrapper));
114 - 116 + if (maxRequestsTimeout > 0) {
  117 + future = Futures.withTimeout(future, maxRequestsTimeout, TimeUnit.MILLISECONDS, timeoutExecutorService);
  118 + }
115 kafkaPushedMsgs.incrementAndGet(); 119 kafkaPushedMsgs.incrementAndGet();
116 Futures.addCallback(future, new FutureCallback<TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>>() { 120 Futures.addCallback(future, new FutureCallback<TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>>() {
117 @Override 121 @Override
@@ -154,8 +158,8 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService { @@ -154,8 +158,8 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
154 .setTimeout((int) maxRequestsTimeout) 158 .setTimeout((int) maxRequestsTimeout)
155 .setScriptBody(scriptIdToBodysMap.get(scriptId)); 159 .setScriptBody(scriptIdToBodysMap.get(scriptId));
156 160
157 - for (int i = 0; i < args.length; i++) {  
158 - jsRequestBuilder.addArgs(args[i].toString()); 161 + for (Object arg : args) {
  162 + jsRequestBuilder.addArgs(arg.toString());
159 } 163 }
160 164
161 JsInvokeProtos.RemoteJsRequest jsRequestWrapper = JsInvokeProtos.RemoteJsRequest.newBuilder() 165 JsInvokeProtos.RemoteJsRequest jsRequestWrapper = JsInvokeProtos.RemoteJsRequest.newBuilder()
@@ -163,6 +167,9 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService { @@ -163,6 +167,9 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
163 .build(); 167 .build();
164 168
165 ListenableFuture<TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>> future = requestTemplate.send(new TbProtoJsQueueMsg<>(UUID.randomUUID(), jsRequestWrapper)); 169 ListenableFuture<TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>> future = requestTemplate.send(new TbProtoJsQueueMsg<>(UUID.randomUUID(), jsRequestWrapper));
  170 + if (maxRequestsTimeout > 0) {
  171 + future = Futures.withTimeout(future, maxRequestsTimeout, TimeUnit.MILLISECONDS, timeoutExecutorService);
  172 + }
166 kafkaPushedMsgs.incrementAndGet(); 173 kafkaPushedMsgs.incrementAndGet();
167 Futures.addCallback(future, new FutureCallback<TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>>() { 174 Futures.addCallback(future, new FutureCallback<TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>>() {
168 @Override 175 @Override
@@ -203,6 +210,9 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService { @@ -203,6 +210,9 @@ public class RemoteJsInvokeService extends AbstractJsInvokeService {
203 .build(); 210 .build();
204 211
205 ListenableFuture<TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>> future = requestTemplate.send(new TbProtoJsQueueMsg<>(UUID.randomUUID(), jsRequestWrapper)); 212 ListenableFuture<TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>> future = requestTemplate.send(new TbProtoJsQueueMsg<>(UUID.randomUUID(), jsRequestWrapper));
  213 + if (maxRequestsTimeout > 0) {
  214 + future = Futures.withTimeout(future, maxRequestsTimeout, TimeUnit.MILLISECONDS, timeoutExecutorService);
  215 + }
206 JsInvokeProtos.RemoteJsResponse response = future.get().getValue(); 216 JsInvokeProtos.RemoteJsResponse response = future.get().getValue();
207 217
208 JsInvokeProtos.JsReleaseResponse compilationResult = response.getReleaseResponse(); 218 JsInvokeProtos.JsReleaseResponse compilationResult = response.getReleaseResponse();
@@ -33,7 +33,7 @@ public class ControllerSqlTestSuite { @@ -33,7 +33,7 @@ public class ControllerSqlTestSuite {
33 @ClassRule 33 @ClassRule
34 public static CustomSqlUnit sqlUnit = new CustomSqlUnit( 34 public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
35 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql"), 35 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql"),
36 - "sql/drop-all-tables.sql", 36 + "sql/hsql/drop-all-tables.sql",
37 "sql-test.properties"); 37 "sql-test.properties");
38 38
39 @BeforeClass 39 @BeforeClass
@@ -32,7 +32,7 @@ public class MqttSqlTestSuite { @@ -32,7 +32,7 @@ public class MqttSqlTestSuite {
32 @ClassRule 32 @ClassRule
33 public static CustomSqlUnit sqlUnit = new CustomSqlUnit( 33 public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
34 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/system-data.sql"), 34 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/system-data.sql"),
35 - "sql/drop-all-tables.sql", 35 + "sql/hsql/drop-all-tables.sql",
36 "sql-test.properties"); 36 "sql-test.properties");
37 37
38 @BeforeClass 38 @BeforeClass
@@ -33,7 +33,7 @@ public class RuleEngineSqlTestSuite { @@ -33,7 +33,7 @@ public class RuleEngineSqlTestSuite {
33 @ClassRule 33 @ClassRule
34 public static CustomSqlUnit sqlUnit = new CustomSqlUnit( 34 public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
35 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/system-data.sql"), 35 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/system-data.sql"),
36 - "sql/drop-all-tables.sql", 36 + "sql/hsql/drop-all-tables.sql",
37 "sql-test.properties"); 37 "sql-test.properties");
38 38
39 @BeforeClass 39 @BeforeClass
@@ -34,7 +34,7 @@ public class SystemSqlTestSuite { @@ -34,7 +34,7 @@ public class SystemSqlTestSuite {
34 @ClassRule 34 @ClassRule
35 public static CustomSqlUnit sqlUnit = new CustomSqlUnit( 35 public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
36 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/system-data.sql"), 36 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/system-data.sql"),
37 - "sql/drop-all-tables.sql", 37 + "sql/hsql/drop-all-tables.sql",
38 "sql-test.properties"); 38 "sql-test.properties");
39 39
40 @BeforeClass 40 @BeforeClass
@@ -54,7 +54,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -54,7 +54,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
54 @Autowired 54 @Autowired
55 protected InsertTsRepository<TsKvEntity> insertRepository; 55 protected InsertTsRepository<TsKvEntity> insertRepository;
56 56
57 - protected TbSqlBlockingQueue<EntityContainer<TsKvEntity>> tsQueue; 57 + protected TbSqlBlockingQueue<TsKvEntity> tsQueue;
58 58
59 @PostConstruct 59 @PostConstruct
60 protected void init() { 60 protected void init() {
@@ -23,7 +23,6 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -23,7 +23,6 @@ import org.thingsboard.server.common.data.id.TenantId;
23 import org.thingsboard.server.common.data.kv.TsKvEntry; 23 import org.thingsboard.server.common.data.kv.TsKvEntry;
24 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; 24 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity;
25 import org.thingsboard.server.dao.sqlts.AbstractChunkedAggregationTimeseriesDao; 25 import org.thingsboard.server.dao.sqlts.AbstractChunkedAggregationTimeseriesDao;
26 -import org.thingsboard.server.dao.sqlts.EntityContainer;  
27 import org.thingsboard.server.dao.timeseries.TimeseriesDao; 26 import org.thingsboard.server.dao.timeseries.TimeseriesDao;
28 import org.thingsboard.server.dao.util.HsqlDao; 27 import org.thingsboard.server.dao.util.HsqlDao;
29 import org.thingsboard.server.dao.util.SqlTsDao; 28 import org.thingsboard.server.dao.util.SqlTsDao;
@@ -48,7 +47,7 @@ public class JpaHsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa @@ -48,7 +47,7 @@ public class JpaHsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa
48 entity.setLongValue(tsKvEntry.getLongValue().orElse(null)); 47 entity.setLongValue(tsKvEntry.getLongValue().orElse(null));
49 entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null)); 48 entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
50 log.trace("Saving entity: {}", entity); 49 log.trace("Saving entity: {}", entity);
51 - return tsQueue.add(new EntityContainer(entity, null)); 50 + return tsQueue.add(entity);
52 } 51 }
53 52
54 } 53 }
@@ -16,12 +16,11 @@ @@ -16,12 +16,11 @@
16 package org.thingsboard.server.dao.sqlts.insert; 16 package org.thingsboard.server.dao.sqlts.insert;
17 17
18 import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; 18 import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity;
19 -import org.thingsboard.server.dao.sqlts.EntityContainer;  
20 19
21 import java.util.List; 20 import java.util.List;
22 21
23 public interface InsertTsRepository<T extends AbstractTsKvEntity> { 22 public interface InsertTsRepository<T extends AbstractTsKvEntity> {
24 23
25 - void saveOrUpdate(List<EntityContainer<T>> entities); 24 + void saveOrUpdate(List<T> entities);
26 25
27 } 26 }
@@ -19,7 +19,6 @@ import org.springframework.jdbc.core.BatchPreparedStatementSetter; @@ -19,7 +19,6 @@ import org.springframework.jdbc.core.BatchPreparedStatementSetter;
19 import org.springframework.stereotype.Repository; 19 import org.springframework.stereotype.Repository;
20 import org.springframework.transaction.annotation.Transactional; 20 import org.springframework.transaction.annotation.Transactional;
21 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; 21 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity;
22 -import org.thingsboard.server.dao.sqlts.EntityContainer;  
23 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository; 22 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository;
24 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; 23 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository;
25 import org.thingsboard.server.dao.util.HsqlDao; 24 import org.thingsboard.server.dao.util.HsqlDao;
@@ -47,12 +46,11 @@ public class HsqlInsertTsRepository extends AbstractInsertRepository implements @@ -47,12 +46,11 @@ public class HsqlInsertTsRepository extends AbstractInsertRepository implements
47 "VALUES (T.entity_id, T.key, T.ts, T.bool_v, T.str_v, T.long_v, T.dbl_v, T.json_v);"; 46 "VALUES (T.entity_id, T.key, T.ts, T.bool_v, T.str_v, T.long_v, T.dbl_v, T.json_v);";
48 47
49 @Override 48 @Override
50 - public void saveOrUpdate(List<EntityContainer<TsKvEntity>> entities) { 49 + public void saveOrUpdate(List<TsKvEntity> entities) {
51 jdbcTemplate.batchUpdate(INSERT_OR_UPDATE, new BatchPreparedStatementSetter() { 50 jdbcTemplate.batchUpdate(INSERT_OR_UPDATE, new BatchPreparedStatementSetter() {
52 @Override 51 @Override
53 public void setValues(PreparedStatement ps, int i) throws SQLException { 52 public void setValues(PreparedStatement ps, int i) throws SQLException {
54 - EntityContainer<TsKvEntity> tsKvEntityEntityContainer = entities.get(i);  
55 - TsKvEntity tsKvEntity = tsKvEntityEntityContainer.getEntity(); 53 + TsKvEntity tsKvEntity = entities.get(i);
56 ps.setObject(1, tsKvEntity.getEntityId()); 54 ps.setObject(1, tsKvEntity.getEntityId());
57 ps.setInt(2, tsKvEntity.getKey()); 55 ps.setInt(2, tsKvEntity.getKey());
58 ps.setLong(3, tsKvEntity.getTs()); 56 ps.setLong(3, tsKvEntity.getTs());
@@ -20,7 +20,6 @@ import org.springframework.stereotype.Repository; @@ -20,7 +20,6 @@ import org.springframework.stereotype.Repository;
20 import org.springframework.transaction.annotation.Transactional; 20 import org.springframework.transaction.annotation.Transactional;
21 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; 21 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity;
22 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository; 22 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository;
23 -import org.thingsboard.server.dao.sqlts.EntityContainer;  
24 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; 23 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository;
25 import org.thingsboard.server.dao.util.PsqlDao; 24 import org.thingsboard.server.dao.util.PsqlDao;
26 import org.thingsboard.server.dao.util.SqlTsDao; 25 import org.thingsboard.server.dao.util.SqlTsDao;
@@ -28,10 +27,7 @@ import org.thingsboard.server.dao.util.SqlTsDao; @@ -28,10 +27,7 @@ import org.thingsboard.server.dao.util.SqlTsDao;
28 import java.sql.PreparedStatement; 27 import java.sql.PreparedStatement;
29 import java.sql.SQLException; 28 import java.sql.SQLException;
30 import java.sql.Types; 29 import java.sql.Types;
31 -import java.util.ArrayList;  
32 -import java.util.HashMap;  
33 import java.util.List; 30 import java.util.List;
34 -import java.util.Map;  
35 31
36 @SqlTsDao 32 @SqlTsDao
37 @PsqlDao 33 @PsqlDao
@@ -39,22 +35,15 @@ import java.util.Map; @@ -39,22 +35,15 @@ import java.util.Map;
39 @Transactional 35 @Transactional
40 public class PsqlInsertTsRepository extends AbstractInsertRepository implements InsertTsRepository<TsKvEntity> { 36 public class PsqlInsertTsRepository extends AbstractInsertRepository implements InsertTsRepository<TsKvEntity> {
41 37
42 - private static final String INSERT_INTO_TS_KV = "INSERT INTO ts_kv_";  
43 -  
44 - private static final String VALUES_ON_CONFLICT_DO_UPDATE = " (entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) VALUES (?, ?, ?, ?, ?, ?, ?, cast(? AS json)) " + 38 + private static final String INSERT_ON_CONFLICT_DO_UPDATE = "INSERT INTO ts_kv (entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) VALUES (?, ?, ?, ?, ?, ?, ?, cast(? AS json)) " +
45 "ON CONFLICT (entity_id, key, ts) DO UPDATE SET bool_v = ?, str_v = ?, long_v = ?, dbl_v = ?, json_v = cast(? AS json);"; 39 "ON CONFLICT (entity_id, key, ts) DO UPDATE SET bool_v = ?, str_v = ?, long_v = ?, dbl_v = ?, json_v = cast(? AS json);";
46 40
47 @Override 41 @Override
48 - public void saveOrUpdate(List<EntityContainer<TsKvEntity>> entities) {  
49 - Map<String, List<TsKvEntity>> partitionMap = new HashMap<>();  
50 - for (EntityContainer<TsKvEntity> entityContainer : entities) {  
51 - List<TsKvEntity> tsKvEntities = partitionMap.computeIfAbsent(entityContainer.getPartitionDate(), k -> new ArrayList<>());  
52 - tsKvEntities.add(entityContainer.getEntity());  
53 - }  
54 - partitionMap.forEach((partition, entries) -> jdbcTemplate.batchUpdate(getInsertOrUpdateQuery(partition), new BatchPreparedStatementSetter() { 42 + public void saveOrUpdate(List<TsKvEntity> entities) {
  43 + jdbcTemplate.batchUpdate(INSERT_ON_CONFLICT_DO_UPDATE, new BatchPreparedStatementSetter() {
55 @Override 44 @Override
56 public void setValues(PreparedStatement ps, int i) throws SQLException { 45 public void setValues(PreparedStatement ps, int i) throws SQLException {
57 - TsKvEntity tsKvEntity = entries.get(i); 46 + TsKvEntity tsKvEntity = entities.get(i);
58 ps.setObject(1, tsKvEntity.getEntityId()); 47 ps.setObject(1, tsKvEntity.getEntityId());
59 ps.setInt(2, tsKvEntity.getKey()); 48 ps.setInt(2, tsKvEntity.getKey());
60 ps.setLong(3, tsKvEntity.getTs()); 49 ps.setLong(3, tsKvEntity.getTs());
@@ -93,12 +82,9 @@ public class PsqlInsertTsRepository extends AbstractInsertRepository implements @@ -93,12 +82,9 @@ public class PsqlInsertTsRepository extends AbstractInsertRepository implements
93 82
94 @Override 83 @Override
95 public int getBatchSize() { 84 public int getBatchSize() {
96 - return entries.size(); 85 + return entities.size();
97 } 86 }
98 - })); 87 + });
99 } 88 }
100 89
101 - private String getInsertOrUpdateQuery(String partitionDate) {  
102 - return INSERT_INTO_TS_KV + partitionDate + VALUES_ON_CONFLICT_DO_UPDATE;  
103 - }  
104 } 90 }
@@ -20,7 +20,6 @@ import org.springframework.stereotype.Repository; @@ -20,7 +20,6 @@ import org.springframework.stereotype.Repository;
20 import org.springframework.transaction.annotation.Transactional; 20 import org.springframework.transaction.annotation.Transactional;
21 import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; 21 import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity;
22 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository; 22 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository;
23 -import org.thingsboard.server.dao.sqlts.EntityContainer;  
24 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; 23 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository;
25 import org.thingsboard.server.dao.util.PsqlDao; 24 import org.thingsboard.server.dao.util.PsqlDao;
26 import org.thingsboard.server.dao.util.TimescaleDBTsDao; 25 import org.thingsboard.server.dao.util.TimescaleDBTsDao;
@@ -41,11 +40,11 @@ public class TimescaleInsertTsRepository extends AbstractInsertRepository implem @@ -41,11 +40,11 @@ public class TimescaleInsertTsRepository extends AbstractInsertRepository implem
41 "ON CONFLICT (entity_id, key, ts) DO UPDATE SET bool_v = ?, str_v = ?, long_v = ?, dbl_v = ?, json_v = cast(? AS json);"; 40 "ON CONFLICT (entity_id, key, ts) DO UPDATE SET bool_v = ?, str_v = ?, long_v = ?, dbl_v = ?, json_v = cast(? AS json);";
42 41
43 @Override 42 @Override
44 - public void saveOrUpdate(List<EntityContainer<TimescaleTsKvEntity>> entities) { 43 + public void saveOrUpdate(List<TimescaleTsKvEntity> entities) {
45 jdbcTemplate.batchUpdate(INSERT_OR_UPDATE, new BatchPreparedStatementSetter() { 44 jdbcTemplate.batchUpdate(INSERT_OR_UPDATE, new BatchPreparedStatementSetter() {
46 @Override 45 @Override
47 public void setValues(PreparedStatement ps, int i) throws SQLException { 46 public void setValues(PreparedStatement ps, int i) throws SQLException {
48 - TimescaleTsKvEntity tsKvEntity = entities.get(i).getEntity(); 47 + TimescaleTsKvEntity tsKvEntity = entities.get(i);
49 ps.setObject(1, tsKvEntity.getEntityId()); 48 ps.setObject(1, tsKvEntity.getEntityId());
50 ps.setInt(2, tsKvEntity.getKey()); 49 ps.setInt(2, tsKvEntity.getKey());
51 ps.setLong(3, tsKvEntity.getTs()); 50 ps.setLong(3, tsKvEntity.getTs());
@@ -25,7 +25,6 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -25,7 +25,6 @@ import org.thingsboard.server.common.data.id.TenantId;
25 import org.thingsboard.server.common.data.kv.TsKvEntry; 25 import org.thingsboard.server.common.data.kv.TsKvEntry;
26 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; 26 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity;
27 import org.thingsboard.server.dao.sqlts.AbstractChunkedAggregationTimeseriesDao; 27 import org.thingsboard.server.dao.sqlts.AbstractChunkedAggregationTimeseriesDao;
28 -import org.thingsboard.server.dao.sqlts.EntityContainer;  
29 import org.thingsboard.server.dao.sqlts.insert.psql.PsqlPartitioningRepository; 28 import org.thingsboard.server.dao.sqlts.insert.psql.PsqlPartitioningRepository;
30 import org.thingsboard.server.dao.timeseries.PsqlPartition; 29 import org.thingsboard.server.dao.timeseries.PsqlPartition;
31 import org.thingsboard.server.dao.timeseries.SqlTsPartitionDate; 30 import org.thingsboard.server.dao.timeseries.SqlTsPartitionDate;
@@ -42,8 +41,6 @@ import java.util.Optional; @@ -42,8 +41,6 @@ import java.util.Optional;
42 import java.util.concurrent.ConcurrentHashMap; 41 import java.util.concurrent.ConcurrentHashMap;
43 import java.util.concurrent.locks.ReentrantLock; 42 import java.util.concurrent.locks.ReentrantLock;
44 43
45 -import static org.thingsboard.server.dao.timeseries.SqlTsPartitionDate.EPOCH_START;  
46 -  
47 44
48 @Component 45 @Component
49 @Slf4j 46 @Slf4j
@@ -58,7 +55,6 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa @@ -58,7 +55,6 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa
58 private PsqlPartitioningRepository partitioningRepository; 55 private PsqlPartitioningRepository partitioningRepository;
59 56
60 private SqlTsPartitionDate tsFormat; 57 private SqlTsPartitionDate tsFormat;
61 - private PsqlPartition indefinitePartition;  
62 58
63 @Value("${sql.postgres.ts_key_value_partitioning:MONTHS}") 59 @Value("${sql.postgres.ts_key_value_partitioning:MONTHS}")
64 private String partitioning; 60 private String partitioning;
@@ -69,10 +65,6 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa @@ -69,10 +65,6 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa
69 Optional<SqlTsPartitionDate> partition = SqlTsPartitionDate.parse(partitioning); 65 Optional<SqlTsPartitionDate> partition = SqlTsPartitionDate.parse(partitioning);
70 if (partition.isPresent()) { 66 if (partition.isPresent()) {
71 tsFormat = partition.get(); 67 tsFormat = partition.get();
72 - if (tsFormat.equals(SqlTsPartitionDate.INDEFINITE)) {  
73 - indefinitePartition = new PsqlPartition(toMills(EPOCH_START), Long.MAX_VALUE, tsFormat.getPattern());  
74 - savePartition(indefinitePartition);  
75 - }  
76 } else { 68 } else {
77 log.warn("Incorrect configuration of partitioning {}", partitioning); 69 log.warn("Incorrect configuration of partitioning {}", partitioning);
78 throw new RuntimeException("Failed to parse partitioning property: " + partitioning + "!"); 70 throw new RuntimeException("Failed to parse partitioning property: " + partitioning + "!");
@@ -81,6 +73,7 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa @@ -81,6 +73,7 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa
81 73
82 @Override 74 @Override
83 public ListenableFuture<Void> save(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl) { 75 public ListenableFuture<Void> save(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl) {
  76 + savePartitionIfNotExist(tsKvEntry.getTs());
84 String strKey = tsKvEntry.getKey(); 77 String strKey = tsKvEntry.getKey();
85 Integer keyId = getOrSaveKeyId(strKey); 78 Integer keyId = getOrSaveKeyId(strKey);
86 TsKvEntity entity = new TsKvEntity(); 79 TsKvEntity entity = new TsKvEntity();
@@ -92,9 +85,23 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa @@ -92,9 +85,23 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa
92 entity.setLongValue(tsKvEntry.getLongValue().orElse(null)); 85 entity.setLongValue(tsKvEntry.getLongValue().orElse(null));
93 entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null)); 86 entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
94 entity.setJsonValue(tsKvEntry.getJsonValue().orElse(null)); 87 entity.setJsonValue(tsKvEntry.getJsonValue().orElse(null));
95 - PsqlPartition psqlPartition = toPartition(tsKvEntry.getTs());  
96 log.trace("Saving entity: {}", entity); 88 log.trace("Saving entity: {}", entity);
97 - return tsQueue.add(new EntityContainer(entity, psqlPartition.getPartitionDate())); 89 + return tsQueue.add(entity);
  90 + }
  91 +
  92 + private void savePartitionIfNotExist(long ts) {
  93 + if (!tsFormat.equals(SqlTsPartitionDate.INDEFINITE)) {
  94 + LocalDateTime time = LocalDateTime.ofInstant(Instant.ofEpochMilli(ts), ZoneOffset.UTC);
  95 + LocalDateTime localDateTimeStart = tsFormat.trancateTo(time);
  96 + long partitionStartTs = toMills(localDateTimeStart);
  97 + if (partitions.get(partitionStartTs) == null) {
  98 + LocalDateTime localDateTimeEnd = tsFormat.plusTo(localDateTimeStart);
  99 + long partitionEndTs = toMills(localDateTimeEnd);
  100 + ZonedDateTime zonedDateTime = localDateTimeStart.atZone(ZoneOffset.UTC);
  101 + String partitionDate = zonedDateTime.format(DateTimeFormatter.ofPattern(tsFormat.getPattern()));
  102 + savePartition(new PsqlPartition(partitionStartTs, partitionEndTs, partitionDate));
  103 + }
  104 + }
98 } 105 }
99 106
100 private void savePartition(PsqlPartition psqlPartition) { 107 private void savePartition(PsqlPartition psqlPartition) {
@@ -111,28 +118,6 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa @@ -111,28 +118,6 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa
111 } 118 }
112 } 119 }
113 120
114 - private PsqlPartition toPartition(long ts) {  
115 - if (tsFormat.equals(SqlTsPartitionDate.INDEFINITE)) {  
116 - return indefinitePartition;  
117 - } else {  
118 - LocalDateTime time = LocalDateTime.ofInstant(Instant.ofEpochMilli(ts), ZoneOffset.UTC);  
119 - LocalDateTime localDateTimeStart = tsFormat.trancateTo(time);  
120 - long partitionStartTs = toMills(localDateTimeStart);  
121 - PsqlPartition partition = partitions.get(partitionStartTs);  
122 - if (partition != null) {  
123 - return partition;  
124 - } else {  
125 - LocalDateTime localDateTimeEnd = tsFormat.plusTo(localDateTimeStart);  
126 - long partitionEndTs = toMills(localDateTimeEnd);  
127 - ZonedDateTime zonedDateTime = localDateTimeStart.atZone(ZoneOffset.UTC);  
128 - String partitionDate = zonedDateTime.format(DateTimeFormatter.ofPattern(tsFormat.getPattern()));  
129 - partition = new PsqlPartition(partitionStartTs, partitionEndTs, partitionDate);  
130 - savePartition(partition);  
131 - return partition;  
132 - }  
133 - }  
134 - }  
135 -  
136 private static long toMills(LocalDateTime time) { 121 private static long toMills(LocalDateTime time) {
137 return time.toInstant(ZoneOffset.UTC).toEpochMilli(); 122 return time.toInstant(ZoneOffset.UTC).toEpochMilli();
138 } 123 }
@@ -36,7 +36,6 @@ import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; @@ -36,7 +36,6 @@ import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity;
36 import org.thingsboard.server.dao.sql.TbSqlBlockingQueue; 36 import org.thingsboard.server.dao.sql.TbSqlBlockingQueue;
37 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; 37 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams;
38 import org.thingsboard.server.dao.sqlts.AbstractSqlTimeseriesDao; 38 import org.thingsboard.server.dao.sqlts.AbstractSqlTimeseriesDao;
39 -import org.thingsboard.server.dao.sqlts.EntityContainer;  
40 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; 39 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository;
41 import org.thingsboard.server.dao.timeseries.TimeseriesDao; 40 import org.thingsboard.server.dao.timeseries.TimeseriesDao;
42 import org.thingsboard.server.dao.util.TimescaleDBTsDao; 41 import org.thingsboard.server.dao.util.TimescaleDBTsDao;
@@ -64,7 +63,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -64,7 +63,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
64 @Autowired 63 @Autowired
65 protected InsertTsRepository<TimescaleTsKvEntity> insertRepository; 64 protected InsertTsRepository<TimescaleTsKvEntity> insertRepository;
66 65
67 - protected TbSqlBlockingQueue<EntityContainer<TimescaleTsKvEntity>> tsQueue; 66 + protected TbSqlBlockingQueue<TimescaleTsKvEntity> tsQueue;
68 67
69 @PostConstruct 68 @PostConstruct
70 protected void init() { 69 protected void init() {
@@ -175,7 +174,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -175,7 +174,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
175 entity.setJsonValue(tsKvEntry.getJsonValue().orElse(null)); 174 entity.setJsonValue(tsKvEntry.getJsonValue().orElse(null));
176 175
177 log.trace("Saving entity to timescale db: {}", entity); 176 log.trace("Saving entity to timescale db: {}", entity);
178 - return tsQueue.add(new EntityContainer(entity, null)); 177 + return tsQueue.add(entity);
179 } 178 }
180 179
181 @Override 180 @Override
@@ -35,6 +35,6 @@ public class PsqlPartition { @@ -35,6 +35,6 @@ public class PsqlPartition {
35 } 35 }
36 36
37 private String createStatement(long start, long end, String partitionDate) { 37 private String createStatement(long start, long end, String partitionDate) {
38 - return "CREATE TABLE IF NOT EXISTS " + TABLE_REGEX + partitionDate + " PARTITION OF ts_kv(PRIMARY KEY (entity_id, key, ts)) FOR VALUES FROM (" + start + ") TO (" + end + ")"; 38 + return "CREATE TABLE IF NOT EXISTS " + TABLE_REGEX + partitionDate + " PARTITION OF ts_kv FOR VALUES FROM (" + start + ") TO (" + end + ")";
39 } 39 }
40 } 40 }
@@ -23,7 +23,7 @@ import java.util.Optional; @@ -23,7 +23,7 @@ import java.util.Optional;
23 23
24 public enum SqlTsPartitionDate { 24 public enum SqlTsPartitionDate {
25 25
26 - MINUTES("yyyy_MM_dd_HH_mm", ChronoUnit.MINUTES), HOURS("yyyy_MM_dd_HH", ChronoUnit.HOURS), DAYS("yyyy_MM_dd", ChronoUnit.DAYS), MONTHS("yyyy_MM", ChronoUnit.MONTHS), YEARS("yyyy", ChronoUnit.YEARS), INDEFINITE("indefinite", ChronoUnit.FOREVER); 26 + DAYS("yyyy_MM_dd", ChronoUnit.DAYS), MONTHS("yyyy_MM", ChronoUnit.MONTHS), YEARS("yyyy", ChronoUnit.YEARS), INDEFINITE("indefinite", ChronoUnit.FOREVER);
27 27
28 private final String pattern; 28 private final String pattern;
29 private final transient TemporalUnit truncateUnit; 29 private final transient TemporalUnit truncateUnit;
@@ -44,10 +44,6 @@ public enum SqlTsPartitionDate { @@ -44,10 +44,6 @@ public enum SqlTsPartitionDate {
44 44
45 public LocalDateTime trancateTo(LocalDateTime time) { 45 public LocalDateTime trancateTo(LocalDateTime time) {
46 switch (this) { 46 switch (this) {
47 - case MINUTES:  
48 - return time.truncatedTo(ChronoUnit.MINUTES);  
49 - case HOURS:  
50 - return time.truncatedTo(ChronoUnit.HOURS);  
51 case DAYS: 47 case DAYS:
52 return time.truncatedTo(ChronoUnit.DAYS); 48 return time.truncatedTo(ChronoUnit.DAYS);
53 case MONTHS: 49 case MONTHS:
@@ -63,10 +59,6 @@ public enum SqlTsPartitionDate { @@ -63,10 +59,6 @@ public enum SqlTsPartitionDate {
63 59
64 public LocalDateTime plusTo(LocalDateTime time) { 60 public LocalDateTime plusTo(LocalDateTime time) {
65 switch (this) { 61 switch (this) {
66 - case MINUTES:  
67 - return time.plusMinutes(1);  
68 - case HOURS:  
69 - return time.plusHours(1);  
70 case DAYS: 62 case DAYS:
71 return time.plusDays(1); 63 return time.plusDays(1);
72 case MONTHS: 64 case MONTHS:
@@ -23,7 +23,8 @@ CREATE TABLE IF NOT EXISTS ts_kv @@ -23,7 +23,8 @@ CREATE TABLE IF NOT EXISTS ts_kv
23 str_v varchar(10000000), 23 str_v varchar(10000000),
24 long_v bigint, 24 long_v bigint,
25 dbl_v double precision, 25 dbl_v double precision,
26 - json_v json 26 + json_v json,
  27 + CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts)
27 ) PARTITION BY RANGE (ts); 28 ) PARTITION BY RANGE (ts);
28 29
29 CREATE TABLE IF NOT EXISTS ts_kv_latest 30 CREATE TABLE IF NOT EXISTS ts_kv_latest
@@ -31,14 +31,14 @@ public class JpaDaoTestSuite { @@ -31,14 +31,14 @@ public class JpaDaoTestSuite {
31 @ClassRule 31 @ClassRule
32 public static CustomSqlUnit sqlUnit = new CustomSqlUnit( 32 public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
33 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/system-data.sql"), 33 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/system-data.sql"),
34 - "sql/drop-all-tables.sql", 34 + "sql/hsql/drop-all-tables.sql",
35 "sql-test.properties" 35 "sql-test.properties"
36 ); 36 );
37 37
38 // @ClassRule 38 // @ClassRule
39 // public static CustomSqlUnit sqlUnit = new CustomSqlUnit( 39 // public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
40 // Arrays.asList("sql/schema-ts-psql.sql", "sql/schema-entities.sql", "sql/system-data.sql"), 40 // Arrays.asList("sql/schema-ts-psql.sql", "sql/schema-entities.sql", "sql/system-data.sql"),
41 -// "sql/drop-all-tables.sql", 41 +// "sql/psql/drop-all-tables.sql",
42 // "sql-test.properties" 42 // "sql-test.properties"
43 // ); 43 // );
44 44
@@ -31,14 +31,14 @@ public class SqlDaoServiceTestSuite { @@ -31,14 +31,14 @@ public class SqlDaoServiceTestSuite {
31 @ClassRule 31 @ClassRule
32 public static CustomSqlUnit sqlUnit = new CustomSqlUnit( 32 public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
33 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql", "sql/system-test.sql"), 33 Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql", "sql/system-test.sql"),
34 - "sql/drop-all-tables.sql", 34 + "sql/hsql/drop-all-tables.sql",
35 "sql-test.properties" 35 "sql-test.properties"
36 ); 36 );
37 37
38 // @ClassRule 38 // @ClassRule
39 // public static CustomSqlUnit sqlUnit = new CustomSqlUnit( 39 // public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
40 // Arrays.asList("sql/schema-ts-psql.sql", "sql/schema-entities.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql", "sql/system-test.sql"), 40 // Arrays.asList("sql/schema-ts-psql.sql", "sql/schema-entities.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql", "sql/system-test.sql"),
41 -// "sql/drop-all-tables.sql", 41 +// "sql/psql/drop-all-tables.sql",
42 // "sql-test.properties" 42 // "sql-test.properties"
43 // ); 43 // );
44 44
dao/src/test/resources/sql/hsql/drop-all-tables.sql renamed from dao/src/test/resources/sql/drop-all-tables.sql
  1 +DROP TABLE IF EXISTS admin_settings;
  2 +DROP TABLE IF EXISTS alarm;
  3 +DROP TABLE IF EXISTS asset;
  4 +DROP TABLE IF EXISTS audit_log;
  5 +DROP TABLE IF EXISTS attribute_kv;
  6 +DROP TABLE IF EXISTS component_descriptor;
  7 +DROP TABLE IF EXISTS customer;
  8 +DROP TABLE IF EXISTS dashboard;
  9 +DROP TABLE IF EXISTS device;
  10 +DROP TABLE IF EXISTS device_credentials;
  11 +DROP TABLE IF EXISTS event;
  12 +DROP TABLE IF EXISTS relation;
  13 +DROP TABLE IF EXISTS tb_user;
  14 +DROP TABLE IF EXISTS tenant;
  15 +DROP TABLE IF EXISTS ts_kv;
  16 +DROP TABLE IF EXISTS ts_kv_latest;
  17 +DROP TABLE IF EXISTS ts_kv_dictionary;
  18 +DROP TABLE IF EXISTS user_credentials;
  19 +DROP TABLE IF EXISTS widget_type;
  20 +DROP TABLE IF EXISTS widgets_bundle;
  21 +DROP TABLE IF EXISTS rule_node;
  22 +DROP TABLE IF EXISTS rule_chain;
  23 +DROP TABLE IF EXISTS entity_view;
  24 +DROP TABLE IF EXISTS tb_schema_settings;
@@ -14,9 +14,11 @@ DROP TABLE IF EXISTS tb_user; @@ -14,9 +14,11 @@ DROP TABLE IF EXISTS tb_user;
14 DROP TABLE IF EXISTS tenant; 14 DROP TABLE IF EXISTS tenant;
15 DROP TABLE IF EXISTS ts_kv; 15 DROP TABLE IF EXISTS ts_kv;
16 DROP TABLE IF EXISTS ts_kv_latest; 16 DROP TABLE IF EXISTS ts_kv_latest;
  17 +DROP TABLE IF EXISTS ts_kv_dictionary;
17 DROP TABLE IF EXISTS user_credentials; 18 DROP TABLE IF EXISTS user_credentials;
18 DROP TABLE IF EXISTS widget_type; 19 DROP TABLE IF EXISTS widget_type;
19 DROP TABLE IF EXISTS widgets_bundle; 20 DROP TABLE IF EXISTS widgets_bundle;
20 DROP TABLE IF EXISTS rule_node; 21 DROP TABLE IF EXISTS rule_node;
21 DROP TABLE IF EXISTS rule_chain; 22 DROP TABLE IF EXISTS rule_chain;
22 -DROP TABLE IF EXISTS entity_view;  
  23 +DROP TABLE IF EXISTS entity_view;
  24 +DROP TABLE IF EXISTS tb_schema_settings;
@@ -59,7 +59,7 @@ JsInvokeMessageProcessor.prototype.onJsInvokeMessage = function(message) { @@ -59,7 +59,7 @@ JsInvokeMessageProcessor.prototype.onJsInvokeMessage = function(message) {
59 } else if (request.releaseRequest) { 59 } else if (request.releaseRequest) {
60 this.processReleaseRequest(requestId, responseTopic, headers, request.releaseRequest); 60 this.processReleaseRequest(requestId, responseTopic, headers, request.releaseRequest);
61 } else { 61 } else {
62 - logger.error('[%s] Unknown request recevied!', requestId); 62 + logger.error('[%s] Unknown request received!', requestId);
63 } 63 }
64 64
65 } catch (err) { 65 } catch (err) {
@@ -41,8 +41,6 @@ function KafkaProducer() { @@ -41,8 +41,6 @@ function KafkaProducer() {
41 } 41 }
42 } 42 }
43 43
44 - let headersData = headers.data;  
45 - headersData = Object.fromEntries(Object.entries(headersData).map(([key, value]) => [key, Buffer.from(value)]));  
46 return producer.send( 44 return producer.send(
47 { 45 {
48 topic: responseTopic, 46 topic: responseTopic,
@@ -50,7 +48,7 @@ function KafkaProducer() { @@ -50,7 +48,7 @@ function KafkaProducer() {
50 { 48 {
51 key: scriptId, 49 key: scriptId,
52 value: rawResponse, 50 value: rawResponse,
53 - headers: headersData 51 + headers: headers.data
54 } 52 }
55 ] 53 ]
56 }); 54 });
@@ -96,15 +94,10 @@ function KafkaProducer() { @@ -96,15 +94,10 @@ function KafkaProducer() {
96 eachMessage: async ({topic, partition, message}) => { 94 eachMessage: async ({topic, partition, message}) => {
97 let headers = message.headers; 95 let headers = message.headers;
98 let key = message.key; 96 let key = message.key;
99 - let data = message.value;  
100 let msg = {}; 97 let msg = {};
101 -  
102 - headers = Object.fromEntries(  
103 - Object.entries(headers).map(([key, value]) => [key, [...value]]));  
104 -  
105 msg.key = key.toString('utf8'); 98 msg.key = key.toString('utf8');
106 - msg.data = [...data];  
107 - msg.headers = {data: headers} 99 + msg.data = message.value;
  100 + msg.headers = {data: headers};
108 messageProcessor.onJsInvokeMessage(msg); 101 messageProcessor.onJsInvokeMessage(msg);
109 }, 102 },
110 }); 103 });
@@ -38,7 +38,7 @@ import java.io.IOException; @@ -38,7 +38,7 @@ import java.io.IOException;
38 @Slf4j 38 @Slf4j
39 @RuleNode( 39 @RuleNode(
40 type = ComponentType.FILTER, 40 type = ComponentType.FILTER,
41 - name = "checks alarm status", 41 + name = "check alarm status",
42 configClazz = TbCheckAlarmStatusNodeConfig.class, 42 configClazz = TbCheckAlarmStatusNodeConfig.class,
43 relationTypes = {"True", "False"}, 43 relationTypes = {"True", "False"},
44 nodeDescription = "Checks alarm status.", 44 nodeDescription = "Checks alarm status.",
@@ -386,6 +386,26 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, time @@ -386,6 +386,26 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, time
386 deferred.reject(); 386 deferred.reject();
387 } 387 }
388 procceedJwtTokenValidate(); 388 procceedJwtTokenValidate();
  389 + } else if (locationSearch.username && locationSearch.password) {
  390 + var user = {};
  391 + user.name = locationSearch.username;
  392 + user.password = locationSearch.password;
  393 + $location.search('username', null);
  394 + $location.search('password', null);
  395 +
  396 + loginService.login(user).then(function success(response) {
  397 + var token = response.data.token;
  398 + var refreshToken = response.data.refreshToken;
  399 + try {
  400 + updateAndValidateToken(token, 'jwt_token', false);
  401 + updateAndValidateToken(refreshToken, 'refresh_token', false);
  402 + } catch (e) {
  403 + deferred.reject();
  404 + }
  405 + procceedJwtTokenValidate();
  406 + }, function fail() {
  407 + deferred.reject();
  408 + });
389 } else { 409 } else {
390 procceedJwtTokenValidate(); 410 procceedJwtTokenValidate();
391 } 411 }
@@ -20,7 +20,7 @@ import logoSvg from '../../svg/logo_title_white.svg'; @@ -20,7 +20,7 @@ import logoSvg from '../../svg/logo_title_white.svg';
20 /* eslint-enable import/no-unresolved, import/default */ 20 /* eslint-enable import/no-unresolved, import/default */
21 21
22 /*@ngInject*/ 22 /*@ngInject*/
23 -export default function LoginController(toast, loginService, userService, types, $state, $stateParams/*, $rootScope, $log, $translate*/) { 23 +export default function LoginController(toast, loginService, userService, types, $state/*, $rootScope, $log, $translate*/) {
24 var vm = this; 24 var vm = this;
25 25
26 vm.logoSvg = logoSvg; 26 vm.logoSvg = logoSvg;
@@ -32,12 +32,6 @@ export default function LoginController(toast, loginService, userService, types, @@ -32,12 +32,6 @@ export default function LoginController(toast, loginService, userService, types,
32 32
33 vm.login = login; 33 vm.login = login;
34 34
35 - if ($stateParams.username && $stateParams.password) {  
36 - vm.user.name = $stateParams.username;  
37 - vm.user.password = $stateParams.password;  
38 - doLogin();  
39 - }  
40 -  
41 function doLogin() { 35 function doLogin() {
42 loginService.login(vm.user).then(function success(response) { 36 loginService.login(vm.user).then(function success(response) {
43 var token = response.data.token; 37 var token = response.data.token;
@@ -25,7 +25,7 @@ import createPasswordTemplate from './create-password.tpl.html'; @@ -25,7 +25,7 @@ import createPasswordTemplate from './create-password.tpl.html';
25 /*@ngInject*/ 25 /*@ngInject*/
26 export default function LoginRoutes($stateProvider) { 26 export default function LoginRoutes($stateProvider) {
27 $stateProvider.state('login', { 27 $stateProvider.state('login', {
28 - url: '/login?username&password', 28 + url: '/login',
29 module: 'public', 29 module: 'public',
30 views: { 30 views: {
31 "@": { 31 "@": {