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 116 changed files with 1623 additions and 1039 deletions
@@ -28,7 +28,9 @@ import org.thingsboard.server.service.install.DatabaseTsUpgradeService; @@ -28,7 +28,9 @@ import org.thingsboard.server.service.install.DatabaseTsUpgradeService;
28 import org.thingsboard.server.service.install.EntityDatabaseSchemaService; 28 import org.thingsboard.server.service.install.EntityDatabaseSchemaService;
29 import org.thingsboard.server.service.install.SystemDataLoaderService; 29 import org.thingsboard.server.service.install.SystemDataLoaderService;
30 import org.thingsboard.server.service.install.TsDatabaseSchemaService; 30 import org.thingsboard.server.service.install.TsDatabaseSchemaService;
  31 +import org.thingsboard.server.service.install.TsLatestDatabaseSchemaService;
31 import org.thingsboard.server.service.install.migrate.EntitiesMigrateService; 32 import org.thingsboard.server.service.install.migrate.EntitiesMigrateService;
  33 +import org.thingsboard.server.service.install.migrate.TsLatestMigrateService;
32 import org.thingsboard.server.service.install.update.DataUpdateService; 34 import org.thingsboard.server.service.install.update.DataUpdateService;
33 35
34 @Service 36 @Service
@@ -51,6 +53,9 @@ public class ThingsboardInstallService { @@ -51,6 +53,9 @@ public class ThingsboardInstallService {
51 @Autowired 53 @Autowired
52 private TsDatabaseSchemaService tsDatabaseSchemaService; 54 private TsDatabaseSchemaService tsDatabaseSchemaService;
53 55
  56 + @Autowired(required = false)
  57 + private TsLatestDatabaseSchemaService tsLatestDatabaseSchemaService;
  58 +
54 @Autowired 59 @Autowired
55 private DatabaseEntitiesUpgradeService databaseEntitiesUpgradeService; 60 private DatabaseEntitiesUpgradeService databaseEntitiesUpgradeService;
56 61
@@ -72,6 +77,9 @@ public class ThingsboardInstallService { @@ -72,6 +77,9 @@ public class ThingsboardInstallService {
72 @Autowired(required = false) 77 @Autowired(required = false)
73 private EntitiesMigrateService entitiesMigrateService; 78 private EntitiesMigrateService entitiesMigrateService;
74 79
  80 + @Autowired(required = false)
  81 + private TsLatestMigrateService latestMigrateService;
  82 +
75 public void performInstall() { 83 public void performInstall() {
76 try { 84 try {
77 if (isUpgrade) { 85 if (isUpgrade) {
@@ -82,6 +90,10 @@ public class ThingsboardInstallService { @@ -82,6 +90,10 @@ public class ThingsboardInstallService {
82 entitiesMigrateService.migrate(); 90 entitiesMigrateService.migrate();
83 log.info("Updating system data..."); 91 log.info("Updating system data...");
84 systemDataLoaderService.updateSystemWidgets(); 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 } else { 97 } else {
86 switch (upgradeFromVersion) { 98 switch (upgradeFromVersion) {
87 case "1.2.3": //NOSONAR, Need to execute gradual upgrade starting from upgradeFromVersion 99 case "1.2.3": //NOSONAR, Need to execute gradual upgrade starting from upgradeFromVersion
@@ -181,6 +193,10 @@ public class ThingsboardInstallService { @@ -181,6 +193,10 @@ public class ThingsboardInstallService {
181 193
182 tsDatabaseSchemaService.createDatabaseSchema(); 194 tsDatabaseSchemaService.createDatabaseSchema();
183 195
  196 + if (tsLatestDatabaseSchemaService != null) {
  197 + tsLatestDatabaseSchemaService.createDatabaseSchema();
  198 + }
  199 +
184 log.info("Loading system data..."); 200 log.info("Loading system data...");
185 201
186 componentDiscoveryService.discoverComponents(); 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,11 +18,9 @@ package org.thingsboard.server.service.install;
18 import org.springframework.context.annotation.Profile; 18 import org.springframework.context.annotation.Profile;
19 import org.springframework.stereotype.Service; 19 import org.springframework.stereotype.Service;
20 import org.thingsboard.server.dao.util.HsqlDao; 20 import org.thingsboard.server.dao.util.HsqlDao;
21 -import org.thingsboard.server.dao.util.SqlDao;  
22 21
23 @Service 22 @Service
24 @HsqlDao 23 @HsqlDao
25 -@SqlDao  
26 @Profile("install") 24 @Profile("install")
27 public class HsqlEntityDatabaseSchemaService extends SqlAbstractDatabaseSchemaService 25 public class HsqlEntityDatabaseSchemaService extends SqlAbstractDatabaseSchemaService
28 implements EntityDatabaseSchemaService { 26 implements EntityDatabaseSchemaService {
@@ -18,10 +18,8 @@ package org.thingsboard.server.service.install; @@ -18,10 +18,8 @@ package org.thingsboard.server.service.install;
18 import org.springframework.context.annotation.Profile; 18 import org.springframework.context.annotation.Profile;
19 import org.springframework.stereotype.Service; 19 import org.springframework.stereotype.Service;
20 import org.thingsboard.server.dao.util.PsqlDao; 20 import org.thingsboard.server.dao.util.PsqlDao;
21 -import org.thingsboard.server.dao.util.SqlDao;  
22 21
23 @Service 22 @Service
24 -@SqlDao  
25 @PsqlDao 23 @PsqlDao
26 @Profile("install") 24 @Profile("install")
27 public class PsqlEntityDatabaseSchemaService extends SqlAbstractDatabaseSchemaService 25 public class PsqlEntityDatabaseSchemaService extends SqlAbstractDatabaseSchemaService
@@ -21,7 +21,6 @@ import org.springframework.beans.factory.annotation.Value; @@ -21,7 +21,6 @@ import org.springframework.beans.factory.annotation.Value;
21 import org.springframework.context.annotation.Profile; 21 import org.springframework.context.annotation.Profile;
22 import org.springframework.stereotype.Service; 22 import org.springframework.stereotype.Service;
23 import org.thingsboard.server.dao.dashboard.DashboardService; 23 import org.thingsboard.server.dao.dashboard.DashboardService;
24 -import org.thingsboard.server.dao.util.SqlDao;  
25 import org.thingsboard.server.service.install.sql.SqlDbHelper; 24 import org.thingsboard.server.service.install.sql.SqlDbHelper;
26 25
27 import java.nio.charset.Charset; 26 import java.nio.charset.Charset;
@@ -58,7 +57,6 @@ import static org.thingsboard.server.service.install.DatabaseHelper.TYPE; @@ -58,7 +57,6 @@ import static org.thingsboard.server.service.install.DatabaseHelper.TYPE;
58 @Service 57 @Service
59 @Profile("install") 58 @Profile("install")
60 @Slf4j 59 @Slf4j
61 -@SqlDao  
62 public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService { 60 public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService {
63 61
64 private static final String SCHEMA_UPDATE_SQL = "schema_update.sql"; 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,7 +24,6 @@ import org.thingsboard.server.common.data.EntityType;
24 import org.thingsboard.server.common.data.UUIDConverter; 24 import org.thingsboard.server.common.data.UUIDConverter;
25 import org.thingsboard.server.dao.cassandra.CassandraCluster; 25 import org.thingsboard.server.dao.cassandra.CassandraCluster;
26 import org.thingsboard.server.dao.util.NoSqlAnyDao; 26 import org.thingsboard.server.dao.util.NoSqlAnyDao;
27 -import org.thingsboard.server.dao.util.SqlDao;  
28 import org.thingsboard.server.service.install.EntityDatabaseSchemaService; 27 import org.thingsboard.server.service.install.EntityDatabaseSchemaService;
29 28
30 import java.sql.Connection; 29 import java.sql.Connection;
@@ -42,7 +41,6 @@ import static org.thingsboard.server.service.install.migrate.CassandraToSqlColum @@ -42,7 +41,6 @@ import static org.thingsboard.server.service.install.migrate.CassandraToSqlColum
42 41
43 @Service 42 @Service
44 @Profile("install") 43 @Profile("install")
45 -@SqlDao  
46 @NoSqlAnyDao 44 @NoSqlAnyDao
47 @Slf4j 45 @Slf4j
48 public class CassandraEntitiesToSqlMigrateService implements EntitiesMigrateService { 46 public class CassandraEntitiesToSqlMigrateService implements EntitiesMigrateService {
@@ -128,7 +128,7 @@ public class CassandraToSqlTable { @@ -128,7 +128,7 @@ public class CassandraToSqlTable {
128 return this.validateColumnData(data); 128 return this.validateColumnData(data);
129 } 129 }
130 130
131 - private CassandraToSqlColumnData[] validateColumnData(CassandraToSqlColumnData[] data) { 131 + protected CassandraToSqlColumnData[] validateColumnData(CassandraToSqlColumnData[] data) {
132 for (int i=0;i<data.length;i++) { 132 for (int i=0;i<data.length;i++) {
133 CassandraToSqlColumn column = this.columns.get(i); 133 CassandraToSqlColumn column = this.columns.get(i);
134 if (column.getType() == CassandraToSqlColumnType.STRING) { 134 if (column.getType() == CassandraToSqlColumnType.STRING) {
@@ -148,7 +148,7 @@ public class CassandraToSqlTable { @@ -148,7 +148,7 @@ public class CassandraToSqlTable {
148 return data; 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 boolean retry = false; 152 boolean retry = false;
153 for (CassandraToSqlColumnData[] data : batchData) { 153 for (CassandraToSqlColumnData[] data : batchData) {
154 for (CassandraToSqlColumn column: this.columns) { 154 for (CassandraToSqlColumn column: this.columns) {
@@ -269,7 +269,7 @@ public class CassandraToSqlTable { @@ -269,7 +269,7 @@ public class CassandraToSqlTable {
269 return Optional.empty(); 269 return Optional.empty();
270 } 270 }
271 271
272 - private Statement createCassandraSelectStatement() { 272 + protected Statement createCassandraSelectStatement() {
273 StringBuilder selectStatementBuilder = new StringBuilder(); 273 StringBuilder selectStatementBuilder = new StringBuilder();
274 selectStatementBuilder.append("SELECT "); 274 selectStatementBuilder.append("SELECT ");
275 for (CassandraToSqlColumn column : columns) { 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,7 +28,6 @@ import org.thingsboard.server.common.msg.TbActorMsg;
28 import org.thingsboard.server.common.msg.queue.ServiceType; 28 import org.thingsboard.server.common.msg.queue.ServiceType;
29 import org.thingsboard.server.common.msg.queue.TbCallback; 29 import org.thingsboard.server.common.msg.queue.TbCallback;
30 import org.thingsboard.server.dao.util.mapping.JacksonUtil; 30 import org.thingsboard.server.dao.util.mapping.JacksonUtil;
31 -import org.thingsboard.server.gen.transport.TransportProtos;  
32 import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto; 31 import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto;
33 import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto; 32 import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto;
34 import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto; 33 import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto;
@@ -61,7 +60,6 @@ import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWra @@ -61,7 +60,6 @@ import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWra
61 60
62 import javax.annotation.PostConstruct; 61 import javax.annotation.PostConstruct;
63 import javax.annotation.PreDestroy; 62 import javax.annotation.PreDestroy;
64 -import java.util.ArrayList;  
65 import java.util.List; 63 import java.util.List;
66 import java.util.Optional; 64 import java.util.Optional;
67 import java.util.UUID; 65 import java.util.UUID;
@@ -20,7 +20,6 @@ import org.springframework.beans.factory.annotation.Value; @@ -20,7 +20,6 @@ import org.springframework.beans.factory.annotation.Value;
20 import org.springframework.scheduling.annotation.Scheduled; 20 import org.springframework.scheduling.annotation.Scheduled;
21 import org.springframework.stereotype.Service; 21 import org.springframework.stereotype.Service;
22 import org.thingsboard.server.dao.util.PsqlDao; 22 import org.thingsboard.server.dao.util.PsqlDao;
23 -import org.thingsboard.server.dao.util.SqlDao;  
24 import org.thingsboard.server.service.ttl.AbstractCleanUpService; 23 import org.thingsboard.server.service.ttl.AbstractCleanUpService;
25 24
26 import java.sql.Connection; 25 import java.sql.Connection;
@@ -28,7 +27,6 @@ import java.sql.DriverManager; @@ -28,7 +27,6 @@ import java.sql.DriverManager;
28 import java.sql.SQLException; 27 import java.sql.SQLException;
29 28
30 @PsqlDao 29 @PsqlDao
31 -@SqlDao  
32 @Slf4j 30 @Slf4j
33 @Service 31 @Service
34 public class EventsCleanUpService extends AbstractCleanUpService { 32 public class EventsCleanUpService extends AbstractCleanUpService {
@@ -19,11 +19,13 @@ import lombok.extern.slf4j.Slf4j; @@ -19,11 +19,13 @@ import lombok.extern.slf4j.Slf4j;
19 import org.springframework.beans.factory.annotation.Value; 19 import org.springframework.beans.factory.annotation.Value;
20 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
21 import org.thingsboard.server.dao.model.ModelConstants; 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 import java.sql.Connection; 25 import java.sql.Connection;
25 26
26 -@PsqlTsDao 27 +@SqlTsDao
  28 +@PsqlDao
27 @Service 29 @Service
28 @Slf4j 30 @Slf4j
29 public class PsqlTimeseriesCleanUpService extends AbstractTimeseriesCleanUpService { 31 public class PsqlTimeseriesCleanUpService extends AbstractTimeseriesCleanUpService {
@@ -33,9 +35,9 @@ public class PsqlTimeseriesCleanUpService extends AbstractTimeseriesCleanUpServi @@ -33,9 +35,9 @@ public class PsqlTimeseriesCleanUpService extends AbstractTimeseriesCleanUpServi
33 35
34 @Override 36 @Override
35 protected void doCleanUp(Connection connection) { 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 }
@@ -178,8 +178,8 @@ database: @@ -178,8 +178,8 @@ database:
178 ts_max_intervals: "${DATABASE_TS_MAX_INTERVALS:700}" # Max number of DB queries generated by single API call to fetch telemetry records 178 ts_max_intervals: "${DATABASE_TS_MAX_INTERVALS:700}" # Max number of DB queries generated by single API call to fetch telemetry records
179 ts: 179 ts:
180 type: "${DATABASE_TS_TYPE:sql}" # cassandra, sql, or timescale (for hybrid mode, DATABASE_TS_TYPE value should be cassandra, or timescale) 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 # note: timescale works only with postgreSQL database for DATABASE_ENTITIES_TYPE. 184 # note: timescale works only with postgreSQL database for DATABASE_ENTITIES_TYPE.
185 185
@@ -41,7 +41,9 @@ public class MqttNoSqlTestSuite { @@ -41,7 +41,9 @@ public class MqttNoSqlTestSuite {
41 public static CustomCassandraCQLUnit cassandraUnit = 41 public static CustomCassandraCQLUnit cassandraUnit =
42 new CustomCassandraCQLUnit( 42 new CustomCassandraCQLUnit(
43 Arrays.asList( 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 "cassandra-test.yaml", 30000l); 47 "cassandra-test.yaml", 30000l);
46 48
47 @BeforeClass 49 @BeforeClass
@@ -21,6 +21,6 @@ import java.lang.annotation.Retention; @@ -21,6 +21,6 @@ import java.lang.annotation.Retention;
21 import java.lang.annotation.RetentionPolicy; 21 import java.lang.annotation.RetentionPolicy;
22 22
23 @Retention(RetentionPolicy.RUNTIME) 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 public @interface NoSqlAnyDao { 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,9 +15,12 @@
15 */ 15 */
16 package org.thingsboard.server.dao.util; 16 package org.thingsboard.server.dao.util;
17 17
  18 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  19 +
18 import java.lang.annotation.Retention; 20 import java.lang.annotation.Retention;
19 import java.lang.annotation.RetentionPolicy; 21 import java.lang.annotation.RetentionPolicy;
20 22
21 @Retention(RetentionPolicy.RUNTIME) 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,7 +21,7 @@ import java.lang.annotation.Retention;
21 import java.lang.annotation.RetentionPolicy; 21 import java.lang.annotation.RetentionPolicy;
22 22
23 @Retention(RetentionPolicy.RUNTIME) 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 "&& '${spring.jpa.database-platform}'=='org.hibernate.dialect.PostgreSQLDialect'") 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,6 +21,6 @@ import java.lang.annotation.Retention;
21 import java.lang.annotation.RetentionPolicy; 21 import java.lang.annotation.RetentionPolicy;
22 22
23 @Retention(RetentionPolicy.RUNTIME) 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,5 +21,6 @@ import java.lang.annotation.Retention;
21 import java.lang.annotation.RetentionPolicy; 21 import java.lang.annotation.RetentionPolicy;
22 22
23 @Retention(RetentionPolicy.RUNTIME) 23 @Retention(RetentionPolicy.RUNTIME)
24 -@ConditionalOnExpression("'${database.ts.type}'=='sql' && '${spring.jpa.database-platform}'=='org.hibernate.dialect.PostgreSQLDialect'")  
25 -public @interface PsqlTsDao { }  
  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,8 +27,8 @@ import org.thingsboard.server.dao.util.SqlTsDao;
27 @Configuration 27 @Configuration
28 @EnableAutoConfiguration 28 @EnableAutoConfiguration
29 @ComponentScan({"org.thingsboard.server.dao.sqlts.hsql"}) 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 @EnableTransactionManagement 32 @EnableTransactionManagement
33 @SqlTsDao 33 @SqlTsDao
34 @HsqlDao 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,7 +21,6 @@ import org.springframework.context.annotation.ComponentScan;
21 import org.springframework.context.annotation.Configuration; 21 import org.springframework.context.annotation.Configuration;
22 import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 22 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
23 import org.springframework.transaction.annotation.EnableTransactionManagement; 23 import org.springframework.transaction.annotation.EnableTransactionManagement;
24 -import org.thingsboard.server.dao.util.SqlDao;  
25 24
26 /** 25 /**
27 * @author Valerii Sosliuk 26 * @author Valerii Sosliuk
@@ -32,7 +31,6 @@ import org.thingsboard.server.dao.util.SqlDao; @@ -32,7 +31,6 @@ import org.thingsboard.server.dao.util.SqlDao;
32 @EnableJpaRepositories("org.thingsboard.server.dao.sql") 31 @EnableJpaRepositories("org.thingsboard.server.dao.sql")
33 @EntityScan("org.thingsboard.server.dao.model.sql") 32 @EntityScan("org.thingsboard.server.dao.model.sql")
34 @EnableTransactionManagement 33 @EnableTransactionManagement
35 -@SqlDao  
36 public class JpaDaoConfig { 34 public class JpaDaoConfig {
37 35
38 } 36 }
@@ -27,11 +27,11 @@ import org.thingsboard.server.dao.util.SqlTsDao; @@ -27,11 +27,11 @@ import org.thingsboard.server.dao.util.SqlTsDao;
27 @Configuration 27 @Configuration
28 @EnableAutoConfiguration 28 @EnableAutoConfiguration
29 @ComponentScan({"org.thingsboard.server.dao.sqlts.psql"}) 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 @EnableTransactionManagement 32 @EnableTransactionManagement
33 -@SqlTsDao  
34 @PsqlDao 33 @PsqlDao
  34 +@SqlTsDao
35 public class PsqlTsDaoConfig { 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,8 +27,8 @@ import org.thingsboard.server.dao.util.TimescaleDBTsDao;
27 @Configuration 27 @Configuration
28 @EnableAutoConfiguration 28 @EnableAutoConfiguration
29 @ComponentScan({"org.thingsboard.server.dao.sqlts.timescale"}) 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 @EnableTransactionManagement 32 @EnableTransactionManagement
33 @TimescaleDBTsDao 33 @TimescaleDBTsDao
34 @PsqlDao 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,10 +18,8 @@ package org.thingsboard.server.dao.sql;
18 import org.springframework.beans.factory.annotation.Value; 18 import org.springframework.beans.factory.annotation.Value;
19 import org.springframework.stereotype.Component; 19 import org.springframework.stereotype.Component;
20 import org.thingsboard.common.util.AbstractListeningExecutor; 20 import org.thingsboard.common.util.AbstractListeningExecutor;
21 -import org.thingsboard.server.dao.util.SqlDao;  
22 21
23 @Component 22 @Component
24 -@SqlDao  
25 public class JpaExecutorService extends AbstractListeningExecutor { 23 public class JpaExecutorService extends AbstractListeningExecutor {
26 24
27 @Value("${spring.datasource.hikari.maximumPoolSize}") 25 @Value("${spring.datasource.hikari.maximumPoolSize}")
@@ -21,25 +21,15 @@ import org.springframework.data.jpa.repository.Query; @@ -21,25 +21,15 @@ import org.springframework.data.jpa.repository.Query;
21 import org.springframework.data.repository.CrudRepository; 21 import org.springframework.data.repository.CrudRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.common.data.alarm.AlarmStatus; 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 import org.thingsboard.server.dao.model.sql.AlarmEntity; 24 import org.thingsboard.server.dao.model.sql.AlarmEntity;
31 import org.thingsboard.server.dao.model.sql.AlarmInfoEntity; 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 import java.util.List; 27 import java.util.List;
36 -import java.util.Set;  
37 import java.util.UUID; 28 import java.util.UUID;
38 29
39 /** 30 /**
40 * Created by Valerii Sosliuk on 5/21/2017. 31 * Created by Valerii Sosliuk on 5/21/2017.
41 */ 32 */
42 -@SqlDao  
43 public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> { 33 public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
44 34
45 @Query("SELECT a FROM AlarmEntity a WHERE a.originatorId = :originatorId AND a.type = :alarmType ORDER BY a.startTs DESC") 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,7 +39,6 @@ import org.thingsboard.server.dao.model.sql.AlarmEntity;
39 import org.thingsboard.server.dao.relation.RelationDao; 39 import org.thingsboard.server.dao.relation.RelationDao;
40 import org.thingsboard.server.dao.sql.JpaAbstractDao; 40 import org.thingsboard.server.dao.sql.JpaAbstractDao;
41 import org.thingsboard.server.dao.sql.query.AlarmQueryRepository; 41 import org.thingsboard.server.dao.sql.query.AlarmQueryRepository;
42 -import org.thingsboard.server.dao.util.SqlDao;  
43 42
44 import java.util.ArrayList; 43 import java.util.ArrayList;
45 import java.util.Collection; 44 import java.util.Collection;
@@ -54,7 +53,6 @@ import java.util.UUID; @@ -54,7 +53,6 @@ import java.util.UUID;
54 */ 53 */
55 @Slf4j 54 @Slf4j
56 @Component 55 @Component
57 -@SqlDao  
58 public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements AlarmDao { 56 public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements AlarmDao {
59 57
60 @Autowired 58 @Autowired
@@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository; @@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.dao.model.sql.AssetEntity; 23 import org.thingsboard.server.dao.model.sql.AssetEntity;
24 import org.thingsboard.server.dao.model.sql.AssetInfoEntity; 24 import org.thingsboard.server.dao.model.sql.AssetInfoEntity;
25 -import org.thingsboard.server.dao.util.SqlDao;  
26 25
27 import java.util.List; 26 import java.util.List;
28 import java.util.UUID; 27 import java.util.UUID;
@@ -30,7 +29,6 @@ import java.util.UUID; @@ -30,7 +29,6 @@ import java.util.UUID;
30 /** 29 /**
31 * Created by Valerii Sosliuk on 5/21/2017. 30 * Created by Valerii Sosliuk on 5/21/2017.
32 */ 31 */
33 -@SqlDao  
34 public interface AssetRepository extends PagingAndSortingRepository<AssetEntity, UUID> { 32 public interface AssetRepository extends PagingAndSortingRepository<AssetEntity, UUID> {
35 33
36 @Query("SELECT new org.thingsboard.server.dao.model.sql.AssetInfoEntity(a, c.title, c.additionalInfo) " + 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,7 +31,6 @@ import org.thingsboard.server.dao.asset.AssetDao;
31 import org.thingsboard.server.dao.model.sql.AssetEntity; 31 import org.thingsboard.server.dao.model.sql.AssetEntity;
32 import org.thingsboard.server.dao.model.sql.AssetInfoEntity; 32 import org.thingsboard.server.dao.model.sql.AssetInfoEntity;
33 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 33 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
34 -import org.thingsboard.server.dao.util.SqlDao;  
35 34
36 import java.util.ArrayList; 35 import java.util.ArrayList;
37 import java.util.Collections; 36 import java.util.Collections;
@@ -44,7 +43,6 @@ import java.util.UUID; @@ -44,7 +43,6 @@ import java.util.UUID;
44 * Created by Valerii Sosliuk on 5/19/2017. 43 * Created by Valerii Sosliuk on 5/19/2017.
45 */ 44 */
46 @Component 45 @Component
47 -@SqlDao  
48 public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> implements AssetDao { 46 public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> implements AssetDao {
49 47
50 @Autowired 48 @Autowired
@@ -25,7 +25,6 @@ import org.springframework.transaction.TransactionStatus; @@ -25,7 +25,6 @@ import org.springframework.transaction.TransactionStatus;
25 import org.springframework.transaction.support.TransactionCallbackWithoutResult; 25 import org.springframework.transaction.support.TransactionCallbackWithoutResult;
26 import org.springframework.transaction.support.TransactionTemplate; 26 import org.springframework.transaction.support.TransactionTemplate;
27 import org.thingsboard.server.dao.model.sql.AttributeKvEntity; 27 import org.thingsboard.server.dao.model.sql.AttributeKvEntity;
28 -import org.thingsboard.server.dao.util.SqlDao;  
29 28
30 import java.sql.PreparedStatement; 29 import java.sql.PreparedStatement;
31 import java.sql.SQLException; 30 import java.sql.SQLException;
@@ -35,7 +34,6 @@ import java.util.ArrayList; @@ -35,7 +34,6 @@ import java.util.ArrayList;
35 import java.util.List; 34 import java.util.List;
36 import java.util.regex.Pattern; 35 import java.util.regex.Pattern;
37 36
38 -@SqlDao  
39 @Repository 37 @Repository
40 @Slf4j 38 @Slf4j
41 public abstract class AttributeKvInsertRepository { 39 public abstract class AttributeKvInsertRepository {
@@ -23,12 +23,10 @@ import org.springframework.transaction.annotation.Transactional; @@ -23,12 +23,10 @@ import org.springframework.transaction.annotation.Transactional;
23 import org.thingsboard.server.common.data.EntityType; 23 import org.thingsboard.server.common.data.EntityType;
24 import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey; 24 import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey;
25 import org.thingsboard.server.dao.model.sql.AttributeKvEntity; 25 import org.thingsboard.server.dao.model.sql.AttributeKvEntity;
26 -import org.thingsboard.server.dao.util.SqlDao;  
27 26
28 import java.util.List; 27 import java.util.List;
29 import java.util.UUID; 28 import java.util.UUID;
30 29
31 -@SqlDao  
32 public interface AttributeKvRepository extends CrudRepository<AttributeKvEntity, AttributeKvCompositeKey> { 30 public interface AttributeKvRepository extends CrudRepository<AttributeKvEntity, AttributeKvCompositeKey> {
33 31
34 @Query("SELECT a FROM AttributeKvEntity a WHERE a.id.entityType = :entityType " + 32 @Query("SELECT a FROM AttributeKvEntity a WHERE a.id.entityType = :entityType " +
@@ -19,12 +19,10 @@ import org.springframework.stereotype.Repository; @@ -19,12 +19,10 @@ import org.springframework.stereotype.Repository;
19 import org.springframework.transaction.annotation.Transactional; 19 import org.springframework.transaction.annotation.Transactional;
20 import org.thingsboard.server.dao.model.sql.AttributeKvEntity; 20 import org.thingsboard.server.dao.model.sql.AttributeKvEntity;
21 import org.thingsboard.server.dao.util.HsqlDao; 21 import org.thingsboard.server.dao.util.HsqlDao;
22 -import org.thingsboard.server.dao.util.SqlDao;  
23 22
24 import java.sql.Types; 23 import java.sql.Types;
25 import java.util.List; 24 import java.util.List;
26 25
27 -@SqlDao  
28 @HsqlDao 26 @HsqlDao
29 @Repository 27 @Repository
30 @Transactional 28 @Transactional
@@ -34,7 +34,6 @@ import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; @@ -34,7 +34,6 @@ import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService;
34 import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; 34 import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent;
35 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; 35 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams;
36 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; 36 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper;
37 -import org.thingsboard.server.dao.util.SqlDao;  
38 37
39 import javax.annotation.PostConstruct; 38 import javax.annotation.PostConstruct;
40 import javax.annotation.PreDestroy; 39 import javax.annotation.PreDestroy;
@@ -46,7 +45,6 @@ import java.util.stream.Collectors; @@ -46,7 +45,6 @@ import java.util.stream.Collectors;
46 45
47 @Component 46 @Component
48 @Slf4j 47 @Slf4j
49 -@SqlDao  
50 public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService implements AttributesDao { 48 public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService implements AttributesDao {
51 49
52 @Autowired 50 @Autowired
@@ -18,9 +18,7 @@ package org.thingsboard.server.dao.sql.attributes; @@ -18,9 +18,7 @@ package org.thingsboard.server.dao.sql.attributes;
18 import org.springframework.stereotype.Repository; 18 import org.springframework.stereotype.Repository;
19 import org.springframework.transaction.annotation.Transactional; 19 import org.springframework.transaction.annotation.Transactional;
20 import org.thingsboard.server.dao.util.PsqlDao; 20 import org.thingsboard.server.dao.util.PsqlDao;
21 -import org.thingsboard.server.dao.util.SqlDao;  
22 21
23 -@SqlDao  
24 @PsqlDao 22 @PsqlDao
25 @Repository 23 @Repository
26 @Transactional 24 @Transactional
@@ -30,14 +30,12 @@ import org.thingsboard.server.dao.DaoUtil; @@ -30,14 +30,12 @@ import org.thingsboard.server.dao.DaoUtil;
30 import org.thingsboard.server.dao.audit.AuditLogDao; 30 import org.thingsboard.server.dao.audit.AuditLogDao;
31 import org.thingsboard.server.dao.model.sql.AuditLogEntity; 31 import org.thingsboard.server.dao.model.sql.AuditLogEntity;
32 import org.thingsboard.server.dao.sql.JpaAbstractDao; 32 import org.thingsboard.server.dao.sql.JpaAbstractDao;
33 -import org.thingsboard.server.dao.util.SqlDao;  
34 33
35 import java.util.List; 34 import java.util.List;
36 import java.util.Objects; 35 import java.util.Objects;
37 import java.util.UUID; 36 import java.util.UUID;
38 37
39 @Component 38 @Component
40 -@SqlDao  
41 public class JpaAuditLogDao extends JpaAbstractDao<AuditLogEntity, AuditLog> implements AuditLogDao { 39 public class JpaAuditLogDao extends JpaAbstractDao<AuditLogEntity, AuditLog> implements AuditLogDao {
42 40
43 @Autowired 41 @Autowired
@@ -23,14 +23,12 @@ import org.springframework.data.repository.query.Param; @@ -23,14 +23,12 @@ import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.common.data.plugin.ComponentScope; 23 import org.thingsboard.server.common.data.plugin.ComponentScope;
24 import org.thingsboard.server.common.data.plugin.ComponentType; 24 import org.thingsboard.server.common.data.plugin.ComponentType;
25 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity; 25 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity;
26 -import org.thingsboard.server.dao.util.SqlDao;  
27 26
28 import java.util.UUID; 27 import java.util.UUID;
29 28
30 /** 29 /**
31 * Created by Valerii Sosliuk on 5/6/2017. 30 * Created by Valerii Sosliuk on 5/6/2017.
32 */ 31 */
33 -@SqlDao  
34 public interface ComponentDescriptorRepository extends PagingAndSortingRepository<ComponentDescriptorEntity, UUID> { 32 public interface ComponentDescriptorRepository extends PagingAndSortingRepository<ComponentDescriptorEntity, UUID> {
35 33
36 ComponentDescriptorEntity findByClazz(String clazz); 34 ComponentDescriptorEntity findByClazz(String clazz);
@@ -18,11 +18,9 @@ package org.thingsboard.server.dao.sql.component; @@ -18,11 +18,9 @@ package org.thingsboard.server.dao.sql.component;
18 import org.springframework.stereotype.Repository; 18 import org.springframework.stereotype.Repository;
19 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity; 19 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity;
20 import org.thingsboard.server.dao.util.HsqlDao; 20 import org.thingsboard.server.dao.util.HsqlDao;
21 -import org.thingsboard.server.dao.util.SqlDao;  
22 21
23 import javax.persistence.Query; 22 import javax.persistence.Query;
24 23
25 -@SqlDao  
26 @HsqlDao 24 @HsqlDao
27 @Repository 25 @Repository
28 public class HsqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository { 26 public class HsqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository {
@@ -31,7 +31,6 @@ import org.thingsboard.server.dao.DaoUtil; @@ -31,7 +31,6 @@ import org.thingsboard.server.dao.DaoUtil;
31 import org.thingsboard.server.dao.component.ComponentDescriptorDao; 31 import org.thingsboard.server.dao.component.ComponentDescriptorDao;
32 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity; 32 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity;
33 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 33 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
34 -import org.thingsboard.server.dao.util.SqlDao;  
35 34
36 import java.util.Objects; 35 import java.util.Objects;
37 import java.util.Optional; 36 import java.util.Optional;
@@ -41,7 +40,6 @@ import java.util.UUID; @@ -41,7 +40,6 @@ import java.util.UUID;
41 * Created by Valerii Sosliuk on 5/6/2017. 40 * Created by Valerii Sosliuk on 5/6/2017.
42 */ 41 */
43 @Component 42 @Component
44 -@SqlDao  
45 public class JpaBaseComponentDescriptorDao extends JpaAbstractSearchTextDao<ComponentDescriptorEntity, ComponentDescriptor> 43 public class JpaBaseComponentDescriptorDao extends JpaAbstractSearchTextDao<ComponentDescriptorEntity, ComponentDescriptor>
46 implements ComponentDescriptorDao { 44 implements ComponentDescriptorDao {
47 45
@@ -18,9 +18,7 @@ package org.thingsboard.server.dao.sql.component; @@ -18,9 +18,7 @@ package org.thingsboard.server.dao.sql.component;
18 import org.springframework.stereotype.Repository; 18 import org.springframework.stereotype.Repository;
19 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity; 19 import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity;
20 import org.thingsboard.server.dao.util.PsqlDao; 20 import org.thingsboard.server.dao.util.PsqlDao;
21 -import org.thingsboard.server.dao.util.SqlDao;  
22 21
23 -@SqlDao  
24 @PsqlDao 22 @PsqlDao
25 @Repository 23 @Repository
26 public class PsqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository { 24 public class PsqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository {
@@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query; @@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query;
21 import org.springframework.data.repository.PagingAndSortingRepository; 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.dao.model.sql.CustomerEntity; 23 import org.thingsboard.server.dao.model.sql.CustomerEntity;
24 -import org.thingsboard.server.dao.util.SqlDao;  
25 24
26 import java.util.UUID; 25 import java.util.UUID;
27 26
28 /** 27 /**
29 * Created by Valerii Sosliuk on 5/6/2017. 28 * Created by Valerii Sosliuk on 5/6/2017.
30 */ 29 */
31 -@SqlDao  
32 public interface CustomerRepository extends PagingAndSortingRepository<CustomerEntity, UUID> { 30 public interface CustomerRepository extends PagingAndSortingRepository<CustomerEntity, UUID> {
33 31
34 @Query("SELECT c FROM CustomerEntity c WHERE c.tenantId = :tenantId " + 32 @Query("SELECT c FROM CustomerEntity c WHERE c.tenantId = :tenantId " +
@@ -25,7 +25,6 @@ import org.thingsboard.server.dao.DaoUtil; @@ -25,7 +25,6 @@ import org.thingsboard.server.dao.DaoUtil;
25 import org.thingsboard.server.dao.customer.CustomerDao; 25 import org.thingsboard.server.dao.customer.CustomerDao;
26 import org.thingsboard.server.dao.model.sql.CustomerEntity; 26 import org.thingsboard.server.dao.model.sql.CustomerEntity;
27 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 27 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
28 -import org.thingsboard.server.dao.util.SqlDao;  
29 28
30 import java.util.Objects; 29 import java.util.Objects;
31 import java.util.Optional; 30 import java.util.Optional;
@@ -35,7 +34,6 @@ import java.util.UUID; @@ -35,7 +34,6 @@ import java.util.UUID;
35 * Created by Valerii Sosliuk on 5/6/2017. 34 * Created by Valerii Sosliuk on 5/6/2017.
36 */ 35 */
37 @Component 36 @Component
38 -@SqlDao  
39 public class JpaCustomerDao extends JpaAbstractSearchTextDao<CustomerEntity, Customer> implements CustomerDao { 37 public class JpaCustomerDao extends JpaAbstractSearchTextDao<CustomerEntity, Customer> implements CustomerDao {
40 38
41 @Autowired 39 @Autowired
@@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query; @@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query;
21 import org.springframework.data.repository.PagingAndSortingRepository; 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.dao.model.sql.DashboardInfoEntity; 23 import org.thingsboard.server.dao.model.sql.DashboardInfoEntity;
24 -import org.thingsboard.server.dao.util.SqlDao;  
25 24
26 import java.util.UUID; 25 import java.util.UUID;
27 26
28 /** 27 /**
29 * Created by Valerii Sosliuk on 5/6/2017. 28 * Created by Valerii Sosliuk on 5/6/2017.
30 */ 29 */
31 -@SqlDao  
32 public interface DashboardInfoRepository extends PagingAndSortingRepository<DashboardInfoEntity, UUID> { 30 public interface DashboardInfoRepository extends PagingAndSortingRepository<DashboardInfoEntity, UUID> {
33 31
34 @Query("SELECT di FROM DashboardInfoEntity di WHERE di.tenantId = :tenantId " + 32 @Query("SELECT di FROM DashboardInfoEntity di WHERE di.tenantId = :tenantId " +
@@ -17,13 +17,11 @@ package org.thingsboard.server.dao.sql.dashboard; @@ -17,13 +17,11 @@ package org.thingsboard.server.dao.sql.dashboard;
17 17
18 import org.springframework.data.repository.CrudRepository; 18 import org.springframework.data.repository.CrudRepository;
19 import org.thingsboard.server.dao.model.sql.DashboardEntity; 19 import org.thingsboard.server.dao.model.sql.DashboardEntity;
20 -import org.thingsboard.server.dao.util.SqlDao;  
21 20
22 import java.util.UUID; 21 import java.util.UUID;
23 22
24 /** 23 /**
25 * Created by Valerii Sosliuk on 5/6/2017. 24 * Created by Valerii Sosliuk on 5/6/2017.
26 */ 25 */
27 -@SqlDao  
28 public interface DashboardRepository extends CrudRepository<DashboardEntity, UUID> { 26 public interface DashboardRepository extends CrudRepository<DashboardEntity, UUID> {
29 } 27 }
@@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.Dashboard; @@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.Dashboard;
22 import org.thingsboard.server.dao.dashboard.DashboardDao; 22 import org.thingsboard.server.dao.dashboard.DashboardDao;
23 import org.thingsboard.server.dao.model.sql.DashboardEntity; 23 import org.thingsboard.server.dao.model.sql.DashboardEntity;
24 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 24 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
25 -import org.thingsboard.server.dao.util.SqlDao;  
26 25
27 import java.util.UUID; 26 import java.util.UUID;
28 27
@@ -30,7 +29,6 @@ import java.util.UUID; @@ -30,7 +29,6 @@ import java.util.UUID;
30 * Created by Valerii Sosliuk on 5/6/2017. 29 * Created by Valerii Sosliuk on 5/6/2017.
31 */ 30 */
32 @Component 31 @Component
33 -@SqlDao  
34 public class JpaDashboardDao extends JpaAbstractSearchTextDao<DashboardEntity, Dashboard> implements DashboardDao { 32 public class JpaDashboardDao extends JpaAbstractSearchTextDao<DashboardEntity, Dashboard> implements DashboardDao {
35 33
36 @Autowired 34 @Autowired
@@ -27,7 +27,6 @@ import org.thingsboard.server.dao.dashboard.DashboardInfoDao; @@ -27,7 +27,6 @@ import org.thingsboard.server.dao.dashboard.DashboardInfoDao;
27 import org.thingsboard.server.dao.model.sql.DashboardInfoEntity; 27 import org.thingsboard.server.dao.model.sql.DashboardInfoEntity;
28 import org.thingsboard.server.dao.relation.RelationDao; 28 import org.thingsboard.server.dao.relation.RelationDao;
29 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 29 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
30 -import org.thingsboard.server.dao.util.SqlDao;  
31 30
32 import java.util.Objects; 31 import java.util.Objects;
33 import java.util.UUID; 32 import java.util.UUID;
@@ -37,7 +36,6 @@ import java.util.UUID; @@ -37,7 +36,6 @@ import java.util.UUID;
37 */ 36 */
38 @Slf4j 37 @Slf4j
39 @Component 38 @Component
40 -@SqlDao  
41 public class JpaDashboardInfoDao extends JpaAbstractSearchTextDao<DashboardInfoEntity, DashboardInfo> implements DashboardInfoDao { 39 public class JpaDashboardInfoDao extends JpaAbstractSearchTextDao<DashboardInfoEntity, DashboardInfo> implements DashboardInfoDao {
42 40
43 @Autowired 41 @Autowired
@@ -17,14 +17,12 @@ package org.thingsboard.server.dao.sql.device; @@ -17,14 +17,12 @@ package org.thingsboard.server.dao.sql.device;
17 17
18 import org.springframework.data.repository.CrudRepository; 18 import org.springframework.data.repository.CrudRepository;
19 import org.thingsboard.server.dao.model.sql.DeviceCredentialsEntity; 19 import org.thingsboard.server.dao.model.sql.DeviceCredentialsEntity;
20 -import org.thingsboard.server.dao.util.SqlDao;  
21 20
22 import java.util.UUID; 21 import java.util.UUID;
23 22
24 /** 23 /**
25 * Created by Valerii Sosliuk on 5/6/2017. 24 * Created by Valerii Sosliuk on 5/6/2017.
26 */ 25 */
27 -@SqlDao  
28 public interface DeviceCredentialsRepository extends CrudRepository<DeviceCredentialsEntity, UUID> { 26 public interface DeviceCredentialsRepository extends CrudRepository<DeviceCredentialsEntity, UUID> {
29 27
30 DeviceCredentialsEntity findByDeviceId(UUID deviceId); 28 DeviceCredentialsEntity findByDeviceId(UUID deviceId);
@@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository; @@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.dao.model.sql.DeviceEntity; 23 import org.thingsboard.server.dao.model.sql.DeviceEntity;
24 import org.thingsboard.server.dao.model.sql.DeviceInfoEntity; 24 import org.thingsboard.server.dao.model.sql.DeviceInfoEntity;
25 -import org.thingsboard.server.dao.util.SqlDao;  
26 25
27 import java.util.List; 26 import java.util.List;
28 import java.util.UUID; 27 import java.util.UUID;
@@ -30,7 +29,6 @@ import java.util.UUID; @@ -30,7 +29,6 @@ import java.util.UUID;
30 /** 29 /**
31 * Created by Valerii Sosliuk on 5/6/2017. 30 * Created by Valerii Sosliuk on 5/6/2017.
32 */ 31 */
33 -@SqlDao  
34 public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntity, UUID> { 32 public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntity, UUID> {
35 33
36 @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " + 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,7 +24,6 @@ import org.thingsboard.server.dao.DaoUtil;
24 import org.thingsboard.server.dao.device.DeviceCredentialsDao; 24 import org.thingsboard.server.dao.device.DeviceCredentialsDao;
25 import org.thingsboard.server.dao.model.sql.DeviceCredentialsEntity; 25 import org.thingsboard.server.dao.model.sql.DeviceCredentialsEntity;
26 import org.thingsboard.server.dao.sql.JpaAbstractDao; 26 import org.thingsboard.server.dao.sql.JpaAbstractDao;
27 -import org.thingsboard.server.dao.util.SqlDao;  
28 27
29 import java.util.UUID; 28 import java.util.UUID;
30 29
@@ -32,7 +31,6 @@ import java.util.UUID; @@ -32,7 +31,6 @@ import java.util.UUID;
32 * Created by Valerii Sosliuk on 5/6/2017. 31 * Created by Valerii Sosliuk on 5/6/2017.
33 */ 32 */
34 @Component 33 @Component
35 -@SqlDao  
36 public class JpaDeviceCredentialsDao extends JpaAbstractDao<DeviceCredentialsEntity, DeviceCredentials> implements DeviceCredentialsDao { 34 public class JpaDeviceCredentialsDao extends JpaAbstractDao<DeviceCredentialsEntity, DeviceCredentials> implements DeviceCredentialsDao {
37 35
38 @Autowired 36 @Autowired
@@ -32,7 +32,6 @@ import org.thingsboard.server.dao.device.DeviceDao; @@ -32,7 +32,6 @@ import org.thingsboard.server.dao.device.DeviceDao;
32 import org.thingsboard.server.dao.model.sql.DeviceEntity; 32 import org.thingsboard.server.dao.model.sql.DeviceEntity;
33 import org.thingsboard.server.dao.model.sql.DeviceInfoEntity; 33 import org.thingsboard.server.dao.model.sql.DeviceInfoEntity;
34 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 34 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
35 -import org.thingsboard.server.dao.util.SqlDao;  
36 35
37 import java.util.ArrayList; 36 import java.util.ArrayList;
38 import java.util.Collections; 37 import java.util.Collections;
@@ -45,7 +44,6 @@ import java.util.UUID; @@ -45,7 +44,6 @@ import java.util.UUID;
45 * Created by Valerii Sosliuk on 5/6/2017. 44 * Created by Valerii Sosliuk on 5/6/2017.
46 */ 45 */
47 @Component 46 @Component
48 -@SqlDao  
49 public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao { 47 public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao {
50 48
51 @Autowired 49 @Autowired
@@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository; @@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.dao.model.sql.EntityViewEntity; 23 import org.thingsboard.server.dao.model.sql.EntityViewEntity;
24 import org.thingsboard.server.dao.model.sql.EntityViewInfoEntity; 24 import org.thingsboard.server.dao.model.sql.EntityViewInfoEntity;
25 -import org.thingsboard.server.dao.util.SqlDao;  
26 25
27 import java.util.List; 26 import java.util.List;
28 import java.util.UUID; 27 import java.util.UUID;
@@ -30,7 +29,6 @@ import java.util.UUID; @@ -30,7 +29,6 @@ import java.util.UUID;
30 /** 29 /**
31 * Created by Victor Basanets on 8/31/2017. 30 * Created by Victor Basanets on 8/31/2017.
32 */ 31 */
33 -@SqlDao  
34 public interface EntityViewRepository extends PagingAndSortingRepository<EntityViewEntity, UUID> { 32 public interface EntityViewRepository extends PagingAndSortingRepository<EntityViewEntity, UUID> {
35 33
36 @Query("SELECT new org.thingsboard.server.dao.model.sql.EntityViewInfoEntity(e, c.title, c.additionalInfo) " + 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,7 +31,6 @@ import org.thingsboard.server.dao.entityview.EntityViewDao;
31 import org.thingsboard.server.dao.model.sql.EntityViewEntity; 31 import org.thingsboard.server.dao.model.sql.EntityViewEntity;
32 import org.thingsboard.server.dao.model.sql.EntityViewInfoEntity; 32 import org.thingsboard.server.dao.model.sql.EntityViewInfoEntity;
33 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 33 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
34 -import org.thingsboard.server.dao.util.SqlDao;  
35 34
36 import java.util.ArrayList; 35 import java.util.ArrayList;
37 import java.util.Collections; 36 import java.util.Collections;
@@ -44,7 +43,6 @@ import java.util.UUID; @@ -44,7 +43,6 @@ import java.util.UUID;
44 * Created by Victor Basanets on 8/31/2017. 43 * Created by Victor Basanets on 8/31/2017.
45 */ 44 */
46 @Component 45 @Component
47 -@SqlDao  
48 public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity, EntityView> 46 public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity, EntityView>
49 implements EntityViewDao { 47 implements EntityViewDao {
50 48
@@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository; @@ -22,7 +22,6 @@ import org.springframework.data.repository.PagingAndSortingRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.common.data.EntityType; 23 import org.thingsboard.server.common.data.EntityType;
24 import org.thingsboard.server.dao.model.sql.EventEntity; 24 import org.thingsboard.server.dao.model.sql.EventEntity;
25 -import org.thingsboard.server.dao.util.SqlDao;  
26 25
27 import java.util.List; 26 import java.util.List;
28 import java.util.UUID; 27 import java.util.UUID;
@@ -30,7 +29,6 @@ import java.util.UUID; @@ -30,7 +29,6 @@ import java.util.UUID;
30 /** 29 /**
31 * Created by Valerii Sosliuk on 5/3/2017. 30 * Created by Valerii Sosliuk on 5/3/2017.
32 */ 31 */
33 -@SqlDao  
34 public interface EventRepository extends PagingAndSortingRepository<EventEntity, UUID> { 32 public interface EventRepository extends PagingAndSortingRepository<EventEntity, UUID> {
35 33
36 EventEntity findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid(UUID tenantId, 34 EventEntity findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid(UUID tenantId,
@@ -18,11 +18,9 @@ package org.thingsboard.server.dao.sql.event; @@ -18,11 +18,9 @@ package org.thingsboard.server.dao.sql.event;
18 import org.springframework.stereotype.Repository; 18 import org.springframework.stereotype.Repository;
19 import org.thingsboard.server.dao.model.sql.EventEntity; 19 import org.thingsboard.server.dao.model.sql.EventEntity;
20 import org.thingsboard.server.dao.util.HsqlDao; 20 import org.thingsboard.server.dao.util.HsqlDao;
21 -import org.thingsboard.server.dao.util.SqlDao;  
22 21
23 import javax.persistence.Query; 22 import javax.persistence.Query;
24 23
25 -@SqlDao  
26 @HsqlDao 24 @HsqlDao
27 @Repository 25 @Repository
28 public class HsqlEventInsertRepository extends AbstractEventInsertRepository { 26 public class HsqlEventInsertRepository extends AbstractEventInsertRepository {
@@ -21,7 +21,6 @@ import lombok.extern.slf4j.Slf4j; @@ -21,7 +21,6 @@ import lombok.extern.slf4j.Slf4j;
21 import org.apache.commons.lang3.StringUtils; 21 import org.apache.commons.lang3.StringUtils;
22 import org.springframework.beans.factory.annotation.Autowired; 22 import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.data.domain.PageRequest; 23 import org.springframework.data.domain.PageRequest;
24 -import org.springframework.data.jpa.domain.Specification;  
25 import org.springframework.data.repository.CrudRepository; 24 import org.springframework.data.repository.CrudRepository;
26 import org.springframework.stereotype.Component; 25 import org.springframework.stereotype.Component;
27 import org.thingsboard.server.common.data.Event; 26 import org.thingsboard.server.common.data.Event;
@@ -34,10 +33,7 @@ import org.thingsboard.server.dao.DaoUtil; @@ -34,10 +33,7 @@ import org.thingsboard.server.dao.DaoUtil;
34 import org.thingsboard.server.dao.event.EventDao; 33 import org.thingsboard.server.dao.event.EventDao;
35 import org.thingsboard.server.dao.model.sql.EventEntity; 34 import org.thingsboard.server.dao.model.sql.EventEntity;
36 import org.thingsboard.server.dao.sql.JpaAbstractDao; 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 import java.util.List; 37 import java.util.List;
42 import java.util.Objects; 38 import java.util.Objects;
43 import java.util.Optional; 39 import java.util.Optional;
@@ -50,7 +46,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; @@ -50,7 +46,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
50 */ 46 */
51 @Slf4j 47 @Slf4j
52 @Component 48 @Component
53 -@SqlDao  
54 public class JpaBaseEventDao extends JpaAbstractDao<EventEntity, Event> implements EventDao { 49 public class JpaBaseEventDao extends JpaAbstractDao<EventEntity, Event> implements EventDao {
55 50
56 private final UUID systemTenantId = NULL_UUID; 51 private final UUID systemTenantId = NULL_UUID;
@@ -19,10 +19,8 @@ import lombok.extern.slf4j.Slf4j; @@ -19,10 +19,8 @@ import lombok.extern.slf4j.Slf4j;
19 import org.springframework.stereotype.Repository; 19 import org.springframework.stereotype.Repository;
20 import org.thingsboard.server.dao.model.sql.EventEntity; 20 import org.thingsboard.server.dao.model.sql.EventEntity;
21 import org.thingsboard.server.dao.util.PsqlDao; 21 import org.thingsboard.server.dao.util.PsqlDao;
22 -import org.thingsboard.server.dao.util.SqlDao;  
23 22
24 @Slf4j 23 @Slf4j
25 -@SqlDao  
26 @PsqlDao 24 @PsqlDao
27 @Repository 25 @Repository
28 public class PsqlEventInsertRepository extends AbstractEventInsertRepository { 26 public class PsqlEventInsertRepository extends AbstractEventInsertRepository {
@@ -39,7 +39,6 @@ import org.thingsboard.server.common.data.query.EntityDataSortOrder; @@ -39,7 +39,6 @@ import org.thingsboard.server.common.data.query.EntityDataSortOrder;
39 import org.thingsboard.server.common.data.query.EntityKey; 39 import org.thingsboard.server.common.data.query.EntityKey;
40 import org.thingsboard.server.common.data.query.EntityKeyType; 40 import org.thingsboard.server.common.data.query.EntityKeyType;
41 import org.thingsboard.server.dao.model.ModelConstants; 41 import org.thingsboard.server.dao.model.ModelConstants;
42 -import org.thingsboard.server.dao.util.SqlDao;  
43 42
44 import java.util.ArrayList; 43 import java.util.ArrayList;
45 import java.util.Arrays; 44 import java.util.Arrays;
@@ -52,7 +51,6 @@ import java.util.Objects; @@ -52,7 +51,6 @@ import java.util.Objects;
52 import java.util.Set; 51 import java.util.Set;
53 import java.util.stream.Collectors; 52 import java.util.stream.Collectors;
54 53
55 -@SqlDao  
56 @Repository 54 @Repository
57 @Slf4j 55 @Slf4j
58 public class DefaultAlarmQueryRepository implements AlarmQueryRepository { 56 public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
@@ -50,7 +50,6 @@ import org.thingsboard.server.common.data.query.RelationsQueryFilter; @@ -50,7 +50,6 @@ import org.thingsboard.server.common.data.query.RelationsQueryFilter;
50 import org.thingsboard.server.common.data.query.SingleEntityFilter; 50 import org.thingsboard.server.common.data.query.SingleEntityFilter;
51 import org.thingsboard.server.common.data.relation.EntitySearchDirection; 51 import org.thingsboard.server.common.data.relation.EntitySearchDirection;
52 import org.thingsboard.server.common.data.relation.EntityTypeFilter; 52 import org.thingsboard.server.common.data.relation.EntityTypeFilter;
53 -import org.thingsboard.server.dao.util.SqlDao;  
54 53
55 import java.util.Arrays; 54 import java.util.Arrays;
56 import java.util.Collections; 55 import java.util.Collections;
@@ -61,7 +60,6 @@ import java.util.Optional; @@ -61,7 +60,6 @@ import java.util.Optional;
61 import java.util.UUID; 60 import java.util.UUID;
62 import java.util.stream.Collectors; 61 import java.util.stream.Collectors;
63 62
64 -@SqlDao  
65 @Repository 63 @Repository
66 @Slf4j 64 @Slf4j
67 public class DefaultEntityQueryRepository implements EntityQueryRepository { 65 public class DefaultEntityQueryRepository implements EntityQueryRepository {
@@ -24,10 +24,8 @@ import org.thingsboard.server.common.data.query.EntityCountQuery; @@ -24,10 +24,8 @@ import org.thingsboard.server.common.data.query.EntityCountQuery;
24 import org.thingsboard.server.common.data.query.EntityData; 24 import org.thingsboard.server.common.data.query.EntityData;
25 import org.thingsboard.server.common.data.query.EntityDataQuery; 25 import org.thingsboard.server.common.data.query.EntityDataQuery;
26 import org.thingsboard.server.dao.entity.EntityQueryDao; 26 import org.thingsboard.server.dao.entity.EntityQueryDao;
27 -import org.thingsboard.server.dao.util.SqlDao;  
28 27
29 @Component 28 @Component
30 -@SqlDao  
31 public class JpaEntityQueryDao implements EntityQueryDao { 29 public class JpaEntityQueryDao implements EntityQueryDao {
32 30
33 @Autowired 31 @Autowired
@@ -20,12 +20,10 @@ import org.springframework.transaction.annotation.Transactional; @@ -20,12 +20,10 @@ import org.springframework.transaction.annotation.Transactional;
20 import org.thingsboard.server.dao.model.sql.RelationCompositeKey; 20 import org.thingsboard.server.dao.model.sql.RelationCompositeKey;
21 import org.thingsboard.server.dao.model.sql.RelationEntity; 21 import org.thingsboard.server.dao.model.sql.RelationEntity;
22 import org.thingsboard.server.dao.util.HsqlDao; 22 import org.thingsboard.server.dao.util.HsqlDao;
23 -import org.thingsboard.server.dao.util.SqlDao;  
24 23
25 import javax.persistence.Query; 24 import javax.persistence.Query;
26 25
27 @HsqlDao 26 @HsqlDao
28 -@SqlDao  
29 @Repository 27 @Repository
30 @Transactional 28 @Transactional
31 public class HsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository { 29 public class HsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository {
@@ -30,7 +30,6 @@ import org.thingsboard.server.dao.model.sql.RelationCompositeKey; @@ -30,7 +30,6 @@ import org.thingsboard.server.dao.model.sql.RelationCompositeKey;
30 import org.thingsboard.server.dao.model.sql.RelationEntity; 30 import org.thingsboard.server.dao.model.sql.RelationEntity;
31 import org.thingsboard.server.dao.relation.RelationDao; 31 import org.thingsboard.server.dao.relation.RelationDao;
32 import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; 32 import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService;
33 -import org.thingsboard.server.dao.util.SqlDao;  
34 33
35 import javax.persistence.criteria.Predicate; 34 import javax.persistence.criteria.Predicate;
36 import java.util.ArrayList; 35 import java.util.ArrayList;
@@ -41,7 +40,6 @@ import java.util.List; @@ -41,7 +40,6 @@ import java.util.List;
41 */ 40 */
42 @Slf4j 41 @Slf4j
43 @Component 42 @Component
44 -@SqlDao  
45 public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService implements RelationDao { 43 public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService implements RelationDao {
46 44
47 @Autowired 45 @Autowired
@@ -19,10 +19,8 @@ import org.springframework.stereotype.Repository; @@ -19,10 +19,8 @@ import org.springframework.stereotype.Repository;
19 import org.springframework.transaction.annotation.Transactional; 19 import org.springframework.transaction.annotation.Transactional;
20 import org.thingsboard.server.dao.model.sql.RelationEntity; 20 import org.thingsboard.server.dao.model.sql.RelationEntity;
21 import org.thingsboard.server.dao.util.PsqlDao; 21 import org.thingsboard.server.dao.util.PsqlDao;
22 -import org.thingsboard.server.dao.util.SqlDao;  
23 22
24 @PsqlDao 23 @PsqlDao
25 -@SqlDao  
26 @Repository 24 @Repository
27 @Transactional 25 @Transactional
28 public class PsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository { 26 public class PsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository {
@@ -20,12 +20,10 @@ import org.springframework.data.repository.CrudRepository; @@ -20,12 +20,10 @@ import org.springframework.data.repository.CrudRepository;
20 import org.springframework.transaction.annotation.Transactional; 20 import org.springframework.transaction.annotation.Transactional;
21 import org.thingsboard.server.dao.model.sql.RelationCompositeKey; 21 import org.thingsboard.server.dao.model.sql.RelationCompositeKey;
22 import org.thingsboard.server.dao.model.sql.RelationEntity; 22 import org.thingsboard.server.dao.model.sql.RelationEntity;
23 -import org.thingsboard.server.dao.util.SqlDao;  
24 23
25 import java.util.List; 24 import java.util.List;
26 import java.util.UUID; 25 import java.util.UUID;
27 26
28 -@SqlDao  
29 public interface RelationRepository 27 public interface RelationRepository
30 extends CrudRepository<RelationEntity, RelationCompositeKey>, JpaSpecificationExecutor<RelationEntity> { 28 extends CrudRepository<RelationEntity, RelationCompositeKey>, JpaSpecificationExecutor<RelationEntity> {
31 29
@@ -26,14 +26,12 @@ import org.thingsboard.server.dao.DaoUtil; @@ -26,14 +26,12 @@ import org.thingsboard.server.dao.DaoUtil;
26 import org.thingsboard.server.dao.model.sql.RuleChainEntity; 26 import org.thingsboard.server.dao.model.sql.RuleChainEntity;
27 import org.thingsboard.server.dao.rule.RuleChainDao; 27 import org.thingsboard.server.dao.rule.RuleChainDao;
28 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 28 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
29 -import org.thingsboard.server.dao.util.SqlDao;  
30 29
31 import java.util.Objects; 30 import java.util.Objects;
32 import java.util.UUID; 31 import java.util.UUID;
33 32
34 @Slf4j 33 @Slf4j
35 @Component 34 @Component
36 -@SqlDao  
37 public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, RuleChain> implements RuleChainDao { 35 public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, RuleChain> implements RuleChainDao {
38 36
39 @Autowired 37 @Autowired
@@ -23,11 +23,9 @@ import org.thingsboard.server.common.data.rule.RuleNode; @@ -23,11 +23,9 @@ import org.thingsboard.server.common.data.rule.RuleNode;
23 import org.thingsboard.server.dao.model.sql.RuleNodeEntity; 23 import org.thingsboard.server.dao.model.sql.RuleNodeEntity;
24 import org.thingsboard.server.dao.rule.RuleNodeDao; 24 import org.thingsboard.server.dao.rule.RuleNodeDao;
25 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 25 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
26 -import org.thingsboard.server.dao.util.SqlDao;  
27 26
28 @Slf4j 27 @Slf4j
29 @Component 28 @Component
30 -@SqlDao  
31 public class JpaRuleNodeDao extends JpaAbstractSearchTextDao<RuleNodeEntity, RuleNode> implements RuleNodeDao { 29 public class JpaRuleNodeDao extends JpaAbstractSearchTextDao<RuleNodeEntity, RuleNode> implements RuleNodeDao {
32 30
33 @Autowired 31 @Autowired
@@ -21,11 +21,9 @@ import org.springframework.data.jpa.repository.Query; @@ -21,11 +21,9 @@ import org.springframework.data.jpa.repository.Query;
21 import org.springframework.data.repository.PagingAndSortingRepository; 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.dao.model.sql.RuleChainEntity; 23 import org.thingsboard.server.dao.model.sql.RuleChainEntity;
24 -import org.thingsboard.server.dao.util.SqlDao;  
25 24
26 import java.util.UUID; 25 import java.util.UUID;
27 26
28 -@SqlDao  
29 public interface RuleChainRepository extends PagingAndSortingRepository<RuleChainEntity, UUID> { 27 public interface RuleChainRepository extends PagingAndSortingRepository<RuleChainEntity, UUID> {
30 28
31 @Query("SELECT rc FROM RuleChainEntity rc WHERE rc.tenantId = :tenantId " + 29 @Query("SELECT rc FROM RuleChainEntity rc WHERE rc.tenantId = :tenantId " +
@@ -17,9 +17,7 @@ package org.thingsboard.server.dao.sql.rule; @@ -17,9 +17,7 @@ package org.thingsboard.server.dao.sql.rule;
17 17
18 import org.springframework.data.repository.CrudRepository; 18 import org.springframework.data.repository.CrudRepository;
19 import org.thingsboard.server.dao.model.sql.RuleNodeEntity; 19 import org.thingsboard.server.dao.model.sql.RuleNodeEntity;
20 -import org.thingsboard.server.dao.util.SqlDao;  
21 20
22 -@SqlDao  
23 public interface RuleNodeRepository extends CrudRepository<RuleNodeEntity, String> { 21 public interface RuleNodeRepository extends CrudRepository<RuleNodeEntity, String> {
24 22
25 } 23 }
@@ -25,13 +25,11 @@ import org.thingsboard.server.dao.DaoUtil; @@ -25,13 +25,11 @@ import org.thingsboard.server.dao.DaoUtil;
25 import org.thingsboard.server.dao.model.sql.AdminSettingsEntity; 25 import org.thingsboard.server.dao.model.sql.AdminSettingsEntity;
26 import org.thingsboard.server.dao.settings.AdminSettingsDao; 26 import org.thingsboard.server.dao.settings.AdminSettingsDao;
27 import org.thingsboard.server.dao.sql.JpaAbstractDao; 27 import org.thingsboard.server.dao.sql.JpaAbstractDao;
28 -import org.thingsboard.server.dao.util.SqlDao;  
29 28
30 import java.util.UUID; 29 import java.util.UUID;
31 30
32 @Component 31 @Component
33 @Slf4j 32 @Slf4j
34 -@SqlDao  
35 public class JpaAdminSettingsDao extends JpaAbstractDao<AdminSettingsEntity, AdminSettings> implements AdminSettingsDao { 33 public class JpaAdminSettingsDao extends JpaAbstractDao<AdminSettingsEntity, AdminSettings> implements AdminSettingsDao {
36 34
37 @Autowired 35 @Autowired
@@ -26,7 +26,6 @@ import org.thingsboard.server.dao.DaoUtil; @@ -26,7 +26,6 @@ import org.thingsboard.server.dao.DaoUtil;
26 import org.thingsboard.server.dao.model.sql.TenantEntity; 26 import org.thingsboard.server.dao.model.sql.TenantEntity;
27 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 27 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
28 import org.thingsboard.server.dao.tenant.TenantDao; 28 import org.thingsboard.server.dao.tenant.TenantDao;
29 -import org.thingsboard.server.dao.util.SqlDao;  
30 29
31 import java.util.Objects; 30 import java.util.Objects;
32 import java.util.UUID; 31 import java.util.UUID;
@@ -36,7 +35,6 @@ import java.util.UUID; @@ -36,7 +35,6 @@ import java.util.UUID;
36 * Created by Valerii Sosliuk on 4/30/2017. 35 * Created by Valerii Sosliuk on 4/30/2017.
37 */ 36 */
38 @Component 37 @Component
39 -@SqlDao  
40 public class JpaTenantDao extends JpaAbstractSearchTextDao<TenantEntity, Tenant> implements TenantDao { 38 public class JpaTenantDao extends JpaAbstractSearchTextDao<TenantEntity, Tenant> implements TenantDao {
41 39
42 @Autowired 40 @Autowired
@@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query; @@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query;
21 import org.springframework.data.repository.PagingAndSortingRepository; 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.dao.model.sql.TenantEntity; 23 import org.thingsboard.server.dao.model.sql.TenantEntity;
24 -import org.thingsboard.server.dao.util.SqlDao;  
25 24
26 import java.util.UUID; 25 import java.util.UUID;
27 26
28 /** 27 /**
29 * Created by Valerii Sosliuk on 4/30/2017. 28 * Created by Valerii Sosliuk on 4/30/2017.
30 */ 29 */
31 -@SqlDao  
32 public interface TenantRepository extends PagingAndSortingRepository<TenantEntity, UUID> { 30 public interface TenantRepository extends PagingAndSortingRepository<TenantEntity, UUID> {
33 31
34 @Query("SELECT t FROM TenantEntity t WHERE t.region = :region " + 32 @Query("SELECT t FROM TenantEntity t WHERE t.region = :region " +
@@ -24,7 +24,6 @@ import org.thingsboard.server.dao.DaoUtil; @@ -24,7 +24,6 @@ import org.thingsboard.server.dao.DaoUtil;
24 import org.thingsboard.server.dao.model.sql.UserCredentialsEntity; 24 import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
25 import org.thingsboard.server.dao.sql.JpaAbstractDao; 25 import org.thingsboard.server.dao.sql.JpaAbstractDao;
26 import org.thingsboard.server.dao.user.UserCredentialsDao; 26 import org.thingsboard.server.dao.user.UserCredentialsDao;
27 -import org.thingsboard.server.dao.util.SqlDao;  
28 27
29 import java.util.UUID; 28 import java.util.UUID;
30 29
@@ -32,7 +31,6 @@ import java.util.UUID; @@ -32,7 +31,6 @@ import java.util.UUID;
32 * Created by Valerii Sosliuk on 4/22/2017. 31 * Created by Valerii Sosliuk on 4/22/2017.
33 */ 32 */
34 @Component 33 @Component
35 -@SqlDao  
36 public class JpaUserCredentialsDao extends JpaAbstractDao<UserCredentialsEntity, UserCredentials> implements UserCredentialsDao { 34 public class JpaUserCredentialsDao extends JpaAbstractDao<UserCredentialsEntity, UserCredentials> implements UserCredentialsDao {
37 35
38 @Autowired 36 @Autowired
@@ -27,7 +27,6 @@ import org.thingsboard.server.dao.DaoUtil; @@ -27,7 +27,6 @@ import org.thingsboard.server.dao.DaoUtil;
27 import org.thingsboard.server.dao.model.sql.UserEntity; 27 import org.thingsboard.server.dao.model.sql.UserEntity;
28 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 28 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
29 import org.thingsboard.server.dao.user.UserDao; 29 import org.thingsboard.server.dao.user.UserDao;
30 -import org.thingsboard.server.dao.util.SqlDao;  
31 30
32 import java.util.Objects; 31 import java.util.Objects;
33 import java.util.UUID; 32 import java.util.UUID;
@@ -38,7 +37,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; @@ -38,7 +37,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
38 * @author Valerii Sosliuk 37 * @author Valerii Sosliuk
39 */ 38 */
40 @Component 39 @Component
41 -@SqlDao  
42 public class JpaUserDao extends JpaAbstractSearchTextDao<UserEntity, User> implements UserDao { 40 public class JpaUserDao extends JpaAbstractSearchTextDao<UserEntity, User> implements UserDao {
43 41
44 @Autowired 42 @Autowired
@@ -17,14 +17,12 @@ package org.thingsboard.server.dao.sql.user; @@ -17,14 +17,12 @@ package org.thingsboard.server.dao.sql.user;
17 17
18 import org.springframework.data.repository.CrudRepository; 18 import org.springframework.data.repository.CrudRepository;
19 import org.thingsboard.server.dao.model.sql.UserCredentialsEntity; 19 import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
20 -import org.thingsboard.server.dao.util.SqlDao;  
21 20
22 import java.util.UUID; 21 import java.util.UUID;
23 22
24 /** 23 /**
25 * Created by Valerii Sosliuk on 4/22/2017. 24 * Created by Valerii Sosliuk on 4/22/2017.
26 */ 25 */
27 -@SqlDao  
28 public interface UserCredentialsRepository extends CrudRepository<UserCredentialsEntity, UUID> { 26 public interface UserCredentialsRepository extends CrudRepository<UserCredentialsEntity, UUID> {
29 27
30 UserCredentialsEntity findByUserId(UUID userId); 28 UserCredentialsEntity findByUserId(UUID userId);
@@ -22,14 +22,12 @@ import org.springframework.data.repository.PagingAndSortingRepository; @@ -22,14 +22,12 @@ import org.springframework.data.repository.PagingAndSortingRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.common.data.security.Authority; 23 import org.thingsboard.server.common.data.security.Authority;
24 import org.thingsboard.server.dao.model.sql.UserEntity; 24 import org.thingsboard.server.dao.model.sql.UserEntity;
25 -import org.thingsboard.server.dao.util.SqlDao;  
26 25
27 import java.util.UUID; 26 import java.util.UUID;
28 27
29 /** 28 /**
30 * @author Valerii Sosliuk 29 * @author Valerii Sosliuk
31 */ 30 */
32 -@SqlDao  
33 public interface UserRepository extends PagingAndSortingRepository<UserEntity, UUID> { 31 public interface UserRepository extends PagingAndSortingRepository<UserEntity, UUID> {
34 32
35 UserEntity findByEmail(String email); 33 UserEntity findByEmail(String email);
@@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.widget.WidgetType; @@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.widget.WidgetType;
22 import org.thingsboard.server.dao.DaoUtil; 22 import org.thingsboard.server.dao.DaoUtil;
23 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity; 23 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity;
24 import org.thingsboard.server.dao.sql.JpaAbstractDao; 24 import org.thingsboard.server.dao.sql.JpaAbstractDao;
25 -import org.thingsboard.server.dao.util.SqlDao;  
26 import org.thingsboard.server.dao.widget.WidgetTypeDao; 25 import org.thingsboard.server.dao.widget.WidgetTypeDao;
27 26
28 import java.util.List; 27 import java.util.List;
@@ -32,7 +31,6 @@ import java.util.UUID; @@ -32,7 +31,6 @@ import java.util.UUID;
32 * Created by Valerii Sosliuk on 4/29/2017. 31 * Created by Valerii Sosliuk on 4/29/2017.
33 */ 32 */
34 @Component 33 @Component
35 -@SqlDao  
36 public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeEntity, WidgetType> implements WidgetTypeDao { 34 public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeEntity, WidgetType> implements WidgetTypeDao {
37 35
38 @Autowired 36 @Autowired
@@ -25,7 +25,6 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; @@ -25,7 +25,6 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle;
25 import org.thingsboard.server.dao.DaoUtil; 25 import org.thingsboard.server.dao.DaoUtil;
26 import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity; 26 import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity;
27 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 27 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
28 -import org.thingsboard.server.dao.util.SqlDao;  
29 import org.thingsboard.server.dao.widget.WidgetsBundleDao; 28 import org.thingsboard.server.dao.widget.WidgetsBundleDao;
30 29
31 import java.util.Objects; 30 import java.util.Objects;
@@ -37,7 +36,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; @@ -37,7 +36,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
37 * Created by Valerii Sosliuk on 4/23/2017. 36 * Created by Valerii Sosliuk on 4/23/2017.
38 */ 37 */
39 @Component 38 @Component
40 -@SqlDao  
41 public class JpaWidgetsBundleDao extends JpaAbstractSearchTextDao<WidgetsBundleEntity, WidgetsBundle> implements WidgetsBundleDao { 39 public class JpaWidgetsBundleDao extends JpaAbstractSearchTextDao<WidgetsBundleEntity, WidgetsBundle> implements WidgetsBundleDao {
42 40
43 @Autowired 41 @Autowired
@@ -17,7 +17,6 @@ package org.thingsboard.server.dao.sql.widget; @@ -17,7 +17,6 @@ package org.thingsboard.server.dao.sql.widget;
17 17
18 import org.springframework.data.repository.CrudRepository; 18 import org.springframework.data.repository.CrudRepository;
19 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity; 19 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity;
20 -import org.thingsboard.server.dao.util.SqlDao;  
21 20
22 import java.util.List; 21 import java.util.List;
23 import java.util.UUID; 22 import java.util.UUID;
@@ -25,7 +24,6 @@ import java.util.UUID; @@ -25,7 +24,6 @@ import java.util.UUID;
25 /** 24 /**
26 * Created by Valerii Sosliuk on 4/29/2017. 25 * Created by Valerii Sosliuk on 4/29/2017.
27 */ 26 */
28 -@SqlDao  
29 public interface WidgetTypeRepository extends CrudRepository<WidgetTypeEntity, UUID> { 27 public interface WidgetTypeRepository extends CrudRepository<WidgetTypeEntity, UUID> {
30 28
31 List<WidgetTypeEntity> findByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias); 29 List<WidgetTypeEntity> findByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias);
@@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query; @@ -21,14 +21,12 @@ import org.springframework.data.jpa.repository.Query;
21 import org.springframework.data.repository.PagingAndSortingRepository; 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 import org.springframework.data.repository.query.Param; 22 import org.springframework.data.repository.query.Param;
23 import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity; 23 import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity;
24 -import org.thingsboard.server.dao.util.SqlDao;  
25 24
26 import java.util.UUID; 25 import java.util.UUID;
27 26
28 /** 27 /**
29 * Created by Valerii Sosliuk on 4/23/2017. 28 * Created by Valerii Sosliuk on 4/23/2017.
30 */ 29 */
31 -@SqlDao  
32 public interface WidgetsBundleRepository extends PagingAndSortingRepository<WidgetsBundleEntity, UUID> { 30 public interface WidgetsBundleRepository extends PagingAndSortingRepository<WidgetsBundleEntity, UUID> {
33 31
34 WidgetsBundleEntity findWidgetsBundleByTenantIdAndAlias(UUID tenantId, String alias); 32 WidgetsBundleEntity findWidgetsBundleByTenantIdAndAlias(UUID tenantId, String alias);
@@ -17,7 +17,6 @@ package org.thingsboard.server.dao.sqlts; @@ -17,7 +17,6 @@ package org.thingsboard.server.dao.sqlts;
17 17
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
20 -import com.google.common.util.concurrent.ListeningExecutorService;  
21 import com.google.common.util.concurrent.MoreExecutors; 20 import com.google.common.util.concurrent.MoreExecutors;
22 import com.google.common.util.concurrent.SettableFuture; 21 import com.google.common.util.concurrent.SettableFuture;
23 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
@@ -33,7 +32,6 @@ import org.thingsboard.server.common.data.kv.TsKvEntry; @@ -33,7 +32,6 @@ import org.thingsboard.server.common.data.kv.TsKvEntry;
33 import org.thingsboard.server.common.stats.StatsFactory; 32 import org.thingsboard.server.common.stats.StatsFactory;
34 import org.thingsboard.server.dao.DaoUtil; 33 import org.thingsboard.server.dao.DaoUtil;
35 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; 34 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity;
36 -import org.thingsboard.server.dao.sql.TbSqlBlockingQueue;  
37 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; 35 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams;
38 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; 36 import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper;
39 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; 37 import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository;
@@ -64,7 +62,6 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -64,7 +62,6 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
64 62
65 @PostConstruct 63 @PostConstruct
66 protected void init() { 64 protected void init() {
67 - super.init();  
68 TbSqlBlockingQueueParams tsParams = TbSqlBlockingQueueParams.builder() 65 TbSqlBlockingQueueParams tsParams = TbSqlBlockingQueueParams.builder()
69 .logName("TS") 66 .logName("TS")
70 .batchSize(tsBatchSize) 67 .batchSize(tsBatchSize)
@@ -80,7 +77,6 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -80,7 +77,6 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
80 77
81 @PreDestroy 78 @PreDestroy
82 protected void destroy() { 79 protected void destroy() {
83 - super.destroy();  
84 if (tsQueue != null) { 80 if (tsQueue != null) {
85 tsQueue.destroy(); 81 tsQueue.destroy();
86 } 82 }
@@ -99,26 +95,6 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -99,26 +95,6 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
99 } 95 }
100 96
101 @Override 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 public ListenableFuture<Void> savePartition(TenantId tenantId, EntityId entityId, long tsKvEntryTs, String key, long ttl) { 98 public ListenableFuture<Void> savePartition(TenantId tenantId, EntityId entityId, long tsKvEntryTs, String key, long ttl) {
123 return Futures.immediateFuture(null); 99 return Futures.immediateFuture(null);
124 } 100 }
@@ -134,7 +110,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -134,7 +110,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq
134 } 110 }
135 111
136 @Override 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 if (query.getAggregation() == Aggregation.NONE) { 114 if (query.getAggregation() == Aggregation.NONE) {
139 return findAllAsyncWithLimit(entityId, query); 115 return findAllAsyncWithLimit(entityId, query);
140 } else { 116 } else {
@@ -151,8 +127,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @@ -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 Integer keyId = getOrSaveKeyId(query.getKey()); 131 Integer keyId = getOrSaveKeyId(query.getKey());
157 List<TsKvEntity> tsKvEntities = tsKvRepository.findAllWithLimit( 132 List<TsKvEntity> tsKvEntities = tsKvRepository.findAllWithLimit(
158 entityId.getId(), 133 entityId.getId(),
@@ -16,96 +16,28 @@ @@ -16,96 +16,28 @@
16 package org.thingsboard.server.dao.sqlts; 16 package org.thingsboard.server.dao.sqlts;
17 17
18 import com.google.common.base.Function; 18 import com.google.common.base.Function;
19 -import com.google.common.collect.Lists;  
20 -import com.google.common.util.concurrent.FutureCallback;  
21 import com.google.common.util.concurrent.Futures; 19 import com.google.common.util.concurrent.Futures;
22 import com.google.common.util.concurrent.ListenableFuture; 20 import com.google.common.util.concurrent.ListenableFuture;
23 -import com.google.common.util.concurrent.MoreExecutors;  
24 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
25 -import org.hibernate.exception.ConstraintViolationException;  
26 import org.springframework.beans.factory.annotation.Autowired; 22 import org.springframework.beans.factory.annotation.Autowired;
27 import org.springframework.beans.factory.annotation.Value; 23 import org.springframework.beans.factory.annotation.Value;
28 import org.thingsboard.server.common.data.id.EntityId; 24 import org.thingsboard.server.common.data.id.EntityId;
29 import org.thingsboard.server.common.data.id.TenantId; 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 import org.thingsboard.server.common.data.kv.ReadTsKvQuery; 26 import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
35 -import org.thingsboard.server.common.data.kv.StringDataEntry;  
36 import org.thingsboard.server.common.data.kv.TsKvEntry; 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 import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; 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 import javax.annotation.Nullable; 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 import java.util.List; 31 import java.util.List;
59 -import java.util.Map;  
60 import java.util.Objects; 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 import java.util.stream.Collectors; 33 import java.util.stream.Collectors;
67 34
68 @Slf4j 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 @Autowired 38 @Autowired
104 protected ScheduledLogExecutorComponent logExecutor; 39 protected ScheduledLogExecutorComponent logExecutor;
105 40
106 - @Autowired  
107 - private StatsFactory statsFactory;  
108 -  
109 @Value("${sql.ts.batch_size:1000}") 41 @Value("${sql.ts.batch_size:1000}")
110 protected int tsBatchSize; 42 protected int tsBatchSize;
111 43
@@ -121,44 +53,10 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx @@ -121,44 +53,10 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
121 @Value("${sql.timescale.batch_threads:4}") 53 @Value("${sql.timescale.batch_threads:4}")
122 protected int timescaleBatchThreads; 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 protected ListenableFuture<List<TsKvEntry>> processFindAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries) { 56 protected ListenableFuture<List<TsKvEntry>> processFindAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries) {
159 List<ListenableFuture<List<TsKvEntry>>> futures = queries 57 List<ListenableFuture<List<TsKvEntry>>> futures = queries
160 .stream() 58 .stream()
161 - .map(query -> findAllAsync(entityId, query)) 59 + .map(query -> findAllAsync(tenantId, entityId, query))
162 .collect(Collectors.toList()); 60 .collect(Collectors.toList());
163 return Futures.transform(Futures.allAsList(futures), new Function<List<List<TsKvEntry>>, List<TsKvEntry>>() { 61 return Futures.transform(Futures.allAsList(futures), new Function<List<List<TsKvEntry>>, List<TsKvEntry>>() {
164 @Nullable 62 @Nullable
@@ -174,168 +72,4 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx @@ -174,168 +72,4 @@ public abstract class AbstractSqlTimeseriesDao extends JpaAbstractDaoListeningEx
174 } 72 }
175 }, service); 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,11 +18,11 @@ package org.thingsboard.server.dao.sqlts.dictionary;
18 import org.springframework.data.repository.CrudRepository; 18 import org.springframework.data.repository.CrudRepository;
19 import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary; 19 import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary;
20 import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionaryCompositeKey; 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 import java.util.Optional; 23 import java.util.Optional;
24 24
25 -@SqlTsAnyDao 25 +@SqlTsOrTsLatestAnyDao
26 public interface TsKvDictionaryRepository extends CrudRepository<TsKvDictionary, TsKvDictionaryCompositeKey> { 26 public interface TsKvDictionaryRepository extends CrudRepository<TsKvDictionary, TsKvDictionaryCompositeKey> {
27 27
28 Optional<TsKvDictionary> findByKeyId(int keyId); 28 Optional<TsKvDictionary> findByKeyId(int keyId);
@@ -22,14 +22,14 @@ import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; @@ -22,14 +22,14 @@ import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
22 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository; 22 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository;
23 import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository; 23 import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository;
24 import org.thingsboard.server.dao.util.HsqlDao; 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 import java.sql.PreparedStatement; 27 import java.sql.PreparedStatement;
28 import java.sql.SQLException; 28 import java.sql.SQLException;
29 import java.sql.Types; 29 import java.sql.Types;
30 import java.util.List; 30 import java.util.List;
31 31
32 -@SqlTsDao 32 +@SqlTsLatestDao
33 @HsqlDao 33 @HsqlDao
34 @Repository 34 @Repository
35 @Transactional 35 @Transactional
@@ -23,7 +23,7 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult; @@ -23,7 +23,7 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult;
23 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; 23 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
24 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository; 24 import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository;
25 import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository; 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 import java.sql.PreparedStatement; 28 import java.sql.PreparedStatement;
29 import java.sql.SQLException; 29 import java.sql.SQLException;
@@ -32,7 +32,7 @@ import java.util.ArrayList; @@ -32,7 +32,7 @@ import java.util.ArrayList;
32 import java.util.List; 32 import java.util.List;
33 33
34 34
35 -@PsqlTsAnyDao 35 +@PsqlTsLatestAnyDao
36 @Repository 36 @Repository
37 @Transactional 37 @Transactional
38 public class PsqlLatestInsertTsRepository extends AbstractInsertRepository implements InsertLatestTsRepository { 38 public class PsqlLatestInsertTsRepository extends AbstractInsertRepository implements InsertLatestTsRepository {
@@ -17,14 +17,14 @@ package org.thingsboard.server.dao.sqlts.latest; @@ -17,14 +17,14 @@ package org.thingsboard.server.dao.sqlts.latest;
17 17
18 import org.springframework.stereotype.Repository; 18 import org.springframework.stereotype.Repository;
19 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; 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 import javax.persistence.EntityManager; 22 import javax.persistence.EntityManager;
23 import javax.persistence.PersistenceContext; 23 import javax.persistence.PersistenceContext;
24 import java.util.List; 24 import java.util.List;
25 import java.util.UUID; 25 import java.util.UUID;
26 26
27 -@SqlTsAnyDao 27 +@SqlTsLatestAnyDao
28 @Repository 28 @Repository
29 public class SearchTsKvLatestRepository { 29 public class SearchTsKvLatestRepository {
30 30
@@ -18,9 +18,7 @@ package org.thingsboard.server.dao.sqlts.latest; @@ -18,9 +18,7 @@ package org.thingsboard.server.dao.sqlts.latest;
18 import org.springframework.data.repository.CrudRepository; 18 import org.springframework.data.repository.CrudRepository;
19 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestCompositeKey; 19 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestCompositeKey;
20 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; 20 import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity;
21 -import org.thingsboard.server.dao.util.SqlDao;  
22 21
23 -@SqlDao  
24 public interface TsKvLatestRepository extends CrudRepository<TsKvLatestEntity, TsKvLatestCompositeKey> { 22 public interface TsKvLatestRepository extends CrudRepository<TsKvLatestEntity, TsKvLatestCompositeKey> {
25 23
26 } 24 }
@@ -41,11 +41,10 @@ import java.util.Optional; @@ -41,11 +41,10 @@ import java.util.Optional;
41 import java.util.concurrent.ConcurrentHashMap; 41 import java.util.concurrent.ConcurrentHashMap;
42 import java.util.concurrent.locks.ReentrantLock; 42 import java.util.concurrent.locks.ReentrantLock;
43 43
44 -  
45 @Component 44 @Component
46 @Slf4j 45 @Slf4j
47 -@SqlTsDao  
48 @PsqlDao 46 @PsqlDao
  47 +@SqlTsDao
49 public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDao { 48 public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDao {
50 49
51 private final Map<Long, PsqlPartition> partitions = new ConcurrentHashMap<>(); 50 private final Map<Long, PsqlPartition> partitions = new ConcurrentHashMap<>();
@@ -18,7 +18,7 @@ package org.thingsboard.server.dao.sqlts.timescale; @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.sqlts.timescale;
18 import org.springframework.scheduling.annotation.Async; 18 import org.springframework.scheduling.annotation.Async;
19 import org.springframework.stereotype.Repository; 19 import org.springframework.stereotype.Repository;
20 import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; 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 import javax.persistence.EntityManager; 23 import javax.persistence.EntityManager;
24 import javax.persistence.PersistenceContext; 24 import javax.persistence.PersistenceContext;
@@ -27,7 +27,7 @@ import java.util.UUID; @@ -27,7 +27,7 @@ import java.util.UUID;
27 import java.util.concurrent.CompletableFuture; 27 import java.util.concurrent.CompletableFuture;
28 28
29 @Repository 29 @Repository
30 -@TimescaleDBTsDao 30 +@TimescaleDBTsOrTsLatestDao
31 public class AggregationRepository { 31 public class AggregationRepository {
32 32
33 public static final String FIND_AVG = "findAvg"; 33 public static final String FIND_AVG = "findAvg";
@@ -72,7 +72,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -72,7 +72,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
72 72
73 @PostConstruct 73 @PostConstruct
74 protected void init() { 74 protected void init() {
75 - super.init();  
76 TbSqlBlockingQueueParams tsParams = TbSqlBlockingQueueParams.builder() 75 TbSqlBlockingQueueParams tsParams = TbSqlBlockingQueueParams.builder()
77 .logName("TS Timescale") 76 .logName("TS Timescale")
78 .batchSize(tsBatchSize) 77 .batchSize(tsBatchSize)
@@ -89,14 +88,60 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -89,14 +88,60 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
89 88
90 @PreDestroy 89 @PreDestroy
91 protected void destroy() { 90 protected void destroy() {
92 - super.destroy();  
93 if (tsQueue != null) { 91 if (tsQueue != null) {
94 tsQueue.destroy(); 92 tsQueue.destroy();
95 } 93 }
96 } 94 }
97 95
98 @Override 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 if (query.getAggregation() == Aggregation.NONE) { 145 if (query.getAggregation() == Aggregation.NONE) {
101 return findAllAsyncWithLimit(entityId, query); 146 return findAllAsyncWithLimit(entityId, query);
102 } else { 147 } else {
@@ -108,8 +153,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -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 String strKey = query.getKey(); 157 String strKey = query.getKey();
114 Integer keyId = getOrSaveKeyId(strKey); 158 Integer keyId = getOrSaveKeyId(strKey);
115 List<TimescaleTsKvEntity> timescaleTsKvEntities = tsKvRepository.findAllWithLimit( 159 List<TimescaleTsKvEntity> timescaleTsKvEntities = tsKvRepository.findAllWithLimit(
@@ -153,73 +197,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @@ -153,73 +197,6 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements
153 }, MoreExecutors.directExecutor()); 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 private CompletableFuture<List<TimescaleTsKvEntity>> switchAggregation(String key, long startTs, long endTs, long timeBucket, Aggregation aggregation, UUID entityId) { 200 private CompletableFuture<List<TimescaleTsKvEntity>> switchAggregation(String key, long startTs, long endTs, long timeBucket, Aggregation aggregation, UUID entityId) {
224 switch (aggregation) { 201 switch (aggregation) {
225 case AVG: 202 case AVG:
@@ -23,12 +23,12 @@ import org.springframework.data.repository.query.Param; @@ -23,12 +23,12 @@ import org.springframework.data.repository.query.Param;
23 import org.springframework.transaction.annotation.Transactional; 23 import org.springframework.transaction.annotation.Transactional;
24 import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvCompositeKey; 24 import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvCompositeKey;
25 import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; 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 import java.util.List; 28 import java.util.List;
29 import java.util.UUID; 29 import java.util.UUID;
30 30
31 -@TimescaleDBTsDao 31 +@TimescaleDBTsOrTsLatestDao
32 public interface TsKvTimescaleRepository extends CrudRepository<TimescaleTsKvEntity, TimescaleTsKvCompositeKey> { 32 public interface TsKvTimescaleRepository extends CrudRepository<TimescaleTsKvEntity, TimescaleTsKvCompositeKey> {
33 33
34 @Query("SELECT tskv FROM TimescaleTsKvEntity tskv WHERE tskv.entityId = :entityId " + 34 @Query("SELECT tskv FROM TimescaleTsKvEntity tskv WHERE tskv.entityId = :entityId " +
@@ -24,13 +24,11 @@ import org.springframework.scheduling.annotation.Async; @@ -24,13 +24,11 @@ import org.springframework.scheduling.annotation.Async;
24 import org.springframework.transaction.annotation.Transactional; 24 import org.springframework.transaction.annotation.Transactional;
25 import org.thingsboard.server.dao.model.sqlts.ts.TsKvCompositeKey; 25 import org.thingsboard.server.dao.model.sqlts.ts.TsKvCompositeKey;
26 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; 26 import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity;
27 -import org.thingsboard.server.dao.util.SqlDao;  
28 27
29 import java.util.List; 28 import java.util.List;
30 import java.util.UUID; 29 import java.util.UUID;
31 import java.util.concurrent.CompletableFuture; 30 import java.util.concurrent.CompletableFuture;
32 31
33 -@SqlDao  
34 public interface TsKvRepository extends CrudRepository<TsKvEntity, TsKvCompositeKey> { 32 public interface TsKvRepository extends CrudRepository<TsKvEntity, TsKvCompositeKey> {
35 33
36 @Query("SELECT tskv FROM TsKvEntity tskv WHERE tskv.entityId = :entityId " + 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 +}
@@ -60,6 +60,9 @@ public class BaseTimeseriesService implements TimeseriesService { @@ -60,6 +60,9 @@ public class BaseTimeseriesService implements TimeseriesService {
60 private TimeseriesDao timeseriesDao; 60 private TimeseriesDao timeseriesDao;
61 61
62 @Autowired 62 @Autowired
  63 + private TimeseriesLatestDao timeseriesLatestDao;
  64 +
  65 + @Autowired
63 private EntityViewService entityViewService; 66 private EntityViewService entityViewService;
64 67
65 @Override 68 @Override
@@ -103,7 +106,7 @@ public class BaseTimeseriesService implements TimeseriesService { @@ -103,7 +106,7 @@ public class BaseTimeseriesService implements TimeseriesService {
103 return Futures.immediateFuture(new ArrayList<>()); 106 return Futures.immediateFuture(new ArrayList<>());
104 } 107 }
105 } 108 }
106 - keys.forEach(key -> futures.add(timeseriesDao.findLatest(tenantId, entityId, key))); 109 + keys.forEach(key -> futures.add(timeseriesLatestDao.findLatest(tenantId, entityId, key)));
107 return Futures.allAsList(futures); 110 return Futures.allAsList(futures);
108 } 111 }
109 112
@@ -119,7 +122,7 @@ public class BaseTimeseriesService implements TimeseriesService { @@ -119,7 +122,7 @@ public class BaseTimeseriesService implements TimeseriesService {
119 return Futures.immediateFuture(new ArrayList<>()); 122 return Futures.immediateFuture(new ArrayList<>());
120 } 123 }
121 } else { 124 } else {
122 - return timeseriesDao.findAllLatest(tenantId, entityId); 125 + return timeseriesLatestDao.findAllLatest(tenantId, entityId);
123 } 126 }
124 } 127 }
125 128
@@ -151,7 +154,7 @@ public class BaseTimeseriesService implements TimeseriesService { @@ -151,7 +154,7 @@ public class BaseTimeseriesService implements TimeseriesService {
151 throw new IncorrectParameterException("Telemetry data can't be stored for entity view. Read only"); 154 throw new IncorrectParameterException("Telemetry data can't be stored for entity view. Read only");
152 } 155 }
153 futures.add(timeseriesDao.savePartition(tenantId, entityId, tsKvEntry.getTs(), tsKvEntry.getKey(), ttl)); 156 futures.add(timeseriesDao.savePartition(tenantId, entityId, tsKvEntry.getTs(), tsKvEntry.getKey(), ttl));
154 - futures.add(timeseriesDao.saveLatest(tenantId, entityId, tsKvEntry)); 157 + futures.add(timeseriesLatestDao.saveLatest(tenantId, entityId, tsKvEntry));
155 futures.add(timeseriesDao.save(tenantId, entityId, tsKvEntry, ttl)); 158 futures.add(timeseriesDao.save(tenantId, entityId, tsKvEntry, ttl));
156 } 159 }
157 160
@@ -187,7 +190,7 @@ public class BaseTimeseriesService implements TimeseriesService { @@ -187,7 +190,7 @@ public class BaseTimeseriesService implements TimeseriesService {
187 190
188 private void deleteAndRegisterFutures(TenantId tenantId, List<ListenableFuture<Void>> futures, EntityId entityId, DeleteTsKvQuery query) { 191 private void deleteAndRegisterFutures(TenantId tenantId, List<ListenableFuture<Void>> futures, EntityId entityId, DeleteTsKvQuery query) {
189 futures.add(timeseriesDao.remove(tenantId, entityId, query)); 192 futures.add(timeseriesDao.remove(tenantId, entityId, query));
190 - futures.add(timeseriesDao.removeLatest(tenantId, entityId, query)); 193 + futures.add(timeseriesLatestDao.removeLatest(tenantId, entityId, query));
191 futures.add(timeseriesDao.removePartition(tenantId, entityId, query)); 194 futures.add(timeseriesDao.removePartition(tenantId, entityId, query));
192 } 195 }
193 196
@@ -20,7 +20,6 @@ import com.datastax.oss.driver.api.core.cql.BoundStatement; @@ -20,7 +20,6 @@ import com.datastax.oss.driver.api.core.cql.BoundStatement;
20 import com.datastax.oss.driver.api.core.cql.BoundStatementBuilder; 20 import com.datastax.oss.driver.api.core.cql.BoundStatementBuilder;
21 import com.datastax.oss.driver.api.core.cql.PreparedStatement; 21 import com.datastax.oss.driver.api.core.cql.PreparedStatement;
22 import com.datastax.oss.driver.api.core.cql.Row; 22 import com.datastax.oss.driver.api.core.cql.Row;
23 -import com.datastax.oss.driver.api.core.cql.Statement;  
24 import com.datastax.oss.driver.api.querybuilder.QueryBuilder; 23 import com.datastax.oss.driver.api.querybuilder.QueryBuilder;
25 import com.datastax.oss.driver.api.querybuilder.select.Select; 24 import com.datastax.oss.driver.api.querybuilder.select.Select;
26 import com.google.common.base.Function; 25 import com.google.common.base.Function;
@@ -30,7 +29,6 @@ import com.google.common.util.concurrent.Futures; @@ -30,7 +29,6 @@ import com.google.common.util.concurrent.Futures;
30 import com.google.common.util.concurrent.ListenableFuture; 29 import com.google.common.util.concurrent.ListenableFuture;
31 import com.google.common.util.concurrent.MoreExecutors; 30 import com.google.common.util.concurrent.MoreExecutors;
32 import lombok.extern.slf4j.Slf4j; 31 import lombok.extern.slf4j.Slf4j;
33 -import org.apache.commons.lang3.StringUtils;  
34 import org.springframework.beans.factory.annotation.Autowired; 32 import org.springframework.beans.factory.annotation.Autowired;
35 import org.springframework.beans.factory.annotation.Value; 33 import org.springframework.beans.factory.annotation.Value;
36 import org.springframework.core.env.Environment; 34 import org.springframework.core.env.Environment;
@@ -39,21 +37,15 @@ import org.thingsboard.server.common.data.id.EntityId; @@ -39,21 +37,15 @@ import org.thingsboard.server.common.data.id.EntityId;
39 import org.thingsboard.server.common.data.id.TenantId; 37 import org.thingsboard.server.common.data.id.TenantId;
40 import org.thingsboard.server.common.data.kv.Aggregation; 38 import org.thingsboard.server.common.data.kv.Aggregation;
41 import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; 39 import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
42 -import org.thingsboard.server.common.data.kv.BasicTsKvEntry;  
43 -import org.thingsboard.server.common.data.kv.BooleanDataEntry;  
44 import org.thingsboard.server.common.data.kv.DataType; 40 import org.thingsboard.server.common.data.kv.DataType;
45 import org.thingsboard.server.common.data.kv.DeleteTsKvQuery; 41 import org.thingsboard.server.common.data.kv.DeleteTsKvQuery;
46 -import org.thingsboard.server.common.data.kv.DoubleDataEntry;  
47 -import org.thingsboard.server.common.data.kv.JsonDataEntry;  
48 import org.thingsboard.server.common.data.kv.KvEntry; 42 import org.thingsboard.server.common.data.kv.KvEntry;
49 -import org.thingsboard.server.common.data.kv.LongDataEntry;  
50 import org.thingsboard.server.common.data.kv.ReadTsKvQuery; 43 import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
51 -import org.thingsboard.server.common.data.kv.StringDataEntry;  
52 import org.thingsboard.server.common.data.kv.TsKvEntry; 44 import org.thingsboard.server.common.data.kv.TsKvEntry;
53 import org.thingsboard.server.dao.model.ModelConstants; 45 import org.thingsboard.server.dao.model.ModelConstants;
54 -import org.thingsboard.server.dao.nosql.CassandraAbstractAsyncDao;  
55 import org.thingsboard.server.dao.nosql.TbResultSet; 46 import org.thingsboard.server.dao.nosql.TbResultSet;
56 import org.thingsboard.server.dao.nosql.TbResultSetFuture; 47 import org.thingsboard.server.dao.nosql.TbResultSetFuture;
  48 +import org.thingsboard.server.dao.sqlts.AggregationTimeseriesDao;
57 import org.thingsboard.server.dao.util.NoSqlTsDao; 49 import org.thingsboard.server.dao.util.NoSqlTsDao;
58 50
59 import javax.annotation.Nullable; 51 import javax.annotation.Nullable;
@@ -68,7 +60,6 @@ import java.util.Arrays; @@ -68,7 +60,6 @@ import java.util.Arrays;
68 import java.util.Collections; 60 import java.util.Collections;
69 import java.util.List; 61 import java.util.List;
70 import java.util.Optional; 62 import java.util.Optional;
71 -import java.util.concurrent.ExecutionException;  
72 import java.util.stream.Collectors; 63 import java.util.stream.Collectors;
73 64
74 import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal; 65 import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal;
@@ -79,16 +70,11 @@ import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal; @@ -79,16 +70,11 @@ import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal;
79 @Component 70 @Component
80 @Slf4j 71 @Slf4j
81 @NoSqlTsDao 72 @NoSqlTsDao
82 -public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implements TimeseriesDao { 73 +public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesDao implements TimeseriesDao, AggregationTimeseriesDao {
83 74
84 - private static final int MIN_AGGREGATION_STEP_MS = 1000;  
85 - public static final String INSERT_INTO = "INSERT INTO ";  
86 - public static final String GENERATED_QUERY_FOR_ENTITY_TYPE_AND_ENTITY_ID = "Generated query [{}] for entityType {} and entityId {}";  
87 - public static final String SELECT_PREFIX = "SELECT ";  
88 - public static final String EQUALS_PARAM = " = ? "; 75 + protected static final int MIN_AGGREGATION_STEP_MS = 1000;
89 public static final String ASC_ORDER = "ASC"; 76 public static final String ASC_ORDER = "ASC";
90 - public static final String DESC_ORDER = "DESC";  
91 - private static List<Long> FIXED_PARTITION = Arrays.asList(new Long[]{0L}); 77 + protected static List<Long> FIXED_PARTITION = Arrays.asList(new Long[]{0L});
92 78
93 @Autowired 79 @Autowired
94 private Environment environment; 80 private Environment environment;
@@ -106,13 +92,10 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -106,13 +92,10 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
106 92
107 private PreparedStatement partitionInsertStmt; 93 private PreparedStatement partitionInsertStmt;
108 private PreparedStatement partitionInsertTtlStmt; 94 private PreparedStatement partitionInsertTtlStmt;
109 - private PreparedStatement latestInsertStmt;  
110 private PreparedStatement[] saveStmts; 95 private PreparedStatement[] saveStmts;
111 private PreparedStatement[] saveTtlStmts; 96 private PreparedStatement[] saveTtlStmts;
112 private PreparedStatement[] fetchStmtsAsc; 97 private PreparedStatement[] fetchStmtsAsc;
113 private PreparedStatement[] fetchStmtsDesc; 98 private PreparedStatement[] fetchStmtsDesc;
114 - private PreparedStatement findLatestStmt;  
115 - private PreparedStatement findAllLatestStmt;  
116 private PreparedStatement deleteStmt; 99 private PreparedStatement deleteStmt;
117 private PreparedStatement deletePartitionStmt; 100 private PreparedStatement deletePartitionStmt;
118 101
@@ -157,8 +140,113 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -157,8 +140,113 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
157 }, readResultsProcessingExecutor); 140 }, readResultsProcessingExecutor);
158 } 141 }
159 142
  143 + @Override
  144 + public ListenableFuture<Void> save(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl) {
  145 + List<ListenableFuture<Void>> futures = new ArrayList<>();
  146 + ttl = computeTtl(ttl);
  147 + long partition = toPartitionTs(tsKvEntry.getTs());
  148 + DataType type = tsKvEntry.getDataType();
  149 + if (setNullValuesEnabled) {
  150 + processSetNullValues(tenantId, entityId, tsKvEntry, ttl, futures, partition, type);
  151 + }
  152 + BoundStatementBuilder stmtBuilder = new BoundStatementBuilder((ttl == 0 ? getSaveStmt(type) : getSaveTtlStmt(type)).bind());
  153 + stmtBuilder.setString(0, entityId.getEntityType().name())
  154 + .setUuid(1, entityId.getId())
  155 + .setString(2, tsKvEntry.getKey())
  156 + .setLong(3, partition)
  157 + .setLong(4, tsKvEntry.getTs());
  158 + addValue(tsKvEntry, stmtBuilder, 5);
  159 + if (ttl > 0) {
  160 + stmtBuilder.setInt(6, (int) ttl);
  161 + }
  162 + BoundStatement stmt = stmtBuilder.build();
  163 + futures.add(getFuture(executeAsyncWrite(tenantId, stmt), rs -> null));
  164 + return Futures.transform(Futures.allAsList(futures), result -> null, MoreExecutors.directExecutor());
  165 + }
  166 +
  167 + @Override
  168 + public ListenableFuture<Void> savePartition(TenantId tenantId, EntityId entityId, long tsKvEntryTs, String key, long ttl) {
  169 + if (isFixedPartitioning()) {
  170 + return Futures.immediateFuture(null);
  171 + }
  172 + ttl = computeTtl(ttl);
  173 + long partition = toPartitionTs(tsKvEntryTs);
  174 + log.debug("Saving partition {} for the entity [{}-{}] and key {}", partition, entityId.getEntityType(), entityId.getId(), key);
  175 + BoundStatementBuilder stmtBuilder = new BoundStatementBuilder((ttl == 0 ? getPartitionInsertStmt() : getPartitionInsertTtlStmt()).bind());
  176 + stmtBuilder.setString(0, entityId.getEntityType().name())
  177 + .setUuid(1, entityId.getId())
  178 + .setLong(2, partition)
  179 + .setString(3, key);
  180 + if (ttl > 0) {
  181 + stmtBuilder.setInt(4, (int) ttl);
  182 + }
  183 + BoundStatement stmt = stmtBuilder.build();
  184 + return getFuture(executeAsyncWrite(tenantId, stmt), rs -> null);
  185 + }
160 186
161 - private ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { 187 + @Override
  188 + public ListenableFuture<Void> remove(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
  189 + long minPartition = toPartitionTs(query.getStartTs());
  190 + long maxPartition = toPartitionTs(query.getEndTs());
  191 +
  192 + TbResultSetFuture partitionsFuture = fetchPartitions(tenantId, entityId, query.getKey(), minPartition, maxPartition);
  193 +
  194 + final SimpleListenableFuture<Void> resultFuture = new SimpleListenableFuture<>();
  195 + final ListenableFuture<List<Long>> partitionsListFuture = Futures.transformAsync(partitionsFuture, getPartitionsArrayFunction(), readResultsProcessingExecutor);
  196 +
  197 + Futures.addCallback(partitionsListFuture, new FutureCallback<List<Long>>() {
  198 + @Override
  199 + public void onSuccess(@Nullable List<Long> partitions) {
  200 + QueryCursor cursor = new QueryCursor(entityId.getEntityType().name(), entityId.getId(), query, partitions);
  201 + deleteAsync(tenantId, cursor, resultFuture);
  202 + }
  203 +
  204 + @Override
  205 + public void onFailure(Throwable t) {
  206 + log.error("[{}][{}] Failed to fetch partitions for interval {}-{}", entityId.getEntityType().name(), entityId.getId(), minPartition, maxPartition, t);
  207 + }
  208 + }, readResultsProcessingExecutor);
  209 + return resultFuture;
  210 + }
  211 +
  212 + @Override
  213 + public ListenableFuture<Void> removePartition(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
  214 + long minPartition = toPartitionTs(query.getStartTs());
  215 + long maxPartition = toPartitionTs(query.getEndTs());
  216 + if (minPartition == maxPartition) {
  217 + return Futures.immediateFuture(null);
  218 + } else {
  219 + TbResultSetFuture partitionsFuture = fetchPartitions(tenantId, entityId, query.getKey(), minPartition, maxPartition);
  220 +
  221 + final SimpleListenableFuture<Void> resultFuture = new SimpleListenableFuture<>();
  222 + final ListenableFuture<List<Long>> partitionsListFuture = Futures.transformAsync(partitionsFuture, getPartitionsArrayFunction(), readResultsProcessingExecutor);
  223 +
  224 + Futures.addCallback(partitionsListFuture, new FutureCallback<List<Long>>() {
  225 + @Override
  226 + public void onSuccess(@Nullable List<Long> partitions) {
  227 + int index = 0;
  228 + if (minPartition != query.getStartTs()) {
  229 + index = 1;
  230 + }
  231 + List<Long> partitionsToDelete = new ArrayList<>();
  232 + for (int i = index; i < partitions.size() - 1; i++) {
  233 + partitionsToDelete.add(partitions.get(i));
  234 + }
  235 + QueryCursor cursor = new QueryCursor(entityId.getEntityType().name(), entityId.getId(), query, partitionsToDelete);
  236 + deletePartitionAsync(tenantId, cursor, resultFuture);
  237 + }
  238 +
  239 + @Override
  240 + public void onFailure(Throwable t) {
  241 + log.error("[{}][{}] Failed to fetch partitions for interval {}-{}", entityId.getEntityType().name(), entityId.getId(), minPartition, maxPartition, t);
  242 + }
  243 + }, readResultsProcessingExecutor);
  244 + return resultFuture;
  245 + }
  246 + }
  247 +
  248 + @Override
  249 + public ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) {
162 if (query.getAggregation() == Aggregation.NONE) { 250 if (query.getAggregation() == Aggregation.NONE) {
163 return findAllAsyncWithLimit(tenantId, entityId, query); 251 return findAllAsyncWithLimit(tenantId, entityId, query);
164 } else { 252 } else {
@@ -183,18 +271,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -183,18 +271,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
183 } 271 }
184 } 272 }
185 273
186 - public boolean isFixedPartitioning() {  
187 - return tsFormat.getTruncateUnit().equals(ChronoUnit.FOREVER);  
188 - }  
189 -  
190 - private ListenableFuture<List<Long>> getPartitionsFuture(TenantId tenantId, ReadTsKvQuery query, EntityId entityId, long minPartition, long maxPartition) {  
191 - if (isFixedPartitioning()) { //no need to fetch partitions from DB  
192 - return Futures.immediateFuture(FIXED_PARTITION);  
193 - }  
194 - TbResultSetFuture partitionsFuture = fetchPartitions(tenantId, entityId, query.getKey(), minPartition, maxPartition);  
195 - return Futures.transformAsync(partitionsFuture, getPartitionsArrayFunction(), readResultsProcessingExecutor);  
196 - }  
197 -  
198 private ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { 274 private ListenableFuture<List<TsKvEntry>> findAllAsyncWithLimit(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) {
199 long minPartition = toPartitionTs(query.getStartTs()); 275 long minPartition = toPartitionTs(query.getStartTs());
200 long maxPartition = toPartitionTs(query.getEndTs()); 276 long maxPartition = toPartitionTs(query.getEndTs());
@@ -287,10 +363,18 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -287,10 +363,18 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
287 363
288 private AsyncFunction<TbResultSet, List<Long>> getPartitionsArrayFunction() { 364 private AsyncFunction<TbResultSet, List<Long>> getPartitionsArrayFunction() {
289 return rs -> 365 return rs ->
290 - Futures.transform(rs.allRows(readResultsProcessingExecutor), rows ->  
291 - rows.stream()  
292 - .map(row -> row.getLong(ModelConstants.PARTITION_COLUMN)).collect(Collectors.toList()),  
293 - readResultsProcessingExecutor); 366 + Futures.transform(rs.allRows(readResultsProcessingExecutor), rows ->
  367 + rows.stream()
  368 + .map(row -> row.getLong(ModelConstants.PARTITION_COLUMN)).collect(Collectors.toList()),
  369 + readResultsProcessingExecutor);
  370 + }
  371 +
  372 + private ListenableFuture<List<Long>> getPartitionsFuture(TenantId tenantId, ReadTsKvQuery query, EntityId entityId, long minPartition, long maxPartition) {
  373 + if (isFixedPartitioning()) { //no need to fetch partitions from DB
  374 + return Futures.immediateFuture(FIXED_PARTITION);
  375 + }
  376 + TbResultSetFuture partitionsFuture = fetchPartitions(tenantId, entityId, query.getKey(), minPartition, maxPartition);
  377 + return Futures.transformAsync(partitionsFuture, getPartitionsArrayFunction(), readResultsProcessingExecutor);
294 } 378 }
295 379
296 private AsyncFunction<List<Long>, List<TbResultSet>> getFetchChunksAsyncFunction(TenantId tenantId, EntityId entityId, String key, Aggregation aggregation, long startTs, long endTs) { 380 private AsyncFunction<List<Long>, List<TbResultSet>> getFetchChunksAsyncFunction(TenantId tenantId, EntityId entityId, String key, Aggregation aggregation, long startTs, long endTs) {
@@ -319,49 +403,8 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -319,49 +403,8 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
319 }; 403 };
320 } 404 }
321 405
322 - @Override  
323 - public ListenableFuture<TsKvEntry> findLatest(TenantId tenantId, EntityId entityId, String key) {  
324 - BoundStatementBuilder stmtBuilder = new BoundStatementBuilder(getFindLatestStmt().bind());  
325 - stmtBuilder.setString(0, entityId.getEntityType().name());  
326 - stmtBuilder.setUuid(1, entityId.getId());  
327 - stmtBuilder.setString(2, key);  
328 - BoundStatement stmt = stmtBuilder.build();  
329 - log.debug(GENERATED_QUERY_FOR_ENTITY_TYPE_AND_ENTITY_ID, stmt, entityId.getEntityType(), entityId.getId());  
330 - return getFuture(executeAsyncRead(tenantId, stmt), rs -> convertResultToTsKvEntry(key, rs.one()));  
331 - }  
332 -  
333 - @Override  
334 - public ListenableFuture<List<TsKvEntry>> findAllLatest(TenantId tenantId, EntityId entityId) {  
335 - BoundStatementBuilder stmtBuilder = new BoundStatementBuilder(getFindAllLatestStmt().bind());  
336 - stmtBuilder.setString(0, entityId.getEntityType().name());  
337 - stmtBuilder.setUuid(1, entityId.getId());  
338 - BoundStatement stmt = stmtBuilder.build();  
339 - log.debug(GENERATED_QUERY_FOR_ENTITY_TYPE_AND_ENTITY_ID, stmt, entityId.getEntityType(), entityId.getId());  
340 - return getFutureAsync(executeAsyncRead(tenantId, stmt), rs -> convertAsyncResultSetToTsKvEntryList(rs));  
341 - }  
342 -  
343 - @Override  
344 - public ListenableFuture<Void> save(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl) {  
345 - List<ListenableFuture<Void>> futures = new ArrayList<>();  
346 - ttl = computeTtl(ttl);  
347 - long partition = toPartitionTs(tsKvEntry.getTs());  
348 - DataType type = tsKvEntry.getDataType();  
349 - if (setNullValuesEnabled) {  
350 - processSetNullValues(tenantId, entityId, tsKvEntry, ttl, futures, partition, type);  
351 - }  
352 - BoundStatementBuilder stmtBuilder = new BoundStatementBuilder((ttl == 0 ? getSaveStmt(type) : getSaveTtlStmt(type)).bind());  
353 - stmtBuilder.setString(0, entityId.getEntityType().name())  
354 - .setUuid(1, entityId.getId())  
355 - .setString(2, tsKvEntry.getKey())  
356 - .setLong(3, partition)  
357 - .setLong(4, tsKvEntry.getTs());  
358 - addValue(tsKvEntry, stmtBuilder, 5);  
359 - if (ttl > 0) {  
360 - stmtBuilder.setInt(6, (int) ttl);  
361 - }  
362 - BoundStatement stmt = stmtBuilder.build();  
363 - futures.add(getFuture(executeAsyncWrite(tenantId, stmt), rs -> null));  
364 - return Futures.transform(Futures.allAsList(futures), result -> null, MoreExecutors.directExecutor()); 406 + private boolean isFixedPartitioning() {
  407 + return tsFormat.getTruncateUnit().equals(ChronoUnit.FOREVER);
365 } 408 }
366 409
367 private void processSetNullValues(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl, List<ListenableFuture<Void>> futures, long partition, DataType type) { 410 private void processSetNullValues(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl, List<ListenableFuture<Void>> futures, long partition, DataType type) {
@@ -414,26 +457,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -414,26 +457,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
414 return getFuture(executeAsyncWrite(tenantId, stmt), rs -> null); 457 return getFuture(executeAsyncWrite(tenantId, stmt), rs -> null);
415 } 458 }
416 459
417 - @Override  
418 - public ListenableFuture<Void> savePartition(TenantId tenantId, EntityId entityId, long tsKvEntryTs, String key, long ttl) {  
419 - if (isFixedPartitioning()) {  
420 - return Futures.immediateFuture(null);  
421 - }  
422 - ttl = computeTtl(ttl);  
423 - long partition = toPartitionTs(tsKvEntryTs);  
424 - log.debug("Saving partition {} for the entity [{}-{}] and key {}", partition, entityId.getEntityType(), entityId.getId(), key);  
425 - BoundStatementBuilder stmtBuilder = new BoundStatementBuilder((ttl == 0 ? getPartitionInsertStmt() : getPartitionInsertTtlStmt()).bind());  
426 - stmtBuilder.setString(0, entityId.getEntityType().name())  
427 - .setUuid(1, entityId.getId())  
428 - .setLong(2, partition)  
429 - .setString(3, key);  
430 - if (ttl > 0) {  
431 - stmtBuilder.setInt(4, (int) ttl);  
432 - }  
433 - BoundStatement stmt = stmtBuilder.build();  
434 - return getFuture(executeAsyncWrite(tenantId, stmt), rs -> null);  
435 - }  
436 -  
437 private long computeTtl(long ttl) { 460 private long computeTtl(long ttl) {
438 if (systemTtl > 0) { 461 if (systemTtl > 0) {
439 if (ttl == 0) { 462 if (ttl == 0) {
@@ -445,53 +468,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -445,53 +468,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
445 return ttl; 468 return ttl;
446 } 469 }
447 470
448 - @Override  
449 - public ListenableFuture<Void> saveLatest(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry) {  
450 - BoundStatementBuilder stmtBuilder = new BoundStatementBuilder(getLatestStmt().bind());  
451 - stmtBuilder.setString(0, entityId.getEntityType().name())  
452 - .setUuid(1, entityId.getId())  
453 - .setString(2, tsKvEntry.getKey())  
454 - .setLong(3, tsKvEntry.getTs())  
455 - .set(4, tsKvEntry.getBooleanValue().orElse(null), Boolean.class)  
456 - .set(5, tsKvEntry.getStrValue().orElse(null), String.class)  
457 - .set(6, tsKvEntry.getLongValue().orElse(null), Long.class)  
458 - .set(7, tsKvEntry.getDoubleValue().orElse(null), Double.class);  
459 - Optional<String> jsonV = tsKvEntry.getJsonValue();  
460 - if (jsonV.isPresent()) {  
461 - stmtBuilder.setString(8, tsKvEntry.getJsonValue().get());  
462 - } else {  
463 - stmtBuilder.setToNull(8);  
464 - }  
465 - BoundStatement stmt = stmtBuilder.build();  
466 -  
467 - return getFuture(executeAsyncWrite(tenantId, stmt), rs -> null);  
468 - }  
469 -  
470 - @Override  
471 - public ListenableFuture<Void> remove(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {  
472 - long minPartition = toPartitionTs(query.getStartTs());  
473 - long maxPartition = toPartitionTs(query.getEndTs());  
474 -  
475 - TbResultSetFuture partitionsFuture = fetchPartitions(tenantId, entityId, query.getKey(), minPartition, maxPartition);  
476 -  
477 - final SimpleListenableFuture<Void> resultFuture = new SimpleListenableFuture<>();  
478 - final ListenableFuture<List<Long>> partitionsListFuture = Futures.transformAsync(partitionsFuture, getPartitionsArrayFunction(), readResultsProcessingExecutor);  
479 -  
480 - Futures.addCallback(partitionsListFuture, new FutureCallback<List<Long>>() {  
481 - @Override  
482 - public void onSuccess(@Nullable List<Long> partitions) {  
483 - QueryCursor cursor = new QueryCursor(entityId.getEntityType().name(), entityId.getId(), query, partitions);  
484 - deleteAsync(tenantId, cursor, resultFuture);  
485 - }  
486 -  
487 - @Override  
488 - public void onFailure(Throwable t) {  
489 - log.error("[{}][{}] Failed to fetch partitions for interval {}-{}", entityId.getEntityType().name(), entityId.getId(), minPartition, maxPartition, t);  
490 - }  
491 - }, readResultsProcessingExecutor);  
492 - return resultFuture;  
493 - }  
494 -  
495 private void deleteAsync(TenantId tenantId, final QueryCursor cursor, final SimpleListenableFuture<Void> resultFuture) { 471 private void deleteAsync(TenantId tenantId, final QueryCursor cursor, final SimpleListenableFuture<Void> resultFuture) {
496 if (!cursor.hasNextPartition()) { 472 if (!cursor.hasNextPartition()) {
497 resultFuture.set(null); 473 resultFuture.set(null);
@@ -534,119 +510,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -534,119 +510,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
534 return deleteStmt; 510 return deleteStmt;
535 } 511 }
536 512
537 - @Override  
538 - public ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {  
539 - ListenableFuture<TsKvEntry> latestEntryFuture = findLatest(tenantId, entityId, query.getKey());  
540 -  
541 - ListenableFuture<Boolean> booleanFuture = Futures.transform(latestEntryFuture, latestEntry -> {  
542 - long ts = latestEntry.getTs();  
543 - if (ts > query.getStartTs() && ts <= query.getEndTs()) {  
544 - return true;  
545 - } else {  
546 - log.trace("Won't be deleted latest value for [{}], key - {}", entityId, query.getKey());  
547 - }  
548 - return false;  
549 - }, readResultsProcessingExecutor);  
550 -  
551 - ListenableFuture<Void> removedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> {  
552 - if (isRemove) {  
553 - return deleteLatest(tenantId, entityId, query.getKey());  
554 - }  
555 - return Futures.immediateFuture(null);  
556 - }, readResultsProcessingExecutor);  
557 -  
558 - final SimpleListenableFuture<Void> resultFuture = new SimpleListenableFuture<>();  
559 - Futures.addCallback(removedLatestFuture, new FutureCallback<Void>() {  
560 - @Override  
561 - public void onSuccess(@Nullable Void result) {  
562 - if (query.getRewriteLatestIfDeleted()) {  
563 - ListenableFuture<Void> savedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> {  
564 - if (isRemove) {  
565 - return getNewLatestEntryFuture(tenantId, entityId, query);  
566 - }  
567 - return Futures.immediateFuture(null);  
568 - }, readResultsProcessingExecutor);  
569 -  
570 - try {  
571 - resultFuture.set(savedLatestFuture.get());  
572 - } catch (InterruptedException | ExecutionException e) {  
573 - log.warn("Could not get latest saved value for [{}], {}", entityId, query.getKey(), e);  
574 - }  
575 - } else {  
576 - resultFuture.set(null);  
577 - }  
578 - }  
579 -  
580 - @Override  
581 - public void onFailure(Throwable t) {  
582 - log.warn("[{}] Failed to process remove of the latest value", entityId, t);  
583 - }  
584 - }, MoreExecutors.directExecutor());  
585 - return resultFuture;  
586 - }  
587 -  
588 - private ListenableFuture<Void> getNewLatestEntryFuture(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {  
589 - long startTs = 0;  
590 - long endTs = query.getStartTs() - 1;  
591 - ReadTsKvQuery findNewLatestQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, endTs - startTs, 1,  
592 - Aggregation.NONE, DESC_ORDER);  
593 - ListenableFuture<List<TsKvEntry>> future = findAllAsync(tenantId, entityId, findNewLatestQuery);  
594 -  
595 - return Futures.transformAsync(future, entryList -> {  
596 - if (entryList.size() == 1) {  
597 - return saveLatest(tenantId, entityId, entryList.get(0));  
598 - } else {  
599 - log.trace("Could not find new latest value for [{}], key - {}", entityId, query.getKey());  
600 - }  
601 - return Futures.immediateFuture(null);  
602 - }, readResultsProcessingExecutor);  
603 - }  
604 -  
605 - private ListenableFuture<Void> deleteLatest(TenantId tenantId, EntityId entityId, String key) {  
606 - Statement delete = QueryBuilder.deleteFrom(ModelConstants.TS_KV_LATEST_CF)  
607 - .whereColumn(ModelConstants.ENTITY_TYPE_COLUMN).isEqualTo(literal(entityId.getEntityType().name()))  
608 - .whereColumn(ModelConstants.ENTITY_ID_COLUMN).isEqualTo(literal(entityId.getId()))  
609 - .whereColumn(ModelConstants.KEY_COLUMN).isEqualTo(literal(key)).build();  
610 - log.debug("Remove request: {}", delete.toString());  
611 - return getFuture(executeAsyncWrite(tenantId, delete), rs -> null);  
612 - }  
613 -  
614 - @Override  
615 - public ListenableFuture<Void> removePartition(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {  
616 - long minPartition = toPartitionTs(query.getStartTs());  
617 - long maxPartition = toPartitionTs(query.getEndTs());  
618 - if (minPartition == maxPartition) {  
619 - return Futures.immediateFuture(null);  
620 - } else {  
621 - TbResultSetFuture partitionsFuture = fetchPartitions(tenantId, entityId, query.getKey(), minPartition, maxPartition);  
622 -  
623 - final SimpleListenableFuture<Void> resultFuture = new SimpleListenableFuture<>();  
624 - final ListenableFuture<List<Long>> partitionsListFuture = Futures.transformAsync(partitionsFuture, getPartitionsArrayFunction(), readResultsProcessingExecutor);  
625 -  
626 - Futures.addCallback(partitionsListFuture, new FutureCallback<List<Long>>() {  
627 - @Override  
628 - public void onSuccess(@Nullable List<Long> partitions) {  
629 - int index = 0;  
630 - if (minPartition != query.getStartTs()) {  
631 - index = 1;  
632 - }  
633 - List<Long> partitionsToDelete = new ArrayList<>();  
634 - for (int i = index; i < partitions.size() - 1; i++) {  
635 - partitionsToDelete.add(partitions.get(i));  
636 - }  
637 - QueryCursor cursor = new QueryCursor(entityId.getEntityType().name(), entityId.getId(), query, partitionsToDelete);  
638 - deletePartitionAsync(tenantId, cursor, resultFuture);  
639 - }  
640 -  
641 - @Override  
642 - public void onFailure(Throwable t) {  
643 - log.error("[{}][{}] Failed to fetch partitions for interval {}-{}", entityId.getEntityType().name(), entityId.getId(), minPartition, maxPartition, t);  
644 - }  
645 - }, readResultsProcessingExecutor);  
646 - return resultFuture;  
647 - }  
648 - }  
649 -  
650 private void deletePartitionAsync(TenantId tenantId, final QueryCursor cursor, final SimpleListenableFuture<Void> resultFuture) { 513 private void deletePartitionAsync(TenantId tenantId, final QueryCursor cursor, final SimpleListenableFuture<Void> resultFuture) {
651 if (!cursor.hasNextPartition()) { 514 if (!cursor.hasNextPartition()) {
652 resultFuture.set(null); 515 resultFuture.set(null);
@@ -685,79 +548,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -685,79 +548,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
685 return deletePartitionStmt; 548 return deletePartitionStmt;
686 } 549 }
687 550
688 - private ListenableFuture<List<TsKvEntry>> convertAsyncResultSetToTsKvEntryList(TbResultSet rs) {  
689 - return Futures.transform(rs.allRows(readResultsProcessingExecutor),  
690 - rows -> this.convertResultToTsKvEntryList(rows), readResultsProcessingExecutor);  
691 - }  
692 -  
693 - private List<TsKvEntry> convertResultToTsKvEntryList(List<Row> rows) {  
694 - List<TsKvEntry> entries = new ArrayList<>(rows.size());  
695 - if (!rows.isEmpty()) {  
696 - rows.forEach(row -> entries.add(convertResultToTsKvEntry(row)));  
697 - }  
698 - return entries;  
699 - }  
700 -  
701 - private TsKvEntry convertResultToTsKvEntry(String key, Row row) {  
702 - if (row != null) {  
703 - long ts = row.getLong(ModelConstants.TS_COLUMN);  
704 - return new BasicTsKvEntry(ts, toKvEntry(row, key));  
705 - } else {  
706 - return new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(key, null));  
707 - }  
708 - }  
709 -  
710 - private TsKvEntry convertResultToTsKvEntry(Row row) {  
711 - String key = row.getString(ModelConstants.KEY_COLUMN);  
712 - long ts = row.getLong(ModelConstants.TS_COLUMN);  
713 - return new BasicTsKvEntry(ts, toKvEntry(row, key));  
714 - }  
715 -  
716 - public static KvEntry toKvEntry(Row row, String key) {  
717 - KvEntry kvEntry = null;  
718 - String strV = row.get(ModelConstants.STRING_VALUE_COLUMN, String.class);  
719 - if (strV != null) {  
720 - kvEntry = new StringDataEntry(key, strV);  
721 - } else {  
722 - Long longV = row.get(ModelConstants.LONG_VALUE_COLUMN, Long.class);  
723 - if (longV != null) {  
724 - kvEntry = new LongDataEntry(key, longV);  
725 - } else {  
726 - Double doubleV = row.get(ModelConstants.DOUBLE_VALUE_COLUMN, Double.class);  
727 - if (doubleV != null) {  
728 - kvEntry = new DoubleDataEntry(key, doubleV);  
729 - } else {  
730 - Boolean boolV = row.get(ModelConstants.BOOLEAN_VALUE_COLUMN, Boolean.class);  
731 - if (boolV != null) {  
732 - kvEntry = new BooleanDataEntry(key, boolV);  
733 - } else {  
734 - String jsonV = row.get(ModelConstants.JSON_VALUE_COLUMN, String.class);  
735 - if (StringUtils.isNoneEmpty(jsonV)) {  
736 - kvEntry = new JsonDataEntry(key, jsonV);  
737 - } else {  
738 - log.warn("All values in key-value row are nullable ");  
739 - }  
740 - }  
741 - }  
742 - }  
743 - }  
744 - return kvEntry;  
745 - }  
746 -  
747 - /**  
748 - * Select existing partitions from the table  
749 - * <code>{@link ModelConstants#TS_KV_PARTITIONS_CF}</code> for the given entity  
750 - */  
751 - private TbResultSetFuture fetchPartitions(TenantId tenantId, EntityId entityId, String key, long minPartition, long maxPartition) {  
752 - Select select = QueryBuilder.selectFrom(ModelConstants.TS_KV_PARTITIONS_CF).column(ModelConstants.PARTITION_COLUMN)  
753 - .whereColumn(ModelConstants.ENTITY_TYPE_COLUMN).isEqualTo(literal(entityId.getEntityType().name()))  
754 - .whereColumn(ModelConstants.ENTITY_ID_COLUMN).isEqualTo(literal(entityId.getId()))  
755 - .whereColumn(ModelConstants.KEY_COLUMN).isEqualTo(literal(key))  
756 - .whereColumn(ModelConstants.PARTITION_COLUMN).isGreaterThanOrEqualTo(literal(minPartition))  
757 - .whereColumn(ModelConstants.PARTITION_COLUMN).isLessThanOrEqualTo(literal(maxPartition));  
758 - return executeAsyncRead(tenantId, select.build());  
759 - }  
760 -  
761 private PreparedStatement getSaveStmt(DataType dataType) { 551 private PreparedStatement getSaveStmt(DataType dataType) {
762 if (saveStmts == null) { 552 if (saveStmts == null) {
763 saveStmts = new PreparedStatement[DataType.values().length]; 553 saveStmts = new PreparedStatement[DataType.values().length];
@@ -792,63 +582,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -792,63 +582,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
792 return saveTtlStmts[dataType.ordinal()]; 582 return saveTtlStmts[dataType.ordinal()];
793 } 583 }
794 584
795 - private PreparedStatement getFetchStmt(Aggregation aggType, String orderBy) {  
796 - switch (orderBy) {  
797 - case ASC_ORDER:  
798 - if (fetchStmtsAsc == null) {  
799 - fetchStmtsAsc = initFetchStmt(orderBy);  
800 - }  
801 - return fetchStmtsAsc[aggType.ordinal()];  
802 - case DESC_ORDER:  
803 - if (fetchStmtsDesc == null) {  
804 - fetchStmtsDesc = initFetchStmt(orderBy);  
805 - }  
806 - return fetchStmtsDesc[aggType.ordinal()];  
807 - default:  
808 - throw new RuntimeException("Not supported" + orderBy + "order!");  
809 - }  
810 - }  
811 -  
812 - private PreparedStatement[] initFetchStmt(String orderBy) {  
813 - PreparedStatement[] fetchStmts = new PreparedStatement[Aggregation.values().length];  
814 - for (Aggregation type : Aggregation.values()) {  
815 - if (type == Aggregation.SUM && fetchStmts[Aggregation.AVG.ordinal()] != null) {  
816 - fetchStmts[type.ordinal()] = fetchStmts[Aggregation.AVG.ordinal()];  
817 - } else if (type == Aggregation.AVG && fetchStmts[Aggregation.SUM.ordinal()] != null) {  
818 - fetchStmts[type.ordinal()] = fetchStmts[Aggregation.SUM.ordinal()];  
819 - } else {  
820 - fetchStmts[type.ordinal()] = prepare(SELECT_PREFIX +  
821 - String.join(", ", ModelConstants.getFetchColumnNames(type)) + " FROM " + ModelConstants.TS_KV_CF  
822 - + " WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + EQUALS_PARAM  
823 - + "AND " + ModelConstants.ENTITY_ID_COLUMN + EQUALS_PARAM  
824 - + "AND " + ModelConstants.KEY_COLUMN + EQUALS_PARAM  
825 - + "AND " + ModelConstants.PARTITION_COLUMN + EQUALS_PARAM  
826 - + "AND " + ModelConstants.TS_COLUMN + " > ? "  
827 - + "AND " + ModelConstants.TS_COLUMN + " <= ?"  
828 - + (type == Aggregation.NONE ? " ORDER BY " + ModelConstants.TS_COLUMN + " " + orderBy + " LIMIT ?" : ""));  
829 - }  
830 - }  
831 - return fetchStmts;  
832 - }  
833 -  
834 - private PreparedStatement getLatestStmt() {  
835 - if (latestInsertStmt == null) {  
836 - latestInsertStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_LATEST_CF +  
837 - "(" + ModelConstants.ENTITY_TYPE_COLUMN +  
838 - "," + ModelConstants.ENTITY_ID_COLUMN +  
839 - "," + ModelConstants.KEY_COLUMN +  
840 - "," + ModelConstants.TS_COLUMN +  
841 - "," + ModelConstants.BOOLEAN_VALUE_COLUMN +  
842 - "," + ModelConstants.STRING_VALUE_COLUMN +  
843 - "," + ModelConstants.LONG_VALUE_COLUMN +  
844 - "," + ModelConstants.DOUBLE_VALUE_COLUMN +  
845 - "," + ModelConstants.JSON_VALUE_COLUMN + ")" +  
846 - " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)");  
847 - }  
848 - return latestInsertStmt;  
849 - }  
850 -  
851 -  
852 private PreparedStatement getPartitionInsertStmt() { 585 private PreparedStatement getPartitionInsertStmt() {
853 if (partitionInsertStmt == null) { 586 if (partitionInsertStmt == null) {
854 partitionInsertStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_PARTITIONS_CF + 587 partitionInsertStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_PARTITIONS_CF +
@@ -873,42 +606,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -873,42 +606,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
873 return partitionInsertTtlStmt; 606 return partitionInsertTtlStmt;
874 } 607 }
875 608
876 -  
877 - private PreparedStatement getFindLatestStmt() {  
878 - if (findLatestStmt == null) {  
879 - findLatestStmt = prepare(SELECT_PREFIX +  
880 - ModelConstants.KEY_COLUMN + "," +  
881 - ModelConstants.TS_COLUMN + "," +  
882 - ModelConstants.STRING_VALUE_COLUMN + "," +  
883 - ModelConstants.BOOLEAN_VALUE_COLUMN + "," +  
884 - ModelConstants.LONG_VALUE_COLUMN + "," +  
885 - ModelConstants.DOUBLE_VALUE_COLUMN + "," +  
886 - ModelConstants.JSON_VALUE_COLUMN + " " +  
887 - "FROM " + ModelConstants.TS_KV_LATEST_CF + " " +  
888 - "WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + EQUALS_PARAM +  
889 - "AND " + ModelConstants.ENTITY_ID_COLUMN + EQUALS_PARAM +  
890 - "AND " + ModelConstants.KEY_COLUMN + EQUALS_PARAM);  
891 - }  
892 - return findLatestStmt;  
893 - }  
894 -  
895 - private PreparedStatement getFindAllLatestStmt() {  
896 - if (findAllLatestStmt == null) {  
897 - findAllLatestStmt = prepare(SELECT_PREFIX +  
898 - ModelConstants.KEY_COLUMN + "," +  
899 - ModelConstants.TS_COLUMN + "," +  
900 - ModelConstants.STRING_VALUE_COLUMN + "," +  
901 - ModelConstants.BOOLEAN_VALUE_COLUMN + "," +  
902 - ModelConstants.LONG_VALUE_COLUMN + "," +  
903 - ModelConstants.DOUBLE_VALUE_COLUMN + "," +  
904 - ModelConstants.JSON_VALUE_COLUMN + " " +  
905 - "FROM " + ModelConstants.TS_KV_LATEST_CF + " " +  
906 - "WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + EQUALS_PARAM +  
907 - "AND " + ModelConstants.ENTITY_ID_COLUMN + EQUALS_PARAM);  
908 - }  
909 - return findAllLatestStmt;  
910 - }  
911 -  
912 private static String getColumnName(DataType type) { 609 private static String getColumnName(DataType type) {
913 switch (type) { 610 switch (type) {
914 case BOOLEAN: 611 case BOOLEAN:
@@ -951,4 +648,56 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -951,4 +648,56 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
951 } 648 }
952 } 649 }
953 650
  651 + /**
  652 + // * Select existing partitions from the table
  653 + // * <code>{@link ModelConstants#TS_KV_PARTITIONS_CF}</code> for the given entity
  654 + // */
  655 + private TbResultSetFuture fetchPartitions(TenantId tenantId, EntityId entityId, String key, long minPartition, long maxPartition) {
  656 + Select select = QueryBuilder.selectFrom(ModelConstants.TS_KV_PARTITIONS_CF).column(ModelConstants.PARTITION_COLUMN)
  657 + .whereColumn(ModelConstants.ENTITY_TYPE_COLUMN).isEqualTo(literal(entityId.getEntityType().name()))
  658 + .whereColumn(ModelConstants.ENTITY_ID_COLUMN).isEqualTo(literal(entityId.getId()))
  659 + .whereColumn(ModelConstants.KEY_COLUMN).isEqualTo(literal(key))
  660 + .whereColumn(ModelConstants.PARTITION_COLUMN).isGreaterThanOrEqualTo(literal(minPartition))
  661 + .whereColumn(ModelConstants.PARTITION_COLUMN).isLessThanOrEqualTo(literal(maxPartition));
  662 + return executeAsyncRead(tenantId, select.build());
  663 + }
  664 +
  665 + private PreparedStatement getFetchStmt(Aggregation aggType, String orderBy) {
  666 + switch (orderBy) {
  667 + case ASC_ORDER:
  668 + if (fetchStmtsAsc == null) {
  669 + fetchStmtsAsc = initFetchStmt(orderBy);
  670 + }
  671 + return fetchStmtsAsc[aggType.ordinal()];
  672 + case DESC_ORDER:
  673 + if (fetchStmtsDesc == null) {
  674 + fetchStmtsDesc = initFetchStmt(orderBy);
  675 + }
  676 + return fetchStmtsDesc[aggType.ordinal()];
  677 + default:
  678 + throw new RuntimeException("Not supported" + orderBy + "order!");
  679 + }
  680 + }
  681 +
  682 + private PreparedStatement[] initFetchStmt(String orderBy) {
  683 + PreparedStatement[] fetchStmts = new PreparedStatement[Aggregation.values().length];
  684 + for (Aggregation type : Aggregation.values()) {
  685 + if (type == Aggregation.SUM && fetchStmts[Aggregation.AVG.ordinal()] != null) {
  686 + fetchStmts[type.ordinal()] = fetchStmts[Aggregation.AVG.ordinal()];
  687 + } else if (type == Aggregation.AVG && fetchStmts[Aggregation.SUM.ordinal()] != null) {
  688 + fetchStmts[type.ordinal()] = fetchStmts[Aggregation.SUM.ordinal()];
  689 + } else {
  690 + fetchStmts[type.ordinal()] = prepare(SELECT_PREFIX +
  691 + String.join(", ", ModelConstants.getFetchColumnNames(type)) + " FROM " + ModelConstants.TS_KV_CF
  692 + + " WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + EQUALS_PARAM
  693 + + "AND " + ModelConstants.ENTITY_ID_COLUMN + EQUALS_PARAM
  694 + + "AND " + ModelConstants.KEY_COLUMN + EQUALS_PARAM
  695 + + "AND " + ModelConstants.PARTITION_COLUMN + EQUALS_PARAM
  696 + + "AND " + ModelConstants.TS_COLUMN + " > ? "
  697 + + "AND " + ModelConstants.TS_COLUMN + " <= ?"
  698 + + (type == Aggregation.NONE ? " ORDER BY " + ModelConstants.TS_COLUMN + " " + orderBy + " LIMIT ?" : ""));
  699 + }
  700 + }
  701 + return fetchStmts;
  702 + }
954 } 703 }
  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.BoundStatement;
  19 +import com.datastax.oss.driver.api.core.cql.BoundStatementBuilder;
  20 +import com.datastax.oss.driver.api.core.cql.PreparedStatement;
  21 +import com.datastax.oss.driver.api.core.cql.Row;
  22 +import com.datastax.oss.driver.api.core.cql.Statement;
  23 +import com.datastax.oss.driver.api.querybuilder.QueryBuilder;
  24 +import com.google.common.util.concurrent.FutureCallback;
  25 +import com.google.common.util.concurrent.Futures;
  26 +import com.google.common.util.concurrent.ListenableFuture;
  27 +import com.google.common.util.concurrent.MoreExecutors;
  28 +import lombok.extern.slf4j.Slf4j;
  29 +import org.springframework.beans.factory.annotation.Autowired;
  30 +import org.springframework.stereotype.Component;
  31 +import org.thingsboard.server.common.data.id.EntityId;
  32 +import org.thingsboard.server.common.data.id.TenantId;
  33 +import org.thingsboard.server.common.data.kv.Aggregation;
  34 +import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
  35 +import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
  36 +import org.thingsboard.server.common.data.kv.DeleteTsKvQuery;
  37 +import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
  38 +import org.thingsboard.server.common.data.kv.StringDataEntry;
  39 +import org.thingsboard.server.common.data.kv.TsKvEntry;
  40 +import org.thingsboard.server.dao.model.ModelConstants;
  41 +import org.thingsboard.server.dao.nosql.TbResultSet;
  42 +import org.thingsboard.server.dao.sqlts.AggregationTimeseriesDao;
  43 +import org.thingsboard.server.dao.util.NoSqlTsLatestDao;
  44 +
  45 +import javax.annotation.Nullable;
  46 +import java.util.List;
  47 +import java.util.Optional;
  48 +import java.util.concurrent.ExecutionException;
  49 +
  50 +import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal;
  51 +
  52 +@Component
  53 +@Slf4j
  54 +@NoSqlTsLatestDao
  55 +public class CassandraBaseTimeseriesLatestDao extends AbstractCassandraBaseTimeseriesDao implements TimeseriesLatestDao {
  56 +
  57 + @Autowired
  58 + protected AggregationTimeseriesDao aggregationTimeseriesDao;
  59 +
  60 + private PreparedStatement latestInsertStmt;
  61 + private PreparedStatement findLatestStmt;
  62 + private PreparedStatement findAllLatestStmt;
  63 +
  64 + @Override
  65 + public ListenableFuture<TsKvEntry> findLatest(TenantId tenantId, EntityId entityId, String key) {
  66 + BoundStatementBuilder stmtBuilder = new BoundStatementBuilder(getFindLatestStmt().bind());
  67 + stmtBuilder.setString(0, entityId.getEntityType().name());
  68 + stmtBuilder.setUuid(1, entityId.getId());
  69 + stmtBuilder.setString(2, key);
  70 + BoundStatement stmt = stmtBuilder.build();
  71 + log.debug(GENERATED_QUERY_FOR_ENTITY_TYPE_AND_ENTITY_ID, stmt, entityId.getEntityType(), entityId.getId());
  72 + return getFuture(executeAsyncRead(tenantId, stmt), rs -> convertResultToTsKvEntry(key, rs.one()));
  73 + }
  74 +
  75 + @Override
  76 + public ListenableFuture<List<TsKvEntry>> findAllLatest(TenantId tenantId, EntityId entityId) {
  77 + BoundStatementBuilder stmtBuilder = new BoundStatementBuilder(getFindAllLatestStmt().bind());
  78 + stmtBuilder.setString(0, entityId.getEntityType().name());
  79 + stmtBuilder.setUuid(1, entityId.getId());
  80 + BoundStatement stmt = stmtBuilder.build();
  81 + log.debug(GENERATED_QUERY_FOR_ENTITY_TYPE_AND_ENTITY_ID, stmt, entityId.getEntityType(), entityId.getId());
  82 + return getFutureAsync(executeAsyncRead(tenantId, stmt), rs -> convertAsyncResultSetToTsKvEntryList(rs));
  83 + }
  84 +
  85 + @Override
  86 + public ListenableFuture<Void> saveLatest(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry) {
  87 + BoundStatementBuilder stmtBuilder = new BoundStatementBuilder(getLatestStmt().bind());
  88 + stmtBuilder.setString(0, entityId.getEntityType().name())
  89 + .setUuid(1, entityId.getId())
  90 + .setString(2, tsKvEntry.getKey())
  91 + .setLong(3, tsKvEntry.getTs())
  92 + .set(4, tsKvEntry.getBooleanValue().orElse(null), Boolean.class)
  93 + .set(5, tsKvEntry.getStrValue().orElse(null), String.class)
  94 + .set(6, tsKvEntry.getLongValue().orElse(null), Long.class)
  95 + .set(7, tsKvEntry.getDoubleValue().orElse(null), Double.class);
  96 + Optional<String> jsonV = tsKvEntry.getJsonValue();
  97 + if (jsonV.isPresent()) {
  98 + stmtBuilder.setString(8, tsKvEntry.getJsonValue().get());
  99 + } else {
  100 + stmtBuilder.setToNull(8);
  101 + }
  102 + BoundStatement stmt = stmtBuilder.build();
  103 +
  104 + return getFuture(executeAsyncWrite(tenantId, stmt), rs -> null);
  105 + }
  106 +
  107 + @Override
  108 + public ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
  109 + ListenableFuture<TsKvEntry> latestEntryFuture = findLatest(tenantId, entityId, query.getKey());
  110 +
  111 + ListenableFuture<Boolean> booleanFuture = Futures.transform(latestEntryFuture, latestEntry -> {
  112 + long ts = latestEntry.getTs();
  113 + if (ts > query.getStartTs() && ts <= query.getEndTs()) {
  114 + return true;
  115 + } else {
  116 + log.trace("Won't be deleted latest value for [{}], key - {}", entityId, query.getKey());
  117 + }
  118 + return false;
  119 + }, readResultsProcessingExecutor);
  120 +
  121 + ListenableFuture<Void> removedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> {
  122 + if (isRemove) {
  123 + return deleteLatest(tenantId, entityId, query.getKey());
  124 + }
  125 + return Futures.immediateFuture(null);
  126 + }, readResultsProcessingExecutor);
  127 +
  128 + final SimpleListenableFuture<Void> resultFuture = new SimpleListenableFuture<>();
  129 + Futures.addCallback(removedLatestFuture, new FutureCallback<Void>() {
  130 + @Override
  131 + public void onSuccess(@Nullable Void result) {
  132 + if (query.getRewriteLatestIfDeleted()) {
  133 + ListenableFuture<Void> savedLatestFuture = Futures.transformAsync(booleanFuture, isRemove -> {
  134 + if (isRemove) {
  135 + return getNewLatestEntryFuture(tenantId, entityId, query);
  136 + }
  137 + return Futures.immediateFuture(null);
  138 + }, readResultsProcessingExecutor);
  139 +
  140 + try {
  141 + resultFuture.set(savedLatestFuture.get());
  142 + } catch (InterruptedException | ExecutionException e) {
  143 + log.warn("Could not get latest saved value for [{}], {}", entityId, query.getKey(), e);
  144 + }
  145 + } else {
  146 + resultFuture.set(null);
  147 + }
  148 + }
  149 +
  150 + @Override
  151 + public void onFailure(Throwable t) {
  152 + log.warn("[{}] Failed to process remove of the latest value", entityId, t);
  153 + }
  154 + }, MoreExecutors.directExecutor());
  155 + return resultFuture;
  156 + }
  157 +
  158 + private ListenableFuture<Void> getNewLatestEntryFuture(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) {
  159 + long startTs = 0;
  160 + long endTs = query.getStartTs() - 1;
  161 + ReadTsKvQuery findNewLatestQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, endTs - startTs, 1,
  162 + Aggregation.NONE, DESC_ORDER);
  163 + ListenableFuture<List<TsKvEntry>> future = aggregationTimeseriesDao.findAllAsync(tenantId, entityId, findNewLatestQuery);
  164 +
  165 + return Futures.transformAsync(future, entryList -> {
  166 + if (entryList.size() == 1) {
  167 + return saveLatest(tenantId, entityId, entryList.get(0));
  168 + } else {
  169 + log.trace("Could not find new latest value for [{}], key - {}", entityId, query.getKey());
  170 + }
  171 + return Futures.immediateFuture(null);
  172 + }, readResultsProcessingExecutor);
  173 + }
  174 +
  175 + private ListenableFuture<Void> deleteLatest(TenantId tenantId, EntityId entityId, String key) {
  176 + Statement delete = QueryBuilder.deleteFrom(ModelConstants.TS_KV_LATEST_CF)
  177 + .whereColumn(ModelConstants.ENTITY_TYPE_COLUMN).isEqualTo(literal(entityId.getEntityType().name()))
  178 + .whereColumn(ModelConstants.ENTITY_ID_COLUMN).isEqualTo(literal(entityId.getId()))
  179 + .whereColumn(ModelConstants.KEY_COLUMN).isEqualTo(literal(key)).build();
  180 + log.debug("Remove request: {}", delete.toString());
  181 + return getFuture(executeAsyncWrite(tenantId, delete), rs -> null);
  182 + }
  183 +
  184 + private ListenableFuture<List<TsKvEntry>> convertAsyncResultSetToTsKvEntryList(TbResultSet rs) {
  185 + return Futures.transform(rs.allRows(readResultsProcessingExecutor),
  186 + rows -> this.convertResultToTsKvEntryList(rows), readResultsProcessingExecutor);
  187 + }
  188 +
  189 + private TsKvEntry convertResultToTsKvEntry(String key, Row row) {
  190 + if (row != null) {
  191 + long ts = row.getLong(ModelConstants.TS_COLUMN);
  192 + return new BasicTsKvEntry(ts, toKvEntry(row, key));
  193 + } else {
  194 + return new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(key, null));
  195 + }
  196 + }
  197 +
  198 + private PreparedStatement getLatestStmt() {
  199 + if (latestInsertStmt == null) {
  200 + latestInsertStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_LATEST_CF +
  201 + "(" + ModelConstants.ENTITY_TYPE_COLUMN +
  202 + "," + ModelConstants.ENTITY_ID_COLUMN +
  203 + "," + ModelConstants.KEY_COLUMN +
  204 + "," + ModelConstants.TS_COLUMN +
  205 + "," + ModelConstants.BOOLEAN_VALUE_COLUMN +
  206 + "," + ModelConstants.STRING_VALUE_COLUMN +
  207 + "," + ModelConstants.LONG_VALUE_COLUMN +
  208 + "," + ModelConstants.DOUBLE_VALUE_COLUMN +
  209 + "," + ModelConstants.JSON_VALUE_COLUMN + ")" +
  210 + " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)");
  211 + }
  212 + return latestInsertStmt;
  213 + }
  214 +
  215 + private PreparedStatement getFindLatestStmt() {
  216 + if (findLatestStmt == null) {
  217 + findLatestStmt = prepare(SELECT_PREFIX +
  218 + ModelConstants.KEY_COLUMN + "," +
  219 + ModelConstants.TS_COLUMN + "," +
  220 + ModelConstants.STRING_VALUE_COLUMN + "," +
  221 + ModelConstants.BOOLEAN_VALUE_COLUMN + "," +
  222 + ModelConstants.LONG_VALUE_COLUMN + "," +
  223 + ModelConstants.DOUBLE_VALUE_COLUMN + "," +
  224 + ModelConstants.JSON_VALUE_COLUMN + " " +
  225 + "FROM " + ModelConstants.TS_KV_LATEST_CF + " " +
  226 + "WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + EQUALS_PARAM +
  227 + "AND " + ModelConstants.ENTITY_ID_COLUMN + EQUALS_PARAM +
  228 + "AND " + ModelConstants.KEY_COLUMN + EQUALS_PARAM);
  229 + }
  230 + return findLatestStmt;
  231 + }
  232 +
  233 + private PreparedStatement getFindAllLatestStmt() {
  234 + if (findAllLatestStmt == null) {
  235 + findAllLatestStmt = prepare(SELECT_PREFIX +
  236 + ModelConstants.KEY_COLUMN + "," +
  237 + ModelConstants.TS_COLUMN + "," +
  238 + ModelConstants.STRING_VALUE_COLUMN + "," +
  239 + ModelConstants.BOOLEAN_VALUE_COLUMN + "," +
  240 + ModelConstants.LONG_VALUE_COLUMN + "," +
  241 + ModelConstants.DOUBLE_VALUE_COLUMN + "," +
  242 + ModelConstants.JSON_VALUE_COLUMN + " " +
  243 + "FROM " + ModelConstants.TS_KV_LATEST_CF + " " +
  244 + "WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + EQUALS_PARAM +
  245 + "AND " + ModelConstants.ENTITY_ID_COLUMN + EQUALS_PARAM);
  246 + }
  247 + return findAllLatestStmt;
  248 + }
  249 +}
@@ -31,19 +31,11 @@ public interface TimeseriesDao { @@ -31,19 +31,11 @@ public interface TimeseriesDao {
31 31
32 ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries); 32 ListenableFuture<List<TsKvEntry>> findAllAsync(TenantId tenantId, EntityId entityId, List<ReadTsKvQuery> queries);
33 33
34 - ListenableFuture<TsKvEntry> findLatest(TenantId tenantId, EntityId entityId, String key);  
35 -  
36 - ListenableFuture<List<TsKvEntry>> findAllLatest(TenantId tenantId, EntityId entityId);  
37 -  
38 ListenableFuture<Void> save(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl); 34 ListenableFuture<Void> save(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl);
39 35
40 ListenableFuture<Void> savePartition(TenantId tenantId, EntityId entityId, long tsKvEntryTs, String key, long ttl); 36 ListenableFuture<Void> savePartition(TenantId tenantId, EntityId entityId, long tsKvEntryTs, String key, long ttl);
41 37
42 - ListenableFuture<Void> saveLatest(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry);  
43 -  
44 ListenableFuture<Void> remove(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query); 38 ListenableFuture<Void> remove(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query);
45 39
46 - ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query);  
47 -  
48 ListenableFuture<Void> removePartition(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query); 40 ListenableFuture<Void> removePartition(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query);
49 } 41 }
  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.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.DeleteTsKvQuery;
  22 +import org.thingsboard.server.common.data.kv.TsKvEntry;
  23 +
  24 +import java.util.List;
  25 +
  26 +public interface TimeseriesLatestDao {
  27 +
  28 + ListenableFuture<TsKvEntry> findLatest(TenantId tenantId, EntityId entityId, String key);
  29 +
  30 + ListenableFuture<List<TsKvEntry>> findAllLatest(TenantId tenantId, EntityId entityId);
  31 +
  32 + ListenableFuture<Void> saveLatest(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry);
  33 +
  34 + ListenableFuture<Void> removeLatest(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query);
  35 +
  36 +}
  1 +--
  2 +-- Copyright © 2016-2020 The Thingsboard Authors
  3 +--
  4 +-- Licensed under the Apache License, Version 2.0 (the "License");
  5 +-- you may not use this file except in compliance with the License.
  6 +-- You may obtain a copy of the License at
  7 +--
  8 +-- http://www.apache.org/licenses/LICENSE-2.0
  9 +--
  10 +-- Unless required by applicable law or agreed to in writing, software
  11 +-- distributed under the License is distributed on an "AS IS" BASIS,
  12 +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +-- See the License for the specific language governing permissions and
  14 +-- limitations under the License.
  15 +--
  16 +
  17 +CREATE KEYSPACE IF NOT EXISTS thingsboard
  18 +WITH replication = {
  19 + 'class' : 'SimpleStrategy',
  20 + 'replication_factor' : 1
  21 +};
  22 +
  23 +CREATE TABLE IF NOT EXISTS thingsboard.ts_kv_latest_cf (
  24 + entity_type text, // (DEVICE, CUSTOMER, TENANT)
  25 + entity_id timeuuid,
  26 + key text,
  27 + ts bigint,
  28 + bool_v boolean,
  29 + str_v text,
  30 + long_v bigint,
  31 + dbl_v double,
  32 + json_v text,
  33 + PRIMARY KEY (( entity_type, entity_id ), key)
  34 +) WITH compaction = { 'class' : 'LeveledCompactionStrategy' };
@@ -42,16 +42,3 @@ CREATE TABLE IF NOT EXISTS thingsboard.ts_kv_partitions_cf ( @@ -42,16 +42,3 @@ CREATE TABLE IF NOT EXISTS thingsboard.ts_kv_partitions_cf (
42 PRIMARY KEY (( entity_type, entity_id, key ), partition) 42 PRIMARY KEY (( entity_type, entity_id, key ), partition)
43 ) WITH CLUSTERING ORDER BY ( partition ASC ) 43 ) WITH CLUSTERING ORDER BY ( partition ASC )
44 AND compaction = { 'class' : 'LeveledCompactionStrategy' }; 44 AND compaction = { 'class' : 'LeveledCompactionStrategy' };
45 -  
46 -CREATE TABLE IF NOT EXISTS thingsboard.ts_kv_latest_cf (  
47 - entity_type text, // (DEVICE, CUSTOMER, TENANT)  
48 - entity_id timeuuid,  
49 - key text,  
50 - ts bigint,  
51 - bool_v boolean,  
52 - str_v text,  
53 - long_v bigint,  
54 - dbl_v double,  
55 - json_v text,  
56 - PRIMARY KEY (( entity_type, entity_id ), key)  
57 -) WITH compaction = { 'class' : 'LeveledCompactionStrategy' };  
@@ -272,3 +272,20 @@ CREATE TABLE IF NOT EXISTS entity_view ( @@ -272,3 +272,20 @@ CREATE TABLE IF NOT EXISTS entity_view (
272 additional_info varchar 272 additional_info varchar
273 ); 273 );
274 274
  275 +CREATE TABLE IF NOT EXISTS ts_kv_latest (
  276 + entity_id uuid NOT NULL,
  277 + key int NOT NULL,
  278 + ts bigint NOT NULL,
  279 + bool_v boolean,
  280 + str_v varchar(10000000),
  281 + long_v bigint,
  282 + dbl_v double precision,
  283 + json_v varchar(10000000),
  284 + CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key)
  285 +);
  286 +
  287 +CREATE TABLE IF NOT EXISTS ts_kv_dictionary (
  288 + key varchar(255) NOT NULL,
  289 + key_id int GENERATED BY DEFAULT AS IDENTITY(start with 0 increment by 1) UNIQUE,
  290 + CONSTRAINT ts_key_id_pkey PRIMARY KEY (key)
  291 +);
@@ -14,6 +14,13 @@ @@ -14,6 +14,13 @@
14 -- limitations under the License. 14 -- limitations under the License.
15 -- 15 --
16 16
  17 +CREATE TABLE IF NOT EXISTS tb_schema_settings
  18 +(
  19 + schema_version bigint NOT NULL,
  20 + CONSTRAINT tb_schema_settings_pkey PRIMARY KEY (schema_version)
  21 +);
  22 +
  23 +INSERT INTO tb_schema_settings (schema_version) VALUES (3001000) ON CONFLICT (schema_version) DO UPDATE SET schema_version = 3001000;
17 24
18 CREATE TABLE IF NOT EXISTS admin_settings ( 25 CREATE TABLE IF NOT EXISTS admin_settings (
19 id uuid NOT NULL CONSTRAINT admin_settings_pkey PRIMARY KEY, 26 id uuid NOT NULL CONSTRAINT admin_settings_pkey PRIMARY KEY,
@@ -331,3 +338,4 @@ BEGIN @@ -331,3 +338,4 @@ BEGIN
331 '-' || substring(entity_id, 16, 4) || '-' || substring(entity_id, 20, 12); 338 '-' || substring(entity_id, 16, 4) || '-' || substring(entity_id, 20, 12);
332 END; 339 END;
333 $$ LANGUAGE plpgsql; 340 $$ LANGUAGE plpgsql;
  341 +
@@ -46,14 +46,6 @@ CREATE TABLE IF NOT EXISTS ts_kv_latest ( @@ -46,14 +46,6 @@ CREATE TABLE IF NOT EXISTS ts_kv_latest (
46 CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key) 46 CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key)
47 ); 47 );
48 48
49 -CREATE TABLE IF NOT EXISTS tb_schema_settings  
50 -(  
51 - schema_version bigint NOT NULL,  
52 - CONSTRAINT tb_schema_settings_pkey PRIMARY KEY (schema_version)  
53 -);  
54 -  
55 -INSERT INTO tb_schema_settings (schema_version) VALUES (2005001) ON CONFLICT (schema_version) DO UPDATE SET schema_version = 2005001;  
56 -  
57 CREATE OR REPLACE FUNCTION to_uuid(IN entity_id varchar, OUT uuid_id uuid) AS 49 CREATE OR REPLACE FUNCTION to_uuid(IN entity_id varchar, OUT uuid_id uuid) AS
58 $$ 50 $$
59 BEGIN 51 BEGIN
@@ -28,18 +28,6 @@ CREATE TABLE IF NOT EXISTS ts_kv ( @@ -28,18 +28,6 @@ CREATE TABLE IF NOT EXISTS ts_kv (
28 CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts) 28 CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts)
29 ); 29 );
30 30
31 -CREATE TABLE IF NOT EXISTS ts_kv_latest (  
32 - entity_id uuid NOT NULL,  
33 - key int NOT NULL,  
34 - ts bigint NOT NULL,  
35 - bool_v boolean,  
36 - str_v varchar(10000000),  
37 - long_v bigint,  
38 - dbl_v double precision,  
39 - json_v varchar(10000000),  
40 - CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key)  
41 -);  
42 -  
43 CREATE TABLE IF NOT EXISTS ts_kv_dictionary ( 31 CREATE TABLE IF NOT EXISTS ts_kv_dictionary (
44 key varchar(255) NOT NULL, 32 key varchar(255) NOT NULL,
45 key_id int GENERATED BY DEFAULT AS IDENTITY(start with 0 increment by 1) UNIQUE, 33 key_id int GENERATED BY DEFAULT AS IDENTITY(start with 0 increment by 1) UNIQUE,
@@ -27,19 +27,6 @@ CREATE TABLE IF NOT EXISTS ts_kv @@ -27,19 +27,6 @@ CREATE TABLE IF NOT EXISTS ts_kv
27 CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts) 27 CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts)
28 ) PARTITION BY RANGE (ts); 28 ) PARTITION BY RANGE (ts);
29 29
30 -CREATE TABLE IF NOT EXISTS ts_kv_latest  
31 -(  
32 - entity_id uuid NOT NULL,  
33 - key int NOT NULL,  
34 - ts bigint NOT NULL,  
35 - bool_v boolean,  
36 - str_v varchar(10000000),  
37 - long_v bigint,  
38 - dbl_v double precision,  
39 - json_v json,  
40 - CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key)  
41 -);  
42 -  
43 CREATE TABLE IF NOT EXISTS ts_kv_dictionary 30 CREATE TABLE IF NOT EXISTS ts_kv_dictionary
44 ( 31 (
45 key varchar(255) NOT NULL, 32 key varchar(255) NOT NULL,
@@ -47,14 +34,6 @@ CREATE TABLE IF NOT EXISTS ts_kv_dictionary @@ -47,14 +34,6 @@ CREATE TABLE IF NOT EXISTS ts_kv_dictionary
47 CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) 34 CONSTRAINT ts_key_id_pkey PRIMARY KEY (key)
48 ); 35 );
49 36
50 -CREATE TABLE IF NOT EXISTS tb_schema_settings  
51 -(  
52 - schema_version bigint NOT NULL,  
53 - CONSTRAINT tb_schema_settings_pkey PRIMARY KEY (schema_version)  
54 -);  
55 -  
56 -INSERT INTO tb_schema_settings (schema_version) VALUES (2005001) ON CONFLICT (schema_version) DO UPDATE SET schema_version = 2005001;  
57 -  
58 CREATE OR REPLACE PROCEDURE drop_partitions_by_max_ttl(IN partition_type varchar, IN system_ttl bigint, INOUT deleted bigint) 37 CREATE OR REPLACE PROCEDURE drop_partitions_by_max_ttl(IN partition_type varchar, IN system_ttl bigint, INOUT deleted bigint)
59 LANGUAGE plpgsql AS 38 LANGUAGE plpgsql AS
60 $$ 39 $$
@@ -22,7 +22,6 @@ import org.dbunit.ext.hsqldb.HsqldbDataTypeFactory; @@ -22,7 +22,6 @@ import org.dbunit.ext.hsqldb.HsqldbDataTypeFactory;
22 import org.springframework.beans.factory.annotation.Autowired; 22 import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.context.annotation.Bean; 23 import org.springframework.context.annotation.Bean;
24 import org.springframework.context.annotation.Configuration; 24 import org.springframework.context.annotation.Configuration;
25 -import org.thingsboard.server.dao.util.SqlDao;  
26 25
27 import javax.sql.DataSource; 26 import javax.sql.DataSource;
28 import java.io.IOException; 27 import java.io.IOException;
@@ -32,7 +31,6 @@ import java.sql.SQLException; @@ -32,7 +31,6 @@ import java.sql.SQLException;
32 * Created by Valerii Sosliuk on 5/6/2017. 31 * Created by Valerii Sosliuk on 5/6/2017.
33 */ 32 */
34 @Configuration 33 @Configuration
35 -@SqlDao  
36 public class JpaDbunitTestConfig { 34 public class JpaDbunitTestConfig {
37 35
38 @Autowired 36 @Autowired
@@ -40,7 +40,8 @@ public class NoSqlDaoServiceTestSuite { @@ -40,7 +40,8 @@ public class NoSqlDaoServiceTestSuite {
40 public static CustomCassandraCQLUnit cassandraUnit = 40 public static CustomCassandraCQLUnit cassandraUnit =
41 new CustomCassandraCQLUnit( 41 new CustomCassandraCQLUnit(
42 Arrays.asList( 42 Arrays.asList(
43 - new ClassPathCQLDataSet("cassandra/schema-ts.cql", false, false) 43 + new ClassPathCQLDataSet("cassandra/schema-ts.cql", false, false),
  44 + new ClassPathCQLDataSet("cassandra/schema-ts-latest.cql", false, false)
44 ), 45 ),
45 "cassandra-test.yaml", 30000L); 46 "cassandra-test.yaml", 30000L);
46 47
1 database.ts.type=cassandra 1 database.ts.type=cassandra
  2 +database.ts_latest.type=cassandra
2 3
3 sql.ts_inserts_executor_type=fixed 4 sql.ts_inserts_executor_type=fixed
4 sql.ts_inserts_fixed_thread_pool_size=10 5 sql.ts_inserts_fixed_thread_pool_size=10
1 database.ts.type=sql 1 database.ts.type=sql
  2 +database.ts_latest.type=sql
2 3
3 sql.ts_inserts_executor_type=fixed 4 sql.ts_inserts_executor_type=fixed
4 sql.ts_inserts_fixed_thread_pool_size=200 5 sql.ts_inserts_fixed_thread_pool_size=200