diff --git a/application/src/main/data/upgrade/2.4.x/schema_update.cql b/application/src/main/data/upgrade/2.4.x/schema_update.cql index b518c7e68a..7592b803fa 100644 --- a/application/src/main/data/upgrade/2.4.x/schema_update.cql +++ b/application/src/main/data/upgrade/2.4.x/schema_update.cql @@ -23,7 +23,7 @@ CREATE TABLE IF NOT EXISTS thingsboard.edge ( configuration text, additional_info text, PRIMARY KEY (id, tenant_id) - ); +); CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_name AS SELECT * @@ -58,4 +58,6 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_customer_by_type_and_ 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 ); \ No newline at end of file + WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC ); + +-- VOBA ADD changes for the MATERIALIZED view for DEVICE ASSET ENTITY_VIEW RULE_CHAIN \ No newline at end of file diff --git a/application/src/main/data/upgrade/2.4.x/schema_update.sql b/application/src/main/data/upgrade/2.4.x/schema_update.sql index c080457d70..7cc234e47b 100644 --- a/application/src/main/data/upgrade/2.4.x/schema_update.sql +++ b/application/src/main/data/upgrade/2.4.x/schema_update.sql @@ -23,10 +23,3 @@ CREATE TABLE IF NOT EXISTS edge ( search_text varchar(255), tenant_id varchar(31) ); - -ALTER TABLE asset ADD edge_id varchar(31); -ALTER TABLE device ADD edge_id varchar(31); -ALTER TABLE entity_view ADD edge_id varchar(31); - -ALTER TABLE dashboard ADD assigned_edges varchar(1000000); -ALTER TABLE rule_chain ADD assigned_edges varchar(1000000); \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java index 388f7f394f..010fd58243 100644 --- a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java @@ -37,8 +37,8 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.aware.DeviceAwareMsg; import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; @@ -46,9 +46,6 @@ import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import scala.concurrent.duration.Duration; -import java.util.HashMap; -import java.util.Map; - public class TenantActor extends RuleChainManagerActor { private final TenantId tenantId; @@ -139,11 +136,17 @@ public class TenantActor extends RuleChainManagerActor { } private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { + RuleChain ruleChain = null; + if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { + ruleChain = systemContext.getRuleChainService().findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId())); + if (RuleChainType.SYSTEM.equals(ruleChain.getType())) { + log.debug("[{}] Non SYSTEM rule chains are ignored and not started. Current rule chain type [{}]", tenantId, ruleChain.getType()); + return; + } + } ActorRef target = getEntityActorRef(msg.getEntityId()); if (target != null) { - if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { - RuleChain ruleChain = systemContext.getRuleChainService(). - findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId())); + if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN && ruleChain != null) { ruleChainManager.visit(ruleChain, target); } target.tell(msg, ActorRef.noSender()); diff --git a/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java index 4886e346ba..73d144c135 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java @@ -272,6 +272,32 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService { log.info("Updating schema ..."); schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.4.x", SCHEMA_UPDATE_CQL); loadCql(schemaUpdateFile); + + try { + cluster.getSession().execute("alter table asset add edge_id text"); + Thread.sleep(2500); + } catch (InvalidQueryException e) {} + try { + cluster.getSession().execute("alter table device add edge_id text"); + Thread.sleep(2500); + } catch (InvalidQueryException e) {} + try { + cluster.getSession().execute("alter table entity_view add edge_id text"); + Thread.sleep(2500); + } catch (InvalidQueryException e) {} + try { + cluster.getSession().execute("alter table dashboard add assigned_edges text"); + Thread.sleep(2500); + } catch (InvalidQueryException e) {} + try { + cluster.getSession().execute("alter table rule_chain add assigned_edges text"); + Thread.sleep(2500); + } catch (InvalidQueryException e) {} + try { + cluster.getSession().execute("alter table rule_chain add type text"); + Thread.sleep(2500); + } catch (InvalidQueryException e) {} + log.info("Schema updated."); break; 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 eed3ddc263..9fd97f22a2 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 @@ -181,6 +181,24 @@ public class SqlDatabaseUpgradeService implements DatabaseUpgradeService { log.info("Updating schema ..."); schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.4.x", SCHEMA_UPDATE_SQL); loadSql(schemaUpdateFile, conn); + try { + conn.createStatement().execute("ALTER TABLE asset ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script + } catch (Exception e) {} + try { + conn.createStatement().execute("ALTER TABLE device ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script + } catch (Exception e) {} + try { + conn.createStatement().execute("ALTER TABLE entity_view ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script + } catch (Exception e) {} + try { + conn.createStatement().execute("ALTER TABLE dashboard ADD assigned_edges varchar(1000000)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script + } catch (Exception e) {} + try { + conn.createStatement().execute("ALTER TABLE rule_chain ADD assigned_edges varchar(1000000)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script + } catch (Exception e) {} + try { + conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'SYSTEM'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script + } catch (Exception e) {} log.info("Schema updated."); } break; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java index 4ea158322a..92295a6363 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java @@ -42,6 +42,7 @@ public class RuleChain extends SearchTextBasedWithAdditionalInfo im private TenantId tenantId; private String name; + private RuleChainType type; private RuleNodeId firstRuleNodeId; private boolean root; private boolean debugMode; @@ -63,6 +64,7 @@ public class RuleChain extends SearchTextBasedWithAdditionalInfo im super(ruleChain); this.tenantId = ruleChain.getTenantId(); this.name = ruleChain.getName(); + this.type = ruleChain.getType(); this.firstRuleNodeId = ruleChain.getFirstRuleNodeId(); this.root = ruleChain.isRoot(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainType.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainType.java new file mode 100644 index 0000000000..19f78aa068 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainType.java @@ -0,0 +1,5 @@ +package org.thingsboard.server.common.data.rule; + +public enum RuleChainType { + SYSTEM, EDGE +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 7d78876d5e..089ddaa0c7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -336,6 +336,7 @@ public class ModelConstants { public static final String RULE_CHAIN_COLUMN_FAMILY_NAME = "rule_chain"; public static final String RULE_CHAIN_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; public static final String RULE_CHAIN_NAME_PROPERTY = "name"; + public static final String RULE_CHAIN_TYPE_PROPERTY = "type"; public static final String RULE_CHAIN_FIRST_RULE_NODE_ID_PROPERTY = "first_rule_node_id"; public static final String RULE_CHAIN_ROOT_PROPERTY = "root"; public static final String RULE_CHAIN_CONFIGURATION_PROPERTY = "configuration"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleChainEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleChainEntity.java index 442e1f2f22..268dd1a02e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleChainEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleChainEntity.java @@ -35,9 +35,11 @@ import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.SearchTextEntity; import org.thingsboard.server.dao.model.type.JsonCodec; +import org.thingsboard.server.dao.model.type.RuleChainTypeCodec; import java.io.IOException; import java.util.HashSet; @@ -53,6 +55,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_FIRST_R import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_NAME_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_ROOT_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_TENANT_ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_TYPE_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; @Slf4j @@ -73,6 +76,8 @@ public class RuleChainEntity implements SearchTextEntity { private UUID tenantId; @Column(name = RULE_CHAIN_NAME_PROPERTY) private String name; + @Column(name = RULE_CHAIN_TYPE_PROPERTY, codec = RuleChainTypeCodec.class) + private RuleChainType type; @Column(name = SEARCH_TEXT_PROPERTY) private String searchText; @Column(name = RULE_CHAIN_FIRST_RULE_NODE_ID_PROPERTY) @@ -101,6 +106,11 @@ public class RuleChainEntity implements SearchTextEntity { } this.tenantId = DaoUtil.getId(ruleChain.getTenantId()); this.name = ruleChain.getName(); + if (ruleChain.getType() != null) { + this.type = ruleChain.getType(); + } else { + this.type = RuleChainType.SYSTEM; + } this.searchText = ruleChain.getName(); this.firstRuleNodeId = DaoUtil.getId(ruleChain.getFirstRuleNodeId()); this.root = ruleChain.isRoot(); @@ -194,6 +204,11 @@ public class RuleChainEntity implements SearchTextEntity { ruleChain.setCreatedTime(UUIDs.unixTimestamp(id)); ruleChain.setTenantId(new TenantId(tenantId)); ruleChain.setName(name); + if (type != null) { + ruleChain.setType(type); + } else { + ruleChain.setType(RuleChainType.SYSTEM); + } if (this.firstRuleNodeId != null) { ruleChain.setFirstRuleNodeId(new RuleNodeId(this.firstRuleNodeId)); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainEntity.java index 92ea3b8529..cb17e783e1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainEntity.java @@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; @@ -40,10 +41,14 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.persistence.Table; import java.io.IOException; import java.util.HashSet; +import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_TYPE_PROPERTY; + @Data @Slf4j @EqualsAndHashCode(callSuper = true) @@ -62,6 +67,10 @@ public class RuleChainEntity extends BaseSqlEntity implements SearchT @Column(name = ModelConstants.RULE_CHAIN_NAME_PROPERTY) private String name; + @Enumerated(EnumType.STRING) + @Column(name = RULE_CHAIN_TYPE_PROPERTY) + private RuleChainType type; + @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) private String searchText; @@ -94,6 +103,11 @@ public class RuleChainEntity extends BaseSqlEntity implements SearchT } this.tenantId = toString(DaoUtil.getId(ruleChain.getTenantId())); this.name = ruleChain.getName(); + if (ruleChain.getType() != null) { + this.type = ruleChain.getType(); + } else { + this.type = RuleChainType.SYSTEM; + } this.searchText = ruleChain.getName(); if (ruleChain.getFirstRuleNodeId() != null) { this.firstRuleNodeId = UUIDConverter.fromTimeUUID(ruleChain.getFirstRuleNodeId().getId()); @@ -127,6 +141,11 @@ public class RuleChainEntity extends BaseSqlEntity implements SearchT ruleChain.setCreatedTime(UUIDs.unixTimestamp(getId())); ruleChain.setTenantId(new TenantId(toUUID(tenantId))); ruleChain.setName(name); + if (type != null) { + ruleChain.setType(type); + } else { + ruleChain.setType(RuleChainType.SYSTEM); + } if (firstRuleNodeId != null) { ruleChain.setFirstRuleNodeId(new RuleNodeId(UUIDConverter.fromString(firstRuleNodeId))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/type/RuleChainTypeCodec.java b/dao/src/main/java/org/thingsboard/server/dao/model/type/RuleChainTypeCodec.java new file mode 100644 index 0000000000..d475709f16 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/type/RuleChainTypeCodec.java @@ -0,0 +1,27 @@ +/** + * Copyright © 2016-2019 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. + */ +package org.thingsboard.server.dao.model.type; + +import com.datastax.driver.extras.codecs.enums.EnumNameCodec; +import org.thingsboard.server.common.data.rule.RuleChainType; + +public class RuleChainTypeCodec extends EnumNameCodec { + + public RuleChainTypeCodec() { + super(RuleChainType.class); + } + +} diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 7b881c9ea1..0b0257a8e8 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -214,6 +214,7 @@ CREATE TABLE IF NOT EXISTS rule_chain ( additional_info varchar, configuration varchar(10000000), name varchar(255), + type varchar(255), first_rule_node_id varchar(31), root boolean, debug_mode boolean, diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index 35e7ccd7b2..678f72e309 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -606,6 +606,8 @@ export default angular.module('thingsboard.types', []) clientSide: false } }, + systemRuleChainType: "SYSTEM", + ruleChainTypes: ["SYSTEM", "EDGE"], ruleNodeTypeComponentTypes: ["FILTER", "ENRICHMENT", "TRANSFORMATION", "ACTION", "EXTERNAL"], ruleChainNodeComponent: { type: 'RULE_CHAIN', diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json index 0c99306d45..629a151e03 100644 --- a/ui/src/app/locale/locale.constant-en_US.json +++ b/ui/src/app/locale/locale.constant-en_US.json @@ -1386,6 +1386,7 @@ "root": "Root", "delete": "Delete rule chain", "name": "Name", + "type": "Type", "name-required": "Name is required.", "description": "Description", "add": "Add Rule Chain", diff --git a/ui/src/app/rulechain/rulechain-fieldset.tpl.html b/ui/src/app/rulechain/rulechain-fieldset.tpl.html index e0718273eb..941f850d11 100644 --- a/ui/src/app/rulechain/rulechain-fieldset.tpl.html +++ b/ui/src/app/rulechain/rulechain-fieldset.tpl.html @@ -49,6 +49,14 @@
rulechain.name-required
+ + + + + {{ruleChainType}} + + + {{ 'rulechain.debug-mode' | translate }} diff --git a/ui/src/app/rulechain/rulechain.directive.js b/ui/src/app/rulechain/rulechain.directive.js index ae26d78ec8..ccfe9bf6a9 100644 --- a/ui/src/app/rulechain/rulechain.directive.js +++ b/ui/src/app/rulechain/rulechain.directive.js @@ -22,9 +22,16 @@ import ruleChainFieldsetTemplate from './rulechain-fieldset.tpl.html'; /*@ngInject*/ export default function RuleChainDirective($compile, $templateCache, $mdDialog, $document, $q, $translate, types, toast) { var linker = function (scope, element) { + var template = $templateCache.get(ruleChainFieldsetTemplate); element.html(template); + scope.ruleChainTypes = types.ruleChainTypes; + + if (angular.isDefined(scope.ruleChain) && scope.ruleChain != null && angular.isUndefined(scope.ruleChain.type)) { + scope.ruleChain.type = types.systemRuleChainType; + } + scope.onRuleChainIdCopied = function() { toast.showSuccess($translate.instant('rulechain.idCopiedMessage'), 750, angular.element(element).parent().parent(), 'bottom left'); };