Showing
16 changed files
with
146 additions
and
16 deletions
... | ... | @@ -23,7 +23,7 @@ CREATE TABLE IF NOT EXISTS thingsboard.edge ( |
23 | 23 | configuration text, |
24 | 24 | additional_info text, |
25 | 25 | PRIMARY KEY (id, tenant_id) |
26 | - ); | |
26 | +); | |
27 | 27 | |
28 | 28 | CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_name AS |
29 | 29 | SELECT * |
... | ... | @@ -58,4 +58,6 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_customer_by_type_and_ |
58 | 58 | from thingsboard.edge |
59 | 59 | 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 |
60 | 60 | PRIMARY KEY ( customer_id, tenant_id, type, search_text, id ) |
61 | - WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC ); | |
\ No newline at end of file | ||
61 | + WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC ); | |
62 | + | |
63 | +-- VOBA ADD changes for the MATERIALIZED view for DEVICE ASSET ENTITY_VIEW RULE_CHAIN | |
\ No newline at end of file | ... | ... |
... | ... | @@ -23,10 +23,3 @@ CREATE TABLE IF NOT EXISTS edge ( |
23 | 23 | search_text varchar(255), |
24 | 24 | tenant_id varchar(31) |
25 | 25 | ); |
26 | - | |
27 | -ALTER TABLE asset ADD edge_id varchar(31); | |
28 | -ALTER TABLE device ADD edge_id varchar(31); | |
29 | -ALTER TABLE entity_view ADD edge_id varchar(31); | |
30 | - | |
31 | -ALTER TABLE dashboard ADD assigned_edges varchar(1000000); | |
32 | -ALTER TABLE rule_chain ADD assigned_edges varchar(1000000); | |
\ No newline at end of file | ... | ... |
... | ... | @@ -37,8 +37,8 @@ import org.thingsboard.server.common.data.EntityType; |
37 | 37 | import org.thingsboard.server.common.data.id.DeviceId; |
38 | 38 | import org.thingsboard.server.common.data.id.RuleChainId; |
39 | 39 | import org.thingsboard.server.common.data.id.TenantId; |
40 | -import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | |
41 | 40 | import org.thingsboard.server.common.data.rule.RuleChain; |
41 | +import org.thingsboard.server.common.data.rule.RuleChainType; | |
42 | 42 | import org.thingsboard.server.common.msg.TbActorMsg; |
43 | 43 | import org.thingsboard.server.common.msg.aware.DeviceAwareMsg; |
44 | 44 | import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; |
... | ... | @@ -46,9 +46,6 @@ import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; |
46 | 46 | import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; |
47 | 47 | import scala.concurrent.duration.Duration; |
48 | 48 | |
49 | -import java.util.HashMap; | |
50 | -import java.util.Map; | |
51 | - | |
52 | 49 | public class TenantActor extends RuleChainManagerActor { |
53 | 50 | |
54 | 51 | private final TenantId tenantId; |
... | ... | @@ -139,11 +136,17 @@ public class TenantActor extends RuleChainManagerActor { |
139 | 136 | } |
140 | 137 | |
141 | 138 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { |
139 | + RuleChain ruleChain = null; | |
140 | + if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { | |
141 | + ruleChain = systemContext.getRuleChainService().findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId())); | |
142 | + if (RuleChainType.SYSTEM.equals(ruleChain.getType())) { | |
143 | + log.debug("[{}] Non SYSTEM rule chains are ignored and not started. Current rule chain type [{}]", tenantId, ruleChain.getType()); | |
144 | + return; | |
145 | + } | |
146 | + } | |
142 | 147 | ActorRef target = getEntityActorRef(msg.getEntityId()); |
143 | 148 | if (target != null) { |
144 | - if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { | |
145 | - RuleChain ruleChain = systemContext.getRuleChainService(). | |
146 | - findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId())); | |
149 | + if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN && ruleChain != null) { | |
147 | 150 | ruleChainManager.visit(ruleChain, target); |
148 | 151 | } |
149 | 152 | target.tell(msg, ActorRef.noSender()); | ... | ... |
... | ... | @@ -272,6 +272,32 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService { |
272 | 272 | log.info("Updating schema ..."); |
273 | 273 | schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.4.x", SCHEMA_UPDATE_CQL); |
274 | 274 | loadCql(schemaUpdateFile); |
275 | + | |
276 | + try { | |
277 | + cluster.getSession().execute("alter table asset add edge_id text"); | |
278 | + Thread.sleep(2500); | |
279 | + } catch (InvalidQueryException e) {} | |
280 | + try { | |
281 | + cluster.getSession().execute("alter table device add edge_id text"); | |
282 | + Thread.sleep(2500); | |
283 | + } catch (InvalidQueryException e) {} | |
284 | + try { | |
285 | + cluster.getSession().execute("alter table entity_view add edge_id text"); | |
286 | + Thread.sleep(2500); | |
287 | + } catch (InvalidQueryException e) {} | |
288 | + try { | |
289 | + cluster.getSession().execute("alter table dashboard add assigned_edges text"); | |
290 | + Thread.sleep(2500); | |
291 | + } catch (InvalidQueryException e) {} | |
292 | + try { | |
293 | + cluster.getSession().execute("alter table rule_chain add assigned_edges text"); | |
294 | + Thread.sleep(2500); | |
295 | + } catch (InvalidQueryException e) {} | |
296 | + try { | |
297 | + cluster.getSession().execute("alter table rule_chain add type text"); | |
298 | + Thread.sleep(2500); | |
299 | + } catch (InvalidQueryException e) {} | |
300 | + | |
275 | 301 | log.info("Schema updated."); |
276 | 302 | |
277 | 303 | break; | ... | ... |
... | ... | @@ -181,6 +181,24 @@ public class SqlDatabaseUpgradeService implements DatabaseUpgradeService { |
181 | 181 | log.info("Updating schema ..."); |
182 | 182 | schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.4.x", SCHEMA_UPDATE_SQL); |
183 | 183 | loadSql(schemaUpdateFile, conn); |
184 | + try { | |
185 | + conn.createStatement().execute("ALTER TABLE asset ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script | |
186 | + } catch (Exception e) {} | |
187 | + try { | |
188 | + conn.createStatement().execute("ALTER TABLE device ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script | |
189 | + } catch (Exception e) {} | |
190 | + try { | |
191 | + conn.createStatement().execute("ALTER TABLE entity_view ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script | |
192 | + } catch (Exception e) {} | |
193 | + try { | |
194 | + conn.createStatement().execute("ALTER TABLE dashboard ADD assigned_edges varchar(1000000)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script | |
195 | + } catch (Exception e) {} | |
196 | + try { | |
197 | + conn.createStatement().execute("ALTER TABLE rule_chain ADD assigned_edges varchar(1000000)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script | |
198 | + } catch (Exception e) {} | |
199 | + try { | |
200 | + conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'SYSTEM'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script | |
201 | + } catch (Exception e) {} | |
184 | 202 | log.info("Schema updated."); |
185 | 203 | } |
186 | 204 | break; | ... | ... |
... | ... | @@ -42,6 +42,7 @@ public class RuleChain extends SearchTextBasedWithAdditionalInfo<RuleChainId> im |
42 | 42 | |
43 | 43 | private TenantId tenantId; |
44 | 44 | private String name; |
45 | + private RuleChainType type; | |
45 | 46 | private RuleNodeId firstRuleNodeId; |
46 | 47 | private boolean root; |
47 | 48 | private boolean debugMode; |
... | ... | @@ -63,6 +64,7 @@ public class RuleChain extends SearchTextBasedWithAdditionalInfo<RuleChainId> im |
63 | 64 | super(ruleChain); |
64 | 65 | this.tenantId = ruleChain.getTenantId(); |
65 | 66 | this.name = ruleChain.getName(); |
67 | + this.type = ruleChain.getType(); | |
66 | 68 | this.firstRuleNodeId = ruleChain.getFirstRuleNodeId(); |
67 | 69 | this.root = ruleChain.isRoot(); |
68 | 70 | ... | ... |
... | ... | @@ -336,6 +336,7 @@ public class ModelConstants { |
336 | 336 | public static final String RULE_CHAIN_COLUMN_FAMILY_NAME = "rule_chain"; |
337 | 337 | public static final String RULE_CHAIN_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; |
338 | 338 | public static final String RULE_CHAIN_NAME_PROPERTY = "name"; |
339 | + public static final String RULE_CHAIN_TYPE_PROPERTY = "type"; | |
339 | 340 | public static final String RULE_CHAIN_FIRST_RULE_NODE_ID_PROPERTY = "first_rule_node_id"; |
340 | 341 | public static final String RULE_CHAIN_ROOT_PROPERTY = "root"; |
341 | 342 | public static final String RULE_CHAIN_CONFIGURATION_PROPERTY = "configuration"; | ... | ... |
... | ... | @@ -35,9 +35,11 @@ import org.thingsboard.server.common.data.id.RuleChainId; |
35 | 35 | import org.thingsboard.server.common.data.id.RuleNodeId; |
36 | 36 | import org.thingsboard.server.common.data.id.TenantId; |
37 | 37 | import org.thingsboard.server.common.data.rule.RuleChain; |
38 | +import org.thingsboard.server.common.data.rule.RuleChainType; | |
38 | 39 | import org.thingsboard.server.dao.DaoUtil; |
39 | 40 | import org.thingsboard.server.dao.model.SearchTextEntity; |
40 | 41 | import org.thingsboard.server.dao.model.type.JsonCodec; |
42 | +import org.thingsboard.server.dao.model.type.RuleChainTypeCodec; | |
41 | 43 | |
42 | 44 | import java.io.IOException; |
43 | 45 | import java.util.HashSet; |
... | ... | @@ -53,6 +55,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_FIRST_R |
53 | 55 | import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_NAME_PROPERTY; |
54 | 56 | import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_ROOT_PROPERTY; |
55 | 57 | import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_TENANT_ID_PROPERTY; |
58 | +import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_TYPE_PROPERTY; | |
56 | 59 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; |
57 | 60 | |
58 | 61 | @Slf4j |
... | ... | @@ -73,6 +76,8 @@ public class RuleChainEntity implements SearchTextEntity<RuleChain> { |
73 | 76 | private UUID tenantId; |
74 | 77 | @Column(name = RULE_CHAIN_NAME_PROPERTY) |
75 | 78 | private String name; |
79 | + @Column(name = RULE_CHAIN_TYPE_PROPERTY, codec = RuleChainTypeCodec.class) | |
80 | + private RuleChainType type; | |
76 | 81 | @Column(name = SEARCH_TEXT_PROPERTY) |
77 | 82 | private String searchText; |
78 | 83 | @Column(name = RULE_CHAIN_FIRST_RULE_NODE_ID_PROPERTY) |
... | ... | @@ -101,6 +106,11 @@ public class RuleChainEntity implements SearchTextEntity<RuleChain> { |
101 | 106 | } |
102 | 107 | this.tenantId = DaoUtil.getId(ruleChain.getTenantId()); |
103 | 108 | this.name = ruleChain.getName(); |
109 | + if (ruleChain.getType() != null) { | |
110 | + this.type = ruleChain.getType(); | |
111 | + } else { | |
112 | + this.type = RuleChainType.SYSTEM; | |
113 | + } | |
104 | 114 | this.searchText = ruleChain.getName(); |
105 | 115 | this.firstRuleNodeId = DaoUtil.getId(ruleChain.getFirstRuleNodeId()); |
106 | 116 | this.root = ruleChain.isRoot(); |
... | ... | @@ -194,6 +204,11 @@ public class RuleChainEntity implements SearchTextEntity<RuleChain> { |
194 | 204 | ruleChain.setCreatedTime(UUIDs.unixTimestamp(id)); |
195 | 205 | ruleChain.setTenantId(new TenantId(tenantId)); |
196 | 206 | ruleChain.setName(name); |
207 | + if (type != null) { | |
208 | + ruleChain.setType(type); | |
209 | + } else { | |
210 | + ruleChain.setType(RuleChainType.SYSTEM); | |
211 | + } | |
197 | 212 | if (this.firstRuleNodeId != null) { |
198 | 213 | ruleChain.setFirstRuleNodeId(new RuleNodeId(this.firstRuleNodeId)); |
199 | 214 | } | ... | ... |
... | ... | @@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.id.RuleChainId; |
32 | 32 | import org.thingsboard.server.common.data.id.RuleNodeId; |
33 | 33 | import org.thingsboard.server.common.data.id.TenantId; |
34 | 34 | import org.thingsboard.server.common.data.rule.RuleChain; |
35 | +import org.thingsboard.server.common.data.rule.RuleChainType; | |
35 | 36 | import org.thingsboard.server.dao.DaoUtil; |
36 | 37 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
37 | 38 | import org.thingsboard.server.dao.model.ModelConstants; |
... | ... | @@ -40,10 +41,14 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; |
40 | 41 | |
41 | 42 | import javax.persistence.Column; |
42 | 43 | import javax.persistence.Entity; |
44 | +import javax.persistence.EnumType; | |
45 | +import javax.persistence.Enumerated; | |
43 | 46 | import javax.persistence.Table; |
44 | 47 | import java.io.IOException; |
45 | 48 | import java.util.HashSet; |
46 | 49 | |
50 | +import static org.thingsboard.server.dao.model.ModelConstants.RULE_CHAIN_TYPE_PROPERTY; | |
51 | + | |
47 | 52 | @Data |
48 | 53 | @Slf4j |
49 | 54 | @EqualsAndHashCode(callSuper = true) |
... | ... | @@ -62,6 +67,10 @@ public class RuleChainEntity extends BaseSqlEntity<RuleChain> implements SearchT |
62 | 67 | @Column(name = ModelConstants.RULE_CHAIN_NAME_PROPERTY) |
63 | 68 | private String name; |
64 | 69 | |
70 | + @Enumerated(EnumType.STRING) | |
71 | + @Column(name = RULE_CHAIN_TYPE_PROPERTY) | |
72 | + private RuleChainType type; | |
73 | + | |
65 | 74 | @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) |
66 | 75 | private String searchText; |
67 | 76 | |
... | ... | @@ -94,6 +103,11 @@ public class RuleChainEntity extends BaseSqlEntity<RuleChain> implements SearchT |
94 | 103 | } |
95 | 104 | this.tenantId = toString(DaoUtil.getId(ruleChain.getTenantId())); |
96 | 105 | this.name = ruleChain.getName(); |
106 | + if (ruleChain.getType() != null) { | |
107 | + this.type = ruleChain.getType(); | |
108 | + } else { | |
109 | + this.type = RuleChainType.SYSTEM; | |
110 | + } | |
97 | 111 | this.searchText = ruleChain.getName(); |
98 | 112 | if (ruleChain.getFirstRuleNodeId() != null) { |
99 | 113 | this.firstRuleNodeId = UUIDConverter.fromTimeUUID(ruleChain.getFirstRuleNodeId().getId()); |
... | ... | @@ -127,6 +141,11 @@ public class RuleChainEntity extends BaseSqlEntity<RuleChain> implements SearchT |
127 | 141 | ruleChain.setCreatedTime(UUIDs.unixTimestamp(getId())); |
128 | 142 | ruleChain.setTenantId(new TenantId(toUUID(tenantId))); |
129 | 143 | ruleChain.setName(name); |
144 | + if (type != null) { | |
145 | + ruleChain.setType(type); | |
146 | + } else { | |
147 | + ruleChain.setType(RuleChainType.SYSTEM); | |
148 | + } | |
130 | 149 | if (firstRuleNodeId != null) { |
131 | 150 | ruleChain.setFirstRuleNodeId(new RuleNodeId(UUIDConverter.fromString(firstRuleNodeId))); |
132 | 151 | } | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2019 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.dao.model.type; | |
17 | + | |
18 | +import com.datastax.driver.extras.codecs.enums.EnumNameCodec; | |
19 | +import org.thingsboard.server.common.data.rule.RuleChainType; | |
20 | + | |
21 | +public class RuleChainTypeCodec extends EnumNameCodec<RuleChainType> { | |
22 | + | |
23 | + public RuleChainTypeCodec() { | |
24 | + super(RuleChainType.class); | |
25 | + } | |
26 | + | |
27 | +} | ... | ... |
... | ... | @@ -606,6 +606,8 @@ export default angular.module('thingsboard.types', []) |
606 | 606 | clientSide: false |
607 | 607 | } |
608 | 608 | }, |
609 | + systemRuleChainType: "SYSTEM", | |
610 | + ruleChainTypes: ["SYSTEM", "EDGE"], | |
609 | 611 | ruleNodeTypeComponentTypes: ["FILTER", "ENRICHMENT", "TRANSFORMATION", "ACTION", "EXTERNAL"], |
610 | 612 | ruleChainNodeComponent: { |
611 | 613 | type: 'RULE_CHAIN', | ... | ... |
... | ... | @@ -50,6 +50,14 @@ |
50 | 50 | </div> |
51 | 51 | </md-input-container> |
52 | 52 | <md-input-container class="md-block"> |
53 | + <label translate>rulechain.type</label> | |
54 | + <md-select ng-disabled="$root.loading || !isEdit" name="type" ng-model="ruleChain.type"> | |
55 | + <md-option ng-repeat="ruleChainType in ruleChainTypes" value="{{ruleChainType}}"> | |
56 | + {{ruleChainType}} | |
57 | + </md-option> | |
58 | + </md-select> | |
59 | + </md-input-container> | |
60 | + <md-input-container class="md-block"> | |
53 | 61 | <md-checkbox ng-disabled="$root.loading || !isEdit" aria-label="{{ 'rulechain.debug-mode' | translate }}" |
54 | 62 | ng-model="ruleChain.debugMode">{{ 'rulechain.debug-mode' | translate }} |
55 | 63 | </md-checkbox> | ... | ... |
... | ... | @@ -22,9 +22,16 @@ import ruleChainFieldsetTemplate from './rulechain-fieldset.tpl.html'; |
22 | 22 | /*@ngInject*/ |
23 | 23 | export default function RuleChainDirective($compile, $templateCache, $mdDialog, $document, $q, $translate, types, toast) { |
24 | 24 | var linker = function (scope, element) { |
25 | + | |
25 | 26 | var template = $templateCache.get(ruleChainFieldsetTemplate); |
26 | 27 | element.html(template); |
27 | 28 | |
29 | + scope.ruleChainTypes = types.ruleChainTypes; | |
30 | + | |
31 | + if (angular.isDefined(scope.ruleChain) && scope.ruleChain != null && angular.isUndefined(scope.ruleChain.type)) { | |
32 | + scope.ruleChain.type = types.systemRuleChainType; | |
33 | + } | |
34 | + | |
28 | 35 | scope.onRuleChainIdCopied = function() { |
29 | 36 | toast.showSuccess($translate.instant('rulechain.idCopiedMessage'), 750, angular.element(element).parent().parent(), 'bottom left'); |
30 | 37 | }; | ... | ... |