diff --git a/application/src/main/data/json/demo/rule_chains/edge_root_rule_chain.json b/application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json similarity index 100% rename from application/src/main/data/json/demo/rule_chains/edge_root_rule_chain.json rename to application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json diff --git a/application/src/main/data/json/tenant/rule_chains/edge_root_rule_chain.json b/application/src/main/data/json/tenant/edge_management/rule_chains/edge_root_rule_chain.json similarity index 100% rename from application/src/main/data/json/tenant/rule_chains/edge_root_rule_chain.json rename to application/src/main/data/json/tenant/edge_management/rule_chains/edge_root_rule_chain.json diff --git a/application/src/main/data/upgrade/2.6.0/schema_update.cql b/application/src/main/data/upgrade/2.6.0/schema_update.cql deleted file mode 100644 index 8a95c62969..0000000000 --- a/application/src/main/data/upgrade/2.6.0/schema_update.cql +++ /dev/null @@ -1,126 +0,0 @@ --- --- Copyright © 2016-2020 The Thingsboard Authors --- --- Licensed under the Apache License, Version 2.0 (the "License"); --- you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- - -DROP MATERIALIZED VIEW IF EXISTS thingsboard.rule_chain_by_tenant_and_search_text; - -DROP TABLE IF EXISTS thingsboard.rule_chain; - -CREATE TABLE IF NOT EXISTS thingsboard.rule_chain ( - id uuid, - tenant_id uuid, - name text, - type text, - search_text text, - first_rule_node_id uuid, - root boolean, - debug_mode boolean, - configuration text, - additional_info text, - PRIMARY KEY (id, tenant_id, type) -); - -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.rule_chain_by_tenant_and_search_text AS - SELECT * - from thingsboard.rule_chain - WHERE tenant_id IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL AND type IS NOT NULL - PRIMARY KEY ( tenant_id, search_text, id, type ) - WITH CLUSTERING ORDER BY ( search_text ASC, id DESC ); - -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.rule_chain_by_tenant_by_type_and_search_text AS - SELECT * - from thingsboard.rule_chain - WHERE tenant_id IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL AND type IS NOT NULL - PRIMARY KEY ( tenant_id, type, search_text, id ) - WITH CLUSTERING ORDER BY ( type ASC, search_text ASC, id DESC ); - -CREATE TABLE IF NOT EXISTS thingsboard.edge ( - id timeuuid, - tenant_id timeuuid, - customer_id timeuuid, - root_rule_chain_id timeuuid, - type text, - name text, - label text, - search_text text, - routing_key text, - secret text, - edge_license_key text, - cloud_endpoint text, - additional_info text, - PRIMARY KEY (id, tenant_id, customer_id, type) -); - -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_name AS - SELECT * - from thingsboard.edge - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL - PRIMARY KEY ( tenant_id, name, id, customer_id, type) - WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC); - -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_routing_key AS - SELECT * - from thingsboard.edge - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND routing_key IS NOT NULL AND id IS NOT NULL - PRIMARY KEY ( routing_key, tenant_id, id, customer_id, type) - WITH CLUSTERING ORDER BY ( tenant_id DESC, id DESC, customer_id DESC); - -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_search_text AS - SELECT * - from thingsboard.edge - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL - PRIMARY KEY ( tenant_id, search_text, id, customer_id, type) - WITH CLUSTERING ORDER BY ( search_text ASC, id DESC, customer_id DESC); - -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_by_type_and_search_text AS - SELECT * - from thingsboard.edge - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL - PRIMARY KEY ( tenant_id, type, search_text, id, customer_id) - WITH CLUSTERING ORDER BY ( type ASC, search_text ASC, id DESC, customer_id DESC); - -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_customer_and_search_text AS - SELECT * - from thingsboard.edge - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL - PRIMARY KEY ( customer_id, tenant_id, search_text, id, type ) - WITH CLUSTERING ORDER BY ( tenant_id DESC, search_text ASC, id DESC ); - -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_customer_by_type_and_search_text AS - SELECT * - from thingsboard.edge - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL - PRIMARY KEY ( customer_id, tenant_id, type, search_text, id ) - WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC ); - -CREATE TABLE IF NOT EXISTS thingsboard.edge_event ( - id timeuuid, - tenant_id timeuuid, - edge_id timeuuid, - edge_event_type text, - edge_event_action text, - edge_event_uid text, - entity_id timeuuid, - body text, - PRIMARY KEY ((tenant_id, edge_id), edge_event_type, edge_event_uid) -); - -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_event_by_id AS - SELECT * - FROM thingsboard.edge_event - WHERE tenant_id IS NOT NULL AND edge_id IS NOT NULL AND edge_event_type IS NOT NULL - AND id IS NOT NULL AND edge_event_uid IS NOT NULL - PRIMARY KEY ((tenant_id, edge_id), id, edge_event_type, edge_event_uid) - WITH CLUSTERING ORDER BY (id ASC); \ No newline at end of file diff --git a/application/src/main/data/upgrade/2.6.0/schema_update.sql b/application/src/main/data/upgrade/3.2.0/schema_update.sql similarity index 79% rename from application/src/main/data/upgrade/2.6.0/schema_update.sql rename to application/src/main/data/upgrade/3.2.0/schema_update.sql index c08a854a66..c22caa47cb 100644 --- a/application/src/main/data/upgrade/2.6.0/schema_update.sql +++ b/application/src/main/data/upgrade/3.2.0/schema_update.sql @@ -15,10 +15,11 @@ -- CREATE TABLE IF NOT EXISTS edge ( - id varchar(31) NOT NULL CONSTRAINT edge_pkey PRIMARY KEY, + id uuid NOT NULL CONSTRAINT edge_pkey PRIMARY KEY, + created_time bigint NOT NULL, additional_info varchar, - customer_id varchar(31), - root_rule_chain_id varchar(31), + customer_id uuid, + root_rule_chain_id uuid, type varchar(255), name varchar(255), label varchar(255), @@ -27,19 +28,20 @@ CREATE TABLE IF NOT EXISTS edge ( edge_license_key varchar(30), cloud_endpoint varchar(255), search_text varchar(255), - tenant_id varchar(31), + tenant_id uuid, CONSTRAINT edge_name_unq_key UNIQUE (tenant_id, name), CONSTRAINT edge_routing_key_unq_key UNIQUE (routing_key) ); CREATE TABLE IF NOT EXISTS edge_event ( - id varchar(31) NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY, - edge_id varchar(31), + id uuid NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY, + created_time bigint NOT NULL, + edge_id uuid, edge_event_type varchar(255), edge_event_uid varchar(255), - entity_id varchar(31), + entity_id uuid, edge_event_action varchar(255), body varchar(10000000), - tenant_id varchar(31), + tenant_id uuid, ts bigint NOT NULL ); diff --git a/application/src/main/data/upgrade/2.6.0/schema_update_ttl.sql b/application/src/main/data/upgrade/3.2.0/schema_update_ttl.sql similarity index 100% rename from application/src/main/data/upgrade/2.6.0/schema_update_ttl.sql rename to application/src/main/data/upgrade/3.2.0/schema_update_ttl.sql diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java index 993ac9bb46..731aa453ff 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -106,10 +106,10 @@ public class EdgeController extends BaseController { edge.setTenantId(tenantId); boolean created = edge.getId() == null; - RuleChain defaultRootEdgeRuleChain = null; + RuleChain edgeTemplateRootRuleChain = null; if (created) { - defaultRootEdgeRuleChain = ruleChainService.getEdgeTemplateRootRuleChain(tenantId); - if (defaultRootEdgeRuleChain == null) { + edgeTemplateRootRuleChain = ruleChainService.getEdgeTemplateRootRuleChain(tenantId); + if (edgeTemplateRootRuleChain == null) { throw new DataValidationException("Root edge rule chain is not available!"); } } @@ -122,8 +122,8 @@ public class EdgeController extends BaseController { Edge savedEdge = checkNotNull(edgeService.saveEdge(edge)); if (created) { - ruleChainService.assignRuleChainToEdge(tenantId, defaultRootEdgeRuleChain.getId(), savedEdge.getId()); - edgeNotificationService.setEdgeRootRuleChain(tenantId, savedEdge, defaultRootEdgeRuleChain.getId()); + ruleChainService.assignRuleChainToEdge(tenantId, edgeTemplateRootRuleChain.getId(), savedEdge.getId()); + edgeNotificationService.setEdgeRootRuleChain(tenantId, savedEdge, edgeTemplateRootRuleChain.getId()); edgeService.assignDefaultRuleChainsToEdge(tenantId, savedEdge.getId()); } @@ -456,10 +456,12 @@ public class EdgeController extends BaseController { checkNotNull(query.getEdgeTypes()); checkEntityId(query.getParameters().getEntityId(), Operation.READ); try { - List edges = checkNotNull(edgeService.findEdgesByQuery(getCurrentUser().getTenantId(), query).get()); + SecurityUser user = getCurrentUser(); + TenantId tenantId = user.getTenantId(); + List edges = checkNotNull(edgeService.findEdgesByQuery(tenantId, query).get()); edges = edges.stream().filter(edge -> { try { - accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, Operation.READ, edge.getId(), edge); + accessControlService.checkPermission(user, Resource.EDGE, Operation.READ, edge.getId(), edge); return true; } catch (ThingsboardException e) { return false; diff --git a/application/src/main/java/org/thingsboard/server/controller/TenantController.java b/application/src/main/java/org/thingsboard/server/controller/TenantController.java index a42cbb0f91..6644508dd1 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TenantController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TenantController.java @@ -90,6 +90,9 @@ public class TenantController extends BaseController { tenant = checkNotNull(tenantService.saveTenant(tenant)); if (newTenant) { installScripts.createDefaultRuleChains(tenant.getId()); + if (edgesEnabled) { + installScripts.createDefaultEdgeRuleChains(tenant.getId()); + } } tenantProfileCache.evict(tenant.getId()); tbClusterService.onTenantChange(tenant, null); 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 b4d5a0ff94..18892e6d37 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -192,6 +192,13 @@ public class ThingsboardInstallService { } databaseEntitiesUpgradeService.upgradeDatabase("3.1.1"); dataUpdateService.updateData("3.1.1"); + case "3.2.0": + log.info("Upgrading ThingsBoard from version 3.2.0 to 3.3.0 ..."); + if (databaseTsUpgradeService != null) { + databaseTsUpgradeService.upgradeDatabase("3.2.0"); + } + databaseEntitiesUpgradeService.upgradeDatabase("3.2.0"); + dataUpdateService.updateData("3.2.0"); log.info("Updating system data..."); systemDataLoaderService.updateSystemWidgets(); systemDataLoaderService.createOAuth2Templates(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 56262cb7ef..3ccdd40a17 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; 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 0a62395ef0..a5ae7719fe 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 @@ -52,6 +52,7 @@ public class CassandraTsDatabaseUpgradeService extends AbstractCassandraDatabase case "2.5.4": case "2.5.5": case "3.1.1": + case "3.2.0": 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/InstallScripts.java b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java index ff74c1cb14..4b74c79711 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java +++ b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java @@ -67,6 +67,8 @@ public class InstallScripts { public static final String OAUTH2_CONFIG_TEMPLATES_DIR = "oauth2_config_templates"; public static final String DASHBOARDS_DIR = "dashboards"; + public static final String EDGE_MANAGEMENT = "edge_management"; + public static final String JSON_EXT = ".json"; @Value("${install.data_dir:}") @@ -87,14 +89,18 @@ public class InstallScripts { @Autowired private OAuth2ConfigTemplateService oAuth2TemplateService; - public Path getTenantRuleChainsDir() { + private Path getTenantRuleChainsDir() { return Paths.get(getDataDir(), JSON_DIR, TENANT_DIR, RULE_CHAINS_DIR); } - public Path getDeviceProfileDefaultRuleChainTemplateFilePath() { + private Path getDeviceProfileDefaultRuleChainTemplateFilePath() { return Paths.get(getDataDir(), JSON_DIR, TENANT_DIR, DEVICE_PROFILE_DIR, "rule_chain_template.json"); } + private Path getEdgeRuleChainsDir() { + return Paths.get(getDataDir(), JSON_DIR, TENANT_DIR, EDGE_MANAGEMENT, RULE_CHAINS_DIR); + } + public String getDataDir() { if (!StringUtils.isEmpty(dataDir)) { if (!Paths.get(this.dataDir).toFile().isDirectory()) { @@ -118,7 +124,16 @@ public class InstallScripts { public void createDefaultRuleChains(TenantId tenantId) throws IOException { Path tenantChainsDir = getTenantRuleChainsDir(); - try (DirectoryStream dirStream = Files.newDirectoryStream(tenantChainsDir, path -> path.toString().endsWith(InstallScripts.JSON_EXT))) { + loadRuleChainsFromPath(tenantId, tenantChainsDir); + } + + public void createDefaultEdgeRuleChains(TenantId tenantId) throws IOException { + Path edgeChainsDir = getEdgeRuleChainsDir(); + loadRuleChainsFromPath(tenantId, edgeChainsDir); + } + + private void loadRuleChainsFromPath(TenantId tenantId, Path ruleChainsPath) throws IOException { + try (DirectoryStream dirStream = Files.newDirectoryStream(ruleChainsPath, path -> path.toString().endsWith(InstallScripts.JSON_EXT))) { dirStream.forEach( path -> { try { @@ -211,15 +226,16 @@ public class InstallScripts { try { createDefaultRuleChains(tenantId); createDefaultRuleChain(tenantId, "Thermostat"); + loadEdgeDemoRuleChains(tenantId); } catch (Exception e) { log.error("Unable to load dashboard from json", e); throw new RuntimeException("Unable to load dashboard from json", e); } } - public void createDefaultEdgeRuleChains(TenantId tenantId) throws IOException { - Path tenantChainsDir = getTenantRuleChainsDir(); - createRuleChainFromFile(tenantId, tenantChainsDir.resolve("edge_root_rule_chain.json"), null); + private void loadEdgeDemoRuleChains(TenantId tenantId) throws Exception { + Path edgeDemoRuleChainsDir = Paths.get(getDataDir(), JSON_DIR, DEMO_DIR, EDGE_MANAGEMENT, RULE_CHAINS_DIR); + loadRuleChainsFromPath(tenantId, edgeDemoRuleChainsDir); } public void createOAuth2Templates() throws Exception { 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 ce5799a8ac..792b991190 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,12 +195,6 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe executeQuery(conn, "UPDATE tb_schema_settings SET schema_version = 2005001"); } break; - case "2.5.5": - try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { - log.info("Load TTL functions ..."); - loadSql(conn, "2.6.0", LOAD_TTL_FUNCTIONS_SQL); - } - break; case "3.1.1": try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { log.info("Load TTL functions ..."); @@ -209,6 +203,12 @@ public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSe loadSql(conn, "2.4.3", LOAD_DROP_PARTITIONS_FUNCTIONS_SQL); } break; + case "3.2.0": + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { + log.info("Load Edge TTL functions ..."); + loadSql(conn, "3.2.0", LOAD_TTL_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/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index f7b03af092..5dd657e7cb 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -264,19 +264,6 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService log.info("Schema updated."); } break; - case "2.5.5": - try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { - log.info("Updating schema ..."); - // TODO: voba - should be 2.6.0 - schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.5.0", SCHEMA_UPDATE_SQL); - loadSql(schemaUpdateFile, conn); - - try { - conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'CORE'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script - } catch (Exception e) {} - log.info("Schema updated."); - } - break; case "3.0.1": try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { log.info("Updating schema ..."); @@ -434,7 +421,17 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService log.error("Failed updating schema!!!", e); } break; - + case "3.2.0": + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { + log.info("Updating schema ..."); + schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.2.0", SCHEMA_UPDATE_SQL); + loadSql(schemaUpdateFile, conn); + try { + conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'CORE'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script + } catch (Exception e) {} + log.info("Schema updated."); + } + 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 5d614449de..b3d7d3cf4c 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 @@ -179,7 +179,7 @@ public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgr break; case "3.1.1": break; - case "2.5.5": + case "3.2.0": 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/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 23eda0f5ff..a03cdf6db9 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -79,10 +79,6 @@ public class DefaultDataUpdateService implements DataUpdateService { log.info("Updating data from version 1.4.0 to 2.0.0 ..."); tenantsDefaultRuleChainUpdater.updateEntities(null); break; - case "2.5.5": - log.info("Updating data from version 2.5.5 to 2.6.0 ..."); - tenantsDefaultEdgeRuleChainUpdater.updateEntities(null); - break; case "3.0.1": log.info("Updating data from version 3.0.1 to 3.1.0 ..."); tenantsEntityViewsUpdater.updateEntities(null); @@ -91,6 +87,10 @@ public class DefaultDataUpdateService implements DataUpdateService { log.info("Updating data from version 3.1.1 to 3.2.0 ..."); tenantsRootRuleChainUpdater.updateEntities(null); break; + case "3.2.0": + log.info("Updating data from version 3.2.0 to 3.3.0 ..."); + tenantsDefaultEdgeRuleChainUpdater.updateEntities(null); + break; default: throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 386701efb8..46a6745438 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -46,8 +46,6 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.common.data.edge.EdgeEventActionType; -import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.edge.EdgeInfo; import org.thingsboard.server.common.data.edge.EdgeSearchQuery; import org.thingsboard.server.common.data.id.CustomerId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 14c0768364..64aa6ab32b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -105,7 +105,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN)); } catch (Exception e) { log.warn("[{}] Failed to create tenant to root rule chain relation. from: [{}], to: [{}]", - savedRuleChain.getTenantId(), savedRuleChain.getId()); + savedRuleChain.getTenantId(), savedRuleChain.getTenantId(), savedRuleChain.getId(), e); throw new RuntimeException(e); } } diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index 90220e2bc7..e25c77708e 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -2798,7 +2798,9 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { } public void syncEdge(EdgeId edgeId) { - restTemplate.postForEntity(baseURL + "/api/edge/sync", edgeId, EdgeId.class); + Map params = new HashMap<>(); + params.put("edgeId", edgeId.toString()); + restTemplate.postForEntity(baseURL + "/api/edge/sync/{edgeId}", null, EdgeId.class, params); } @Deprecated diff --git a/ui-ngx/src/assets/locale/locale.constant-de_DE.json b/ui-ngx/src/assets/locale/locale.constant-de_DE.json index 3b2eade5e5..541bf1469f 100644 --- a/ui-ngx/src/assets/locale/locale.constant-de_DE.json +++ b/ui-ngx/src/assets/locale/locale.constant-de_DE.json @@ -431,7 +431,7 @@ "customer-required": "Kunde ist erforderlich", "select-default-customer": "Wählen Sie den Standardkunden aus.", "default-customer": "Standardkunde", - "edges": "Kunden Rand", + "edge-instances": "Kunden Rand", "default-customer-required": "Ein Standardkunde ist erforderlich, um das Dashboard auf Mandantenebene zu testen." }, "datetime": { @@ -1404,7 +1404,8 @@ "set-auto-assign-to-edge-text": "Nach der Bestätigung wird die Kantenregelkette bei der Erstellung automatisch den Kanten zugewiesen.", "unset-auto-assign-to-edge": "Deaktiviert die Zuordnung der Regelkette zu Kanten bei der Erstellung", "unset-auto-assign-to-edge-title": "Möchten Sie die Kantenregelkette '{{ruleChainName}}' bei der Erstellung unbedingt den Kanten zuweisen?", - "unset-auto-assign-to-edge-text": "Nach der Bestätigung wird die Kantenregelkette bei der Erstellung nicht mehr automatisch den Kanten zugewiesen." + "unset-auto-assign-to-edge-text": "Nach der Bestätigung wird die Kantenregelkette bei der Erstellung nicht mehr automatisch den Kanten zugewiesen.", + "edge-template-root": "Vorlagenstamm" }, "rulenode": { "details": "Details", diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 44a4d7326e..bf7b38735f 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -584,7 +584,6 @@ "devices": "Customer Devices", "entity-views": "Customer Entity Views", "assets": "Customer Assets", - "edges": "Customer Edges", "public-dashboards": "Public Dashboards", "public-devices": "Public Devices", "public-assets": "Public Assets", @@ -627,7 +626,8 @@ "default-customer": "Default customer", "default-customer-required": "Default customer is required in order to debug dashboard on Tenant level", "search": "Search customers", - "selected-customers": "{ count, plural, 1 {1 customer} other {# customers} } selected" + "selected-customers": "{ count, plural, 1 {1 customer} other {# customers} } selected", + "edges": "Customer edge instances" }, "datetime": { "date-from": "Date from", @@ -1186,144 +1186,144 @@ "row": "Row" }, "edge": { - "edge": "Edge", - "edge-instances": "Edge instances", - "edge-file": "Edge file", - "management": "Edge management", - "no-edges-matching": "No edges matching '{{entity}}' were found.", - "rulechain-templates": "Rule chain templates", - "rulechains": "Rule chains", - "edge-rulechains": "Edge Rule chains", - "add": "Add Edge", - "view": "View Edge", - "no-edges-text": "No edges found", - "edge-details": "Edge details", - "add-edge-text": "Add new edge", - "delete": "Delete edge", - "delete-edges": "Delete edges", - "delete-edge-title": "Are you sure you want to delete the edge '{{edgeName}}'?", - "delete-edge-text": "Be careful, after the confirmation the edge and all related data will become unrecoverable.", - "delete-edges-title": "Are you sure you want to edge { count, plural, 1 {1 edge} other {# edges} }?", - "delete-edges-text": "Be careful, after the confirmation all selected edges will be removed and all related data will become unrecoverable.", - "name": "Name", - "name-starts-with": "Edge name starts with", - "name-required": "Name is required.", - "edge-license-key": "Edge License Key", - "edge-license-key-required": "Edge License Key is required.", - "edge-license-key-hint": "To obtain your license please navigate to the pricing page and select the best license option for your case.", - "cloud-endpoint": "Cloud Endpoint", - "cloud-endpoint-required": "Cloud Endpoint is required.", - "cloud-endpoint-hint": "Edge requires HTTP(s) access to Cloud (ThingsBoard CE/PE) to verify the license key. Please specify Cloud URL that Edge is able to connect to.", - "description": "Description", - "entity-info": "Entity info", - "details": "Details", - "events": "Events", - "copy-id": "Copy Edge Id", - "id-copied-message": "Edge Id has been copied to clipboard", - "sync": "Sync Edge", - "sync-message": "Edge has been synchronized", - "permissions": "Permissions", - "edge-required": "Edge required", - "edge-type": "Edge type", - "edge-type-required": "Edge type is required.", - "event-action": "Event action", - "entity-id": "Entity ID", - "select-edge-type": "Select edge type", - "assign-to-customer": "Assign to customer", - "assign-to-customer-text": "Please select the customer to assign the edge(s)", - "assign-edge-to-customer": "Assign Edge(s) To Customer", - "assign-edge-to-customer-text": "Please select the edges to assign to the customer", - "assigned-to-customer": "Assigned to customer", - "unassign-from-customer": "Unassign from customer", - "assign-edges-text": "Assign { count, plural, 1 {1 edge} other {# edges} } to customer", - "unassign-edge-title": "Are you sure you want to unassign the edge '{{edgeName}}'?", - "unassign-edge-text": "After the confirmation the edge will be unassigned and won't be accessible by the customer.", - "unassign-edges-title": "Are you sure you want to unassign { count, plural, 1 {1 edge} other {# edges} }?", - "unassign-edges-text": "After the confirmation all selected edges will be unassigned and won't be accessible by the customer.", - "make-public": "Make edge public", - "make-public-edge-title": "Are you sure you want to make the edge '{{edgeName}}' public?", - "make-public-edge-text": "After the confirmation the edge and all its data will be made public and accessible by others.", - "make-private": "Make edge private", - "public": "Public", - "make-private-edge-title": "Are you sure you want to make the edge '{{edgeName}}' private?", - "make-private-edge-text": "After the confirmation the edge and all its data will be made private and won't be accessible by others.", - "import": "Import edge", - "label": "Label", - "load-entity-error": "Failed to load data. Entity not found or has been deleted.", - "assign-new-edge": "Assign new edge", - "manage-edge-dashboards": "Edge dashboards", - "unassign-from-edge": "Unassign from edge", - "dashboards": "Edge Dashboards", - "manage-edge-rulechains": "Edge rule chains", - "edge-key": "Edge key", - "copy-edge-key": "Copy Edge key", - "edge-key-copied-message": "Edge key has been copied to clipboard", - "edge-secret": "Edge secret", - "copy-edge-secret": "Copy Edge secret", - "edge-secret-copied-message": "Edge secret has been copied to clipboard", - "manage-edge-assets": "Edge assets", - "manage-edge-devices": "Edge devices", - "manage-edge-entity-views": "Edge entity views", - "assets": "Edge assets", - "devices": "Edge devices", - "entity-views": "Edge entity views", - "set-root-rule-chain-text": "Please select root rule chain for edge(s)", - "set-root-rule-chain-to-edges": "Set root rule chain for Edge(s)", - "set-root-rule-chain-to-edges-text": "Set root rule chain for { count, plural, 1 {1 edge} other {# edges} }", - "status": "Received by edge", - "success": "Deployed", - "failed": "Pending", - "search": "Search edges", - "selected-edges": "{ count, plural, 1 {1 edge} other {# edges} } selected", - "any-edge": "Any edge", - "no-edge-types-matching": "No edge types matching '{{entitySubtype}}' were found.", - "edge-type-list-empty": "No edge types selected.", - "edge-types": "Edge types", - "dashboard": "Edge dashboard", - "enter-edge-type": "Enter edge type", - "deployed": "Deployed", - "pending": "Pending", - "downlinks": "Downlinks", - "no-downlinks-prompt": "No downlinks found", - "sync-process-started-successfully": "Sync process started successfully!", - "missing-related-rule-chains-title": "Edge has missing related rule chain(s)", - "missing-related-rule-chains-text": "Assigned to edge rule chain(s) use rule nodes that forward message(s) to rule chain(s) that are not assigned to this edge.

List of missing rule chain(s):
{{missingRuleChains}}" + "edge": "Edge", + "edge-instances": "Edge instances", + "edge-file": "Edge file", + "management": "Edge management", + "no-edges-matching": "No edges matching '{{entity}}' were found.", + "rulechain-templates": "Rule chain templates", + "rulechains": "Rule chains", + "edge-rulechains": "Edge Rule chains", + "add": "Add Edge", + "view": "View Edge", + "no-edges-text": "No edges found", + "edge-details": "Edge details", + "add-edge-text": "Add new edge", + "delete": "Delete edge", + "delete-edges": "Delete edges", + "delete-edge-title": "Are you sure you want to delete the edge '{{edgeName}}'?", + "delete-edge-text": "Be careful, after the confirmation the edge and all related data will become unrecoverable.", + "delete-edges-title": "Are you sure you want to edge { count, plural, 1 {1 edge} other {# edges} }?", + "delete-edges-text": "Be careful, after the confirmation all selected edges will be removed and all related data will become unrecoverable.", + "name": "Name", + "name-starts-with": "Edge name starts with", + "name-required": "Name is required.", + "edge-license-key": "Edge License Key", + "edge-license-key-required": "Edge License Key is required.", + "edge-license-key-hint": "To obtain your license please navigate to the pricing page and select the best license option for your case.", + "cloud-endpoint": "Cloud Endpoint", + "cloud-endpoint-required": "Cloud Endpoint is required.", + "cloud-endpoint-hint": "Edge requires HTTP(s) access to Cloud (ThingsBoard CE/PE) to verify the license key. Please specify Cloud URL that Edge is able to connect to.", + "description": "Description", + "entity-info": "Entity info", + "details": "Details", + "events": "Events", + "copy-id": "Copy Edge Id", + "id-copied-message": "Edge Id has been copied to clipboard", + "sync": "Sync Edge", + "sync-message": "Edge has been synchronized", + "permissions": "Permissions", + "edge-required": "Edge required", + "edge-type": "Edge type", + "edge-type-required": "Edge type is required.", + "event-action": "Event action", + "entity-id": "Entity ID", + "select-edge-type": "Select edge type", + "assign-to-customer": "Assign to customer", + "assign-to-customer-text": "Please select the customer to assign the edge(s)", + "assign-edge-to-customer": "Assign Edge(s) To Customer", + "assign-edge-to-customer-text": "Please select the edges to assign to the customer", + "assigned-to-customer": "Assigned to customer", + "unassign-from-customer": "Unassign from customer", + "assign-edges-text": "Assign { count, plural, 1 {1 edge} other {# edges} } to customer", + "unassign-edge-title": "Are you sure you want to unassign the edge '{{edgeName}}'?", + "unassign-edge-text": "After the confirmation the edge will be unassigned and won't be accessible by the customer.", + "unassign-edges-title": "Are you sure you want to unassign { count, plural, 1 {1 edge} other {# edges} }?", + "unassign-edges-text": "After the confirmation all selected edges will be unassigned and won't be accessible by the customer.", + "make-public": "Make edge public", + "make-public-edge-title": "Are you sure you want to make the edge '{{edgeName}}' public?", + "make-public-edge-text": "After the confirmation the edge and all its data will be made public and accessible by others.", + "make-private": "Make edge private", + "public": "Public", + "make-private-edge-title": "Are you sure you want to make the edge '{{edgeName}}' private?", + "make-private-edge-text": "After the confirmation the edge and all its data will be made private and won't be accessible by others.", + "import": "Import edge", + "label": "Label", + "load-entity-error": "Failed to load data. Entity not found or has been deleted.", + "assign-new-edge": "Assign new edge", + "manage-edge-dashboards": "Edge dashboards", + "unassign-from-edge": "Unassign from edge", + "dashboards": "Edge Dashboards", + "manage-edge-rulechains": "Edge rule chains", + "edge-key": "Edge key", + "copy-edge-key": "Copy Edge key", + "edge-key-copied-message": "Edge key has been copied to clipboard", + "edge-secret": "Edge secret", + "copy-edge-secret": "Copy Edge secret", + "edge-secret-copied-message": "Edge secret has been copied to clipboard", + "manage-edge-assets": "Edge assets", + "manage-edge-devices": "Edge devices", + "manage-edge-entity-views": "Edge entity views", + "assets": "Edge assets", + "devices": "Edge devices", + "entity-views": "Edge entity views", + "set-root-rule-chain-text": "Please select root rule chain for edge(s)", + "set-root-rule-chain-to-edges": "Set root rule chain for Edge(s)", + "set-root-rule-chain-to-edges-text": "Set root rule chain for { count, plural, 1 {1 edge} other {# edges} }", + "status": "Received by edge", + "success": "Deployed", + "failed": "Pending", + "search": "Search edges", + "selected-edges": "{ count, plural, 1 {1 edge} other {# edges} } selected", + "any-edge": "Any edge", + "no-edge-types-matching": "No edge types matching '{{entitySubtype}}' were found.", + "edge-type-list-empty": "No edge types selected.", + "edge-types": "Edge types", + "dashboard": "Edge dashboard", + "enter-edge-type": "Enter edge type", + "deployed": "Deployed", + "pending": "Pending", + "downlinks": "Downlinks", + "no-downlinks-prompt": "No downlinks found", + "sync-process-started-successfully": "Sync process started successfully!", + "missing-related-rule-chains-title": "Edge has missing related rule chain(s)", + "missing-related-rule-chains-text": "Assigned to edge rule chain(s) use rule nodes that forward message(s) to rule chain(s) that are not assigned to this edge.

List of missing rule chain(s):
{{missingRuleChains}}" }, "edge-event": { - "type-dashboard": "Dashboard", - "type-asset": "Asset", - "type-device": "Device", - "type-device-profile": "Device Profile", - "type-entity-view": "Entity View", - "type-alarm": "Alar", - "type-rule-chain": "Rule Chain", - "type-rule-chain-metadata": "Rule Chain Metadata", - "type-edge": "Edge", - "type-user": "User", - "type-customer": "Customer", - "type-relation": "Relation", - "type-widgets-bundle": "Widgets Bundle", - "type-widgets-type": "Widgets Type", - "type-admin-settings": "Admin Settings", - "action-type-added": "Added", - "action-type-deleted": "Deleted", - "action-type-updated": "Updated", - "action-type-post-attributes": "Post Attributes", - "action-type-attributes-updated": "Attributes Updated", - "action-type-attributes-deleted": "Attributes Deleted", - "action-type-timeseries-updated": "Timeseries Updated", - "action-type-credentials-updated": "Credentials Updated", - "action-type-assigned-to-customer": "Assigned to Customer", - "action-type-unassigned-from-customer": "Unassigned from Customer", - "action-type-relation-add-or-update": "Relation Add or Update", - "action-type-relation-deleted": "Relation Deleted", - "action-type-rpc-call": "RPC Call", - "action-type-alarm-ack": "Alarm Ack", - "action-type-alarm-clear": "Alarm Clear", - "action-type-assigned-to-edge": "Assigned to Edge", - "action-type-unassigned-from-edge": "Unassigned from Edge", - "action-type-credentials-request": "Credentials Request", - "action-type-entity-merge-request": "Entity Merge Request" + "type-dashboard": "Dashboard", + "type-asset": "Asset", + "type-device": "Device", + "type-device-profile": "Device Profile", + "type-entity-view": "Entity View", + "type-alarm": "Alar", + "type-rule-chain": "Rule Chain", + "type-rule-chain-metadata": "Rule Chain Metadata", + "type-edge": "Edge", + "type-user": "User", + "type-customer": "Customer", + "type-relation": "Relation", + "type-widgets-bundle": "Widgets Bundle", + "type-widgets-type": "Widgets Type", + "type-admin-settings": "Admin Settings", + "action-type-added": "Added", + "action-type-deleted": "Deleted", + "action-type-updated": "Updated", + "action-type-post-attributes": "Post Attributes", + "action-type-attributes-updated": "Attributes Updated", + "action-type-attributes-deleted": "Attributes Deleted", + "action-type-timeseries-updated": "Timeseries Updated", + "action-type-credentials-updated": "Credentials Updated", + "action-type-assigned-to-customer": "Assigned to Customer", + "action-type-unassigned-from-customer": "Unassigned from Customer", + "action-type-relation-add-or-update": "Relation Add or Update", + "action-type-relation-deleted": "Relation Deleted", + "action-type-rpc-call": "RPC Call", + "action-type-alarm-ack": "Alarm Ack", + "action-type-alarm-clear": "Alarm Clear", + "action-type-assigned-to-edge": "Assigned to Edge", + "action-type-unassigned-from-edge": "Unassigned from Edge", + "action-type-credentials-request": "Credentials Request", + "action-type-entity-merge-request": "Entity Merge Request" }, "error": { "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", diff --git a/ui-ngx/src/assets/locale/locale.constant-es_ES.json b/ui-ngx/src/assets/locale/locale.constant-es_ES.json index 7c2118fd3d..125e6cf4b1 100644 --- a/ui-ngx/src/assets/locale/locale.constant-es_ES.json +++ b/ui-ngx/src/assets/locale/locale.constant-es_ES.json @@ -1575,7 +1575,8 @@ "set-auto-assign-to-edge-text": "Después de la confirmación, la cadena de reglas de borde se asignará automáticamente a los bordes en la creación.", "unset-auto-assign-to-edge": "Desmarcar asignar cadena de reglas a los bordes en la creación", "unset-auto-assign-to-edge-title": "¿Está seguro de que desea anular la asignación de la cadena de reglas de borde '{{ruleChainName}}' a los bordes en la creación?", - "unset-auto-assign-to-edge-text": "Después de la confirmación, la cadena de reglas de borde ya no se asignará automáticamente a los bordes en la creación." + "unset-auto-assign-to-edge-text": "Después de la confirmación, la cadena de reglas de borde ya no se asignará automáticamente a los bordes en la creación.", + "edge-template-root": "Raíz de plantilla" }, "rulenode": { "details": "Detalles", diff --git a/ui-ngx/src/assets/locale/locale.constant-fr_FR.json b/ui-ngx/src/assets/locale/locale.constant-fr_FR.json index e44a333d32..b16ffe3268 100644 --- a/ui-ngx/src/assets/locale/locale.constant-fr_FR.json +++ b/ui-ngx/src/assets/locale/locale.constant-fr_FR.json @@ -1449,7 +1449,8 @@ "set-auto-assign-to-edge-text": "Après la confirmation, la chaîne de règles d'arête sera automatiquement affectée à l'arête (s) lors de la création.", "unset-auto-assign-to-edge": "Non défini, attribuer une chaîne de règles aux arêtes lors de la création", "unset-auto-assign-to-edge-title": "Voulez-vous vraiment annuler l'attribution de la chaîne de règles d'arête \"{{ruleChainName}}\" aux arêtes lors de la création?", - "unset-auto-assign-to-edge-text": "Après la confirmation, la chaîne de règles d'arêtes ne sera plus automatiquement affectée aux arêtes lors de la création." + "unset-auto-assign-to-edge-text": "Après la confirmation, la chaîne de règles d'arêtes ne sera plus automatiquement affectée aux arêtes lors de la création.", + "edge-template-root": "Racine du modèle" }, "rulenode": { "add": "Ajouter un noeud de règle",