Showing
61 changed files
with
161 additions
and
96 deletions
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>application</artifactId> | ... | ... |
... | ... | @@ -166,7 +166,7 @@ |
166 | 166 | "controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'state'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.typeParameters = function() {\n return {\n stateData: true\n };\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.getSettingsSchema = function() {\n return TbFlot.settingsSchema('graph');\n}\n\nself.getDataKeySettingsSchema = function() {\n return TbFlot.datakeySettingsSchema(true, 'graph');\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n", |
167 | 167 | "settingsSchema": "{}", |
168 | 168 | "dataKeySettingsSchema": "{}", |
169 | - "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Switch 1\",\"color\":\"#2196f3\",\"settings\":{\"showLines\":true,\"fillLines\":true,\"showPoints\":false,\"axisPosition\":\"left\",\"showSeparateAxis\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"return Math.random() > 0.5 ? 1 : 0;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Switch 2\",\"color\":\"#ffc107\",\"settings\":{\"showLines\":true,\"fillLines\":false,\"showPoints\":false,\"axisPosition\":\"left\"},\"_hash\":0.12775350966079668,\"funcBody\":\"return Math.random() <= 0.5 ? 1 : 0;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"shadowSize\":4,\"fontColor\":\"#545454\",\"fontSize\":10,\"xaxis\":{\"showLabels\":true,\"color\":\"#545454\"},\"yaxis\":{\"showLabels\":true,\"color\":\"#545454\",\"ticksFormatter\":\"if (value > 0 && value <= 1) {\\n return 'On';\\n} else if (value === 0) {\\n return 'Off';\\n} else {\\n return '';\\n}\"},\"grid\":{\"color\":\"#545454\",\"tickColor\":\"#DDDDDD\",\"verticalLines\":true,\"horizontalLines\":true,\"outlineWidth\":1},\"stack\":false,\"tooltipIndividual\":false,\"tooltipValueFormatter\":\"if (value > 0 && value <= 1) {\\n return 'On';\\n} else if (value === 0) {\\n return 'Off';\\n} else {\\n return '';\\n}\",\"smoothLines\":false},\"title\":\"State Chart\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"mobileHeight\":null,\"widgetStyle\":{},\"useDashboardTimewindow\":true,\"showLegend\":true,\"actions\":{},\"legendConfig\":{\"position\":\"bottom\",\"showMin\":false,\"showMax\":false,\"showAvg\":false,\"showTotal\":false}}" | |
169 | + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Switch 1\",\"color\":\"#2196f3\",\"settings\":{\"showLines\":true,\"fillLines\":true,\"showPoints\":false,\"axisPosition\":\"left\",\"showSeparateAxis\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"return Math.random() > 0.5 ? 1 : 0;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Switch 2\",\"color\":\"#ffc107\",\"settings\":{\"showLines\":true,\"fillLines\":false,\"showPoints\":false,\"axisPosition\":\"left\"},\"_hash\":0.12775350966079668,\"funcBody\":\"return Math.random() <= 0.5 ? 1 : 0;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"shadowSize\":4,\"fontColor\":\"#545454\",\"fontSize\":10,\"xaxis\":{\"showLabels\":true,\"color\":\"#545454\"},\"yaxis\":{\"showLabels\":true,\"color\":\"#545454\",\"ticksFormatter\":\"if (value > 0 && value <= 1) {\\n return 'On';\\n} else if (value === 0) {\\n return 'Off';\\n} else {\\n return '';\\n}\"},\"grid\":{\"color\":\"#545454\",\"tickColor\":\"#DDDDDD\",\"verticalLines\":true,\"horizontalLines\":true,\"outlineWidth\":1},\"stack\":false,\"tooltipIndividual\":false,\"tooltipValueFormatter\":\"if (value > 0 && value <= 1) {\\n return 'On';\\n} else if (value === 0) {\\n return 'Off';\\n} else {\\n return '';\\n}\",\"smoothLines\":false},\"title\":\"State Chart\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"mobileHeight\":null,\"widgetStyle\":{},\"useDashboardTimewindow\":true,\"showLegend\":true,\"actions\":{},\"legendConfig\":{\"direction\":\"column\",\",position\":\"bottom\",\"showMin\":false,\"showMax\":false,\"showAvg\":false,\"showTotal\":false}}" | |
170 | 170 | } |
171 | 171 | } |
172 | 172 | ] | ... | ... |
... | ... | @@ -39,8 +39,7 @@ public abstract class AbstractCleanUpService { |
39 | 39 | protected String dbPassword; |
40 | 40 | |
41 | 41 | protected long executeQuery(Connection conn, String query) throws SQLException { |
42 | - try (Statement statement = conn.createStatement()) { | |
43 | - ResultSet resultSet = statement.executeQuery(query); | |
42 | + try (Statement statement = conn.createStatement(); ResultSet resultSet = statement.executeQuery(query)) { | |
44 | 43 | if (log.isDebugEnabled()) { |
45 | 44 | getWarnings(statement); |
46 | 45 | } | ... | ... |
... | ... | @@ -33,4 +33,4 @@ public class TimescaleTimeseriesCleanUpService extends AbstractTimeseriesCleanUp |
33 | 33 | long totalEntitiesTelemetryRemoved = executeQuery(connection, "call cleanup_timeseries_by_ttl('" + ModelConstants.NULL_UUID + "'," + systemTtl + ", 0);"); |
34 | 34 | log.info("Total telemetry removed stats by TTL for entities: [{}]", totalEntitiesTelemetryRemoved); |
35 | 35 | } |
36 | -} | |
\ No newline at end of file | ||
36 | +} | ... | ... |
... | ... | @@ -284,6 +284,8 @@ sql: |
284 | 284 | batch_max_delay: "${SQL_TS_LATEST_BATCH_MAX_DELAY_MS:100}" |
285 | 285 | stats_print_interval_ms: "${SQL_TS_LATEST_BATCH_STATS_PRINT_MS:10000}" |
286 | 286 | batch_threads: "${SQL_TS_LATEST_BATCH_THREADS:4}" |
287 | + # Specify whether to sort entities before batch update. Should be enabled for cluster mode to avoid deadlocks | |
288 | + batch_sort: "${SQL_BATCH_SORT:false}" | |
287 | 289 | # Specify whether to remove null characters from strValue of attributes and timeseries before insert |
288 | 290 | remove_null_chars: "${SQL_REMOVE_NULL_CHARS:true}" |
289 | 291 | # Specify whether to log database queries and their parameters generated by entity query repository |
... | ... | @@ -651,11 +653,11 @@ queue: |
651 | 653 | security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" |
652 | 654 | other: |
653 | 655 | topic-properties: |
654 | - rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
655 | - core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
656 | - transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
657 | - notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
658 | - js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}" | |
656 | + rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
657 | + core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
658 | + transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
659 | + notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
660 | + js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}" | |
659 | 661 | aws_sqs: |
660 | 662 | use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}" |
661 | 663 | access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}" | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>common</artifactId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -37,6 +37,7 @@ public class TbKafkaAdmin implements TbQueueAdmin { |
37 | 37 | private final AdminClient client; |
38 | 38 | private final Map<String, String> topicConfigs; |
39 | 39 | private final Set<String> topics = ConcurrentHashMap.newKeySet(); |
40 | + private final int numPartitions; | |
40 | 41 | |
41 | 42 | private final short replicationFactor; |
42 | 43 | |
... | ... | @@ -50,6 +51,13 @@ public class TbKafkaAdmin implements TbQueueAdmin { |
50 | 51 | log.error("Failed to get all topics.", e); |
51 | 52 | } |
52 | 53 | |
54 | + String numPartitionsStr = topicConfigs.get("partitions"); | |
55 | + if (numPartitionsStr != null) { | |
56 | + numPartitions = Integer.parseInt(numPartitionsStr); | |
57 | + topicConfigs.remove("partitions"); | |
58 | + } else { | |
59 | + numPartitions = 1; | |
60 | + } | |
53 | 61 | replicationFactor = settings.getReplicationFactor(); |
54 | 62 | } |
55 | 63 | |
... | ... | @@ -59,7 +67,7 @@ public class TbKafkaAdmin implements TbQueueAdmin { |
59 | 67 | return; |
60 | 68 | } |
61 | 69 | try { |
62 | - NewTopic newTopic = new NewTopic(topic, 1, replicationFactor).configs(topicConfigs); | |
70 | + NewTopic newTopic = new NewTopic(topic, numPartitions, replicationFactor).configs(topicConfigs); | |
63 | 71 | createTopic(newTopic).values().get(topic).get(); |
64 | 72 | topics.add(topic); |
65 | 73 | } catch (ExecutionException ee) { | ... | ... |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | <modelVersion>4.0.0</modelVersion> |
23 | 23 | <parent> |
24 | 24 | <groupId>org.thingsboard</groupId> |
25 | - <version>3.1.2-SNAPSHOT</version> | |
25 | + <version>3.2.0-SNAPSHOT</version> | |
26 | 26 | <artifactId>common</artifactId> |
27 | 27 | </parent> |
28 | 28 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.common</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>dao</artifactId> | ... | ... |
... | ... | @@ -22,6 +22,7 @@ import org.thingsboard.common.util.ThingsBoardThreadFactory; |
22 | 22 | import org.thingsboard.server.common.stats.MessagesStats; |
23 | 23 | |
24 | 24 | import java.util.ArrayList; |
25 | +import java.util.Comparator; | |
25 | 26 | import java.util.List; |
26 | 27 | import java.util.concurrent.BlockingQueue; |
27 | 28 | import java.util.concurrent.ExecutorService; |
... | ... | @@ -30,6 +31,7 @@ import java.util.concurrent.LinkedBlockingQueue; |
30 | 31 | import java.util.concurrent.TimeUnit; |
31 | 32 | import java.util.function.Consumer; |
32 | 33 | import java.util.stream.Collectors; |
34 | +import java.util.stream.Stream; | |
33 | 35 | |
34 | 36 | @Slf4j |
35 | 37 | public class TbSqlBlockingQueue<E> implements TbSqlQueue<E> { |
... | ... | @@ -46,7 +48,7 @@ public class TbSqlBlockingQueue<E> implements TbSqlQueue<E> { |
46 | 48 | } |
47 | 49 | |
48 | 50 | @Override |
49 | - public void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction, int index) { | |
51 | + public void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction, Comparator<E> batchUpdateComparator, int index) { | |
50 | 52 | executor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("sql-queue-" + index + "-" + params.getLogName().toLowerCase())); |
51 | 53 | executor.submit(() -> { |
52 | 54 | String logName = params.getLogName(); |
... | ... | @@ -65,7 +67,11 @@ public class TbSqlBlockingQueue<E> implements TbSqlQueue<E> { |
65 | 67 | queue.drainTo(entities, batchSize - 1); |
66 | 68 | boolean fullPack = entities.size() == batchSize; |
67 | 69 | log.debug("[{}] Going to save {} entities", logName, entities.size()); |
68 | - saveFunction.accept(entities.stream().map(TbSqlQueueElement::getEntity).collect(Collectors.toList())); | |
70 | + Stream<E> entitiesStream = entities.stream().map(TbSqlQueueElement::getEntity); | |
71 | + saveFunction.accept( | |
72 | + (params.isBatchSortEnabled() ? entitiesStream.sorted(batchUpdateComparator) : entitiesStream) | |
73 | + .collect(Collectors.toList()) | |
74 | + ); | |
69 | 75 | entities.forEach(v -> v.getFuture().set(null)); |
70 | 76 | stats.incrementSuccessful(entities.size()); |
71 | 77 | if (!fullPack) { | ... | ... |
... | ... | @@ -21,6 +21,7 @@ import lombok.extern.slf4j.Slf4j; |
21 | 21 | import org.thingsboard.server.common.stats.MessagesStats; |
22 | 22 | import org.thingsboard.server.common.stats.StatsFactory; |
23 | 23 | |
24 | +import java.util.Comparator; | |
24 | 25 | import java.util.List; |
25 | 26 | import java.util.concurrent.CopyOnWriteArrayList; |
26 | 27 | import java.util.function.Consumer; |
... | ... | @@ -36,12 +37,20 @@ public class TbSqlBlockingQueueWrapper<E> { |
36 | 37 | private final int maxThreads; |
37 | 38 | private final StatsFactory statsFactory; |
38 | 39 | |
39 | - public void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction) { | |
40 | + /** | |
41 | + * Starts TbSqlBlockingQueues. | |
42 | + * | |
43 | + * @param logExecutor executor that will be printing logs and statistics | |
44 | + * @param saveFunction function to save entities in database | |
45 | + * @param batchUpdateComparator comparator to sort entities by primary key to avoid deadlocks in cluster mode | |
46 | + * NOTE: you must use all of primary key parts in your comparator | |
47 | + */ | |
48 | + public void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction, Comparator<E> batchUpdateComparator) { | |
40 | 49 | for (int i = 0; i < maxThreads; i++) { |
41 | 50 | MessagesStats stats = statsFactory.createMessagesStats(params.getStatsNamePrefix() + ".queue." + i); |
42 | 51 | TbSqlBlockingQueue<E> queue = new TbSqlBlockingQueue<>(params, stats); |
43 | 52 | queues.add(queue); |
44 | - queue.init(logExecutor, saveFunction, i); | |
53 | + queue.init(logExecutor, saveFunction, batchUpdateComparator, i); | |
45 | 54 | } |
46 | 55 | } |
47 | 56 | ... | ... |
... | ... | @@ -17,12 +17,13 @@ package org.thingsboard.server.dao.sql; |
17 | 17 | |
18 | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | 19 | |
20 | +import java.util.Comparator; | |
20 | 21 | import java.util.List; |
21 | 22 | import java.util.function.Consumer; |
22 | 23 | |
23 | 24 | public interface TbSqlQueue<E> { |
24 | 25 | |
25 | - void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction, int queueIndex); | |
26 | + void init(ScheduledLogExecutorComponent logExecutor, Consumer<List<E>> saveFunction, Comparator<E> batchUpdateComparator, int queueIndex); | |
26 | 27 | |
27 | 28 | void destroy(); |
28 | 29 | ... | ... |
... | ... | @@ -38,6 +38,7 @@ import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; |
38 | 38 | import javax.annotation.PostConstruct; |
39 | 39 | import javax.annotation.PreDestroy; |
40 | 40 | import java.util.Collection; |
41 | +import java.util.Comparator; | |
41 | 42 | import java.util.List; |
42 | 43 | import java.util.Optional; |
43 | 44 | import java.util.function.Function; |
... | ... | @@ -71,6 +72,9 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl |
71 | 72 | @Value("${sql.attributes.batch_threads:4}") |
72 | 73 | private int batchThreads; |
73 | 74 | |
75 | + @Value("${sql.batch_sort:false}") | |
76 | + private boolean batchSortEnabled; | |
77 | + | |
74 | 78 | private TbSqlBlockingQueueWrapper<AttributeKvEntity> queue; |
75 | 79 | |
76 | 80 | @PostConstruct |
... | ... | @@ -81,11 +85,17 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl |
81 | 85 | .maxDelay(maxDelay) |
82 | 86 | .statsPrintIntervalMs(statsPrintIntervalMs) |
83 | 87 | .statsNamePrefix("attributes") |
88 | + .batchSortEnabled(batchSortEnabled) | |
84 | 89 | .build(); |
85 | 90 | |
86 | 91 | Function<AttributeKvEntity, Integer> hashcodeFunction = entity -> entity.getId().getEntityId().hashCode(); |
87 | 92 | queue = new TbSqlBlockingQueueWrapper<>(params, hashcodeFunction, batchThreads, statsFactory); |
88 | - queue.init(logExecutor, v -> attributeKvInsertRepository.saveOrUpdate(v)); | |
93 | + queue.init(logExecutor, v -> attributeKvInsertRepository.saveOrUpdate(v), | |
94 | + Comparator.comparing((AttributeKvEntity attributeKvEntity) -> attributeKvEntity.getId().getEntityId()) | |
95 | + .thenComparing(attributeKvEntity -> attributeKvEntity.getId().getEntityType().name()) | |
96 | + .thenComparing(attributeKvEntity -> attributeKvEntity.getId().getAttributeType()) | |
97 | + .thenComparing(attributeKvEntity -> attributeKvEntity.getId().getAttributeKey()) | |
98 | + ); | |
89 | 99 | } |
90 | 100 | |
91 | 101 | @PreDestroy | ... | ... |
... | ... | @@ -21,6 +21,7 @@ import com.google.common.util.concurrent.MoreExecutors; |
21 | 21 | import com.google.common.util.concurrent.SettableFuture; |
22 | 22 | import lombok.extern.slf4j.Slf4j; |
23 | 23 | import org.springframework.beans.factory.annotation.Autowired; |
24 | +import org.springframework.beans.factory.annotation.Value; | |
24 | 25 | import org.springframework.data.domain.PageRequest; |
25 | 26 | import org.springframework.data.domain.Sort; |
26 | 27 | import org.thingsboard.server.common.data.id.EntityId; |
... | ... | @@ -31,6 +32,7 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery; |
31 | 32 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
32 | 33 | import org.thingsboard.server.common.stats.StatsFactory; |
33 | 34 | import org.thingsboard.server.dao.DaoUtil; |
35 | +import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; | |
34 | 36 | import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; |
35 | 37 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; |
36 | 38 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; |
... | ... | @@ -40,9 +42,7 @@ import org.thingsboard.server.dao.timeseries.TimeseriesDao; |
40 | 42 | |
41 | 43 | import javax.annotation.PostConstruct; |
42 | 44 | import javax.annotation.PreDestroy; |
43 | -import java.util.ArrayList; | |
44 | -import java.util.List; | |
45 | -import java.util.Optional; | |
45 | +import java.util.*; | |
46 | 46 | import java.util.concurrent.CompletableFuture; |
47 | 47 | import java.util.function.Function; |
48 | 48 | import java.util.stream.Collectors; |
... | ... | @@ -68,11 +68,16 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq |
68 | 68 | .maxDelay(tsMaxDelay) |
69 | 69 | .statsPrintIntervalMs(tsStatsPrintIntervalMs) |
70 | 70 | .statsNamePrefix("ts") |
71 | + .batchSortEnabled(batchSortEnabled) | |
71 | 72 | .build(); |
72 | 73 | |
73 | 74 | Function<TsKvEntity, Integer> hashcodeFunction = entity -> entity.getEntityId().hashCode(); |
74 | 75 | tsQueue = new TbSqlBlockingQueueWrapper<>(tsParams, hashcodeFunction, tsBatchThreads, statsFactory); |
75 | - tsQueue.init(logExecutor, v -> insertRepository.saveOrUpdate(v)); | |
76 | + tsQueue.init(logExecutor, v -> insertRepository.saveOrUpdate(v), | |
77 | + Comparator.comparing((Function<TsKvEntity, UUID>) AbstractTsKvEntity::getEntityId) | |
78 | + .thenComparing(AbstractTsKvEntity::getKey) | |
79 | + .thenComparing(AbstractTsKvEntity::getTs) | |
80 | + ); | |
76 | 81 | } |
77 | 82 | |
78 | 83 | @PreDestroy | ... | ... |
... | ... | @@ -53,6 +53,9 @@ public abstract class AbstractSqlTimeseriesDao extends BaseAbstractSqlTimeseries |
53 | 53 | @Value("${sql.timescale.batch_threads:4}") |
54 | 54 | protected int timescaleBatchThreads; |
55 | 55 | |
56 | + @Value("${sql.batch_sort:false}") | |
57 | + protected boolean batchSortEnabled; | |
58 | + | |
56 | 59 | protected ListenableFuture<List<TsKvEntry>> processFindAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries) { |
57 | 60 | List<ListenableFuture<List<TsKvEntry>>> futures = queries |
58 | 61 | .stream() | ... | ... |
... | ... | @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.kv.StringDataEntry; |
35 | 35 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
36 | 36 | import org.thingsboard.server.common.stats.StatsFactory; |
37 | 37 | import org.thingsboard.server.dao.DaoUtil; |
38 | +import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; | |
38 | 39 | import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestCompositeKey; |
39 | 40 | import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; |
40 | 41 | import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; |
... | ... | @@ -50,12 +51,10 @@ import org.thingsboard.server.dao.util.SqlTsLatestAnyDao; |
50 | 51 | import javax.annotation.Nullable; |
51 | 52 | import javax.annotation.PostConstruct; |
52 | 53 | import javax.annotation.PreDestroy; |
53 | -import java.util.ArrayList; | |
54 | -import java.util.HashMap; | |
55 | -import java.util.List; | |
56 | -import java.util.Map; | |
57 | -import java.util.Optional; | |
54 | +import java.util.*; | |
58 | 55 | import java.util.concurrent.ExecutionException; |
56 | +import java.util.function.Function; | |
57 | +import java.util.stream.Collectors; | |
59 | 58 | |
60 | 59 | @Slf4j |
61 | 60 | @Component |
... | ... | @@ -90,6 +89,9 @@ public class SqlTimeseriesLatestDao extends BaseAbstractSqlTimeseriesDao impleme |
90 | 89 | @Value("${sql.ts_latest.batch_threads:4}") |
91 | 90 | private int tsLatestBatchThreads; |
92 | 91 | |
92 | + @Value("${sql.batch_sort:false}") | |
93 | + protected boolean batchSortEnabled; | |
94 | + | |
93 | 95 | @Autowired |
94 | 96 | protected ScheduledLogExecutorComponent logExecutor; |
95 | 97 | |
... | ... | @@ -104,6 +106,7 @@ public class SqlTimeseriesLatestDao extends BaseAbstractSqlTimeseriesDao impleme |
104 | 106 | .maxDelay(tsLatestMaxDelay) |
105 | 107 | .statsPrintIntervalMs(tsLatestStatsPrintIntervalMs) |
106 | 108 | .statsNamePrefix("ts.latest") |
109 | + .batchSortEnabled(false) | |
107 | 110 | .build(); |
108 | 111 | |
109 | 112 | java.util.function.Function<TsKvLatestEntity, Integer> hashcodeFunction = entity -> entity.getEntityId().hashCode(); |
... | ... | @@ -113,14 +116,15 @@ public class SqlTimeseriesLatestDao extends BaseAbstractSqlTimeseriesDao impleme |
113 | 116 | Map<TsKey, TsKvLatestEntity> trueLatest = new HashMap<>(); |
114 | 117 | v.forEach(ts -> { |
115 | 118 | TsKey key = new TsKey(ts.getEntityId(), ts.getKey()); |
116 | - TsKvLatestEntity old = trueLatest.get(key); | |
117 | - if (old == null || old.getTs() < ts.getTs()) { | |
118 | - trueLatest.put(key, ts); | |
119 | - } | |
119 | + trueLatest.merge(key, ts, (oldTs, newTs) -> oldTs.getTs() < newTs.getTs() ? newTs : oldTs); | |
120 | 120 | }); |
121 | 121 | List<TsKvLatestEntity> latestEntities = new ArrayList<>(trueLatest.values()); |
122 | + if (batchSortEnabled) { | |
123 | + latestEntities.sort(Comparator.comparing((Function<TsKvLatestEntity, UUID>) AbstractTsKvEntity::getEntityId) | |
124 | + .thenComparingInt(AbstractTsKvEntity::getKey)); | |
125 | + } | |
122 | 126 | insertLatestTsRepository.saveOrUpdate(latestEntities); |
123 | - }); | |
127 | + }, (l, r) -> 0); | |
124 | 128 | } |
125 | 129 | |
126 | 130 | @PreDestroy | ... | ... |
... | ... | @@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery; |
33 | 33 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
34 | 34 | import org.thingsboard.server.common.stats.StatsFactory; |
35 | 35 | import org.thingsboard.server.dao.DaoUtil; |
36 | +import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; | |
36 | 37 | import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; |
37 | 38 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; |
38 | 39 | import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; |
... | ... | @@ -43,11 +44,7 @@ import org.thingsboard.server.dao.util.TimescaleDBTsDao; |
43 | 44 | |
44 | 45 | import javax.annotation.PostConstruct; |
45 | 46 | import javax.annotation.PreDestroy; |
46 | -import java.util.ArrayList; | |
47 | -import java.util.Collections; | |
48 | -import java.util.List; | |
49 | -import java.util.Optional; | |
50 | -import java.util.UUID; | |
47 | +import java.util.*; | |
51 | 48 | import java.util.concurrent.CompletableFuture; |
52 | 49 | import java.util.function.Function; |
53 | 50 | |
... | ... | @@ -78,12 +75,17 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements |
78 | 75 | .maxDelay(tsMaxDelay) |
79 | 76 | .statsPrintIntervalMs(tsStatsPrintIntervalMs) |
80 | 77 | .statsNamePrefix("ts.timescale") |
78 | + .batchSortEnabled(batchSortEnabled) | |
81 | 79 | .build(); |
82 | 80 | |
83 | 81 | Function<TimescaleTsKvEntity, Integer> hashcodeFunction = entity -> entity.getEntityId().hashCode(); |
84 | 82 | tsQueue = new TbSqlBlockingQueueWrapper<>(tsParams, hashcodeFunction, timescaleBatchThreads, statsFactory); |
85 | 83 | |
86 | - tsQueue.init(logExecutor, v -> insertRepository.saveOrUpdate(v)); | |
84 | + tsQueue.init(logExecutor, v -> insertRepository.saveOrUpdate(v), | |
85 | + Comparator.comparing((Function<TimescaleTsKvEntity, UUID>) AbstractTsKvEntity::getEntityId) | |
86 | + .thenComparing(AbstractTsKvEntity::getKey) | |
87 | + .thenComparing(AbstractTsKvEntity::getTs) | |
88 | + ); | |
87 | 89 | } |
88 | 90 | |
89 | 91 | @PreDestroy | ... | ... |
... | ... | @@ -25,7 +25,7 @@ kafka: |
25 | 25 | # Kafka Bootstrap Servers |
26 | 26 | servers: "localhost:9092" |
27 | 27 | replication_factor: "1" |
28 | - topic_properties: "retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600" | |
28 | + topic_properties: "retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100" | |
29 | 29 | use_confluent_cloud: false |
30 | 30 | confluent: |
31 | 31 | sasl: | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>msa</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa</groupId> | ... | ... |
... | ... | @@ -34,7 +34,7 @@ function KafkaProducer() { |
34 | 34 | this.send = async (responseTopic, scriptId, rawResponse, headers) => { |
35 | 35 | |
36 | 36 | if (!topics.includes(responseTopic)) { |
37 | - let createResponseTopicResult = await createTopic(responseTopic); | |
37 | + let createResponseTopicResult = await createTopic(responseTopic, 1); | |
38 | 38 | topics.push(responseTopic); |
39 | 39 | if (createResponseTopicResult) { |
40 | 40 | logger.info('Created new topic: %s', requestTopic); |
... | ... | @@ -88,7 +88,18 @@ function KafkaProducer() { |
88 | 88 | kafkaAdmin = kafkaClient.admin(); |
89 | 89 | await kafkaAdmin.connect(); |
90 | 90 | |
91 | - let createRequestTopicResult = await createTopic(requestTopic); | |
91 | + let partitions = 1; | |
92 | + | |
93 | + for (let i = 0; i < configEntries.length; i++) { | |
94 | + let param = configEntries[i]; | |
95 | + if (param.name === 'partitions') { | |
96 | + partitions = param.value; | |
97 | + configEntries.splice(i, 1); | |
98 | + break; | |
99 | + } | |
100 | + } | |
101 | + | |
102 | + let createRequestTopicResult = await createTopic(requestTopic, partitions); | |
92 | 103 | |
93 | 104 | if (createRequestTopicResult) { |
94 | 105 | logger.info('Created new topic: %s', requestTopic); |
... | ... | @@ -121,10 +132,11 @@ function KafkaProducer() { |
121 | 132 | } |
122 | 133 | })(); |
123 | 134 | |
124 | -function createTopic(topic) { | |
135 | +function createTopic(topic, partitions) { | |
125 | 136 | return kafkaAdmin.createTopics({ |
126 | 137 | topics: [{ |
127 | 138 | topic: topic, |
139 | + numPartitions: partitions, | |
128 | 140 | replicationFactor: replicationFactor, |
129 | 141 | configEntries: configEntries |
130 | 142 | }] | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>msa</artifactId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>msa</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>msa</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.msa</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.msa</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard.msa</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>msa</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>msa</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.msa</groupId> | ... | ... |
... | ... | @@ -19,11 +19,11 @@ |
19 | 19 | <modelVersion>4.0.0</modelVersion> |
20 | 20 | <parent> |
21 | 21 | <groupId>org.thingsboard</groupId> |
22 | - <version>3.1.2-SNAPSHOT</version> | |
22 | + <version>3.2.0-SNAPSHOT</version> | |
23 | 23 | <artifactId>thingsboard</artifactId> |
24 | 24 | </parent> |
25 | 25 | <artifactId>netty-mqtt</artifactId> |
26 | - <version>3.1.2-SNAPSHOT</version> | |
26 | + <version>3.2.0-SNAPSHOT</version> | |
27 | 27 | <packaging>jar</packaging> |
28 | 28 | |
29 | 29 | <name>Netty MQTT Client</name> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <groupId>org.thingsboard</groupId> |
22 | 22 | <artifactId>thingsboard</artifactId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <packaging>pom</packaging> |
25 | 25 | |
26 | 26 | <name>Thingsboard</name> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>rest-client</artifactId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>rule-engine</artifactId> | ... | ... |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | <modelVersion>4.0.0</modelVersion> |
23 | 23 | <parent> |
24 | 24 | <groupId>org.thingsboard</groupId> |
25 | - <version>3.1.2-SNAPSHOT</version> | |
25 | + <version>3.2.0-SNAPSHOT</version> | |
26 | 26 | <artifactId>rule-engine</artifactId> |
27 | 27 | </parent> |
28 | 28 | <groupId>org.thingsboard.rule-engine</groupId> | ... | ... |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | <modelVersion>4.0.0</modelVersion> |
23 | 23 | <parent> |
24 | 24 | <groupId>org.thingsboard</groupId> |
25 | - <version>3.1.2-SNAPSHOT</version> | |
25 | + <version>3.2.0-SNAPSHOT</version> | |
26 | 26 | <artifactId>rule-engine</artifactId> |
27 | 27 | </parent> |
28 | 28 | <groupId>org.thingsboard.rule-engine</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>tools</artifactId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.transport</groupId> | ... | ... |
... | ... | @@ -77,11 +77,11 @@ queue: |
77 | 77 | security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" |
78 | 78 | other: |
79 | 79 | topic-properties: |
80 | - rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
81 | - core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
82 | - transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
83 | - notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
84 | - js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}" | |
80 | + rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
81 | + core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
82 | + transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
83 | + notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
84 | + js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}" | |
85 | 85 | aws_sqs: |
86 | 86 | use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}" |
87 | 87 | access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}" | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.transport</groupId> | ... | ... |
... | ... | @@ -70,11 +70,11 @@ queue: |
70 | 70 | security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" |
71 | 71 | other: |
72 | 72 | topic-properties: |
73 | - rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
74 | - core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
75 | - transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
76 | - notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
77 | - js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}" | |
73 | + rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
74 | + core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
75 | + transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
76 | + notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
77 | + js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}" | |
78 | 78 | aws_sqs: |
79 | 79 | use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}" |
80 | 80 | access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}" | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.transport</groupId> | ... | ... |
... | ... | @@ -98,11 +98,11 @@ queue: |
98 | 98 | security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" |
99 | 99 | other: |
100 | 100 | topic-properties: |
101 | - rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
102 | - core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
103 | - transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
104 | - notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}" | |
105 | - js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}" | |
101 | + rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
102 | + core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
103 | + transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
104 | + notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}" | |
105 | + js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}" | |
106 | 106 | aws_sqs: |
107 | 107 | use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}" |
108 | 108 | access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}" | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <artifactId>transport</artifactId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>3.1.2-SNAPSHOT</version> | |
23 | + <version>3.2.0-SNAPSHOT</version> | |
24 | 24 | <artifactId>thingsboard</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard</groupId> | ... | ... |
... | ... | @@ -123,7 +123,7 @@ export abstract class EntityComponent<T extends BaseData<HasId>, |
123 | 123 | if (isString(obj[curr])) { |
124 | 124 | acc[curr] = obj[curr].trim(); |
125 | 125 | } else if (isObject(obj[curr])) { |
126 | - acc[curr] = this.deepTrim(obj[curr]) | |
126 | + acc[curr] = this.deepTrim(obj[curr]); | |
127 | 127 | } else { |
128 | 128 | acc[curr] = obj[curr]; |
129 | 129 | } | ... | ... |
... | ... | @@ -37,6 +37,7 @@ import { getCurrentAuthUser } from '@app/core/auth/auth.selectors'; |
37 | 37 | import { Authority } from '@shared/models/authority.enum'; |
38 | 38 | import { DialogService } from '@core/services/dialog.service'; |
39 | 39 | import { ImportExportService } from '@home/components/import-export/import-export.service'; |
40 | +import { Direction } from "@shared/models/page/sort-order"; | |
40 | 41 | |
41 | 42 | @Injectable() |
42 | 43 | export class WidgetsBundlesTableConfigResolver implements Resolve<EntityTableConfig<WidgetsBundle>> { |
... | ... | @@ -55,6 +56,7 @@ export class WidgetsBundlesTableConfigResolver implements Resolve<EntityTableCon |
55 | 56 | this.config.entityComponent = WidgetsBundleComponent; |
56 | 57 | this.config.entityTranslations = entityTypeTranslations.get(EntityType.WIDGETS_BUNDLE); |
57 | 58 | this.config.entityResources = entityTypeResources.get(EntityType.WIDGETS_BUNDLE); |
59 | + this.config.defaultSortOrder = {property: 'title', direction: Direction.ASC}; | |
58 | 60 | |
59 | 61 | this.config.entityTitle = (widgetsBundle) => widgetsBundle ? |
60 | 62 | widgetsBundle.title : ''; | ... | ... |