Commit 237c2880501db168bde86588ffc12132a88dd65b
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 | } |
dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/timescale/TimescaleInsertTsRepository.java
@@ -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 | "@": { |