From f647c69f509db991039f7b0dd7a990c7fa860f2c Mon Sep 17 00:00:00 2001 From: Dmytro Shvaika Date: Tue, 1 Sep 2020 19:57:57 +0300 Subject: [PATCH 1/6] cherry-pick bfdd52c from fix/ttlCleanUpServices and added the upgrade from 3.1.1 --- .../schema_update_psql_drop_partitions.sql | 1 + .../install/ThingsboardInstallService.java | 5 +++++ .../CassandraTsDatabaseUpgradeService.java | 1 + .../install/PsqlTsDatabaseUpgradeService.java | 6 ++++++ .../TimescaleTsDatabaseUpgradeService.java | 2 ++ .../service/ttl/AbstractCleanUpService.java | 18 +++++++----------- .../ttl/events/EventsCleanUpService.java | 2 +- .../PsqlTimeseriesCleanUpService.java | 11 ++++++----- .../TimescaleTimeseriesCleanUpService.java | 3 ++- dao/src/main/resources/sql/schema-ts-psql.sql | 1 + 10 files changed, 32 insertions(+), 18 deletions(-) diff --git a/application/src/main/data/upgrade/2.4.3/schema_update_psql_drop_partitions.sql b/application/src/main/data/upgrade/2.4.3/schema_update_psql_drop_partitions.sql index 0916c241a1..41e1cfbb7a 100644 --- a/application/src/main/data/upgrade/2.4.3/schema_update_psql_drop_partitions.sql +++ b/application/src/main/data/upgrade/2.4.3/schema_update_psql_drop_partitions.sql @@ -64,6 +64,7 @@ BEGIN AND tablename like 'ts_kv_' || '%' AND tablename != 'ts_kv_latest' AND tablename != 'ts_kv_dictionary' + AND tablename != 'ts_kv_indefinite' LOOP IF partition != partition_by_max_ttl_date THEN IF partition_year IS NOT NULL THEN diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index de7b2bdce3..09945a3894 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -175,6 +175,11 @@ public class ThingsboardInstallService { case "3.1.0": log.info("Upgrading ThingsBoard from version 3.1.0 to 3.1.1 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.1.0"); + case "3.1.1": + log.info("Upgrading ThingsBoard from version 3.1.1 to 3.1.2 ..."); + if (databaseTsUpgradeService != null) { + databaseTsUpgradeService.upgradeDatabase("3.1.1"); + } log.info("Updating system data..."); systemDataLoaderService.updateSystemWidgets(); break; diff --git a/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java index 58180583ef..17857e2807 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java @@ -49,6 +49,7 @@ public class CassandraTsDatabaseUpgradeService extends AbstractCassandraDatabase log.info("Schema updated."); break; case "2.5.0": + case "3.1.1": break; default: throw new RuntimeException("Unable to upgrade Cassandra database, unsupported fromVersion: " + fromVersion); diff --git a/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java index 7a8174af16..3f663a0fc8 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java @@ -195,6 +195,12 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe executeQuery(conn, "UPDATE tb_schema_settings SET schema_version = 2005001"); } break; + case "3.1.1": + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { + log.info("Load Drop Partitions functions ..."); + loadSql(conn, LOAD_DROP_PARTITIONS_FUNCTIONS_SQL); + } + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java index d8f7ea61f9..260db325e5 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java @@ -177,6 +177,8 @@ public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgr executeQuery(conn, "UPDATE tb_schema_settings SET schema_version = 2005001"); } break; + case "3.1.1": + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/AbstractCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/AbstractCleanUpService.java index 4fc4df0048..e81788958d 100644 --- a/application/src/main/java/org/thingsboard/server/service/ttl/AbstractCleanUpService.java +++ b/application/src/main/java/org/thingsboard/server/service/ttl/AbstractCleanUpService.java @@ -38,19 +38,15 @@ public abstract class AbstractCleanUpService { @Value("${spring.datasource.password}") protected String dbPassword; - protected long executeQuery(Connection conn, String query) { - long removed = 0L; - try { - Statement statement = conn.createStatement(); + protected long executeQuery(Connection conn, String query) throws SQLException { + try (Statement statement = conn.createStatement()) { ResultSet resultSet = statement.executeQuery(query); - getWarnings(statement); + if (log.isDebugEnabled()) { + getWarnings(statement); + } resultSet.next(); - removed = resultSet.getLong(1); - log.debug("Successfully executed query: {}", query); - } catch (SQLException e) { - log.debug("Failed to execute query: {} due to: {}", query, e.getMessage()); + return resultSet.getLong(1); } - return removed; } protected void getWarnings(Statement statement) throws SQLException { @@ -65,6 +61,6 @@ public abstract class AbstractCleanUpService { } } - protected abstract void doCleanUp(Connection connection); + protected abstract void doCleanUp(Connection connection) throws SQLException; } diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/events/EventsCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/events/EventsCleanUpService.java index a608ca257b..0f3cd71f00 100644 --- a/application/src/main/java/org/thingsboard/server/service/ttl/events/EventsCleanUpService.java +++ b/application/src/main/java/org/thingsboard/server/service/ttl/events/EventsCleanUpService.java @@ -52,7 +52,7 @@ public class EventsCleanUpService extends AbstractCleanUpService { } @Override - protected void doCleanUp(Connection connection) { + protected void doCleanUp(Connection connection) throws SQLException { long totalEventsRemoved = executeQuery(connection, "call cleanup_events_by_ttl(" + ttl + ", " + debugTtl + ", 0);"); log.info("Total events removed by TTL: [{}]", totalEventsRemoved); } diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/PsqlTimeseriesCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/PsqlTimeseriesCleanUpService.java index fb09a7eab4..73a5c73732 100644 --- a/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/PsqlTimeseriesCleanUpService.java +++ b/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/PsqlTimeseriesCleanUpService.java @@ -23,6 +23,7 @@ import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.SqlTsDao; import java.sql.Connection; +import java.sql.SQLException; @SqlTsDao @PsqlDao @@ -34,10 +35,10 @@ public class PsqlTimeseriesCleanUpService extends AbstractTimeseriesCleanUpServi private String partitionType; @Override - protected void doCleanUp(Connection connection) { - long totalPartitionsRemoved = executeQuery(connection, "call drop_partitions_by_max_ttl('" + partitionType + "'," + systemTtl + ", 0);"); - log.info("Total partitions removed by TTL: [{}]", totalPartitionsRemoved); - long totalEntitiesTelemetryRemoved = executeQuery(connection, "call cleanup_timeseries_by_ttl('" + ModelConstants.NULL_UUID + "'," + systemTtl + ", 0);"); - log.info("Total telemetry removed stats by TTL for entities: [{}]", totalEntitiesTelemetryRemoved); + protected void doCleanUp(Connection connection) throws SQLException { + long totalPartitionsRemoved = executeQuery(connection, "call drop_partitions_by_max_ttl('" + partitionType + "'," + systemTtl + ", 0);"); + log.info("Total partitions removed by TTL: [{}]", totalPartitionsRemoved); + long totalEntitiesTelemetryRemoved = executeQuery(connection, "call cleanup_timeseries_by_ttl('" + ModelConstants.NULL_UUID + "'," + systemTtl + ", 0);"); + log.info("Total telemetry removed stats by TTL for entities: [{}]", totalEntitiesTelemetryRemoved); } } \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/TimescaleTimeseriesCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/TimescaleTimeseriesCleanUpService.java index 7070ef5dc3..8a1b17c549 100644 --- a/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/TimescaleTimeseriesCleanUpService.java +++ b/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/TimescaleTimeseriesCleanUpService.java @@ -21,6 +21,7 @@ import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.util.TimescaleDBTsDao; import java.sql.Connection; +import java.sql.SQLException; @TimescaleDBTsDao @Service @@ -28,7 +29,7 @@ import java.sql.Connection; public class TimescaleTimeseriesCleanUpService extends AbstractTimeseriesCleanUpService { @Override - protected void doCleanUp(Connection connection) { + protected void doCleanUp(Connection connection) throws SQLException { long totalEntitiesTelemetryRemoved = executeQuery(connection, "call cleanup_timeseries_by_ttl('" + ModelConstants.NULL_UUID + "'," + systemTtl + ", 0);"); log.info("Total telemetry removed stats by TTL for entities: [{}]", totalEntitiesTelemetryRemoved); } diff --git a/dao/src/main/resources/sql/schema-ts-psql.sql b/dao/src/main/resources/sql/schema-ts-psql.sql index ef6c51aa0a..5509e58624 100644 --- a/dao/src/main/resources/sql/schema-ts-psql.sql +++ b/dao/src/main/resources/sql/schema-ts-psql.sql @@ -84,6 +84,7 @@ BEGIN AND tablename like 'ts_kv_' || '%' AND tablename != 'ts_kv_latest' AND tablename != 'ts_kv_dictionary' + AND tablename != 'ts_kv_indefinite' LOOP IF partition != partition_by_max_ttl_date THEN IF partition_year IS NOT NULL THEN From f510b142a786cd755344924f003913efb05db4c2 Mon Sep 17 00:00:00 2001 From: Dmytro Shvaika Date: Tue, 1 Sep 2020 20:48:45 +0300 Subject: [PATCH 2/6] fix cleanup_timeseries_by_ttl procedure --- application/src/main/data/upgrade/2.4.3/schema_update_ttl.sql | 4 ++-- .../server/service/install/PsqlTsDatabaseUpgradeService.java | 2 ++ dao/src/main/resources/sql/schema-ts-psql.sql | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/application/src/main/data/upgrade/2.4.3/schema_update_ttl.sql b/application/src/main/data/upgrade/2.4.3/schema_update_ttl.sql index 5e20e1c664..7de74032ce 100644 --- a/application/src/main/data/upgrade/2.4.3/schema_update_ttl.sql +++ b/application/src/main/data/upgrade/2.4.3/schema_update_ttl.sql @@ -59,8 +59,8 @@ $$ DECLARE tenant_cursor CURSOR FOR select tenant.id as tenant_id from tenant; - tenant_id_record varchar; - customer_id_record varchar; + tenant_id_record uuid; + customer_id_record uuid; tenant_ttl bigint; customer_ttl bigint; deleted_for_entities bigint; diff --git a/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java index 3f663a0fc8..ddfaf69d3a 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java @@ -197,6 +197,8 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe break; case "3.1.1": try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { + log.info("Load TTL functions ..."); + loadSql(conn, LOAD_TTL_FUNCTIONS_SQL); log.info("Load Drop Partitions functions ..."); loadSql(conn, LOAD_DROP_PARTITIONS_FUNCTIONS_SQL); } diff --git a/dao/src/main/resources/sql/schema-ts-psql.sql b/dao/src/main/resources/sql/schema-ts-psql.sql index 5509e58624..48f74b17da 100644 --- a/dao/src/main/resources/sql/schema-ts-psql.sql +++ b/dao/src/main/resources/sql/schema-ts-psql.sql @@ -188,8 +188,8 @@ $$ DECLARE tenant_cursor CURSOR FOR select tenant.id as tenant_id from tenant; - tenant_id_record varchar; - customer_id_record varchar; + tenant_id_record uuid; + customer_id_record uuid; tenant_ttl bigint; customer_ttl bigint; deleted_for_entities bigint; From 47a7e3b31bf266d9b2edb07465bc15073446ffb1 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 2 Sep 2020 19:20:13 +0300 Subject: [PATCH 3/6] Fixed after sort legend keys, is not correct dataKey index; Refactoring --- ui-ngx/src/app/core/api/widget-subscription.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/ui-ngx/src/app/core/api/widget-subscription.ts b/ui-ngx/src/app/core/api/widget-subscription.ts index 0eb71c7e90..df5fac2e9a 100644 --- a/ui-ngx/src/app/core/api/widget-subscription.ts +++ b/ui-ngx/src/app/core/api/widget-subscription.ts @@ -403,7 +403,7 @@ export class WidgetSubscription implements IWidgetSubscription { configDatasource: datasource, configDatasourceIndex: index, dataLoaded: (pageData, data1, datasourceIndex, pageLink) => { - this.dataLoaded(pageData, data1, datasourceIndex, pageLink, true) + this.dataLoaded(pageData, data1, datasourceIndex, pageLink, true); }, initialPageDataChanged: this.initialPageDataChanged.bind(this), dataUpdated: this.dataUpdated.bind(this), @@ -804,7 +804,7 @@ export class WidgetSubscription implements IWidgetSubscription { configDatasourceIndex: datasourceIndex, subscriptionTimewindow: this.subscriptionTimewindow, dataLoaded: (pageData, data1, datasourceIndex1, pageLink1) => { - this.dataLoaded(pageData, data1, datasourceIndex1, pageLink1, true) + this.dataLoaded(pageData, data1, datasourceIndex1, pageLink1, true); }, dataUpdated: this.dataUpdated.bind(this), updateRealtimeSubscription: () => { @@ -1149,7 +1149,7 @@ export class WidgetSubscription implements IWidgetSubscription { this.onSubscriptionMessage({ severity: 'warn', message - }) + }); } } if (isUpdate) { @@ -1226,9 +1226,6 @@ export class WidgetSubscription implements IWidgetSubscription { }); }); } - if (this.displayLegend) { - this.legendData.keys = this.legendData.keys.sort((key1, key2) => key1.dataKey.label.localeCompare(key2.dataKey.label)); - } if (this.caulculateLegendData) { this.data.forEach((dataSetHolder, keyIndex) => { this.updateLegend(keyIndex, dataSetHolder.data, false); @@ -1274,7 +1271,7 @@ export class WidgetSubscription implements IWidgetSubscription { const configuredDatasource = this.configuredDatasources[datasourceIndex]; const startIndex = configuredDatasource.dataKeyStartIndex; const dataKeysCount = configuredDatasource.dataKeys.length; - const index = startIndex + dataIndex*dataKeysCount + dataKeyIndex; + const index = startIndex + dataIndex * dataKeysCount + dataKeyIndex; let update = true; let currentData: DataSetHolder; if (this.displayLegend && this.legendData.keys[index].dataKey.hidden) { From b1e019816414a8f6ee1dfe111b0a01ce5a61d251 Mon Sep 17 00:00:00 2001 From: Vladyslav Prykhodko Date: Wed, 2 Sep 2020 23:54:31 +0300 Subject: [PATCH 4/6] Add module-map Material tooltip module --- ui-ngx/src/app/modules/common/modules-map.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui-ngx/src/app/modules/common/modules-map.ts b/ui-ngx/src/app/modules/common/modules-map.ts index e6955106bb..7c56df331e 100644 --- a/ui-ngx/src/app/modules/common/modules-map.ts +++ b/ui-ngx/src/app/modules/common/modules-map.ts @@ -60,6 +60,7 @@ import * as AngularMaterialStepper from '@angular/material/stepper'; import * as AngularMaterialTable from '@angular/material/table'; import * as AngularMaterialTabs from '@angular/material/tabs'; import * as AngularMaterialToolbar from '@angular/material/toolbar'; +import * as AngularMaterialTooltip from '@angular/material/tooltip'; import * as AngularMaterialTree from '@angular/material/tree'; import * as NgrxStore from '@ngrx/store'; import * as RxJs from 'rxjs'; @@ -119,6 +120,7 @@ export const modulesMap: {[key: string]: any} = { '@angular/material/table': SystemJS.newModule(AngularMaterialTable), '@angular/material/tabs': SystemJS.newModule(AngularMaterialTabs), '@angular/material/toolbar': SystemJS.newModule(AngularMaterialToolbar), + '@angular/material/tooltip': SystemJS.newModule(AngularMaterialTooltip), '@angular/material/tree': SystemJS.newModule(AngularMaterialTree), '@ngrx/store': SystemJS.newModule(NgrxStore), rxjs: SystemJS.newModule(RxJs), From 903080f4f3c6ffdd530af9c37012276ccf88ebc0 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Thu, 3 Sep 2020 12:40:17 +0300 Subject: [PATCH 5/6] Add correct sort dataKey --- ui-ngx/src/app/core/api/widget-subscription.ts | 7 +++++-- .../modules/home/components/widget/legend.component.html | 4 ++-- .../app/modules/home/components/widget/legend.component.ts | 5 +++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ui-ngx/src/app/core/api/widget-subscription.ts b/ui-ngx/src/app/core/api/widget-subscription.ts index df5fac2e9a..bb594f0802 100644 --- a/ui-ngx/src/app/core/api/widget-subscription.ts +++ b/ui-ngx/src/app/core/api/widget-subscription.ts @@ -575,7 +575,7 @@ export class WidgetSubscription implements IWidgetSubscription { updateDataVisibility(index: number): void { if (this.displayLegend) { - const hidden = this.legendData.keys[index].dataKey.hidden; + const hidden = this.legendData.keys.find(key => key.dataIndex === index).dataKey.hidden; if (hidden) { this.hiddenData[index].data = this.data[index].data; this.data[index].data = []; @@ -1226,6 +1226,9 @@ export class WidgetSubscription implements IWidgetSubscription { }); }); } + if (this.displayLegend) { + this.legendData.keys = this.legendData.keys.sort((key1, key2) => key1.dataKey.label.localeCompare(key2.dataKey.label)); + } if (this.caulculateLegendData) { this.data.forEach((dataSetHolder, keyIndex) => { this.updateLegend(keyIndex, dataSetHolder.data, false); @@ -1328,7 +1331,7 @@ export class WidgetSubscription implements IWidgetSubscription { } private updateLegend(dataIndex: number, data: DataSet, detectChanges: boolean) { - const dataKey = this.legendData.keys[dataIndex].dataKey; + const dataKey = this.legendData.keys.find(key => key.dataIndex === dataIndex).dataKey; const decimals = isDefined(dataKey.decimals) ? dataKey.decimals : this.decimals; const units = dataKey.units && dataKey.units.length ? dataKey.units : this.units; const legendKeyData = this.legendData.data[dataIndex]; diff --git a/ui-ngx/src/app/modules/home/components/widget/legend.component.html b/ui-ngx/src/app/modules/home/components/widget/legend.component.html index 3d0eda2856..272e5fae64 100644 --- a/ui-ngx/src/app/modules/home/components/widget/legend.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/legend.component.html @@ -32,7 +32,7 @@ + [ngClass]="{ 'tb-hidden-label': legendKey.dataKey.hidden, 'tb-horizontal': isHorizontal }"> {{ legendKey.dataKey.label }} {{ legendData.data[legendKey.dataIndex].min }} @@ -47,7 +47,7 @@ + [ngClass]="{ 'tb-hidden-label': legendKey.dataKey.hidden}"> {{ legendKey.dataKey.label }} diff --git a/ui-ngx/src/app/modules/home/components/widget/legend.component.ts b/ui-ngx/src/app/modules/home/components/widget/legend.component.ts index b47ba317c0..55fffa2b5b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/legend.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/legend.component.ts @@ -52,8 +52,9 @@ export class LegendComponent implements OnInit { } toggleHideData(index: number) { - if (!this.legendData.keys[index].dataKey.settings.disableDataHiding) { - this.legendData.keys[index].dataKey.hidden = !this.legendData.keys[index].dataKey.hidden; + const dataKey = this.legendData.keys.find(key => key.dataIndex === index).dataKey; + if (!dataKey.settings.disableDataHiding) { + dataKey.hidden = !dataKey.hidden; this.legendKeyHiddenChange.emit(index); } } From 57076e64a6f8158e259a60446f3f5085fce07899 Mon Sep 17 00:00:00 2001 From: Trevor Muraro Date: Thu, 3 Sep 2020 21:52:29 +0000 Subject: [PATCH 6/6] Add full DataStax Java Driver SSL configs --- .../src/main/resources/thingsboard.yml | 19 ++++++++++-- .../dao/cassandra/CassandraDriverOptions.java | 30 +++++++++++++++++-- .../test/resources/cassandra-test.properties | 8 ++++- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index ac0b6f614c..4345e5a757 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -194,8 +194,21 @@ cassandra: url: "${CASSANDRA_URL:127.0.0.1:9042}" # Specify local datacenter name local_datacenter: "${CASSANDRA_LOCAL_DATACENTER:datacenter1}" - # Enable/disable secure connection - ssl: "${CASSANDRA_USE_SSL:false}" + ssl: + # Enable/disable secure connection + enabled: "${CASSANDRA_USE_SSL:false}" + # Enable/disable validation of Cassandra server hostname + # If enabled, hostname of Cassandra server must match CN of server certificate + hostname_validation: "${CASSANDRA_SSL_HOSTNAME_VALIDATION:true}" + # Set trust store for client authentication of server (optional, uses trust store from default SSLContext if not set) + trust_store: "${CASSANDRA_SSL_TRUST_STORE:}" + trust_store_password: "${CASSANDRA_SSL_TRUST_STORE_PASSWORD:}" + # Set key store for server authentication of client (optional, uses key store from default SSLContext if not set) + # A key store is only needed if the Cassandra server requires client authentication + key_store: "${CASSANDRA_SSL_KEY_STORE:}" + key_store_password: "${CASSANDRA_SSL_KEY_STORE_PASSWORD:}" + # Comma separated list of cipher suites (optional, uses Java default cipher suites if not set) + cipher_suites: "${CASSANDRA_SSL_CIPHER_SUITES:}" # Enable/disable JMX jmx: "${CASSANDRA_USE_JMX:false}" # Enable/disable metrics collection. @@ -797,4 +810,4 @@ management: web: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). - include: '${METRICS_ENDPOINTS_EXPOSE:info}' \ No newline at end of file + include: '${METRICS_ENDPOINTS_EXPOSE:info}' diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java index 21b20f7427..6db7f84dc3 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java @@ -80,8 +80,22 @@ public class CassandraDriverOptions { @Value("${cassandra.compression}") private String compression; - @Value("${cassandra.ssl}") + + @Value("${cassandra.ssl.enabled}") private Boolean ssl; + @Value("${cassandra.ssl.key_store}") + private String sslKeyStore; + @Value("${cassandra.ssl.key_store_password}") + private String sslKeyStorePassword; + @Value("${cassandra.ssl.trust_store}") + private String sslTrustStore; + @Value("${cassandra.ssl.trust_store_password}") + private String sslTrustStorePassword; + @Value("${cassandra.ssl.hostname_validation}") + private Boolean sslHostnameValidation; + @Value("${cassandra.ssl.cipher_suites}") + private List sslCipherSuites; + @Value("${cassandra.metrics}") private Boolean metrics; @@ -120,7 +134,19 @@ public class CassandraDriverOptions { if (this.ssl) { driverConfigBuilder.withString(DefaultDriverOption.SSL_ENGINE_FACTORY_CLASS, - "DefaultSslEngineFactory"); + "DefaultSslEngineFactory") + .withBoolean(DefaultDriverOption.SSL_HOSTNAME_VALIDATION, this.sslHostnameValidation); + if(!this.sslTrustStore.isEmpty()) { + driverConfigBuilder.withString(DefaultDriverOption.SSL_TRUSTSTORE_PATH, this.sslTrustStore) + .withString(DefaultDriverOption.SSL_TRUSTSTORE_PASSWORD, this.sslTrustStorePassword); + } + if(!this.sslKeyStore.isEmpty()) { + driverConfigBuilder.withString(DefaultDriverOption.SSL_KEYSTORE_PATH, this.sslKeyStore) + .withString(DefaultDriverOption.SSL_KEYSTORE_PASSWORD, this.sslKeyStorePassword); + } + if(!this.sslCipherSuites.isEmpty()) { + driverConfigBuilder.withStringList(DefaultDriverOption.SSL_CIPHER_SUITES, this.sslCipherSuites); + } } if (this.metrics) { diff --git a/dao/src/test/resources/cassandra-test.properties b/dao/src/test/resources/cassandra-test.properties index 4cb4cd662a..43a78abac4 100644 --- a/dao/src/test/resources/cassandra-test.properties +++ b/dao/src/test/resources/cassandra-test.properties @@ -6,7 +6,13 @@ cassandra.url=127.0.0.1:9142 cassandra.local_datacenter=datacenter1 -cassandra.ssl=false +cassandra.ssl.enabled=false +cassandra.ssl.hostname_validation=false +cassandra.ssl.trust_store= +cassandra.ssl.trust_store_password= +cassandra.ssl.key_store= +cassandra.ssl.key_store_password= +cassandra.ssl.cipher_suites= cassandra.jmx=false