Commit 02db986546d0f4c87addac63837843e4ba78504a

Authored by Yevhen Bondarenko
Committed by GitHub
1 parent 9e331a17

Feature/separate ts (#3190)

* created annotations for ts latest and created LatestDatabaseSchemaService for cassandra, hsql, psql, timescale

* created ts latest dao

* fixed tests and refactored

* refactored

* refactored

* created latest dao configs

* fix SqlTimeseriesDaoConfig

* refactoring, and deleted annotation @SqlDao

* refactoring

* created migration script for ts latest

* refactoring

Co-authored-by: Andrew Shvayka <ashvayka@thingsboard.io>
Showing 100 changed files with 1092 additions and 543 deletions

Too many changes to show.

To preserve performance only 100 of 116 files are displayed.

... ... @@ -28,7 +28,9 @@ import org.thingsboard.server.service.install.DatabaseTsUpgradeService;
28 28 import org.thingsboard.server.service.install.EntityDatabaseSchemaService;
29 29 import org.thingsboard.server.service.install.SystemDataLoaderService;
30 30 import org.thingsboard.server.service.install.TsDatabaseSchemaService;
  31 +import org.thingsboard.server.service.install.TsLatestDatabaseSchemaService;
31 32 import org.thingsboard.server.service.install.migrate.EntitiesMigrateService;
  33 +import org.thingsboard.server.service.install.migrate.TsLatestMigrateService;
32 34 import org.thingsboard.server.service.install.update.DataUpdateService;
33 35
34 36 @Service
... ... @@ -51,6 +53,9 @@ public class ThingsboardInstallService {
51 53 @Autowired
52 54 private TsDatabaseSchemaService tsDatabaseSchemaService;
53 55
  56 + @Autowired(required = false)
  57 + private TsLatestDatabaseSchemaService tsLatestDatabaseSchemaService;
  58 +
54 59 @Autowired
55 60 private DatabaseEntitiesUpgradeService databaseEntitiesUpgradeService;
56 61
... ... @@ -72,6 +77,9 @@ public class ThingsboardInstallService {
72 77 @Autowired(required = false)
73 78 private EntitiesMigrateService entitiesMigrateService;
74 79
  80 + @Autowired(required = false)
  81 + private TsLatestMigrateService latestMigrateService;
  82 +
75 83 public void performInstall() {
76 84 try {
77 85 if (isUpgrade) {
... ... @@ -82,6 +90,10 @@ public class ThingsboardInstallService {
82 90 entitiesMigrateService.migrate();
83 91 log.info("Updating system data...");
84 92 systemDataLoaderService.updateSystemWidgets();
  93 + } else if ("3.0.1-cassandra".equals(upgradeFromVersion)) {
  94 + log.info("Migrating ThingsBoard latest timeseries data from cassandra to SQL database ...");
  95 + latestMigrateService.migrate();
  96 + log.info("Updating system data...");
85 97 } else {
86 98 switch (upgradeFromVersion) {
87 99 case "1.2.3": //NOSONAR, Need to execute gradual upgrade starting from upgradeFromVersion
... ... @@ -181,6 +193,10 @@ public class ThingsboardInstallService {
181 193
182 194 tsDatabaseSchemaService.createDatabaseSchema();
183 195
  196 + if (tsLatestDatabaseSchemaService != null) {
  197 + tsLatestDatabaseSchemaService.createDatabaseSchema();
  198 + }
  199 +
184 200 log.info("Loading system data...");
185 201
186 202 componentDiscoveryService.discoverComponents();
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.install;
  17 +
  18 +import org.springframework.context.annotation.Profile;
  19 +import org.springframework.stereotype.Service;
  20 +import org.thingsboard.server.dao.util.NoSqlTsLatestDao;
  21 +
  22 +@Service
  23 +@NoSqlTsLatestDao
  24 +@Profile("install")
  25 +public class CassandraTsLatestDatabaseSchemaService extends CassandraAbstractDatabaseSchemaService
  26 + implements TsLatestDatabaseSchemaService {
  27 + public CassandraTsLatestDatabaseSchemaService() {
  28 + super("schema-ts-latest.cql");
  29 + }
  30 +}
... ...
... ... @@ -18,11 +18,9 @@ package org.thingsboard.server.service.install;
18 18 import org.springframework.context.annotation.Profile;
19 19 import org.springframework.stereotype.Service;
20 20 import org.thingsboard.server.dao.util.HsqlDao;
21   -import org.thingsboard.server.dao.util.SqlDao;
22 21
23 22 @Service
24 23 @HsqlDao
25   -@SqlDao
26 24 @Profile("install")
27 25 public class HsqlEntityDatabaseSchemaService extends SqlAbstractDatabaseSchemaService
28 26 implements EntityDatabaseSchemaService {
... ...
... ... @@ -18,10 +18,8 @@ package org.thingsboard.server.service.install;
18 18 import org.springframework.context.annotation.Profile;
19 19 import org.springframework.stereotype.Service;
20 20 import org.thingsboard.server.dao.util.PsqlDao;
21   -import org.thingsboard.server.dao.util.SqlDao;
22 21
23 22 @Service
24   -@SqlDao
25 23 @PsqlDao
26 24 @Profile("install")
27 25 public class PsqlEntityDatabaseSchemaService extends SqlAbstractDatabaseSchemaService
... ...
... ... @@ -21,7 +21,6 @@ import org.springframework.beans.factory.annotation.Value;
21 21 import org.springframework.context.annotation.Profile;
22 22 import org.springframework.stereotype.Service;
23 23 import org.thingsboard.server.dao.dashboard.DashboardService;
24   -import org.thingsboard.server.dao.util.SqlDao;
25 24 import org.thingsboard.server.service.install.sql.SqlDbHelper;
26 25
27 26 import java.nio.charset.Charset;
... ... @@ -58,7 +57,6 @@ import static org.thingsboard.server.service.install.DatabaseHelper.TYPE;
58 57 @Service
59 58 @Profile("install")
60 59 @Slf4j
61   -@SqlDao
62 60 public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService {
63 61
64 62 private static final String SCHEMA_UPDATE_SQL = "schema_update.sql";
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.install;
  17 +
  18 +public interface TsLatestDatabaseSchemaService extends DatabaseSchemaService {
  19 +}
... ...
... ... @@ -24,7 +24,6 @@ import org.thingsboard.server.common.data.EntityType;
24 24 import org.thingsboard.server.common.data.UUIDConverter;
25 25 import org.thingsboard.server.dao.cassandra.CassandraCluster;
26 26 import org.thingsboard.server.dao.util.NoSqlAnyDao;
27   -import org.thingsboard.server.dao.util.SqlDao;
28 27 import org.thingsboard.server.service.install.EntityDatabaseSchemaService;
29 28
30 29 import java.sql.Connection;
... ... @@ -42,7 +41,6 @@ import static org.thingsboard.server.service.install.migrate.CassandraToSqlColum
42 41
43 42 @Service
44 43 @Profile("install")
45   -@SqlDao
46 44 @NoSqlAnyDao
47 45 @Slf4j
48 46 public class CassandraEntitiesToSqlMigrateService implements EntitiesMigrateService {
... ...
... ... @@ -128,7 +128,7 @@ public class CassandraToSqlTable {
128 128 return this.validateColumnData(data);
129 129 }
130 130
131   - private CassandraToSqlColumnData[] validateColumnData(CassandraToSqlColumnData[] data) {
  131 + protected CassandraToSqlColumnData[] validateColumnData(CassandraToSqlColumnData[] data) {
132 132 for (int i=0;i<data.length;i++) {
133 133 CassandraToSqlColumn column = this.columns.get(i);
134 134 if (column.getType() == CassandraToSqlColumnType.STRING) {
... ... @@ -148,7 +148,7 @@ public class CassandraToSqlTable {
148 148 return data;
149 149 }
150 150
151   - private void batchInsert(List<CassandraToSqlColumnData[]> batchData, Connection conn) throws SQLException {
  151 + protected void batchInsert(List<CassandraToSqlColumnData[]> batchData, Connection conn) throws SQLException {
152 152 boolean retry = false;
153 153 for (CassandraToSqlColumnData[] data : batchData) {
154 154 for (CassandraToSqlColumn column: this.columns) {
... ... @@ -269,7 +269,7 @@ public class CassandraToSqlTable {
269 269 return Optional.empty();
270 270 }
271 271
272   - private Statement createCassandraSelectStatement() {
  272 + protected Statement createCassandraSelectStatement() {
273 273 StringBuilder selectStatementBuilder = new StringBuilder();
274 274 selectStatementBuilder.append("SELECT ");
275 275 for (CassandraToSqlColumn column : columns) {
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.install.migrate;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.apache.commons.lang3.StringUtils;
  20 +import org.hibernate.exception.ConstraintViolationException;
  21 +import org.springframework.beans.factory.annotation.Autowired;
  22 +import org.springframework.beans.factory.annotation.Value;
  23 +import org.springframework.context.annotation.Profile;
  24 +import org.springframework.stereotype.Service;
  25 +import org.thingsboard.server.common.data.UUIDConverter;
  26 +import org.thingsboard.server.dao.cassandra.CassandraCluster;
  27 +import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary;
  28 +import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionaryCompositeKey;
  29 +import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
  30 +import org.thingsboard.server.dao.sqlts.dictionary.TsKvDictionaryRepository;
  31 +import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository;
  32 +import org.thingsboard.server.dao.util.NoSqlAnyDao;
  33 +import org.thingsboard.server.service.install.EntityDatabaseSchemaService;
  34 +
  35 +import java.sql.Connection;
  36 +import java.sql.DriverManager;
  37 +import java.util.Arrays;
  38 +import java.util.List;
  39 +import java.util.Optional;
  40 +import java.util.concurrent.ConcurrentHashMap;
  41 +import java.util.concurrent.ConcurrentMap;
  42 +import java.util.concurrent.locks.ReentrantLock;
  43 +import java.util.stream.Collectors;
  44 +
  45 +import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.bigintColumn;
  46 +import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.booleanColumn;
  47 +import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.doubleColumn;
  48 +import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.idColumn;
  49 +import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.jsonColumn;
  50 +import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.stringColumn;
  51 +
  52 +@Service
  53 +@Profile("install")
  54 +@NoSqlAnyDao
  55 +@Slf4j
  56 +public class CassandraTsLatestToSqlMigrateService implements TsLatestMigrateService {
  57 +
  58 + @Autowired
  59 + private EntityDatabaseSchemaService entityDatabaseSchemaService;
  60 +
  61 + @Autowired
  62 + private InsertLatestTsRepository insertLatestTsRepository;
  63 +
  64 + @Autowired
  65 + protected CassandraCluster cluster;
  66 +
  67 + @Autowired
  68 + protected TsKvDictionaryRepository dictionaryRepository;
  69 +
  70 + @Value("${spring.datasource.url}")
  71 + protected String dbUrl;
  72 +
  73 + @Value("${spring.datasource.username}")
  74 + protected String dbUserName;
  75 +
  76 + @Value("${spring.datasource.password}")
  77 + protected String dbPassword;
  78 +
  79 + private final ConcurrentMap<String, Integer> tsKvDictionaryMap = new ConcurrentHashMap<>();
  80 +
  81 + protected static final ReentrantLock tsCreationLock = new ReentrantLock();
  82 +
  83 + @Override
  84 + public void migrate() throws Exception {
  85 + log.info("Performing migration of latest timeseries data from cassandra to SQL database ...");
  86 + entityDatabaseSchemaService.createDatabaseSchema(false);
  87 + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
  88 + conn.setAutoCommit(false);
  89 + for (CassandraToSqlTable table : tables) {
  90 + table.migrateToSql(cluster.getSession(), conn);
  91 + }
  92 + } catch (Exception e) {
  93 + log.error("Unexpected error during ThingsBoard entities data migration!", e);
  94 + throw e;
  95 + }
  96 + entityDatabaseSchemaService.createDatabaseIndexes();
  97 + }
  98 +
  99 + private List<CassandraToSqlTable> tables = Arrays.asList(
  100 + new CassandraToSqlTable("ts_kv_latest_cf",
  101 + idColumn("entity_id"),
  102 + stringColumn("key"),
  103 + bigintColumn("ts"),
  104 + booleanColumn("bool_v"),
  105 + stringColumn("str_v"),
  106 + bigintColumn("long_v"),
  107 + doubleColumn("dbl_v"),
  108 + jsonColumn("json_v")) {
  109 +
  110 + @Override
  111 + protected void batchInsert(List<CassandraToSqlColumnData[]> batchData, Connection conn) {
  112 + insertLatestTsRepository
  113 + .saveOrUpdate(batchData.stream().map(data -> getTsKvLatestEntity(data)).collect(Collectors.toList()));
  114 + }
  115 +
  116 + @Override
  117 + protected CassandraToSqlColumnData[] validateColumnData(CassandraToSqlColumnData[] data) {
  118 + return data;
  119 + }
  120 + });
  121 +
  122 + private TsKvLatestEntity getTsKvLatestEntity(CassandraToSqlColumnData[] data) {
  123 + TsKvLatestEntity latestEntity = new TsKvLatestEntity();
  124 + latestEntity.setEntityId(UUIDConverter.fromString(data[0].getValue()));
  125 + latestEntity.setKey(getOrSaveKeyId(data[1].getValue()));
  126 + latestEntity.setTs(Long.parseLong(data[2].getValue()));
  127 +
  128 + String strV = data[4].getValue();
  129 + if (strV != null) {
  130 + latestEntity.setStrValue(strV);
  131 + } else {
  132 + Long longV = null;
  133 + try {
  134 + longV = Long.parseLong(data[5].getValue());
  135 + } catch (Exception e) {
  136 + }
  137 + if (longV != null) {
  138 + latestEntity.setLongValue(longV);
  139 + } else {
  140 + Double doubleV = null;
  141 + try {
  142 + doubleV = Double.parseDouble(data[6].getValue());
  143 + } catch (Exception e) {
  144 + }
  145 + if (doubleV != null) {
  146 + latestEntity.setDoubleValue(doubleV);
  147 + } else {
  148 +
  149 + String jsonV = data[7].getValue();
  150 + if (StringUtils.isNoneEmpty(jsonV)) {
  151 + latestEntity.setJsonValue(jsonV);
  152 + } else {
  153 + Boolean boolV = null;
  154 + try {
  155 + boolV = Boolean.parseBoolean(data[3].getValue());
  156 + } catch (Exception e) {
  157 + }
  158 + if (boolV != null) {
  159 + latestEntity.setBooleanValue(boolV);
  160 + } else {
  161 + log.warn("All values in key-value row are nullable ");
  162 + }
  163 + }
  164 + }
  165 + }
  166 + }
  167 + return latestEntity;
  168 + }
  169 +
  170 + protected Integer getOrSaveKeyId(String strKey) {
  171 + Integer keyId = tsKvDictionaryMap.get(strKey);
  172 + if (keyId == null) {
  173 + Optional<TsKvDictionary> tsKvDictionaryOptional;
  174 + tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey));
  175 + if (!tsKvDictionaryOptional.isPresent()) {
  176 + tsCreationLock.lock();
  177 + try {
  178 + tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey));
  179 + if (!tsKvDictionaryOptional.isPresent()) {
  180 + TsKvDictionary tsKvDictionary = new TsKvDictionary();
  181 + tsKvDictionary.setKey(strKey);
  182 + try {
  183 + TsKvDictionary saved = dictionaryRepository.save(tsKvDictionary);
  184 + tsKvDictionaryMap.put(saved.getKey(), saved.getKeyId());
  185 + keyId = saved.getKeyId();
  186 + } catch (ConstraintViolationException e) {
  187 + tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey));
  188 + TsKvDictionary dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get TsKvDictionary entity from DB!"));
  189 + tsKvDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId());
  190 + keyId = dictionary.getKeyId();
  191 + }
  192 + } else {
  193 + keyId = tsKvDictionaryOptional.get().getKeyId();
  194 + }
  195 + } finally {
  196 + tsCreationLock.unlock();
  197 + }
  198 + } else {
  199 + keyId = tsKvDictionaryOptional.get().getKeyId();
  200 + tsKvDictionaryMap.put(strKey, keyId);
  201 + }
  202 + }
  203 + return keyId;
  204 + }
  205 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.install.migrate;
  17 +
  18 +public interface TsLatestMigrateService {
  19 +
  20 + void migrate() throws Exception;
  21 +}
... ...
... ... @@ -28,7 +28,6 @@ import org.thingsboard.server.common.msg.TbActorMsg;
28 28 import org.thingsboard.server.common.msg.queue.ServiceType;
29 29 import org.thingsboard.server.common.msg.queue.TbCallback;
30 30 import org.thingsboard.server.dao.util.mapping.JacksonUtil;
31   -import org.thingsboard.server.gen.transport.TransportProtos;
32 31 import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto;
33 32 import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto;
34 33 import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto;
... ... @@ -61,7 +60,6 @@ import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWra
61 60
62 61 import javax.annotation.PostConstruct;
63 62 import javax.annotation.PreDestroy;
64   -import java.util.ArrayList;
65 63 import java.util.List;
66 64 import java.util.Optional;
67 65 import java.util.UUID;
... ...
... ... @@ -20,7 +20,6 @@ import org.springframework.beans.factory.annotation.Value;
20 20 import org.springframework.scheduling.annotation.Scheduled;
21 21 import org.springframework.stereotype.Service;
22 22 import org.thingsboard.server.dao.util.PsqlDao;
23   -import org.thingsboard.server.dao.util.SqlDao;
24 23 import org.thingsboard.server.service.ttl.AbstractCleanUpService;
25 24
26 25 import java.sql.Connection;
... ... @@ -28,7 +27,6 @@ import java.sql.DriverManager;
28 27 import java.sql.SQLException;
29 28
30 29 @PsqlDao
31   -@SqlDao
32 30 @Slf4j
33 31 @Service
34 32 public class EventsCleanUpService extends AbstractCleanUpService {
... ...
... ... @@ -19,11 +19,13 @@ import lombok.extern.slf4j.Slf4j;
19 19 import org.springframework.beans.factory.annotation.Value;
20 20 import org.springframework.stereotype.Service;
21 21 import org.thingsboard.server.dao.model.ModelConstants;
22   -import org.thingsboard.server.dao.util.PsqlTsDao;
  22 +import org.thingsboard.server.dao.util.PsqlDao;
  23 +import org.thingsboard.server.dao.util.SqlTsDao;
23 24
24 25 import java.sql.Connection;
25 26
26   -@PsqlTsDao
  27 +@SqlTsDao
  28 +@PsqlDao
27 29 @Service
28 30 @Slf4j
29 31 public class PsqlTimeseriesCleanUpService extends AbstractTimeseriesCleanUpService {
... ... @@ -33,9 +35,9 @@ public class PsqlTimeseriesCleanUpService extends AbstractTimeseriesCleanUpServi
33 35
34 36 @Override
35 37 protected void doCleanUp(Connection connection) {
36   - long totalPartitionsRemoved = executeQuery(connection, "call drop_partitions_by_max_ttl('" + partitionType + "'," + systemTtl + ", 0);");
37   - log.info("Total partitions removed by TTL: [{}]", totalPartitionsRemoved);
38   - long totalEntitiesTelemetryRemoved = executeQuery(connection, "call cleanup_timeseries_by_ttl('" + ModelConstants.NULL_UUID + "'," + systemTtl + ", 0);");
39   - log.info("Total telemetry removed stats by TTL for entities: [{}]", totalEntitiesTelemetryRemoved);
  38 + long totalPartitionsRemoved = executeQuery(connection, "call drop_partitions_by_max_ttl('" + partitionType + "'," + systemTtl + ", 0);");
  39 + log.info("Total partitions removed by TTL: [{}]", totalPartitionsRemoved);
  40 + long totalEntitiesTelemetryRemoved = executeQuery(connection, "call cleanup_timeseries_by_ttl('" + ModelConstants.NULL_UUID + "'," + systemTtl + ", 0);");
  41 + log.info("Total telemetry removed stats by TTL for entities: [{}]", totalEntitiesTelemetryRemoved);
40 42 }
41 43 }
\ No newline at end of file
... ...
... ... @@ -178,8 +178,8 @@ database:
178 178 ts_max_intervals: "${DATABASE_TS_MAX_INTERVALS:700}" # Max number of DB queries generated by single API call to fetch telemetry records
179 179 ts:
180 180 type: "${DATABASE_TS_TYPE:sql}" # cassandra, sql, or timescale (for hybrid mode, DATABASE_TS_TYPE value should be cassandra, or timescale)
181   - latest_ts:
182   - type: "${DATABASE_TS_TYPE:sql}" # cassandra, sql, or timescale (for hybrid mode, DATABASE_TS_TYPE value should be cassandra, or timescale)
  181 + ts_latest:
  182 + type: "${DATABASE_TS_LATEST_TYPE:sql}" # cassandra, sql, or timescale (for hybrid mode, DATABASE_TS_TYPE value should be cassandra, or timescale)
183 183
184 184 # note: timescale works only with postgreSQL database for DATABASE_ENTITIES_TYPE.
185 185
... ...
... ... @@ -41,7 +41,9 @@ public class MqttNoSqlTestSuite {
41 41 public static CustomCassandraCQLUnit cassandraUnit =
42 42 new CustomCassandraCQLUnit(
43 43 Arrays.asList(
44   - new ClassPathCQLDataSet("cassandra/schema-ts.cql", false, false)),
  44 + new ClassPathCQLDataSet("cassandra/schema-ts.cql", false, false),
  45 + new ClassPathCQLDataSet("cassandra/schema-ts-latest.cql", false, false)
  46 + ),
45 47 "cassandra-test.yaml", 30000l);
46 48
47 49 @BeforeClass
... ...
... ... @@ -21,6 +21,6 @@ import java.lang.annotation.Retention;
21 21 import java.lang.annotation.RetentionPolicy;
22 22
23 23 @Retention(RetentionPolicy.RUNTIME)
24   -@ConditionalOnExpression("'${database.ts.type}'=='cassandra' || '${database.entities.type}'=='cassandra'")
  24 +@ConditionalOnExpression("'${database.ts.type}'=='cassandra' || '${database.ts_latest.type}'=='cassandra'")
25 25 public @interface NoSqlAnyDao {
26 26 }
... ...
common/dao-api/src/main/java/org/thingsboard/server/dao/util/NoSqlTsLatestDao.java renamed from common/dao-api/src/main/java/org/thingsboard/server/dao/util/SqlDao.java
... ... @@ -15,9 +15,12 @@
15 15 */
16 16 package org.thingsboard.server.dao.util;
17 17
  18 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  19 +
18 20 import java.lang.annotation.Retention;
19 21 import java.lang.annotation.RetentionPolicy;
20 22
21 23 @Retention(RetentionPolicy.RUNTIME)
22   -public @interface SqlDao {
  24 +@ConditionalOnProperty(prefix = "database.ts_latest", value = "type", havingValue = "cassandra")
  25 +public @interface NoSqlTsLatestDao {
23 26 }
... ...
common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsLatestAnyDao.java renamed from common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsAnyDao.java
... ... @@ -21,7 +21,7 @@ import java.lang.annotation.Retention;
21 21 import java.lang.annotation.RetentionPolicy;
22 22
23 23 @Retention(RetentionPolicy.RUNTIME)
24   -@ConditionalOnExpression("('${database.ts.type}'=='sql' || '${database.ts.type}'=='timescale') " +
  24 +@ConditionalOnExpression("('${database.ts_latest.type}'=='sql' || '${database.ts_latest.type}'=='timescale') " +
25 25 "&& '${spring.jpa.database-platform}'=='org.hibernate.dialect.PostgreSQLDialect'")
26   -public @interface PsqlTsAnyDao {
  26 +public @interface PsqlTsLatestAnyDao {
27 27 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.util;
  17 +
  18 +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  19 +
  20 +import java.lang.annotation.Retention;
  21 +import java.lang.annotation.RetentionPolicy;
  22 +
  23 +@Retention(RetentionPolicy.RUNTIME)
  24 +@ConditionalOnExpression("'${database.ts_latest.type}'=='sql' || '${database.ts_latest.type}'=='timescale'")
  25 +public @interface SqlTsLatestAnyDao {
  26 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.util;
  17 +
  18 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  19 +
  20 +import java.lang.annotation.Retention;
  21 +import java.lang.annotation.RetentionPolicy;
  22 +
  23 +@Retention(RetentionPolicy.RUNTIME)
  24 +@ConditionalOnProperty(prefix = "database.ts_latest", value = "type", havingValue = "sql")
  25 +public @interface SqlTsLatestDao {
  26 +}
... ...
common/dao-api/src/main/java/org/thingsboard/server/dao/util/SqlTsOrTsLatestAnyDao.java renamed from common/dao-api/src/main/java/org/thingsboard/server/dao/util/SqlTsAnyDao.java
... ... @@ -21,6 +21,6 @@ import java.lang.annotation.Retention;
21 21 import java.lang.annotation.RetentionPolicy;
22 22
23 23 @Retention(RetentionPolicy.RUNTIME)
24   -@ConditionalOnExpression("'${database.ts.type}'=='sql' || '${database.ts.type}'=='timescale'")
25   -public @interface SqlTsAnyDao {
  24 +@ConditionalOnExpression("'${database.ts.type}'=='sql' || '${database.ts.type}'=='timescale' || '${database.ts_latest.type}'=='sql' || '${database.ts_latest.type}'=='timescale'")
  25 +public @interface SqlTsOrTsLatestAnyDao {
26 26 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.util;
  17 +
  18 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  19 +
  20 +import java.lang.annotation.Retention;
  21 +import java.lang.annotation.RetentionPolicy;
  22 +
  23 +@Retention(RetentionPolicy.RUNTIME)
  24 +@ConditionalOnProperty(prefix = "database.ts_latest", value = "type", havingValue = "timescale")
  25 +public @interface TimescaleDBTsLatestDao {
  26 +}
... ...
common/dao-api/src/main/java/org/thingsboard/server/dao/util/TimescaleDBTsOrTsLatestDao.java renamed from common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsDao.java
... ... @@ -21,5 +21,6 @@ import java.lang.annotation.Retention;
21 21 import java.lang.annotation.RetentionPolicy;
22 22
23 23 @Retention(RetentionPolicy.RUNTIME)
24   -@ConditionalOnExpression("'${database.ts.type}'=='sql' && '${spring.jpa.database-platform}'=='org.hibernate.dialect.PostgreSQLDialect'")
25   -public @interface PsqlTsDao { }
\ No newline at end of file
  24 +@ConditionalOnExpression("'${database.ts.type}'=='timescale' || '${database.ts_latest.type}'=='timescale'")
  25 +public @interface TimescaleDBTsOrTsLatestDao {
  26 +}
... ...
... ... @@ -27,8 +27,8 @@ import org.thingsboard.server.dao.util.SqlTsDao;
27 27 @Configuration
28 28 @EnableAutoConfiguration
29 29 @ComponentScan({"org.thingsboard.server.dao.sqlts.hsql"})
30   -@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.ts", "org.thingsboard.server.dao.sqlts.insert.hsql", "org.thingsboard.server.dao.sqlts.insert.latest.hsql", "org.thingsboard.server.dao.sqlts.latest", "org.thingsboard.server.dao.sqlts.dictionary"})
31   -@EntityScan({"org.thingsboard.server.dao.model.sqlts.ts", "org.thingsboard.server.dao.model.sqlts.latest", "org.thingsboard.server.dao.model.sqlts.dictionary"})
  30 +@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.ts", "org.thingsboard.server.dao.sqlts.insert.hsql"})
  31 +@EntityScan({"org.thingsboard.server.dao.model.sqlts.ts"})
32 32 @EnableTransactionManagement
33 33 @SqlTsDao
34 34 @HsqlDao
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao;
  17 +
  18 +import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  19 +import org.springframework.boot.autoconfigure.domain.EntityScan;
  20 +import org.springframework.context.annotation.ComponentScan;
  21 +import org.springframework.context.annotation.Configuration;
  22 +import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  23 +import org.springframework.transaction.annotation.EnableTransactionManagement;
  24 +import org.thingsboard.server.dao.util.HsqlDao;
  25 +import org.thingsboard.server.dao.util.SqlTsLatestDao;
  26 +
  27 +@Configuration
  28 +@EnableAutoConfiguration
  29 +@ComponentScan({"org.thingsboard.server.dao.sqlts.hsql"})
  30 +@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.insert.latest.hsql", "org.thingsboard.server.dao.sqlts.latest"})
  31 +@EntityScan({"org.thingsboard.server.dao.model.sqlts.latest"})
  32 +@EnableTransactionManagement
  33 +@SqlTsLatestDao
  34 +@HsqlDao
  35 +public class HsqlTsLatestDaoConfig {
  36 +
  37 +}
... ...
... ... @@ -21,7 +21,6 @@ import org.springframework.context.annotation.ComponentScan;
21 21 import org.springframework.context.annotation.Configuration;
22 22 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
23 23 import org.springframework.transaction.annotation.EnableTransactionManagement;
24   -import org.thingsboard.server.dao.util.SqlDao;
25 24
26 25 /**
27 26 * @author Valerii Sosliuk
... ... @@ -32,7 +31,6 @@ import org.thingsboard.server.dao.util.SqlDao;
32 31 @EnableJpaRepositories("org.thingsboard.server.dao.sql")
33 32 @EntityScan("org.thingsboard.server.dao.model.sql")
34 33 @EnableTransactionManagement
35   -@SqlDao
36 34 public class JpaDaoConfig {
37 35
38 36 }
... ...
... ... @@ -27,11 +27,11 @@ import org.thingsboard.server.dao.util.SqlTsDao;
27 27 @Configuration
28 28 @EnableAutoConfiguration
29 29 @ComponentScan({"org.thingsboard.server.dao.sqlts.psql"})
30   -@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.ts", "org.thingsboard.server.dao.sqlts.insert.psql", "org.thingsboard.server.dao.sqlts.insert.latest.psql", "org.thingsboard.server.dao.sqlts.latest", "org.thingsboard.server.dao.sqlts.dictionary"})
31   -@EntityScan({"org.thingsboard.server.dao.model.sqlts.ts", "org.thingsboard.server.dao.model.sqlts.latest", "org.thingsboard.server.dao.model.sqlts.dictionary"})
  30 +@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.ts", "org.thingsboard.server.dao.sqlts.insert.psql"})
  31 +@EntityScan({"org.thingsboard.server.dao.model.sqlts.ts"})
32 32 @EnableTransactionManagement
33   -@SqlTsDao
34 33 @PsqlDao
  34 +@SqlTsDao
35 35 public class PsqlTsDaoConfig {
36 36
37 37 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao;
  17 +
  18 +import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  19 +import org.springframework.boot.autoconfigure.domain.EntityScan;
  20 +import org.springframework.context.annotation.ComponentScan;
  21 +import org.springframework.context.annotation.Configuration;
  22 +import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  23 +import org.springframework.transaction.annotation.EnableTransactionManagement;
  24 +import org.thingsboard.server.dao.util.PsqlDao;
  25 +import org.thingsboard.server.dao.util.SqlTsLatestDao;
  26 +
  27 +@Configuration
  28 +@EnableAutoConfiguration
  29 +@ComponentScan({"org.thingsboard.server.dao.sqlts.psql"})
  30 +@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.insert.latest.psql", "org.thingsboard.server.dao.sqlts.latest"})
  31 +@EntityScan({"org.thingsboard.server.dao.model.sqlts.latest"})
  32 +@EnableTransactionManagement
  33 +@SqlTsLatestDao
  34 +@PsqlDao
  35 +public class PsqlTsLatestDaoConfig {
  36 +
  37 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao;
  17 +
  18 +import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  19 +import org.springframework.boot.autoconfigure.domain.EntityScan;
  20 +import org.springframework.context.annotation.Configuration;
  21 +import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  22 +import org.springframework.transaction.annotation.EnableTransactionManagement;
  23 +import org.thingsboard.server.dao.util.PsqlDao;
  24 +import org.thingsboard.server.dao.util.SqlTsOrTsLatestAnyDao;
  25 +
  26 +@Configuration
  27 +@EnableAutoConfiguration
  28 +@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.dictionary"})
  29 +@EntityScan({"org.thingsboard.server.dao.model.sqlts.dictionary"})
  30 +@EnableTransactionManagement
  31 +@SqlTsOrTsLatestAnyDao
  32 +public class SqlTimeseriesDaoConfig {
  33 +
  34 +}
... ...
... ... @@ -27,8 +27,8 @@ import org.thingsboard.server.dao.util.TimescaleDBTsDao;
27 27 @Configuration
28 28 @EnableAutoConfiguration
29 29 @ComponentScan({"org.thingsboard.server.dao.sqlts.timescale"})
30   -@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.timescale", "org.thingsboard.server.dao.sqlts.insert.latest.psql", "org.thingsboard.server.dao.sqlts.insert.timescale", "org.thingsboard.server.dao.sqlts.dictionary", "org.thingsboard.server.dao.sqlts.latest"})
31   -@EntityScan({"org.thingsboard.server.dao.model.sqlts.timescale", "org.thingsboard.server.dao.model.sqlts.dictionary", "org.thingsboard.server.dao.model.sqlts.latest"})
  30 +@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.timescale", "org.thingsboard.server.dao.sqlts.insert.timescale"})
  31 +@EntityScan({"org.thingsboard.server.dao.model.sqlts.timescale"})
32 32 @EnableTransactionManagement
33 33 @TimescaleDBTsDao
34 34 @PsqlDao
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao;
  17 +
  18 +import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  19 +import org.springframework.boot.autoconfigure.domain.EntityScan;
  20 +import org.springframework.context.annotation.ComponentScan;
  21 +import org.springframework.context.annotation.Configuration;
  22 +import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  23 +import org.springframework.transaction.annotation.EnableTransactionManagement;
  24 +import org.thingsboard.server.dao.util.PsqlDao;
  25 +import org.thingsboard.server.dao.util.TimescaleDBTsLatestDao;
  26 +
  27 +@Configuration
  28 +@EnableAutoConfiguration
  29 +@ComponentScan({"org.thingsboard.server.dao.sqlts.timescale"})
  30 +@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.insert.latest.psql", "org.thingsboard.server.dao.sqlts.latest"})
  31 +@EntityScan({"org.thingsboard.server.dao.model.sqlts.latest"})
  32 +@EnableTransactionManagement
  33 +@TimescaleDBTsLatestDao
  34 +@PsqlDao
  35 +public class TimescaleTsLatestDaoConfig {
  36 +
  37 +}
... ...
... ... @@ -18,10 +18,8 @@ package org.thingsboard.server.dao.sql;
18 18 import org.springframework.beans.factory.annotation.Value;
19 19 import org.springframework.stereotype.Component;
20 20 import org.thingsboard.common.util.AbstractListeningExecutor;
21   -import org.thingsboard.server.dao.util.SqlDao;
22 21
23 22 @Component
24   -@SqlDao
25 23 public class JpaExecutorService extends AbstractListeningExecutor {
26 24
27 25 @Value("${spring.datasource.hikari.maximumPoolSize}")
... ...
... ... @@ -21,25 +21,15 @@ import org.springframework.data.jpa.repository.Query;
21 21 import org.springframework.data.repository.CrudRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.common.data.alarm.AlarmStatus;
24   -import org.thingsboard.server.common.data.id.CustomerId;
25   -import org.thingsboard.server.common.data.id.EntityId;
26   -import org.thingsboard.server.common.data.id.TenantId;
27   -import org.thingsboard.server.common.data.page.PageData;
28   -import org.thingsboard.server.common.data.query.AlarmData;
29   -import org.thingsboard.server.common.data.query.AlarmDataQuery;
30 24 import org.thingsboard.server.dao.model.sql.AlarmEntity;
31 25 import org.thingsboard.server.dao.model.sql.AlarmInfoEntity;
32   -import org.thingsboard.server.dao.util.SqlDao;
33 26
34   -import java.util.Collection;
35 27 import java.util.List;
36   -import java.util.Set;
37 28 import java.util.UUID;
38 29
39 30 /**
40 31 * Created by Valerii Sosliuk on 5/21/2017.
41 32 */
42   -@SqlDao
43 33 public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
44 34
45 35 @Query("SELECT a FROM AlarmEntity a WHERE a.originatorId = :originatorId AND a.type = :alarmType ORDER BY a.startTs DESC")
... ...
... ... @@ -39,7 +39,6 @@ import org.thingsboard.server.dao.model.sql.AlarmEntity;
39 39 import org.thingsboard.server.dao.relation.RelationDao;
40 40 import org.thingsboard.server.dao.sql.JpaAbstractDao;
41 41 import org.thingsboard.server.dao.sql.query.AlarmQueryRepository;
42   -import org.thingsboard.server.dao.util.SqlDao;
43 42
44 43 import java.util.ArrayList;
45 44 import java.util.Collection;
... ... @@ -54,7 +53,6 @@ import java.util.UUID;
54 53 */
55 54 @Slf4j
56 55 @Component
57   -@SqlDao
58 56 public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements AlarmDao {
59 57
60 58 @Autowired
... ...
... ... @@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.dao.model.sql.AssetEntity;
24 24 import org.thingsboard.server.dao.model.sql.AssetInfoEntity;
25   -import org.thingsboard.server.dao.util.SqlDao;
26 25
27 26 import java.util.List;
28 27 import java.util.UUID;
... ... @@ -30,7 +29,6 @@ import java.util.UUID;
30 29 /**
31 30 * Created by Valerii Sosliuk on 5/21/2017.
32 31 */
33   -@SqlDao
34 32 public interface AssetRepository extends PagingAndSortingRepository<AssetEntity, UUID> {
35 33
36 34 @Query("SELECT new org.thingsboard.server.dao.model.sql.AssetInfoEntity(a, c.title, c.additionalInfo) " +
... ...
... ... @@ -31,7 +31,6 @@ import org.thingsboard.server.dao.asset.AssetDao;
31 31 import org.thingsboard.server.dao.model.sql.AssetEntity;
32 32 import org.thingsboard.server.dao.model.sql.AssetInfoEntity;
33 33 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
34   -import org.thingsboard.server.dao.util.SqlDao;
35 34
36 35 import java.util.ArrayList;
37 36 import java.util.Collections;
... ... @@ -44,7 +43,6 @@ import java.util.UUID;
44 43 * Created by Valerii Sosliuk on 5/19/2017.
45 44 */
46 45 @Component
47   -@SqlDao
48 46 public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> implements AssetDao {
49 47
50 48 @Autowired
... ...
... ... @@ -25,7 +25,6 @@ import org.springframework.transaction.TransactionStatus;
25 25 import org.springframework.transaction.support.TransactionCallbackWithoutResult;
26 26 import org.springframework.transaction.support.TransactionTemplate;
27 27 import org.thingsboard.server.dao.model.sql.AttributeKvEntity;
28   -import org.thingsboard.server.dao.util.SqlDao;
29 28
30 29 import java.sql.PreparedStatement;
31 30 import java.sql.SQLException;
... ... @@ -35,7 +34,6 @@ import java.util.ArrayList;
35 34 import java.util.List;
36 35 import java.util.regex.Pattern;
37 36
38   -@SqlDao
39 37 @Repository
40 38 @Slf4j
41 39 public abstract class AttributeKvInsertRepository {
... ...
... ... @@ -23,12 +23,10 @@ import org.springframework.transaction.annotation.Transactional;
23 23 import org.thingsboard.server.common.data.EntityType;
24 24 import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey;
25 25 import org.thingsboard.server.dao.model.sql.AttributeKvEntity;
26   -import org.thingsboard.server.dao.util.SqlDao;
27 26
28 27 import java.util.List;
29 28 import java.util.UUID;
30 29
31   -@SqlDao
32 30 public interface AttributeKvRepository extends CrudRepository<AttributeKvEntity, AttributeKvCompositeKey> {
33 31
34 32 @Query("SELECT a FROM AttributeKvEntity a WHERE a.id.entityType = :entityType " +
... ...
... ... @@ -19,12 +19,10 @@ import org.springframework.stereotype.Repository;
19 19 import org.springframework.transaction.annotation.Transactional;
20 20 import org.thingsboard.server.dao.model.sql.AttributeKvEntity;
21 21 import org.thingsboard.server.dao.util.HsqlDao;
22   -import org.thingsboard.server.dao.util.SqlDao;
23 22
24 23 import java.sql.Types;
25 24 import java.util.List;
26 25
27   -@SqlDao
28 26 @HsqlDao
29 27 @Repository
30 28 @Transactional
... ...
... ... @@ -34,7 +34,6 @@ import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService;
34 34 import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent;
35 35 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams;
36 36 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper;
37   -import org.thingsboard.server.dao.util.SqlDao;
38 37
39 38 import javax.annotation.PostConstruct;
40 39 import javax.annotation.PreDestroy;
... ... @@ -46,7 +45,6 @@ import java.util.stream.Collectors;
46 45
47 46 @Component
48 47 @Slf4j
49   -@SqlDao
50 48 public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService implements AttributesDao {
51 49
52 50 @Autowired
... ...
... ... @@ -18,9 +18,7 @@ package org.thingsboard.server.dao.sql.attributes;
18 18 import org.springframework.stereotype.Repository;
19 19 import org.springframework.transaction.annotation.Transactional;
20 20 import org.thingsboard.server.dao.util.PsqlDao;
21   -import org.thingsboard.server.dao.util.SqlDao;
22 21
23   -@SqlDao
24 22 @PsqlDao
25 23 @Repository
26 24 @Transactional
... ...
... ... @@ -30,14 +30,12 @@ import org.thingsboard.server.dao.DaoUtil;
30 30 import org.thingsboard.server.dao.audit.AuditLogDao;
31 31 import org.thingsboard.server.dao.model.sql.AuditLogEntity;
32 32 import org.thingsboard.server.dao.sql.JpaAbstractDao;
33   -import org.thingsboard.server.dao.util.SqlDao;
34 33
35 34 import java.util.List;
36 35 import java.util.Objects;
37 36 import java.util.UUID;
38 37
39 38 @Component
40   -@SqlDao
41 39 public class JpaAuditLogDao extends JpaAbstractDao<AuditLogEntity, AuditLog> implements AuditLogDao {
42 40
43 41 @Autowired
... ...
... ... @@ -23,14 +23,12 @@ import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.common.data.plugin.ComponentScope;
24 24 import org.thingsboard.server.common.data.plugin.ComponentType;
25 25 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity;
26   -import org.thingsboard.server.dao.util.SqlDao;
27 26
28 27 import java.util.UUID;
29 28
30 29 /**
31 30 * Created by Valerii Sosliuk on 5/6/2017.
32 31 */
33   -@SqlDao
34 32 public interface ComponentDescriptorRepository extends PagingAndSortingRepository<ComponentDescriptorEntity, UUID> {
35 33
36 34 ComponentDescriptorEntity findByClazz(String clazz);
... ...
... ... @@ -18,11 +18,9 @@ package org.thingsboard.server.dao.sql.component;
18 18 import org.springframework.stereotype.Repository;
19 19 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity;
20 20 import org.thingsboard.server.dao.util.HsqlDao;
21   -import org.thingsboard.server.dao.util.SqlDao;
22 21
23 22 import javax.persistence.Query;
24 23
25   -@SqlDao
26 24 @HsqlDao
27 25 @Repository
28 26 public class HsqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository {
... ...
... ... @@ -31,7 +31,6 @@ import org.thingsboard.server.dao.DaoUtil;
31 31 import org.thingsboard.server.dao.component.ComponentDescriptorDao;
32 32 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity;
33 33 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
34   -import org.thingsboard.server.dao.util.SqlDao;
35 34
36 35 import java.util.Objects;
37 36 import java.util.Optional;
... ... @@ -41,7 +40,6 @@ import java.util.UUID;
41 40 * Created by Valerii Sosliuk on 5/6/2017.
42 41 */
43 42 @Component
44   -@SqlDao
45 43 public class JpaBaseComponentDescriptorDao extends JpaAbstractSearchTextDao<ComponentDescriptorEntity, ComponentDescriptor>
46 44 implements ComponentDescriptorDao {
47 45
... ...
... ... @@ -18,9 +18,7 @@ package org.thingsboard.server.dao.sql.component;
18 18 import org.springframework.stereotype.Repository;
19 19 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity;
20 20 import org.thingsboard.server.dao.util.PsqlDao;
21   -import org.thingsboard.server.dao.util.SqlDao;
22 21
23   -@SqlDao
24 22 @PsqlDao
25 23 @Repository
26 24 public class PsqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository {
... ...
... ... @@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query;
21 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.dao.model.sql.CustomerEntity;
24   -import org.thingsboard.server.dao.util.SqlDao;
25 24
26 25 import java.util.UUID;
27 26
28 27 /**
29 28 * Created by Valerii Sosliuk on 5/6/2017.
30 29 */
31   -@SqlDao
32 30 public interface CustomerRepository extends PagingAndSortingRepository<CustomerEntity, UUID> {
33 31
34 32 @Query("SELECT c FROM CustomerEntity c WHERE c.tenantId = :tenantId " +
... ...
... ... @@ -25,7 +25,6 @@ import org.thingsboard.server.dao.DaoUtil;
25 25 import org.thingsboard.server.dao.customer.CustomerDao;
26 26 import org.thingsboard.server.dao.model.sql.CustomerEntity;
27 27 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
28   -import org.thingsboard.server.dao.util.SqlDao;
29 28
30 29 import java.util.Objects;
31 30 import java.util.Optional;
... ... @@ -35,7 +34,6 @@ import java.util.UUID;
35 34 * Created by Valerii Sosliuk on 5/6/2017.
36 35 */
37 36 @Component
38   -@SqlDao
39 37 public class JpaCustomerDao extends JpaAbstractSearchTextDao<CustomerEntity, Customer> implements CustomerDao {
40 38
41 39 @Autowired
... ...
... ... @@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query;
21 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.dao.model.sql.DashboardInfoEntity;
24   -import org.thingsboard.server.dao.util.SqlDao;
25 24
26 25 import java.util.UUID;
27 26
28 27 /**
29 28 * Created by Valerii Sosliuk on 5/6/2017.
30 29 */
31   -@SqlDao
32 30 public interface DashboardInfoRepository extends PagingAndSortingRepository<DashboardInfoEntity, UUID> {
33 31
34 32 @Query("SELECT di FROM DashboardInfoEntity di WHERE di.tenantId = :tenantId " +
... ...
... ... @@ -17,13 +17,11 @@ package org.thingsboard.server.dao.sql.dashboard;
17 17
18 18 import org.springframework.data.repository.CrudRepository;
19 19 import org.thingsboard.server.dao.model.sql.DashboardEntity;
20   -import org.thingsboard.server.dao.util.SqlDao;
21 20
22 21 import java.util.UUID;
23 22
24 23 /**
25 24 * Created by Valerii Sosliuk on 5/6/2017.
26 25 */
27   -@SqlDao
28 26 public interface DashboardRepository extends CrudRepository<DashboardEntity, UUID> {
29 27 }
... ...
... ... @@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.Dashboard;
22 22 import org.thingsboard.server.dao.dashboard.DashboardDao;
23 23 import org.thingsboard.server.dao.model.sql.DashboardEntity;
24 24 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
25   -import org.thingsboard.server.dao.util.SqlDao;
26 25
27 26 import java.util.UUID;
28 27
... ... @@ -30,7 +29,6 @@ import java.util.UUID;
30 29 * Created by Valerii Sosliuk on 5/6/2017.
31 30 */
32 31 @Component
33   -@SqlDao
34 32 public class JpaDashboardDao extends JpaAbstractSearchTextDao<DashboardEntity, Dashboard> implements DashboardDao {
35 33
36 34 @Autowired
... ...
... ... @@ -27,7 +27,6 @@ import org.thingsboard.server.dao.dashboard.DashboardInfoDao;
27 27 import org.thingsboard.server.dao.model.sql.DashboardInfoEntity;
28 28 import org.thingsboard.server.dao.relation.RelationDao;
29 29 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
30   -import org.thingsboard.server.dao.util.SqlDao;
31 30
32 31 import java.util.Objects;
33 32 import java.util.UUID;
... ... @@ -37,7 +36,6 @@ import java.util.UUID;
37 36 */
38 37 @Slf4j
39 38 @Component
40   -@SqlDao
41 39 public class JpaDashboardInfoDao extends JpaAbstractSearchTextDao<DashboardInfoEntity, DashboardInfo> implements DashboardInfoDao {
42 40
43 41 @Autowired
... ...
... ... @@ -17,14 +17,12 @@ package org.thingsboard.server.dao.sql.device;
17 17
18 18 import org.springframework.data.repository.CrudRepository;
19 19 import org.thingsboard.server.dao.model.sql.DeviceCredentialsEntity;
20   -import org.thingsboard.server.dao.util.SqlDao;
21 20
22 21 import java.util.UUID;
23 22
24 23 /**
25 24 * Created by Valerii Sosliuk on 5/6/2017.
26 25 */
27   -@SqlDao
28 26 public interface DeviceCredentialsRepository extends CrudRepository<DeviceCredentialsEntity, UUID> {
29 27
30 28 DeviceCredentialsEntity findByDeviceId(UUID deviceId);
... ...
... ... @@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.dao.model.sql.DeviceEntity;
24 24 import org.thingsboard.server.dao.model.sql.DeviceInfoEntity;
25   -import org.thingsboard.server.dao.util.SqlDao;
26 25
27 26 import java.util.List;
28 27 import java.util.UUID;
... ... @@ -30,7 +29,6 @@ import java.util.UUID;
30 29 /**
31 30 * Created by Valerii Sosliuk on 5/6/2017.
32 31 */
33   -@SqlDao
34 32 public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntity, UUID> {
35 33
36 34 @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
... ...
... ... @@ -24,7 +24,6 @@ import org.thingsboard.server.dao.DaoUtil;
24 24 import org.thingsboard.server.dao.device.DeviceCredentialsDao;
25 25 import org.thingsboard.server.dao.model.sql.DeviceCredentialsEntity;
26 26 import org.thingsboard.server.dao.sql.JpaAbstractDao;
27   -import org.thingsboard.server.dao.util.SqlDao;
28 27
29 28 import java.util.UUID;
30 29
... ... @@ -32,7 +31,6 @@ import java.util.UUID;
32 31 * Created by Valerii Sosliuk on 5/6/2017.
33 32 */
34 33 @Component
35   -@SqlDao
36 34 public class JpaDeviceCredentialsDao extends JpaAbstractDao<DeviceCredentialsEntity, DeviceCredentials> implements DeviceCredentialsDao {
37 35
38 36 @Autowired
... ...
... ... @@ -32,7 +32,6 @@ import org.thingsboard.server.dao.device.DeviceDao;
32 32 import org.thingsboard.server.dao.model.sql.DeviceEntity;
33 33 import org.thingsboard.server.dao.model.sql.DeviceInfoEntity;
34 34 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
35   -import org.thingsboard.server.dao.util.SqlDao;
36 35
37 36 import java.util.ArrayList;
38 37 import java.util.Collections;
... ... @@ -45,7 +44,6 @@ import java.util.UUID;
45 44 * Created by Valerii Sosliuk on 5/6/2017.
46 45 */
47 46 @Component
48   -@SqlDao
49 47 public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao {
50 48
51 49 @Autowired
... ...
... ... @@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.dao.model.sql.EntityViewEntity;
24 24 import org.thingsboard.server.dao.model.sql.EntityViewInfoEntity;
25   -import org.thingsboard.server.dao.util.SqlDao;
26 25
27 26 import java.util.List;
28 27 import java.util.UUID;
... ... @@ -30,7 +29,6 @@ import java.util.UUID;
30 29 /**
31 30 * Created by Victor Basanets on 8/31/2017.
32 31 */
33   -@SqlDao
34 32 public interface EntityViewRepository extends PagingAndSortingRepository<EntityViewEntity, UUID> {
35 33
36 34 @Query("SELECT new org.thingsboard.server.dao.model.sql.EntityViewInfoEntity(e, c.title, c.additionalInfo) " +
... ...
... ... @@ -31,7 +31,6 @@ import org.thingsboard.server.dao.entityview.EntityViewDao;
31 31 import org.thingsboard.server.dao.model.sql.EntityViewEntity;
32 32 import org.thingsboard.server.dao.model.sql.EntityViewInfoEntity;
33 33 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
34   -import org.thingsboard.server.dao.util.SqlDao;
35 34
36 35 import java.util.ArrayList;
37 36 import java.util.Collections;
... ... @@ -44,7 +43,6 @@ import java.util.UUID;
44 43 * Created by Victor Basanets on 8/31/2017.
45 44 */
46 45 @Component
47   -@SqlDao
48 46 public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity, EntityView>
49 47 implements EntityViewDao {
50 48
... ...
... ... @@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.common.data.EntityType;
24 24 import org.thingsboard.server.dao.model.sql.EventEntity;
25   -import org.thingsboard.server.dao.util.SqlDao;
26 25
27 26 import java.util.List;
28 27 import java.util.UUID;
... ... @@ -30,7 +29,6 @@ import java.util.UUID;
30 29 /**
31 30 * Created by Valerii Sosliuk on 5/3/2017.
32 31 */
33   -@SqlDao
34 32 public interface EventRepository extends PagingAndSortingRepository<EventEntity, UUID> {
35 33
36 34 EventEntity findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid(UUID tenantId,
... ...
... ... @@ -18,11 +18,9 @@ package org.thingsboard.server.dao.sql.event;
18 18 import org.springframework.stereotype.Repository;
19 19 import org.thingsboard.server.dao.model.sql.EventEntity;
20 20 import org.thingsboard.server.dao.util.HsqlDao;
21   -import org.thingsboard.server.dao.util.SqlDao;
22 21
23 22 import javax.persistence.Query;
24 23
25   -@SqlDao
26 24 @HsqlDao
27 25 @Repository
28 26 public class HsqlEventInsertRepository extends AbstractEventInsertRepository {
... ...
... ... @@ -21,7 +21,6 @@ import lombok.extern.slf4j.Slf4j;
21 21 import org.apache.commons.lang3.StringUtils;
22 22 import org.springframework.beans.factory.annotation.Autowired;
23 23 import org.springframework.data.domain.PageRequest;
24   -import org.springframework.data.jpa.domain.Specification;
25 24 import org.springframework.data.repository.CrudRepository;
26 25 import org.springframework.stereotype.Component;
27 26 import org.thingsboard.server.common.data.Event;
... ... @@ -34,10 +33,7 @@ import org.thingsboard.server.dao.DaoUtil;
34 33 import org.thingsboard.server.dao.event.EventDao;
35 34 import org.thingsboard.server.dao.model.sql.EventEntity;
36 35 import org.thingsboard.server.dao.sql.JpaAbstractDao;
37   -import org.thingsboard.server.dao.util.SqlDao;
38 36
39   -import javax.persistence.criteria.Predicate;
40   -import java.util.ArrayList;
41 37 import java.util.List;
42 38 import java.util.Objects;
43 39 import java.util.Optional;
... ... @@ -50,7 +46,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
50 46 */
51 47 @Slf4j
52 48 @Component
53   -@SqlDao
54 49 public class JpaBaseEventDao extends JpaAbstractDao<EventEntity, Event> implements EventDao {
55 50
56 51 private final UUID systemTenantId = NULL_UUID;
... ...
... ... @@ -19,10 +19,8 @@ import lombok.extern.slf4j.Slf4j;
19 19 import org.springframework.stereotype.Repository;
20 20 import org.thingsboard.server.dao.model.sql.EventEntity;
21 21 import org.thingsboard.server.dao.util.PsqlDao;
22   -import org.thingsboard.server.dao.util.SqlDao;
23 22
24 23 @Slf4j
25   -@SqlDao
26 24 @PsqlDao
27 25 @Repository
28 26 public class PsqlEventInsertRepository extends AbstractEventInsertRepository {
... ...
... ... @@ -39,7 +39,6 @@ import org.thingsboard.server.common.data.query.EntityDataSortOrder;
39 39 import org.thingsboard.server.common.data.query.EntityKey;
40 40 import org.thingsboard.server.common.data.query.EntityKeyType;
41 41 import org.thingsboard.server.dao.model.ModelConstants;
42   -import org.thingsboard.server.dao.util.SqlDao;
43 42
44 43 import java.util.ArrayList;
45 44 import java.util.Arrays;
... ... @@ -52,7 +51,6 @@ import java.util.Objects;
52 51 import java.util.Set;
53 52 import java.util.stream.Collectors;
54 53
55   -@SqlDao
56 54 @Repository
57 55 @Slf4j
58 56 public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
... ...
... ... @@ -50,7 +50,6 @@ import org.thingsboard.server.common.data.query.RelationsQueryFilter;
50 50 import org.thingsboard.server.common.data.query.SingleEntityFilter;
51 51 import org.thingsboard.server.common.data.relation.EntitySearchDirection;
52 52 import org.thingsboard.server.common.data.relation.EntityTypeFilter;
53   -import org.thingsboard.server.dao.util.SqlDao;
54 53
55 54 import java.util.Arrays;
56 55 import java.util.Collections;
... ... @@ -61,7 +60,6 @@ import java.util.Optional;
61 60 import java.util.UUID;
62 61 import java.util.stream.Collectors;
63 62
64   -@SqlDao
65 63 @Repository
66 64 @Slf4j
67 65 public class DefaultEntityQueryRepository implements EntityQueryRepository {
... ...
... ... @@ -24,10 +24,8 @@ import org.thingsboard.server.common.data.query.EntityCountQuery;
24 24 import org.thingsboard.server.common.data.query.EntityData;
25 25 import org.thingsboard.server.common.data.query.EntityDataQuery;
26 26 import org.thingsboard.server.dao.entity.EntityQueryDao;
27   -import org.thingsboard.server.dao.util.SqlDao;
28 27
29 28 @Component
30   -@SqlDao
31 29 public class JpaEntityQueryDao implements EntityQueryDao {
32 30
33 31 @Autowired
... ...
... ... @@ -20,12 +20,10 @@ import org.springframework.transaction.annotation.Transactional;
20 20 import org.thingsboard.server.dao.model.sql.RelationCompositeKey;
21 21 import org.thingsboard.server.dao.model.sql.RelationEntity;
22 22 import org.thingsboard.server.dao.util.HsqlDao;
23   -import org.thingsboard.server.dao.util.SqlDao;
24 23
25 24 import javax.persistence.Query;
26 25
27 26 @HsqlDao
28   -@SqlDao
29 27 @Repository
30 28 @Transactional
31 29 public class HsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository {
... ...
... ... @@ -30,7 +30,6 @@ import org.thingsboard.server.dao.model.sql.RelationCompositeKey;
30 30 import org.thingsboard.server.dao.model.sql.RelationEntity;
31 31 import org.thingsboard.server.dao.relation.RelationDao;
32 32 import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService;
33   -import org.thingsboard.server.dao.util.SqlDao;
34 33
35 34 import javax.persistence.criteria.Predicate;
36 35 import java.util.ArrayList;
... ... @@ -41,7 +40,6 @@ import java.util.List;
41 40 */
42 41 @Slf4j
43 42 @Component
44   -@SqlDao
45 43 public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService implements RelationDao {
46 44
47 45 @Autowired
... ...
... ... @@ -19,10 +19,8 @@ import org.springframework.stereotype.Repository;
19 19 import org.springframework.transaction.annotation.Transactional;
20 20 import org.thingsboard.server.dao.model.sql.RelationEntity;
21 21 import org.thingsboard.server.dao.util.PsqlDao;
22   -import org.thingsboard.server.dao.util.SqlDao;
23 22
24 23 @PsqlDao
25   -@SqlDao
26 24 @Repository
27 25 @Transactional
28 26 public class PsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository {
... ...
... ... @@ -20,12 +20,10 @@ import org.springframework.data.repository.CrudRepository;
20 20 import org.springframework.transaction.annotation.Transactional;
21 21 import org.thingsboard.server.dao.model.sql.RelationCompositeKey;
22 22 import org.thingsboard.server.dao.model.sql.RelationEntity;
23   -import org.thingsboard.server.dao.util.SqlDao;
24 23
25 24 import java.util.List;
26 25 import java.util.UUID;
27 26
28   -@SqlDao
29 27 public interface RelationRepository
30 28 extends CrudRepository<RelationEntity, RelationCompositeKey>, JpaSpecificationExecutor<RelationEntity> {
31 29
... ...
... ... @@ -26,14 +26,12 @@ import org.thingsboard.server.dao.DaoUtil;
26 26 import org.thingsboard.server.dao.model.sql.RuleChainEntity;
27 27 import org.thingsboard.server.dao.rule.RuleChainDao;
28 28 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
29   -import org.thingsboard.server.dao.util.SqlDao;
30 29
31 30 import java.util.Objects;
32 31 import java.util.UUID;
33 32
34 33 @Slf4j
35 34 @Component
36   -@SqlDao
37 35 public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, RuleChain> implements RuleChainDao {
38 36
39 37 @Autowired
... ...
... ... @@ -23,11 +23,9 @@ import org.thingsboard.server.common.data.rule.RuleNode;
23 23 import org.thingsboard.server.dao.model.sql.RuleNodeEntity;
24 24 import org.thingsboard.server.dao.rule.RuleNodeDao;
25 25 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
26   -import org.thingsboard.server.dao.util.SqlDao;
27 26
28 27 @Slf4j
29 28 @Component
30   -@SqlDao
31 29 public class JpaRuleNodeDao extends JpaAbstractSearchTextDao<RuleNodeEntity, RuleNode> implements RuleNodeDao {
32 30
33 31 @Autowired
... ...
... ... @@ -21,11 +21,9 @@ import org.springframework.data.jpa.repository.Query;
21 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.dao.model.sql.RuleChainEntity;
24   -import org.thingsboard.server.dao.util.SqlDao;
25 24
26 25 import java.util.UUID;
27 26
28   -@SqlDao
29 27 public interface RuleChainRepository extends PagingAndSortingRepository<RuleChainEntity, UUID> {
30 28
31 29 @Query("SELECT rc FROM RuleChainEntity rc WHERE rc.tenantId = :tenantId " +
... ...
... ... @@ -17,9 +17,7 @@ package org.thingsboard.server.dao.sql.rule;
17 17
18 18 import org.springframework.data.repository.CrudRepository;
19 19 import org.thingsboard.server.dao.model.sql.RuleNodeEntity;
20   -import org.thingsboard.server.dao.util.SqlDao;
21 20
22   -@SqlDao
23 21 public interface RuleNodeRepository extends CrudRepository<RuleNodeEntity, String> {
24 22
25 23 }
... ...
... ... @@ -25,13 +25,11 @@ import org.thingsboard.server.dao.DaoUtil;
25 25 import org.thingsboard.server.dao.model.sql.AdminSettingsEntity;
26 26 import org.thingsboard.server.dao.settings.AdminSettingsDao;
27 27 import org.thingsboard.server.dao.sql.JpaAbstractDao;
28   -import org.thingsboard.server.dao.util.SqlDao;
29 28
30 29 import java.util.UUID;
31 30
32 31 @Component
33 32 @Slf4j
34   -@SqlDao
35 33 public class JpaAdminSettingsDao extends JpaAbstractDao<AdminSettingsEntity, AdminSettings> implements AdminSettingsDao {
36 34
37 35 @Autowired
... ...
... ... @@ -26,7 +26,6 @@ import org.thingsboard.server.dao.DaoUtil;
26 26 import org.thingsboard.server.dao.model.sql.TenantEntity;
27 27 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
28 28 import org.thingsboard.server.dao.tenant.TenantDao;
29   -import org.thingsboard.server.dao.util.SqlDao;
30 29
31 30 import java.util.Objects;
32 31 import java.util.UUID;
... ... @@ -36,7 +35,6 @@ import java.util.UUID;
36 35 * Created by Valerii Sosliuk on 4/30/2017.
37 36 */
38 37 @Component
39   -@SqlDao
40 38 public class JpaTenantDao extends JpaAbstractSearchTextDao<TenantEntity, Tenant> implements TenantDao {
41 39
42 40 @Autowired
... ...
... ... @@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query;
21 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.dao.model.sql.TenantEntity;
24   -import org.thingsboard.server.dao.util.SqlDao;
25 24
26 25 import java.util.UUID;
27 26
28 27 /**
29 28 * Created by Valerii Sosliuk on 4/30/2017.
30 29 */
31   -@SqlDao
32 30 public interface TenantRepository extends PagingAndSortingRepository<TenantEntity, UUID> {
33 31
34 32 @Query("SELECT t FROM TenantEntity t WHERE t.region = :region " +
... ...
... ... @@ -24,7 +24,6 @@ import org.thingsboard.server.dao.DaoUtil;
24 24 import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
25 25 import org.thingsboard.server.dao.sql.JpaAbstractDao;
26 26 import org.thingsboard.server.dao.user.UserCredentialsDao;
27   -import org.thingsboard.server.dao.util.SqlDao;
28 27
29 28 import java.util.UUID;
30 29
... ... @@ -32,7 +31,6 @@ import java.util.UUID;
32 31 * Created by Valerii Sosliuk on 4/22/2017.
33 32 */
34 33 @Component
35   -@SqlDao
36 34 public class JpaUserCredentialsDao extends JpaAbstractDao<UserCredentialsEntity, UserCredentials> implements UserCredentialsDao {
37 35
38 36 @Autowired
... ...
... ... @@ -27,7 +27,6 @@ import org.thingsboard.server.dao.DaoUtil;
27 27 import org.thingsboard.server.dao.model.sql.UserEntity;
28 28 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
29 29 import org.thingsboard.server.dao.user.UserDao;
30   -import org.thingsboard.server.dao.util.SqlDao;
31 30
32 31 import java.util.Objects;
33 32 import java.util.UUID;
... ... @@ -38,7 +37,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
38 37 * @author Valerii Sosliuk
39 38 */
40 39 @Component
41   -@SqlDao
42 40 public class JpaUserDao extends JpaAbstractSearchTextDao<UserEntity, User> implements UserDao {
43 41
44 42 @Autowired
... ...
... ... @@ -17,14 +17,12 @@ package org.thingsboard.server.dao.sql.user;
17 17
18 18 import org.springframework.data.repository.CrudRepository;
19 19 import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
20   -import org.thingsboard.server.dao.util.SqlDao;
21 20
22 21 import java.util.UUID;
23 22
24 23 /**
25 24 * Created by Valerii Sosliuk on 4/22/2017.
26 25 */
27   -@SqlDao
28 26 public interface UserCredentialsRepository extends CrudRepository<UserCredentialsEntity, UUID> {
29 27
30 28 UserCredentialsEntity findByUserId(UUID userId);
... ...
... ... @@ -22,14 +22,12 @@ import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.common.data.security.Authority;
24 24 import org.thingsboard.server.dao.model.sql.UserEntity;
25   -import org.thingsboard.server.dao.util.SqlDao;
26 25
27 26 import java.util.UUID;
28 27
29 28 /**
30 29 * @author Valerii Sosliuk
31 30 */
32   -@SqlDao
33 31 public interface UserRepository extends PagingAndSortingRepository<UserEntity, UUID> {
34 32
35 33 UserEntity findByEmail(String email);
... ...
... ... @@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.widget.WidgetType;
22 22 import org.thingsboard.server.dao.DaoUtil;
23 23 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity;
24 24 import org.thingsboard.server.dao.sql.JpaAbstractDao;
25   -import org.thingsboard.server.dao.util.SqlDao;
26 25 import org.thingsboard.server.dao.widget.WidgetTypeDao;
27 26
28 27 import java.util.List;
... ... @@ -32,7 +31,6 @@ import java.util.UUID;
32 31 * Created by Valerii Sosliuk on 4/29/2017.
33 32 */
34 33 @Component
35   -@SqlDao
36 34 public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeEntity, WidgetType> implements WidgetTypeDao {
37 35
38 36 @Autowired
... ...
... ... @@ -25,7 +25,6 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle;
25 25 import org.thingsboard.server.dao.DaoUtil;
26 26 import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity;
27 27 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
28   -import org.thingsboard.server.dao.util.SqlDao;
29 28 import org.thingsboard.server.dao.widget.WidgetsBundleDao;
30 29
31 30 import java.util.Objects;
... ... @@ -37,7 +36,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
37 36 * Created by Valerii Sosliuk on 4/23/2017.
38 37 */
39 38 @Component
40   -@SqlDao
41 39 public class JpaWidgetsBundleDao extends JpaAbstractSearchTextDao<WidgetsBundleEntity, WidgetsBundle> implements WidgetsBundleDao {
42 40
43 41 @Autowired
... ...
... ... @@ -17,7 +17,6 @@ package org.thingsboard.server.dao.sql.widget;
17 17
18 18 import org.springframework.data.repository.CrudRepository;
19 19 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity;
20   -import org.thingsboard.server.dao.util.SqlDao;
21 20
22 21 import java.util.List;
23 22 import java.util.UUID;
... ... @@ -25,7 +24,6 @@ import java.util.UUID;
25 24 /**
26 25 * Created by Valerii Sosliuk on 4/29/2017.
27 26 */
28   -@SqlDao
29 27 public interface WidgetTypeRepository extends CrudRepository<WidgetTypeEntity, UUID> {
30 28
31 29 List<WidgetTypeEntity> findByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias);
... ...
... ... @@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query;
21 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity;
24   -import org.thingsboard.server.dao.util.SqlDao;
25 24
26 25 import java.util.UUID;
27 26
28 27 /**
29 28 * Created by Valerii Sosliuk on 4/23/2017.
30 29 */
31   -@SqlDao
32 30 public interface WidgetsBundleRepository extends PagingAndSortingRepository<WidgetsBundleEntity, UUID> {
33 31
34 32 WidgetsBundleEntity findWidgetsBundleByTenantIdAndAlias(UUID tenantId, String alias);
... ...
... ... @@ -17,7 +17,6 @@ package org.thingsboard.server.dao.sqlts;
17 17
18 18 import com.google.common.util.concurrent.Futures;
19 19 import com.google.common.util.concurrent.ListenableFuture;
20   -import com.google.common.util.concurrent.ListeningExecutorService;
21 20 import com.google.common.util.concurrent.MoreExecutors;
22 21 import com.google.common.util.concurrent.SettableFuture;
23 22 import lombok.extern.slf4j.Slf4j;
... ... @@ -33,7 +32,6 @@ import org.thingsboard.server.common.data.kv.TsKvEntry;
33 32 import org.thingsboard.server.common.stats.StatsFactory;
34 33 import org.thingsboard.server.dao.DaoUtil;
35 34 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity;
36   -import org.thingsboard.server.dao.sql.TbSqlBlockingQueue;
37 35 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams;
38 36 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper;
39 37 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository;
... ... @@ -64,7 +62,6 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
64 62
65 63 @PostConstruct
66 64 protected void init() {
67   - super.init();
68 65 TbSqlBlockingQueueParams tsParams = TbSqlBlockingQueueParams.builder()
69 66 .logName("TS")
70 67 .batchSize(tsBatchSize)
... ... @@ -80,7 +77,6 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
80 77
81 78 @PreDestroy
82 79 protected void destroy() {
83   - super.destroy();
84 80 if (tsQueue != null) {
85 81 tsQueue.destroy();
86 82 }
... ... @@ -99,26 +95,6 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
99 95 }
100 96
101 97 @Override
102   - public ListenableFuture<Void> saveLatest(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry) {
103   - return getSaveLatestFuture(entityId, tsKvEntry);
104   - }
105   -
106   - @Override
107   - public ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
108   - return getRemoveLatestFuture(entityId, query);
109   - }
110   -
111   - @Override
112   - public ListenableFuture<TsKvEntry> findLatest(TenantId tenantId, EntityId entityId, String key) {
113   - return getFindLatestFuture(entityId, key);
114   - }
115   -
116   - @Override
117   - public ListenableFuture<List<TsKvEntry>> findAllLatest(TenantId tenantId, EntityId entityId) {
118   - return getFindAllLatestFuture(entityId);
119   - }
120   -
121   - @Override
122 98 public ListenableFuture<Void> savePartition(TenantId tenantId, EntityId entityId, long tsKvEntryTs, String key, long ttl) {
123 99 return Futures.immediateFuture(null);
124 100 }
... ... @@ -134,7 +110,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
134 110 }
135 111
136 112 @Override
137   - protected ListenableFuture<List<TsKvEntry>> findAllAsync(EntityId entityId, ReadTsKvQuery query) {
  113 + public ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) {
138 114 if (query.getAggregation() == Aggregation.NONE) {
139 115 return findAllAsyncWithLimit(entityId, query);
140 116 } else {
... ... @@ -151,8 +127,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
151 127 }
152 128 }
153 129
154   - @Override
155   - protected ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(EntityId entityId, ReadTsKvQuery query) {
  130 + private ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(EntityId entityId, ReadTsKvQuery query) {
156 131 Integer keyId = getOrSaveKeyId(query.getKey());
157 132 List<TsKvEntity> tsKvEntities = tsKvRepository.findAllWithLimit(
158 133 entityId.getId(),
... ...
... ... @@ -16,96 +16,28 @@
16 16 package org.thingsboard.server.dao.sqlts;
17 17
18 18 import com.google.common.base.Function;
19   -import com.google.common.collect.Lists;
20   -import com.google.common.util.concurrent.FutureCallback;
21 19 import com.google.common.util.concurrent.Futures;
22 20 import com.google.common.util.concurrent.ListenableFuture;
23   -import com.google.common.util.concurrent.MoreExecutors;
24 21 import lombok.extern.slf4j.Slf4j;
25   -import org.hibernate.exception.ConstraintViolationException;
26 22 import org.springframework.beans.factory.annotation.Autowired;
27 23 import org.springframework.beans.factory.annotation.Value;
28 24 import org.thingsboard.server.common.data.id.EntityId;
29 25 import org.thingsboard.server.common.data.id.TenantId;
30   -import org.thingsboard.server.common.data.kv.Aggregation;
31   -import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
32   -import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
33   -import org.thingsboard.server.common.data.kv.DeleteTsKvQuery;
34 26 import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
35   -import org.thingsboard.server.common.data.kv.StringDataEntry;
36 27 import org.thingsboard.server.common.data.kv.TsKvEntry;
37   -import org.thingsboard.server.common.stats.StatsFactory;
38   -import org.thingsboard.server.dao.DaoUtil;
39   -import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary;
40   -import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionaryCompositeKey;
41   -import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestCompositeKey;
42   -import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
43   -import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService;
44 28 import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent;
45   -import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams;
46   -import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper;
47   -import org.thingsboard.server.dao.sqlts.dictionary.TsKvDictionaryRepository;
48   -import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository;
49   -import org.thingsboard.server.dao.sqlts.latest.SearchTsKvLatestRepository;
50   -import org.thingsboard.server.dao.sqlts.latest.TsKvLatestRepository;
51   -import org.thingsboard.server.dao.timeseries.SimpleListenableFuture;
52 29
53 30 import javax.annotation.Nullable;
54   -import javax.annotation.PostConstruct;
55   -import javax.annotation.PreDestroy;
56   -import java.util.ArrayList;
57   -import java.util.HashMap;
58 31 import java.util.List;
59   -import java.util.Map;
60 32 import java.util.Objects;
61   -import java.util.Optional;
62   -import java.util.concurrent.ConcurrentHashMap;
63   -import java.util.concurrent.ConcurrentMap;
64   -import java.util.concurrent.ExecutionException;
65   -import java.util.concurrent.locks.ReentrantLock;
66 33 import java.util.stream.Collectors;
67 34
68 35 @Slf4j
69   -public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningExecutorService {
70   -
71   - private static final String DESC_ORDER = "DESC";
72   -
73   - private final ConcurrentMap<String, Integer> tsKvDictionaryMap = new ConcurrentHashMap<>();
74   -
75   - private static final ReentrantLock tsCreationLock = new ReentrantLock();
76   -
77   - @Autowired
78   - private TsKvLatestRepository tsKvLatestRepository;
79   -
80   - @Autowired
81   - private SearchTsKvLatestRepository searchTsKvLatestRepository;
82   -
83   - @Autowired
84   - private InsertLatestTsRepository insertLatestTsRepository;
85   -
86   - @Autowired
87   - private TsKvDictionaryRepository dictionaryRepository;
88   -
89   - private TbSqlBlockingQueueWrapper<TsKvLatestEntity> tsLatestQueue;
90   -
91   - @Value("${sql.ts_latest.batch_size:1000}")
92   - private int tsLatestBatchSize;
93   -
94   - @Value("${sql.ts_latest.batch_max_delay:100}")
95   - private long tsLatestMaxDelay;
96   -
97   - @Value("${sql.ts_latest.stats_print_interval_ms:1000}")
98   - private long tsLatestStatsPrintIntervalMs;
99   -
100   - @Value("${sql.ts_latest.batch_threads:4}")
101   - private int tsLatestBatchThreads;
  36 +public abstract class AbstractSqlTimeseriesDao extends BaseAbstractSqlTimeseriesDao implements AggregationTimeseriesDao {
102 37
103 38 @Autowired
104 39 protected ScheduledLogExecutorComponent logExecutor;
105 40
106   - @Autowired
107   - private StatsFactory statsFactory;
108   -
109 41 @Value("${sql.ts.batch_size:1000}")
110 42 protected int tsBatchSize;
111 43
... ... @@ -121,44 +53,10 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
121 53 @Value("${sql.timescale.batch_threads:4}")
122 54 protected int timescaleBatchThreads;
123 55
124   - @PostConstruct
125   - protected void init() {
126   - TbSqlBlockingQueueParams tsLatestParams = TbSqlBlockingQueueParams.builder()
127   - .logName("TS Latest")
128   - .batchSize(tsLatestBatchSize)
129   - .maxDelay(tsLatestMaxDelay)
130   - .statsPrintIntervalMs(tsLatestStatsPrintIntervalMs)
131   - .statsNamePrefix("ts.latest")
132   - .build();
133   -
134   - java.util.function.Function<TsKvLatestEntity, Integer> hashcodeFunction = entity -> entity.getEntityId().hashCode();
135   - tsLatestQueue = new TbSqlBlockingQueueWrapper<>(tsLatestParams, hashcodeFunction, tsLatestBatchThreads, statsFactory);
136   -
137   - tsLatestQueue.init(logExecutor, v -> {
138   - Map<TsKey, TsKvLatestEntity> trueLatest = new HashMap<>();
139   - v.forEach(ts -> {
140   - TsKey key = new TsKey(ts.getEntityId(), ts.getKey());
141   - TsKvLatestEntity old = trueLatest.get(key);
142   - if (old == null || old.getTs() < ts.getTs()) {
143   - trueLatest.put(key, ts);
144   - }
145   - });
146   - List<TsKvLatestEntity> latestEntities = new ArrayList<>(trueLatest.values());
147   - insertLatestTsRepository.saveOrUpdate(latestEntities);
148   - });
149   - }
150   -
151   - @PreDestroy
152   - protected void destroy() {
153   - if (tsLatestQueue != null) {
154   - tsLatestQueue.destroy();
155   - }
156   - }
157   -
158 56 protected ListenableFuture<List<TsKvEntry>> processFindAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries) {
159 57 List<ListenableFuture<List<TsKvEntry>>> futures = queries
160 58 .stream()
161   - .map(query -> findAllAsync(entityId, query))
  59 + .map(query -> findAllAsync(tenantId, entityId, query))
162 60 .collect(Collectors.toList());
163 61 return Futures.transform(Futures.allAsList(futures), new Function<List<List<TsKvEntry>>, List<TsKvEntry>>() {
164 62 @Nullable
... ... @@ -174,168 +72,4 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
174 72 }
175 73 }, service);
176 74 }
177   -
178   - protected abstract ListenableFuture<List<TsKvEntry>> findAllAsync(EntityId entityId, ReadTsKvQuery query);
179   -
180   - protected abstract ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(EntityId entityId, ReadTsKvQuery query);
181   -
182   - protected ListenableFuture<List<TsKvEntry>> getTskvEntriesFuture(ListenableFuture<List<Optional<TsKvEntry>>> future) {
183   - return Futures.transform(future, new Function<List<Optional<TsKvEntry>>, List<TsKvEntry>>() {
184   - @Nullable
185   - @Override
186   - public List<TsKvEntry> apply(@Nullable List<Optional<TsKvEntry>> results) {
187   - if (results == null || results.isEmpty()) {
188   - return null;
189   - }
190   - return results.stream()
191   - .filter(Optional::isPresent)
192   - .map(Optional::get)
193   - .collect(Collectors.toList());
194   - }
195   - }, service);
196   - }
197   -
198   - protected ListenableFuture<List<TsKvEntry>> findNewLatestEntryFuture(EntityId entityId, DeleteTsKvQuery query) {
199   - long startTs = 0;
200   - long endTs = query.getStartTs() - 1;
201   - ReadTsKvQuery findNewLatestQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, endTs - startTs, 1,
202   - Aggregation.NONE, DESC_ORDER);
203   - return findAllAsync(entityId, findNewLatestQuery);
204   - }
205   -
206   - protected ListenableFuture<TsKvEntry> getFindLatestFuture(EntityId entityId, String key) {
207   - TsKvLatestCompositeKey compositeKey =
208   - new TsKvLatestCompositeKey(
209   - entityId.getId(),
210   - getOrSaveKeyId(key));
211   - Optional<TsKvLatestEntity> entry = tsKvLatestRepository.findById(compositeKey);
212   - TsKvEntry result;
213   - if (entry.isPresent()) {
214   - TsKvLatestEntity tsKvLatestEntity = entry.get();
215   - tsKvLatestEntity.setStrKey(key);
216   - result = DaoUtil.getData(tsKvLatestEntity);
217   - } else {
218   - result = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(key, null));
219   - }
220   - return Futures.immediateFuture(result);
221   - }
222   -
223   - protected ListenableFuture<Void> getRemoveLatestFuture(EntityId entityId, DeleteTsKvQuery query) {
224   - ListenableFuture<TsKvEntry> latestFuture = getFindLatestFuture(entityId, query.getKey());
225   -
226   - ListenableFuture<Boolean> booleanFuture = Futures.transform(latestFuture, tsKvEntry -> {
227   - long ts = tsKvEntry.getTs();
228   - return ts > query.getStartTs() && ts <= query.getEndTs();
229   - }, service);
230   -
231   - ListenableFuture<Void> removedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> {
232   - if (isRemove) {
233   - TsKvLatestEntity latestEntity = new TsKvLatestEntity();
234   - latestEntity.setEntityId(entityId.getId());
235   - latestEntity.setKey(getOrSaveKeyId(query.getKey()));
236   - return service.submit(() -> {
237   - tsKvLatestRepository.delete(latestEntity);
238   - return null;
239   - });
240   - }
241   - return Futures.immediateFuture(null);
242   - }, service);
243   -
244   - final SimpleListenableFuture<Void> resultFuture = new SimpleListenableFuture<>();
245   - Futures.addCallback(removedLatestFuture, new FutureCallback<Void>() {
246   - @Override
247   - public void onSuccess(@Nullable Void result) {
248   - if (query.getRewriteLatestIfDeleted()) {
249   - ListenableFuture<Void> savedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> {
250   - if (isRemove) {
251   - return getNewLatestEntryFuture(entityId, query);
252   - }
253   - return Futures.immediateFuture(null);
254   - }, service);
255   -
256   - try {
257   - resultFuture.set(savedLatestFuture.get());
258   - } catch (InterruptedException | ExecutionException e) {
259   - log.warn("Could not get latest saved value for [{}], {}", entityId, query.getKey(), e);
260   - }
261   - } else {
262   - resultFuture.set(null);
263   - }
264   - }
265   -
266   - @Override
267   - public void onFailure(Throwable t) {
268   - log.warn("[{}] Failed to process remove of the latest value", entityId, t);
269   - }
270   - }, MoreExecutors.directExecutor());
271   - return resultFuture;
272   - }
273   -
274   - protected ListenableFuture<List<TsKvEntry>> getFindAllLatestFuture(EntityId entityId) {
275   - return Futures.immediateFuture(
276   - DaoUtil.convertDataList(Lists.newArrayList(
277   - searchTsKvLatestRepository.findAllByEntityId(entityId.getId()))));
278   - }
279   -
280   - protected ListenableFuture<Void> getSaveLatestFuture(EntityId entityId, TsKvEntry tsKvEntry) {
281   - TsKvLatestEntity latestEntity = new TsKvLatestEntity();
282   - latestEntity.setEntityId(entityId.getId());
283   - latestEntity.setTs(tsKvEntry.getTs());
284   - latestEntity.setKey(getOrSaveKeyId(tsKvEntry.getKey()));
285   - latestEntity.setStrValue(tsKvEntry.getStrValue().orElse(null));
286   - latestEntity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null));
287   - latestEntity.setLongValue(tsKvEntry.getLongValue().orElse(null));
288   - latestEntity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
289   - latestEntity.setJsonValue(tsKvEntry.getJsonValue().orElse(null));
290   -
291   - return tsLatestQueue.add(latestEntity);
292   - }
293   -
294   - protected Integer getOrSaveKeyId(String strKey) {
295   - Integer keyId = tsKvDictionaryMap.get(strKey);
296   - if (keyId == null) {
297   - Optional<TsKvDictionary> tsKvDictionaryOptional;
298   - tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey));
299   - if (!tsKvDictionaryOptional.isPresent()) {
300   - tsCreationLock.lock();
301   - try {
302   - tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey));
303   - if (!tsKvDictionaryOptional.isPresent()) {
304   - TsKvDictionary tsKvDictionary = new TsKvDictionary();
305   - tsKvDictionary.setKey(strKey);
306   - try {
307   - TsKvDictionary saved = dictionaryRepository.save(tsKvDictionary);
308   - tsKvDictionaryMap.put(saved.getKey(), saved.getKeyId());
309   - keyId = saved.getKeyId();
310   - } catch (ConstraintViolationException e) {
311   - tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey));
312   - TsKvDictionary dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get TsKvDictionary entity from DB!"));
313   - tsKvDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId());
314   - keyId = dictionary.getKeyId();
315   - }
316   - } else {
317   - keyId = tsKvDictionaryOptional.get().getKeyId();
318   - }
319   - } finally {
320   - tsCreationLock.unlock();
321   - }
322   - } else {
323   - keyId = tsKvDictionaryOptional.get().getKeyId();
324   - tsKvDictionaryMap.put(strKey, keyId);
325   - }
326   - }
327   - return keyId;
328   - }
329   -
330   - private ListenableFuture<Void> getNewLatestEntryFuture(EntityId entityId, DeleteTsKvQuery query) {
331   - ListenableFuture<List<TsKvEntry>> future = findNewLatestEntryFuture(entityId, query);
332   - return Futures.transformAsync(future, entryList -> {
333   - if (entryList.size() == 1) {
334   - return getSaveLatestFuture(entityId, entryList.get(0));
335   - } else {
336   - log.trace("Could not find new latest value for [{}], key - {}", entityId, query.getKey());
337   - }
338   - return Futures.immediateFuture(null);
339   - }, service);
340   - }
341 75 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sqlts;
  17 +
  18 +import com.google.common.util.concurrent.ListenableFuture;
  19 +import org.thingsboard.server.common.data.id.EntityId;
  20 +import org.thingsboard.server.common.data.id.TenantId;
  21 +import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
  22 +import org.thingsboard.server.common.data.kv.TsKvEntry;
  23 +
  24 +import java.util.List;
  25 +
  26 +public interface AggregationTimeseriesDao {
  27 +
  28 + ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query);
  29 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sqlts;
  17 +
  18 +import com.google.common.base.Function;
  19 +import com.google.common.util.concurrent.Futures;
  20 +import com.google.common.util.concurrent.ListenableFuture;
  21 +import lombok.extern.slf4j.Slf4j;
  22 +import org.hibernate.exception.ConstraintViolationException;
  23 +import org.springframework.beans.factory.annotation.Autowired;
  24 +import org.thingsboard.server.common.data.kv.TsKvEntry;
  25 +import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary;
  26 +import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionaryCompositeKey;
  27 +import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService;
  28 +import org.thingsboard.server.dao.sqlts.dictionary.TsKvDictionaryRepository;
  29 +
  30 +import javax.annotation.Nullable;
  31 +import java.util.List;
  32 +import java.util.Optional;
  33 +import java.util.concurrent.ConcurrentHashMap;
  34 +import java.util.concurrent.ConcurrentMap;
  35 +import java.util.concurrent.locks.ReentrantLock;
  36 +import java.util.stream.Collectors;
  37 +
  38 +@Slf4j
  39 +public abstract class BaseAbstractSqlTimeseriesDao extends JpaAbstractDaoListeningExecutorService {
  40 +
  41 + private final ConcurrentMap<String, Integer> tsKvDictionaryMap = new ConcurrentHashMap<>();
  42 +
  43 + protected static final ReentrantLock tsCreationLock = new ReentrantLock();
  44 +
  45 + @Autowired
  46 + protected TsKvDictionaryRepository dictionaryRepository;
  47 +
  48 + protected Integer getOrSaveKeyId(String strKey) {
  49 + Integer keyId = tsKvDictionaryMap.get(strKey);
  50 + if (keyId == null) {
  51 + Optional<TsKvDictionary> tsKvDictionaryOptional;
  52 + tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey));
  53 + if (!tsKvDictionaryOptional.isPresent()) {
  54 + tsCreationLock.lock();
  55 + try {
  56 + tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey));
  57 + if (!tsKvDictionaryOptional.isPresent()) {
  58 + TsKvDictionary tsKvDictionary = new TsKvDictionary();
  59 + tsKvDictionary.setKey(strKey);
  60 + try {
  61 + TsKvDictionary saved = dictionaryRepository.save(tsKvDictionary);
  62 + tsKvDictionaryMap.put(saved.getKey(), saved.getKeyId());
  63 + keyId = saved.getKeyId();
  64 + } catch (ConstraintViolationException e) {
  65 + tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey));
  66 + TsKvDictionary dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get TsKvDictionary entity from DB!"));
  67 + tsKvDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId());
  68 + keyId = dictionary.getKeyId();
  69 + }
  70 + } else {
  71 + keyId = tsKvDictionaryOptional.get().getKeyId();
  72 + }
  73 + } finally {
  74 + tsCreationLock.unlock();
  75 + }
  76 + } else {
  77 + keyId = tsKvDictionaryOptional.get().getKeyId();
  78 + tsKvDictionaryMap.put(strKey, keyId);
  79 + }
  80 + }
  81 + return keyId;
  82 + }
  83 +
  84 + protected ListenableFuture<List<TsKvEntry>> getTskvEntriesFuture(ListenableFuture<List<Optional<TsKvEntry>>> future) {
  85 + return Futures.transform(future, new Function<List<Optional<TsKvEntry>>, List<TsKvEntry>>() {
  86 + @Nullable
  87 + @Override
  88 + public List<TsKvEntry> apply(@Nullable List<Optional<TsKvEntry>> results) {
  89 + if (results == null || results.isEmpty()) {
  90 + return null;
  91 + }
  92 + return results.stream()
  93 + .filter(Optional::isPresent)
  94 + .map(Optional::get)
  95 + .collect(Collectors.toList());
  96 + }
  97 + }, service);
  98 + }
  99 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sqlts;
  17 +
  18 +import com.google.common.collect.Lists;
  19 +import com.google.common.util.concurrent.FutureCallback;
  20 +import com.google.common.util.concurrent.Futures;
  21 +import com.google.common.util.concurrent.ListenableFuture;
  22 +import com.google.common.util.concurrent.MoreExecutors;
  23 +import lombok.extern.slf4j.Slf4j;
  24 +import org.springframework.beans.factory.annotation.Autowired;
  25 +import org.springframework.beans.factory.annotation.Value;
  26 +import org.springframework.stereotype.Component;
  27 +import org.thingsboard.server.common.data.id.EntityId;
  28 +import org.thingsboard.server.common.data.id.TenantId;
  29 +import org.thingsboard.server.common.data.kv.Aggregation;
  30 +import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
  31 +import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
  32 +import org.thingsboard.server.common.data.kv.DeleteTsKvQuery;
  33 +import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
  34 +import org.thingsboard.server.common.data.kv.StringDataEntry;
  35 +import org.thingsboard.server.common.data.kv.TsKvEntry;
  36 +import org.thingsboard.server.common.stats.StatsFactory;
  37 +import org.thingsboard.server.dao.DaoUtil;
  38 +import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestCompositeKey;
  39 +import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
  40 +import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent;
  41 +import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams;
  42 +import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper;
  43 +import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository;
  44 +import org.thingsboard.server.dao.sqlts.latest.SearchTsKvLatestRepository;
  45 +import org.thingsboard.server.dao.sqlts.latest.TsKvLatestRepository;
  46 +import org.thingsboard.server.dao.timeseries.SimpleListenableFuture;
  47 +import org.thingsboard.server.dao.timeseries.TimeseriesLatestDao;
  48 +import org.thingsboard.server.dao.util.SqlTsLatestAnyDao;
  49 +
  50 +import javax.annotation.Nullable;
  51 +import javax.annotation.PostConstruct;
  52 +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;
  58 +import java.util.concurrent.ExecutionException;
  59 +
  60 +@Slf4j
  61 +@Component
  62 +@SqlTsLatestAnyDao
  63 +public class SqlTimeseriesLatestDao extends BaseAbstractSqlTimeseriesDao implements TimeseriesLatestDao {
  64 +
  65 + private static final String DESC_ORDER = "DESC";
  66 +
  67 + @Autowired
  68 + private TsKvLatestRepository tsKvLatestRepository;
  69 +
  70 + @Autowired
  71 + protected AggregationTimeseriesDao aggregationTimeseriesDao;
  72 +
  73 + @Autowired
  74 + private SearchTsKvLatestRepository searchTsKvLatestRepository;
  75 +
  76 + @Autowired
  77 + private InsertLatestTsRepository insertLatestTsRepository;
  78 +
  79 + private TbSqlBlockingQueueWrapper<TsKvLatestEntity> tsLatestQueue;
  80 +
  81 + @Value("${sql.ts_latest.batch_size:1000}")
  82 + private int tsLatestBatchSize;
  83 +
  84 + @Value("${sql.ts_latest.batch_max_delay:100}")
  85 + private long tsLatestMaxDelay;
  86 +
  87 + @Value("${sql.ts_latest.stats_print_interval_ms:1000}")
  88 + private long tsLatestStatsPrintIntervalMs;
  89 +
  90 + @Value("${sql.ts_latest.batch_threads:4}")
  91 + private int tsLatestBatchThreads;
  92 +
  93 + @Autowired
  94 + protected ScheduledLogExecutorComponent logExecutor;
  95 +
  96 + @Autowired
  97 + private StatsFactory statsFactory;
  98 +
  99 + @PostConstruct
  100 + protected void init() {
  101 + TbSqlBlockingQueueParams tsLatestParams = TbSqlBlockingQueueParams.builder()
  102 + .logName("TS Latest")
  103 + .batchSize(tsLatestBatchSize)
  104 + .maxDelay(tsLatestMaxDelay)
  105 + .statsPrintIntervalMs(tsLatestStatsPrintIntervalMs)
  106 + .statsNamePrefix("ts.latest")
  107 + .build();
  108 +
  109 + java.util.function.Function<TsKvLatestEntity, Integer> hashcodeFunction = entity -> entity.getEntityId().hashCode();
  110 + tsLatestQueue = new TbSqlBlockingQueueWrapper<>(tsLatestParams, hashcodeFunction, tsLatestBatchThreads, statsFactory);
  111 +
  112 + tsLatestQueue.init(logExecutor, v -> {
  113 + Map<TsKey, TsKvLatestEntity> trueLatest = new HashMap<>();
  114 + v.forEach(ts -> {
  115 + 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 + }
  120 + });
  121 + List<TsKvLatestEntity> latestEntities = new ArrayList<>(trueLatest.values());
  122 + insertLatestTsRepository.saveOrUpdate(latestEntities);
  123 + });
  124 + }
  125 +
  126 + @PreDestroy
  127 + protected void destroy() {
  128 + if (tsLatestQueue != null) {
  129 + tsLatestQueue.destroy();
  130 + }
  131 + }
  132 +
  133 + @Override
  134 + public ListenableFuture<Void> saveLatest(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry) {
  135 + return getSaveLatestFuture(entityId, tsKvEntry);
  136 + }
  137 +
  138 + @Override
  139 + public ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
  140 + return getRemoveLatestFuture(tenantId, entityId, query);
  141 + }
  142 +
  143 + @Override
  144 + public ListenableFuture<TsKvEntry> findLatest(TenantId tenantId, EntityId entityId, String key) {
  145 + return getFindLatestFuture(entityId, key);
  146 + }
  147 +
  148 + @Override
  149 + public ListenableFuture<List<TsKvEntry>> findAllLatest(TenantId tenantId, EntityId entityId) {
  150 + return getFindAllLatestFuture(entityId);
  151 + }
  152 +
  153 + private ListenableFuture<Void> getNewLatestEntryFuture(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
  154 + ListenableFuture<List<TsKvEntry>> future = findNewLatestEntryFuture(tenantId, entityId, query);
  155 + return Futures.transformAsync(future, entryList -> {
  156 + if (entryList.size() == 1) {
  157 + return getSaveLatestFuture(entityId, entryList.get(0));
  158 + } else {
  159 + log.trace("Could not find new latest value for [{}], key - {}", entityId, query.getKey());
  160 + }
  161 + return Futures.immediateFuture(null);
  162 + }, service);
  163 + }
  164 +
  165 + private ListenableFuture<List<TsKvEntry>> findNewLatestEntryFuture(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
  166 + long startTs = 0;
  167 + long endTs = query.getStartTs() - 1;
  168 + ReadTsKvQuery findNewLatestQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, endTs - startTs, 1,
  169 + Aggregation.NONE, DESC_ORDER);
  170 + return aggregationTimeseriesDao.findAllAsync(tenantId, entityId, findNewLatestQuery);
  171 + }
  172 +
  173 + protected ListenableFuture<TsKvEntry> getFindLatestFuture(EntityId entityId, String key) {
  174 + TsKvLatestCompositeKey compositeKey =
  175 + new TsKvLatestCompositeKey(
  176 + entityId.getId(),
  177 + getOrSaveKeyId(key));
  178 + Optional<TsKvLatestEntity> entry = tsKvLatestRepository.findById(compositeKey);
  179 + TsKvEntry result;
  180 + if (entry.isPresent()) {
  181 + TsKvLatestEntity tsKvLatestEntity = entry.get();
  182 + tsKvLatestEntity.setStrKey(key);
  183 + result = DaoUtil.getData(tsKvLatestEntity);
  184 + } else {
  185 + result = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(key, null));
  186 + }
  187 + return Futures.immediateFuture(result);
  188 + }
  189 +
  190 + protected ListenableFuture<Void> getRemoveLatestFuture(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
  191 + ListenableFuture<TsKvEntry> latestFuture = getFindLatestFuture(entityId, query.getKey());
  192 +
  193 + ListenableFuture<Boolean> booleanFuture = Futures.transform(latestFuture, tsKvEntry -> {
  194 + long ts = tsKvEntry.getTs();
  195 + return ts > query.getStartTs() && ts <= query.getEndTs();
  196 + }, service);
  197 +
  198 + ListenableFuture<Void> removedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> {
  199 + if (isRemove) {
  200 + TsKvLatestEntity latestEntity = new TsKvLatestEntity();
  201 + latestEntity.setEntityId(entityId.getId());
  202 + latestEntity.setKey(getOrSaveKeyId(query.getKey()));
  203 + return service.submit(() -> {
  204 + tsKvLatestRepository.delete(latestEntity);
  205 + return null;
  206 + });
  207 + }
  208 + return Futures.immediateFuture(null);
  209 + }, service);
  210 +
  211 + final SimpleListenableFuture<Void> resultFuture = new SimpleListenableFuture<>();
  212 + Futures.addCallback(removedLatestFuture, new FutureCallback<Void>() {
  213 + @Override
  214 + public void onSuccess(@Nullable Void result) {
  215 + if (query.getRewriteLatestIfDeleted()) {
  216 + ListenableFuture<Void> savedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> {
  217 + if (isRemove) {
  218 + return getNewLatestEntryFuture(tenantId, entityId, query);
  219 + }
  220 + return Futures.immediateFuture(null);
  221 + }, service);
  222 +
  223 + try {
  224 + resultFuture.set(savedLatestFuture.get());
  225 + } catch (InterruptedException | ExecutionException e) {
  226 + log.warn("Could not get latest saved value for [{}], {}", entityId, query.getKey(), e);
  227 + }
  228 + } else {
  229 + resultFuture.set(null);
  230 + }
  231 + }
  232 +
  233 + @Override
  234 + public void onFailure(Throwable t) {
  235 + log.warn("[{}] Failed to process remove of the latest value", entityId, t);
  236 + }
  237 + }, MoreExecutors.directExecutor());
  238 + return resultFuture;
  239 + }
  240 +
  241 + protected ListenableFuture<List<TsKvEntry>> getFindAllLatestFuture(EntityId entityId) {
  242 + return Futures.immediateFuture(
  243 + DaoUtil.convertDataList(Lists.newArrayList(
  244 + searchTsKvLatestRepository.findAllByEntityId(entityId.getId()))));
  245 + }
  246 +
  247 + protected ListenableFuture<Void> getSaveLatestFuture(EntityId entityId, TsKvEntry tsKvEntry) {
  248 + TsKvLatestEntity latestEntity = new TsKvLatestEntity();
  249 + latestEntity.setEntityId(entityId.getId());
  250 + latestEntity.setTs(tsKvEntry.getTs());
  251 + latestEntity.setKey(getOrSaveKeyId(tsKvEntry.getKey()));
  252 + latestEntity.setStrValue(tsKvEntry.getStrValue().orElse(null));
  253 + latestEntity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null));
  254 + latestEntity.setLongValue(tsKvEntry.getLongValue().orElse(null));
  255 + latestEntity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
  256 + latestEntity.setJsonValue(tsKvEntry.getJsonValue().orElse(null));
  257 +
  258 + return tsLatestQueue.add(latestEntity);
  259 + }
  260 +
  261 +}
... ...
... ... @@ -18,11 +18,11 @@ package org.thingsboard.server.dao.sqlts.dictionary;
18 18 import org.springframework.data.repository.CrudRepository;
19 19 import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary;
20 20 import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionaryCompositeKey;
21   -import org.thingsboard.server.dao.util.SqlTsAnyDao;
  21 +import org.thingsboard.server.dao.util.SqlTsOrTsLatestAnyDao;
22 22
23 23 import java.util.Optional;
24 24
25   -@SqlTsAnyDao
  25 +@SqlTsOrTsLatestAnyDao
26 26 public interface TsKvDictionaryRepository extends CrudRepository<TsKvDictionary, TsKvDictionaryCompositeKey> {
27 27
28 28 Optional<TsKvDictionary> findByKeyId(int keyId);
... ...
... ... @@ -22,14 +22,14 @@ import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
22 22 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository;
23 23 import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository;
24 24 import org.thingsboard.server.dao.util.HsqlDao;
25   -import org.thingsboard.server.dao.util.SqlTsDao;
  25 +import org.thingsboard.server.dao.util.SqlTsLatestDao;
26 26
27 27 import java.sql.PreparedStatement;
28 28 import java.sql.SQLException;
29 29 import java.sql.Types;
30 30 import java.util.List;
31 31
32   -@SqlTsDao
  32 +@SqlTsLatestDao
33 33 @HsqlDao
34 34 @Repository
35 35 @Transactional
... ...
... ... @@ -23,7 +23,7 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult;
23 23 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
24 24 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository;
25 25 import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository;
26   -import org.thingsboard.server.dao.util.PsqlTsAnyDao;
  26 +import org.thingsboard.server.dao.util.PsqlTsLatestAnyDao;
27 27
28 28 import java.sql.PreparedStatement;
29 29 import java.sql.SQLException;
... ... @@ -32,7 +32,7 @@ import java.util.ArrayList;
32 32 import java.util.List;
33 33
34 34
35   -@PsqlTsAnyDao
  35 +@PsqlTsLatestAnyDao
36 36 @Repository
37 37 @Transactional
38 38 public class PsqlLatestInsertTsRepository extends AbstractInsertRepository implements InsertLatestTsRepository {
... ...
... ... @@ -17,14 +17,14 @@ package org.thingsboard.server.dao.sqlts.latest;
17 17
18 18 import org.springframework.stereotype.Repository;
19 19 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
20   -import org.thingsboard.server.dao.util.SqlTsAnyDao;
  20 +import org.thingsboard.server.dao.util.SqlTsLatestAnyDao;
21 21
22 22 import javax.persistence.EntityManager;
23 23 import javax.persistence.PersistenceContext;
24 24 import java.util.List;
25 25 import java.util.UUID;
26 26
27   -@SqlTsAnyDao
  27 +@SqlTsLatestAnyDao
28 28 @Repository
29 29 public class SearchTsKvLatestRepository {
30 30
... ...
... ... @@ -18,9 +18,7 @@ package org.thingsboard.server.dao.sqlts.latest;
18 18 import org.springframework.data.repository.CrudRepository;
19 19 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestCompositeKey;
20 20 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
21   -import org.thingsboard.server.dao.util.SqlDao;
22 21
23   -@SqlDao
24 22 public interface TsKvLatestRepository extends CrudRepository<TsKvLatestEntity, TsKvLatestCompositeKey> {
25 23
26 24 }
... ...
... ... @@ -41,11 +41,10 @@ import java.util.Optional;
41 41 import java.util.concurrent.ConcurrentHashMap;
42 42 import java.util.concurrent.locks.ReentrantLock;
43 43
44   -
45 44 @Component
46 45 @Slf4j
47   -@SqlTsDao
48 46 @PsqlDao
  47 +@SqlTsDao
49 48 public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDao {
50 49
51 50 private final Map<Long, PsqlPartition> partitions = new ConcurrentHashMap<>();
... ...
... ... @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.sqlts.timescale;
18 18 import org.springframework.scheduling.annotation.Async;
19 19 import org.springframework.stereotype.Repository;
20 20 import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity;
21   -import org.thingsboard.server.dao.util.TimescaleDBTsDao;
  21 +import org.thingsboard.server.dao.util.TimescaleDBTsOrTsLatestDao;
22 22
23 23 import javax.persistence.EntityManager;
24 24 import javax.persistence.PersistenceContext;
... ... @@ -27,7 +27,7 @@ import java.util.UUID;
27 27 import java.util.concurrent.CompletableFuture;
28 28
29 29 @Repository
30   -@TimescaleDBTsDao
  30 +@TimescaleDBTsOrTsLatestDao
31 31 public class AggregationRepository {
32 32
33 33 public static final String FIND_AVG = "findAvg";
... ...
... ... @@ -72,7 +72,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
72 72
73 73 @PostConstruct
74 74 protected void init() {
75   - super.init();
76 75 TbSqlBlockingQueueParams tsParams = TbSqlBlockingQueueParams.builder()
77 76 .logName("TS Timescale")
78 77 .batchSize(tsBatchSize)
... ... @@ -89,14 +88,60 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
89 88
90 89 @PreDestroy
91 90 protected void destroy() {
92   - super.destroy();
93 91 if (tsQueue != null) {
94 92 tsQueue.destroy();
95 93 }
96 94 }
97 95
98 96 @Override
99   - protected ListenableFuture<List<TsKvEntry>> findAllAsync(EntityId entityId, ReadTsKvQuery query) {
  97 + public ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries) {
  98 + return processFindAllAsync(tenantId, entityId, queries);
  99 + }
  100 +
  101 + @Override
  102 + public ListenableFuture<Void> save(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl) {
  103 + String strKey = tsKvEntry.getKey();
  104 + Integer keyId = getOrSaveKeyId(strKey);
  105 + TimescaleTsKvEntity entity = new TimescaleTsKvEntity();
  106 + entity.setEntityId(entityId.getId());
  107 + entity.setTs(tsKvEntry.getTs());
  108 + entity.setKey(keyId);
  109 + entity.setStrValue(tsKvEntry.getStrValue().orElse(null));
  110 + entity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null));
  111 + entity.setLongValue(tsKvEntry.getLongValue().orElse(null));
  112 + entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
  113 + entity.setJsonValue(tsKvEntry.getJsonValue().orElse(null));
  114 +
  115 + log.trace("Saving entity to timescale db: {}", entity);
  116 + return tsQueue.add(entity);
  117 + }
  118 +
  119 + @Override
  120 + public ListenableFuture<Void> savePartition(TenantId tenantId, EntityId entityId, long tsKvEntryTs, String key, long ttl) {
  121 + return Futures.immediateFuture(null);
  122 + }
  123 +
  124 + @Override
  125 + public ListenableFuture<Void> remove(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
  126 + String strKey = query.getKey();
  127 + Integer keyId = getOrSaveKeyId(strKey);
  128 + return service.submit(() -> {
  129 + tsKvRepository.delete(
  130 + entityId.getId(),
  131 + keyId,
  132 + query.getStartTs(),
  133 + query.getEndTs());
  134 + return null;
  135 + });
  136 + }
  137 +
  138 + @Override
  139 + public ListenableFuture<Void> removePartition(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
  140 + return service.submit(() -> null);
  141 + }
  142 +
  143 + @Override
  144 + public ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) {
100 145 if (query.getAggregation() == Aggregation.NONE) {
101 146 return findAllAsyncWithLimit(entityId, query);
102 147 } else {
... ... @@ -108,8 +153,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
108 153 }
109 154 }
110 155
111   - @Override
112   - protected ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(EntityId entityId, ReadTsKvQuery query) {
  156 + private ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(EntityId entityId, ReadTsKvQuery query) {
113 157 String strKey = query.getKey();
114 158 Integer keyId = getOrSaveKeyId(strKey);
115 159 List<TimescaleTsKvEntity> timescaleTsKvEntities = tsKvRepository.findAllWithLimit(
... ... @@ -153,73 +197,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
153 197 }, MoreExecutors.directExecutor());
154 198 }
155 199
156   - @Override
157   - public ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries) {
158   - return processFindAllAsync(tenantId, entityId, queries);
159   - }
160   -
161   - @Override
162   - public ListenableFuture<TsKvEntry> findLatest(TenantId tenantId, EntityId entityId, String key) {
163   - return getFindLatestFuture(entityId, key);
164   - }
165   -
166   - @Override
167   - public ListenableFuture<List<TsKvEntry>> findAllLatest(TenantId tenantId, EntityId entityId) {
168   - return getFindAllLatestFuture(entityId);
169   - }
170   -
171   - @Override
172   - public ListenableFuture<Void> save(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl) {
173   - String strKey = tsKvEntry.getKey();
174   - Integer keyId = getOrSaveKeyId(strKey);
175   - TimescaleTsKvEntity entity = new TimescaleTsKvEntity();
176   - entity.setEntityId(entityId.getId());
177   - entity.setTs(tsKvEntry.getTs());
178   - entity.setKey(keyId);
179   - entity.setStrValue(tsKvEntry.getStrValue().orElse(null));
180   - entity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null));
181   - entity.setLongValue(tsKvEntry.getLongValue().orElse(null));
182   - entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
183   - entity.setJsonValue(tsKvEntry.getJsonValue().orElse(null));
184   -
185   - log.trace("Saving entity to timescale db: {}", entity);
186   - return tsQueue.add(entity);
187   - }
188   -
189   - @Override
190   - public ListenableFuture<Void> savePartition(TenantId tenantId, EntityId entityId, long tsKvEntryTs, String key, long ttl) {
191   - return Futures.immediateFuture(null);
192   - }
193   -
194   - @Override
195   - public ListenableFuture<Void> saveLatest(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry) {
196   - return getSaveLatestFuture(entityId, tsKvEntry);
197   - }
198   -
199   - @Override
200   - public ListenableFuture<Void> remove(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
201   - String strKey = query.getKey();
202   - Integer keyId = getOrSaveKeyId(strKey);
203   - return service.submit(() -> {
204   - tsKvRepository.delete(
205   - entityId.getId(),
206   - keyId,
207   - query.getStartTs(),
208   - query.getEndTs());
209   - return null;
210   - });
211   - }
212   -
213   - @Override
214   - public ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
215   - return getRemoveLatestFuture(entityId, query);
216   - }
217   -
218   - @Override
219   - public ListenableFuture<Void> removePartition(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
220   - return service.submit(() -> null);
221   - }
222   -
223 200 private CompletableFuture<List<TimescaleTsKvEntity>> switchAggregation(String key, long startTs, long endTs, long timeBucket, Aggregation aggregation, UUID entityId) {
224 201 switch (aggregation) {
225 202 case AVG:
... ...
... ... @@ -23,12 +23,12 @@ import org.springframework.data.repository.query.Param;
23 23 import org.springframework.transaction.annotation.Transactional;
24 24 import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvCompositeKey;
25 25 import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity;
26   -import org.thingsboard.server.dao.util.TimescaleDBTsDao;
  26 +import org.thingsboard.server.dao.util.TimescaleDBTsOrTsLatestDao;
27 27
28 28 import java.util.List;
29 29 import java.util.UUID;
30 30
31   -@TimescaleDBTsDao
  31 +@TimescaleDBTsOrTsLatestDao
32 32 public interface TsKvTimescaleRepository extends CrudRepository<TimescaleTsKvEntity, TimescaleTsKvCompositeKey> {
33 33
34 34 @Query("SELECT tskv FROM TimescaleTsKvEntity tskv WHERE tskv.entityId = :entityId " +
... ...
... ... @@ -24,13 +24,11 @@ import org.springframework.scheduling.annotation.Async;
24 24 import org.springframework.transaction.annotation.Transactional;
25 25 import org.thingsboard.server.dao.model.sqlts.ts.TsKvCompositeKey;
26 26 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity;
27   -import org.thingsboard.server.dao.util.SqlDao;
28 27
29 28 import java.util.List;
30 29 import java.util.UUID;
31 30 import java.util.concurrent.CompletableFuture;
32 31
33   -@SqlDao
34 32 public interface TsKvRepository extends CrudRepository<TsKvEntity, TsKvCompositeKey> {
35 33
36 34 @Query("SELECT tskv FROM TsKvEntity tskv WHERE tskv.entityId = :entityId " +
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.timeseries;
  17 +
  18 +import com.datastax.oss.driver.api.core.cql.Row;
  19 +import lombok.extern.slf4j.Slf4j;
  20 +import org.apache.commons.lang3.StringUtils;
  21 +import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
  22 +import org.thingsboard.server.common.data.kv.BooleanDataEntry;
  23 +import org.thingsboard.server.common.data.kv.DoubleDataEntry;
  24 +import org.thingsboard.server.common.data.kv.JsonDataEntry;
  25 +import org.thingsboard.server.common.data.kv.KvEntry;
  26 +import org.thingsboard.server.common.data.kv.LongDataEntry;
  27 +import org.thingsboard.server.common.data.kv.StringDataEntry;
  28 +import org.thingsboard.server.common.data.kv.TsKvEntry;
  29 +import org.thingsboard.server.dao.model.ModelConstants;
  30 +import org.thingsboard.server.dao.nosql.CassandraAbstractAsyncDao;
  31 +
  32 +import java.util.ArrayList;
  33 +import java.util.List;
  34 +
  35 +@Slf4j
  36 +public abstract class AbstractCassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao {
  37 + public static final String DESC_ORDER = "DESC";
  38 + public static final String GENERATED_QUERY_FOR_ENTITY_TYPE_AND_ENTITY_ID = "Generated query [{}] for entityType {} and entityId {}";
  39 + public static final String INSERT_INTO = "INSERT INTO ";
  40 + public static final String SELECT_PREFIX = "SELECT ";
  41 + public static final String EQUALS_PARAM = " = ? ";
  42 +
  43 + public static KvEntry toKvEntry(Row row, String key) {
  44 + KvEntry kvEntry = null;
  45 + String strV = row.get(ModelConstants.STRING_VALUE_COLUMN, String.class);
  46 + if (strV != null) {
  47 + kvEntry = new StringDataEntry(key, strV);
  48 + } else {
  49 + Long longV = row.get(ModelConstants.LONG_VALUE_COLUMN, Long.class);
  50 + if (longV != null) {
  51 + kvEntry = new LongDataEntry(key, longV);
  52 + } else {
  53 + Double doubleV = row.get(ModelConstants.DOUBLE_VALUE_COLUMN, Double.class);
  54 + if (doubleV != null) {
  55 + kvEntry = new DoubleDataEntry(key, doubleV);
  56 + } else {
  57 + Boolean boolV = row.get(ModelConstants.BOOLEAN_VALUE_COLUMN, Boolean.class);
  58 + if (boolV != null) {
  59 + kvEntry = new BooleanDataEntry(key, boolV);
  60 + } else {
  61 + String jsonV = row.get(ModelConstants.JSON_VALUE_COLUMN, String.class);
  62 + if (StringUtils.isNoneEmpty(jsonV)) {
  63 + kvEntry = new JsonDataEntry(key, jsonV);
  64 + } else {
  65 + log.warn("All values in key-value row are nullable ");
  66 + }
  67 + }
  68 + }
  69 + }
  70 + }
  71 + return kvEntry;
  72 + }
  73 +
  74 + protected List<TsKvEntry> convertResultToTsKvEntryList(List<Row> rows) {
  75 + List<TsKvEntry> entries = new ArrayList<>(rows.size());
  76 + if (!rows.isEmpty()) {
  77 + rows.forEach(row -> entries.add(convertResultToTsKvEntry(row)));
  78 + }
  79 + return entries;
  80 + }
  81 +
  82 + private TsKvEntry convertResultToTsKvEntry(Row row) {
  83 + String key = row.getString(ModelConstants.KEY_COLUMN);
  84 + long ts = row.getLong(ModelConstants.TS_COLUMN);
  85 + return new BasicTsKvEntry(ts, toKvEntry(row, key));
  86 + }
  87 +
  88 +}
... ...