Added Rule Chain type

This commit is contained in:
Volodymyr Babak 2019-11-11 19:20:11 +02:00
parent e0881cfc44
commit 66af90bf0a
16 changed files with 146 additions and 16 deletions

View File

@ -23,7 +23,7 @@ CREATE TABLE IF NOT EXISTS thingsboard.edge (
configuration text, configuration text,
additional_info text, additional_info text,
PRIMARY KEY (id, tenant_id) PRIMARY KEY (id, tenant_id)
); );
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_name AS CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_name AS
SELECT * SELECT *
@ -59,3 +59,5 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_customer_by_type_and_
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 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 ) PRIMARY KEY ( customer_id, tenant_id, type, search_text, id )
WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC ); 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

View File

@ -23,10 +23,3 @@ CREATE TABLE IF NOT EXISTS edge (
search_text varchar(255), search_text varchar(255),
tenant_id varchar(31) 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);

View File

@ -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.DeviceId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; 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.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.aware.DeviceAwareMsg; import org.thingsboard.server.common.msg.aware.DeviceAwareMsg;
import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; 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 org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
import scala.concurrent.duration.Duration; import scala.concurrent.duration.Duration;
import java.util.HashMap;
import java.util.Map;
public class TenantActor extends RuleChainManagerActor { public class TenantActor extends RuleChainManagerActor {
private final TenantId tenantId; private final TenantId tenantId;
@ -139,11 +136,17 @@ public class TenantActor extends RuleChainManagerActor {
} }
private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { 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()); ActorRef target = getEntityActorRef(msg.getEntityId());
if (target != null) { if (target != null) {
if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN && ruleChain != null) {
RuleChain ruleChain = systemContext.getRuleChainService().
findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId()));
ruleChainManager.visit(ruleChain, target); ruleChainManager.visit(ruleChain, target);
} }
target.tell(msg, ActorRef.noSender()); target.tell(msg, ActorRef.noSender());

View File

@ -272,6 +272,32 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService {
log.info("Updating schema ..."); log.info("Updating schema ...");
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.4.x", SCHEMA_UPDATE_CQL); schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.4.x", SCHEMA_UPDATE_CQL);
loadCql(schemaUpdateFile); 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."); log.info("Schema updated.");
break; break;

View File

@ -181,6 +181,24 @@ public class SqlDatabaseUpgradeService implements DatabaseUpgradeService {
log.info("Updating schema ..."); log.info("Updating schema ...");
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.4.x", SCHEMA_UPDATE_SQL); schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.4.x", SCHEMA_UPDATE_SQL);
loadSql(schemaUpdateFile, conn); 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."); log.info("Schema updated.");
} }
break; break;

View File

@ -42,6 +42,7 @@ public class RuleChain extends SearchTextBasedWithAdditionalInfo<RuleChainId> im
private TenantId tenantId; private TenantId tenantId;
private String name; private String name;
private RuleChainType type;
private RuleNodeId firstRuleNodeId; private RuleNodeId firstRuleNodeId;
private boolean root; private boolean root;
private boolean debugMode; private boolean debugMode;
@ -63,6 +64,7 @@ public class RuleChain extends SearchTextBasedWithAdditionalInfo<RuleChainId> im
super(ruleChain); super(ruleChain);
this.tenantId = ruleChain.getTenantId(); this.tenantId = ruleChain.getTenantId();
this.name = ruleChain.getName(); this.name = ruleChain.getName();
this.type = ruleChain.getType();
this.firstRuleNodeId = ruleChain.getFirstRuleNodeId(); this.firstRuleNodeId = ruleChain.getFirstRuleNodeId();
this.root = ruleChain.isRoot(); this.root = ruleChain.isRoot();

View File

@ -0,0 +1,5 @@
package org.thingsboard.server.common.data.rule;
public enum RuleChainType {
SYSTEM, EDGE
}

View File

@ -336,6 +336,7 @@ public class ModelConstants {
public static final String RULE_CHAIN_COLUMN_FAMILY_NAME = "rule_chain"; 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_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
public static final String RULE_CHAIN_NAME_PROPERTY = "name"; 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_FIRST_RULE_NODE_ID_PROPERTY = "first_rule_node_id";
public static final String RULE_CHAIN_ROOT_PROPERTY = "root"; public static final String RULE_CHAIN_ROOT_PROPERTY = "root";
public static final String RULE_CHAIN_CONFIGURATION_PROPERTY = "configuration"; public static final String RULE_CHAIN_CONFIGURATION_PROPERTY = "configuration";

View File

@ -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.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.rule.RuleChain; 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.DaoUtil;
import org.thingsboard.server.dao.model.SearchTextEntity; import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.model.type.JsonCodec; import org.thingsboard.server.dao.model.type.JsonCodec;
import org.thingsboard.server.dao.model.type.RuleChainTypeCodec;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet; 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_NAME_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_ROOT_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_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; import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
@Slf4j @Slf4j
@ -73,6 +76,8 @@ public class RuleChainEntity implements SearchTextEntity<RuleChain> {
private UUID tenantId; private UUID tenantId;
@Column(name = RULE_CHAIN_NAME_PROPERTY) @Column(name = RULE_CHAIN_NAME_PROPERTY)
private String name; private String name;
@Column(name = RULE_CHAIN_TYPE_PROPERTY, codec = RuleChainTypeCodec.class)
private RuleChainType type;
@Column(name = SEARCH_TEXT_PROPERTY) @Column(name = SEARCH_TEXT_PROPERTY)
private String searchText; private String searchText;
@Column(name = RULE_CHAIN_FIRST_RULE_NODE_ID_PROPERTY) @Column(name = RULE_CHAIN_FIRST_RULE_NODE_ID_PROPERTY)
@ -101,6 +106,11 @@ public class RuleChainEntity implements SearchTextEntity<RuleChain> {
} }
this.tenantId = DaoUtil.getId(ruleChain.getTenantId()); this.tenantId = DaoUtil.getId(ruleChain.getTenantId());
this.name = ruleChain.getName(); this.name = ruleChain.getName();
if (ruleChain.getType() != null) {
this.type = ruleChain.getType();
} else {
this.type = RuleChainType.SYSTEM;
}
this.searchText = ruleChain.getName(); this.searchText = ruleChain.getName();
this.firstRuleNodeId = DaoUtil.getId(ruleChain.getFirstRuleNodeId()); this.firstRuleNodeId = DaoUtil.getId(ruleChain.getFirstRuleNodeId());
this.root = ruleChain.isRoot(); this.root = ruleChain.isRoot();
@ -194,6 +204,11 @@ public class RuleChainEntity implements SearchTextEntity<RuleChain> {
ruleChain.setCreatedTime(UUIDs.unixTimestamp(id)); ruleChain.setCreatedTime(UUIDs.unixTimestamp(id));
ruleChain.setTenantId(new TenantId(tenantId)); ruleChain.setTenantId(new TenantId(tenantId));
ruleChain.setName(name); ruleChain.setName(name);
if (type != null) {
ruleChain.setType(type);
} else {
ruleChain.setType(RuleChainType.SYSTEM);
}
if (this.firstRuleNodeId != null) { if (this.firstRuleNodeId != null) {
ruleChain.setFirstRuleNodeId(new RuleNodeId(this.firstRuleNodeId)); ruleChain.setFirstRuleNodeId(new RuleNodeId(this.firstRuleNodeId));
} }

View File

@ -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.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.rule.RuleChain; 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.DaoUtil;
import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.ModelConstants; 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.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Table; import javax.persistence.Table;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet; import java.util.HashSet;
import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_TYPE_PROPERTY;
@Data @Data
@Slf4j @Slf4j
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ -62,6 +67,10 @@ public class RuleChainEntity extends BaseSqlEntity<RuleChain> implements SearchT
@Column(name = ModelConstants.RULE_CHAIN_NAME_PROPERTY) @Column(name = ModelConstants.RULE_CHAIN_NAME_PROPERTY)
private String name; private String name;
@Enumerated(EnumType.STRING)
@Column(name = RULE_CHAIN_TYPE_PROPERTY)
private RuleChainType type;
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText; private String searchText;
@ -94,6 +103,11 @@ public class RuleChainEntity extends BaseSqlEntity<RuleChain> implements SearchT
} }
this.tenantId = toString(DaoUtil.getId(ruleChain.getTenantId())); this.tenantId = toString(DaoUtil.getId(ruleChain.getTenantId()));
this.name = ruleChain.getName(); this.name = ruleChain.getName();
if (ruleChain.getType() != null) {
this.type = ruleChain.getType();
} else {
this.type = RuleChainType.SYSTEM;
}
this.searchText = ruleChain.getName(); this.searchText = ruleChain.getName();
if (ruleChain.getFirstRuleNodeId() != null) { if (ruleChain.getFirstRuleNodeId() != null) {
this.firstRuleNodeId = UUIDConverter.fromTimeUUID(ruleChain.getFirstRuleNodeId().getId()); this.firstRuleNodeId = UUIDConverter.fromTimeUUID(ruleChain.getFirstRuleNodeId().getId());
@ -127,6 +141,11 @@ public class RuleChainEntity extends BaseSqlEntity<RuleChain> implements SearchT
ruleChain.setCreatedTime(UUIDs.unixTimestamp(getId())); ruleChain.setCreatedTime(UUIDs.unixTimestamp(getId()));
ruleChain.setTenantId(new TenantId(toUUID(tenantId))); ruleChain.setTenantId(new TenantId(toUUID(tenantId)));
ruleChain.setName(name); ruleChain.setName(name);
if (type != null) {
ruleChain.setType(type);
} else {
ruleChain.setType(RuleChainType.SYSTEM);
}
if (firstRuleNodeId != null) { if (firstRuleNodeId != null) {
ruleChain.setFirstRuleNodeId(new RuleNodeId(UUIDConverter.fromString(firstRuleNodeId))); ruleChain.setFirstRuleNodeId(new RuleNodeId(UUIDConverter.fromString(firstRuleNodeId)));
} }

View File

@ -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<RuleChainType> {
public RuleChainTypeCodec() {
super(RuleChainType.class);
}
}

View File

@ -214,6 +214,7 @@ CREATE TABLE IF NOT EXISTS rule_chain (
additional_info varchar, additional_info varchar,
configuration varchar(10000000), configuration varchar(10000000),
name varchar(255), name varchar(255),
type varchar(255),
first_rule_node_id varchar(31), first_rule_node_id varchar(31),
root boolean, root boolean,
debug_mode boolean, debug_mode boolean,

View File

@ -606,6 +606,8 @@ export default angular.module('thingsboard.types', [])
clientSide: false clientSide: false
} }
}, },
systemRuleChainType: "SYSTEM",
ruleChainTypes: ["SYSTEM", "EDGE"],
ruleNodeTypeComponentTypes: ["FILTER", "ENRICHMENT", "TRANSFORMATION", "ACTION", "EXTERNAL"], ruleNodeTypeComponentTypes: ["FILTER", "ENRICHMENT", "TRANSFORMATION", "ACTION", "EXTERNAL"],
ruleChainNodeComponent: { ruleChainNodeComponent: {
type: 'RULE_CHAIN', type: 'RULE_CHAIN',

View File

@ -1386,6 +1386,7 @@
"root": "Root", "root": "Root",
"delete": "Delete rule chain", "delete": "Delete rule chain",
"name": "Name", "name": "Name",
"type": "Type",
"name-required": "Name is required.", "name-required": "Name is required.",
"description": "Description", "description": "Description",
"add": "Add Rule Chain", "add": "Add Rule Chain",

View File

@ -49,6 +49,14 @@
<div translate ng-message="required">rulechain.name-required</div> <div translate ng-message="required">rulechain.name-required</div>
</div> </div>
</md-input-container> </md-input-container>
<md-input-container class="md-block">
<label translate>rulechain.type</label>
<md-select ng-disabled="$root.loading || !isEdit" name="type" ng-model="ruleChain.type">
<md-option ng-repeat="ruleChainType in ruleChainTypes" value="{{ruleChainType}}">
{{ruleChainType}}
</md-option>
</md-select>
</md-input-container>
<md-input-container class="md-block"> <md-input-container class="md-block">
<md-checkbox ng-disabled="$root.loading || !isEdit" aria-label="{{ 'rulechain.debug-mode' | translate }}" <md-checkbox ng-disabled="$root.loading || !isEdit" aria-label="{{ 'rulechain.debug-mode' | translate }}"
ng-model="ruleChain.debugMode">{{ 'rulechain.debug-mode' | translate }} ng-model="ruleChain.debugMode">{{ 'rulechain.debug-mode' | translate }}

View File

@ -22,9 +22,16 @@ import ruleChainFieldsetTemplate from './rulechain-fieldset.tpl.html';
/*@ngInject*/ /*@ngInject*/
export default function RuleChainDirective($compile, $templateCache, $mdDialog, $document, $q, $translate, types, toast) { export default function RuleChainDirective($compile, $templateCache, $mdDialog, $document, $q, $translate, types, toast) {
var linker = function (scope, element) { var linker = function (scope, element) {
var template = $templateCache.get(ruleChainFieldsetTemplate); var template = $templateCache.get(ruleChainFieldsetTemplate);
element.html(template); 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() { scope.onRuleChainIdCopied = function() {
toast.showSuccess($translate.instant('rulechain.idCopiedMessage'), 750, angular.element(element).parent().parent(), 'bottom left'); toast.showSuccess($translate.instant('rulechain.idCopiedMessage'), 750, angular.element(element).parent().parent(), 'bottom left');
}; };