diff --git a/application/src/main/data/upgrade/1.5.0/schema_update.cql b/application/src/main/data/upgrade/1.5.0/schema_update.cql new file mode 100644 index 0000000000..826373d0ae --- /dev/null +++ b/application/src/main/data/upgrade/1.5.0/schema_update.cql @@ -0,0 +1,93 @@ +-- +-- Copyright © 2016-2018 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. +-- + +CREATE TABLE IF NOT EXISTS thingsboard.msg_queue ( + node_id timeuuid, + clustered_hash bigint, + partition bigint, + ts bigint, + msg blob, + PRIMARY KEY ((node_id, clustered_hash, partition), ts)) +WITH CLUSTERING ORDER BY (ts DESC) +AND compaction = { + 'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', + 'min_threshold': '5', + 'base_time_seconds': '43200', + 'max_window_size_seconds': '43200', + 'tombstone_threshold': '0.9', + 'unchecked_tombstone_compaction': 'true' +}; + +CREATE TABLE IF NOT EXISTS thingsboard.msg_ack_queue ( + node_id timeuuid, + clustered_hash bigint, + partition bigint, + msg_id timeuuid, + PRIMARY KEY ((node_id, clustered_hash, partition), msg_id)) +WITH CLUSTERING ORDER BY (msg_id DESC) +AND compaction = { + 'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', + 'min_threshold': '5', + 'base_time_seconds': '43200', + 'max_window_size_seconds': '43200', + 'tombstone_threshold': '0.9', + 'unchecked_tombstone_compaction': 'true' +}; + +CREATE TABLE IF NOT EXISTS thingsboard.processed_msg_partitions ( + node_id timeuuid, + clustered_hash bigint, + partition bigint, + PRIMARY KEY ((node_id, clustered_hash), partition)) +WITH CLUSTERING ORDER BY (partition DESC) +AND compaction = { + 'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', + 'min_threshold': '5', + 'base_time_seconds': '43200', + 'max_window_size_seconds': '43200', + 'tombstone_threshold': '0.9', + 'unchecked_tombstone_compaction': 'true' +}; + +CREATE TABLE IF NOT EXISTS thingsboard.rule_chain ( + id uuid, + tenant_id uuid, + name text, + search_text text, + first_rule_node_id uuid, + is_root boolean, + configuration text, + additional_info text, + PRIMARY KEY (id, tenant_id) +); + +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 + PRIMARY KEY ( tenant_id, search_text, id ) + WITH CLUSTERING ORDER BY ( search_text ASC, id DESC ); + +CREATE TABLE IF NOT EXISTS thingsboard.rule_node ( + id uuid, + type text, + name text, + search_text text, + configuration text, + additional_info text, + PRIMARY KEY (id) +); + diff --git a/application/src/main/data/upgrade/1.5.0/schema_update.sql b/application/src/main/data/upgrade/1.5.0/schema_update.sql new file mode 100644 index 0000000000..12b80b3072 --- /dev/null +++ b/application/src/main/data/upgrade/1.5.0/schema_update.sql @@ -0,0 +1,35 @@ +-- +-- Copyright © 2016-2018 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. +-- + +CREATE TABLE IF NOT EXISTS rule_chain ( + id varchar(31) NOT NULL CONSTRAINT rule_chain_pkey PRIMARY KEY, + additional_info varchar, + configuration varchar(10000000), + name varchar(255), + first_rule_node_id varchar(31), + is_root boolean, + search_text varchar(255), + tenant_id varchar(31) +); + +CREATE TABLE IF NOT EXISTS rule_node ( + id varchar(31) NOT NULL CONSTRAINT rule_node_pkey PRIMARY KEY, + additional_info varchar, + configuration varchar(10000000), + type varchar(255), + name varchar(255), + search_text varchar(255) +); \ No newline at end of file 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 e765c40c86..1835a937e7 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -77,11 +77,16 @@ public class ThingsboardInstallService { databaseUpgradeService.upgradeDatabase("1.3.0"); - case "1.3.1": + case "1.3.1": //NOSONAR, Need to execute gradual upgrade starting from upgradeFromVersion log.info("Upgrading ThingsBoard from version 1.3.1 to 1.4.0 ..."); databaseUpgradeService.upgradeDatabase("1.3.1"); + case "1.4.0": + log.info("Upgrading ThingsBoard from version 1.4.0 to 1.5.0 ..."); + + databaseUpgradeService.upgradeDatabase("1.4.0"); + log.info("Updating system data..."); systemDataLoaderService.deleteSystemWidgetBundle("charts"); 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 e6826ec736..8dd969839d 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 @@ -185,6 +185,14 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService { Files.deleteIfExists(dashboardsDump); } log.info("Dashboards restored."); + break; + case "1.4.0": + + log.info("Updating schema ..."); + schemaUpdateFile = Paths.get(this.dataDir, "upgrade", "1.5.0", SCHEMA_UPDATE_CQL); + loadCql(schemaUpdateFile); + log.info("Schema updated."); + 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/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index cdd3103358..412ea8b9e6 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 @@ -97,6 +97,15 @@ public class SqlDatabaseUpgradeService implements DatabaseUpgradeService { log.info("Dashboards restored."); } break; + case "1.4.0": + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { + log.info("Updating schema ..."); + schemaUpdateFile = Paths.get(this.dataDir, "upgrade", "1.5.0", SCHEMA_UPDATE_SQL); + String sql = new String(Files.readAllBytes(schemaUpdateFile), Charset.forName("UTF-8")); + conn.createStatement().execute(sql); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script + log.info("Schema updated."); + } + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java index 05b558e6d7..d28a53ffa4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java @@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; * @author Andrew Shvayka */ public enum EntityType { - TENANT, CUSTOMER, USER, RULE, PLUGIN, DASHBOARD, ASSET, DEVICE, ALARM + TENANT, CUSTOMER, USER, RULE, PLUGIN, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java index e45cb91613..76b3e336d8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java @@ -53,6 +53,10 @@ public class EntityIdFactory { return new AssetId(uuid); case ALARM: return new AlarmId(uuid); + case RULE_CHAIN: + return new RuleChainId(uuid); + case RULE_NODE: + return new RuleNodeId(uuid); } throw new IllegalArgumentException("EntityType " + type + " is not supported!"); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java new file mode 100644 index 0000000000..a1a5075d27 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java @@ -0,0 +1,37 @@ +/** + * Copyright © 2016-2018 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.common.data.id; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.thingsboard.server.common.data.EntityType; + +import java.util.UUID; + +public class RuleChainId extends UUIDBased implements EntityId { + + @JsonCreator + public RuleChainId(@JsonProperty("id") UUID id) { + super(id); + } + + @JsonIgnore + @Override + public EntityType getEntityType() { + return EntityType.RULE_CHAIN; + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java new file mode 100644 index 0000000000..ec5ecce0d8 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java @@ -0,0 +1,37 @@ +/** + * Copyright © 2016-2018 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.common.data.id; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.thingsboard.server.common.data.EntityType; + +import java.util.UUID; + +public class RuleNodeId extends UUIDBased implements EntityId { + + @JsonCreator + public RuleNodeId(@JsonProperty("id") UUID id) { + super(id); + } + + @JsonIgnore + @Override + public EntityType getEntityType() { + return EntityType.RULE_NODE; + } +} 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 new file mode 100644 index 0000000000..48bc5de4de --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java @@ -0,0 +1,79 @@ +/** + * Copyright © 2016-2018 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.common.data.rule; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.HasName; +import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.id.RuleNodeId; +import org.thingsboard.server.common.data.id.TenantId; + +@Data +@EqualsAndHashCode(callSuper = true) +@Slf4j +public class RuleChain extends SearchTextBasedWithAdditionalInfo implements HasName { + + private static final long serialVersionUID = -5656679015121935465L; + + private TenantId tenantId; + private String name; + private RuleNodeId firstRuleNodeId; + private boolean isRoot; + private transient JsonNode configuration; + @JsonIgnore + private byte[] configurationBytes; + + public RuleChain() { + super(); + } + + public RuleChain(RuleChainId id) { + super(id); + } + + public RuleChain(RuleChain ruleChain) { + super(ruleChain); + this.tenantId = ruleChain.getTenantId(); + this.name = ruleChain.getName(); + this.firstRuleNodeId = ruleChain.getFirstRuleNodeId(); + this.isRoot = ruleChain.isRoot(); + this.setConfiguration(ruleChain.getConfiguration()); + } + + @Override + public String getSearchText() { + return getName(); + } + + @Override + public String getName() { + return name; + } + + public JsonNode getConfiguration() { + return SearchTextBasedWithAdditionalInfo.getJson(() -> configuration, () -> configurationBytes); + } + + public void setConfiguration(JsonNode data) { + setJson(data, json -> this.configuration = json, bytes -> this.configurationBytes = bytes); + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java new file mode 100644 index 0000000000..d044000117 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java @@ -0,0 +1,74 @@ +/** + * Copyright © 2016-2018 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.common.data.rule; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.HasName; +import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; +import org.thingsboard.server.common.data.id.RuleNodeId; +import org.thingsboard.server.common.data.id.TenantId; + +@Data +@EqualsAndHashCode(callSuper = true) +@Slf4j +public class RuleNode extends SearchTextBasedWithAdditionalInfo implements HasName { + + private static final long serialVersionUID = -5656679015121235465L; + + private String type; + private String name; + private transient JsonNode configuration; + @JsonIgnore + private byte[] configurationBytes; + + public RuleNode() { + super(); + } + + public RuleNode(RuleNodeId id) { + super(id); + } + + public RuleNode(RuleNode ruleNode) { + super(ruleNode); + this.type = ruleNode.getType(); + this.name = ruleNode.getName(); + this.setConfiguration(ruleNode.getConfiguration()); + } + + @Override + public String getSearchText() { + return getName(); + } + + @Override + public String getName() { + return name; + } + + public JsonNode getConfiguration() { + return SearchTextBasedWithAdditionalInfo.getJson(() -> configuration, () -> configurationBytes); + } + + public void setConfiguration(JsonNode data) { + setJson(data, json -> this.configuration = json, bytes -> this.configurationBytes = bytes); + } + +} 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 c2b55c956a..c68c23dc91 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 @@ -332,6 +332,26 @@ public class ModelConstants { public static final String EVENT_BY_TYPE_AND_ID_VIEW_NAME = "event_by_type_and_id"; public static final String EVENT_BY_ID_VIEW_NAME = "event_by_id"; + /** + * Cassandra rule chain constants. + */ + 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_FIRST_RULE_NODE_ID_PROPERTY = "first_rule_node_id"; + public static final String RULE_CHAIN_IS_ROOT_PROPERTY = "is_root"; + public static final String RULE_CHAIN_CONFIGURATION_PROPERTY = "configuration"; + + public static final String RULE_CHAIN_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "rule_chain_by_tenant_and_search_text"; + + /** + * Cassandra rule node constants. + */ + public static final String RULE_NODE_COLUMN_FAMILY_NAME = "rule_node"; + public static final String RULE_NODE_TYPE_PROPERTY = "type"; + public static final String RULE_NODE_NAME_PROPERTY = "name"; + public static final String RULE_NODE_CONFIGURATION_PROPERTY = "configuration"; + /** * Cassandra attributes and timeseries constants. */ 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 new file mode 100644 index 0000000000..962da0a68c --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleChainEntity.java @@ -0,0 +1,165 @@ +/** + * Copyright © 2016-2018 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.nosql; + +import com.datastax.driver.core.utils.UUIDs; +import com.datastax.driver.mapping.annotations.ClusteringColumn; +import com.datastax.driver.mapping.annotations.Column; +import com.datastax.driver.mapping.annotations.PartitionKey; +import com.datastax.driver.mapping.annotations.Table; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; +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.dao.DaoUtil; +import org.thingsboard.server.dao.model.SearchTextEntity; +import org.thingsboard.server.dao.model.type.JsonCodec; + +import java.util.UUID; + +import static org.thingsboard.server.dao.model.ModelConstants.*; + +@Table(name = RULE_CHAIN_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString +public class RuleChainEntity implements SearchTextEntity { + + @PartitionKey + @Column(name = ID_PROPERTY) + private UUID id; + @ClusteringColumn + @Column(name = RULE_CHAIN_TENANT_ID_PROPERTY) + private UUID tenantId; + @Column(name = RULE_CHAIN_NAME_PROPERTY) + private String name; + @Column(name = SEARCH_TEXT_PROPERTY) + private String searchText; + @Column(name = RULE_CHAIN_FIRST_RULE_NODE_ID_PROPERTY) + private UUID firstRuleNodeId; + @Column(name = RULE_CHAIN_IS_ROOT_PROPERTY) + private boolean isRoot; + @Column(name = RULE_CHAIN_CONFIGURATION_PROPERTY, codec = JsonCodec.class) + private JsonNode configuration; + @Column(name = ADDITIONAL_INFO_PROPERTY, codec = JsonCodec.class) + private JsonNode additionalInfo; + + public RuleChainEntity() { + } + + public RuleChainEntity(RuleChain ruleChain) { + if (ruleChain.getId() != null) { + this.id = ruleChain.getUuidId(); + } + this.tenantId = DaoUtil.getId(ruleChain.getTenantId()); + this.name = ruleChain.getName(); + this.searchText = ruleChain.getName(); + this.firstRuleNodeId = DaoUtil.getId(ruleChain.getFirstRuleNodeId()); + this.isRoot = ruleChain.isRoot(); + this.configuration = ruleChain.getConfiguration(); + this.additionalInfo = ruleChain.getAdditionalInfo(); + } + + @Override + public String getSearchTextSource() { + return getSearchText(); + } + + @Override + public void setSearchText(String searchText) { + this.searchText = searchText; + } + + @Override + public UUID getId() { + return id; + } + + @Override + public void setId(UUID id) { + this.id = id; + } + + public UUID getTenantId() { + return tenantId; + } + + public void setTenantId(UUID tenantId) { + this.tenantId = tenantId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public UUID getFirstRuleNodeId() { + return firstRuleNodeId; + } + + public void setFirstRuleNodeId(UUID firstRuleNodeId) { + this.firstRuleNodeId = firstRuleNodeId; + } + + public boolean isRoot() { + return isRoot; + } + + public void setRoot(boolean isRoot) { + this.isRoot = isRoot; + } + + public String getSearchText() { + return searchText; + } + + public JsonNode getConfiguration() { + return configuration; + } + + public void setConfiguration(JsonNode configuration) { + this.configuration = configuration; + } + + public JsonNode getAdditionalInfo() { + return additionalInfo; + } + + public void setAdditionalInfo(JsonNode additionalInfo) { + this.additionalInfo = additionalInfo; + } + + @Override + public RuleChain toData() { + RuleChain ruleChain = new RuleChain(new RuleChainId(id)); + ruleChain.setCreatedTime(UUIDs.unixTimestamp(id)); + ruleChain.setTenantId(new TenantId(tenantId)); + ruleChain.setName(name); + if (this.firstRuleNodeId != null) { + ruleChain.setFirstRuleNodeId(new RuleNodeId(this.firstRuleNodeId)); + } + ruleChain.setRoot(this.isRoot); + ruleChain.setConfiguration(this.configuration); + ruleChain.setAdditionalInfo(this.additionalInfo); + return ruleChain; + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleNodeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleNodeEntity.java new file mode 100644 index 0000000000..ba96e4b98e --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleNodeEntity.java @@ -0,0 +1,134 @@ +/** + * Copyright © 2016-2018 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.nosql; + +import com.datastax.driver.core.utils.UUIDs; +import com.datastax.driver.mapping.annotations.Column; +import com.datastax.driver.mapping.annotations.PartitionKey; +import com.datastax.driver.mapping.annotations.Table; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.thingsboard.server.common.data.id.RuleNodeId; +import org.thingsboard.server.common.data.rule.RuleNode; +import org.thingsboard.server.dao.model.SearchTextEntity; +import org.thingsboard.server.dao.model.type.JsonCodec; + +import java.util.UUID; + +import static org.thingsboard.server.dao.model.ModelConstants.*; + +@Table(name = RULE_NODE_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString +public class RuleNodeEntity implements SearchTextEntity { + + @PartitionKey + @Column(name = ID_PROPERTY) + private UUID id; + @Column(name = RULE_NODE_TYPE_PROPERTY) + private String type; + @Column(name = RULE_NODE_NAME_PROPERTY) + private String name; + @Column(name = SEARCH_TEXT_PROPERTY) + private String searchText; + @Column(name = RULE_NODE_CONFIGURATION_PROPERTY, codec = JsonCodec.class) + private JsonNode configuration; + @Column(name = ADDITIONAL_INFO_PROPERTY, codec = JsonCodec.class) + private JsonNode additionalInfo; + + public RuleNodeEntity() { + } + + public RuleNodeEntity(RuleNode ruleNode) { + if (ruleNode.getId() != null) { + this.id = ruleNode.getUuidId(); + } + this.type = ruleNode.getType(); + this.name = ruleNode.getName(); + this.searchText = ruleNode.getName(); + this.configuration = ruleNode.getConfiguration(); + this.additionalInfo = ruleNode.getAdditionalInfo(); + } + + @Override + public String getSearchTextSource() { + return getSearchText(); + } + + @Override + public void setSearchText(String searchText) { + this.searchText = searchText; + } + + @Override + public UUID getId() { + return id; + } + + @Override + public void setId(UUID id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSearchText() { + return searchText; + } + + public JsonNode getConfiguration() { + return configuration; + } + + public void setConfiguration(JsonNode configuration) { + this.configuration = configuration; + } + + public JsonNode getAdditionalInfo() { + return additionalInfo; + } + + public void setAdditionalInfo(JsonNode additionalInfo) { + this.additionalInfo = additionalInfo; + } + + @Override + public RuleNode toData() { + RuleNode ruleNode = new RuleNode(new RuleNodeId(id)); + ruleNode.setCreatedTime(UUIDs.unixTimestamp(id)); + ruleNode.setType(this.type); + ruleNode.setName(this.name); + ruleNode.setConfiguration(this.configuration); + ruleNode.setAdditionalInfo(this.additionalInfo); + return ruleNode; + } + +} 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 new file mode 100644 index 0000000000..518eda7821 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainEntity.java @@ -0,0 +1,111 @@ +/** + * Copyright © 2016-2018 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.sql; + +import com.datastax.driver.core.utils.UUIDs; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.thingsboard.server.common.data.UUIDConverter; +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.dao.DaoUtil; +import org.thingsboard.server.dao.model.BaseSqlEntity; +import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.dao.model.SearchTextEntity; +import org.thingsboard.server.dao.util.mapping.JsonStringType; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +@Data +@EqualsAndHashCode(callSuper = true) +@Entity +@TypeDef(name = "json", typeClass = JsonStringType.class) +@Table(name = ModelConstants.RULE_CHAIN_COLUMN_FAMILY_NAME) +public class RuleChainEntity extends BaseSqlEntity implements SearchTextEntity { + + @Column(name = ModelConstants.RULE_CHAIN_TENANT_ID_PROPERTY) + private String tenantId; + + @Column(name = ModelConstants.RULE_CHAIN_NAME_PROPERTY) + private String name; + + @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) + private String searchText; + + @Column(name = ModelConstants.RULE_CHAIN_FIRST_RULE_NODE_ID_PROPERTY) + private String firstRuleNodeId; + + @Column(name = ModelConstants.RULE_CHAIN_IS_ROOT_PROPERTY) + private boolean isRoot; + + @Type(type = "json") + @Column(name = ModelConstants.RULE_CHAIN_CONFIGURATION_PROPERTY) + private JsonNode configuration; + + @Type(type = "json") + @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY) + private JsonNode additionalInfo; + + public RuleChainEntity() { + } + + public RuleChainEntity(RuleChain ruleChain) { + if (ruleChain.getId() != null) { + this.setId(ruleChain.getUuidId()); + } + this.tenantId = toString(DaoUtil.getId(ruleChain.getTenantId())); + this.name = ruleChain.getName(); + this.searchText = ruleChain.getName(); + if (ruleChain.getFirstRuleNodeId() != null) { + this.firstRuleNodeId = UUIDConverter.fromTimeUUID(ruleChain.getFirstRuleNodeId().getId()); + } + this.isRoot = ruleChain.isRoot(); + this.configuration = ruleChain.getConfiguration(); + this.additionalInfo = ruleChain.getAdditionalInfo(); + } + + @Override + public String getSearchTextSource() { + return searchText; + } + + @Override + public void setSearchText(String searchText) { + this.searchText = searchText; + } + + @Override + public RuleChain toData() { + RuleChain ruleChain = new RuleChain(new RuleChainId(getId())); + ruleChain.setCreatedTime(UUIDs.unixTimestamp(getId())); + ruleChain.setTenantId(new TenantId(toUUID(tenantId))); + ruleChain.setName(name); + if (firstRuleNodeId != null) { + ruleChain.setFirstRuleNodeId(new RuleNodeId(UUIDConverter.fromString(firstRuleNodeId))); + } + ruleChain.setRoot(isRoot); + ruleChain.setConfiguration(configuration); + ruleChain.setAdditionalInfo(additionalInfo); + return ruleChain; + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java new file mode 100644 index 0000000000..d96048756c --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java @@ -0,0 +1,93 @@ +/** + * Copyright © 2016-2018 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.sql; + +import com.datastax.driver.core.utils.UUIDs; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.thingsboard.server.common.data.id.RuleNodeId; +import org.thingsboard.server.common.data.rule.RuleNode; +import org.thingsboard.server.dao.model.BaseSqlEntity; +import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.dao.model.SearchTextEntity; +import org.thingsboard.server.dao.util.mapping.JsonStringType; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +@Data +@EqualsAndHashCode(callSuper = true) +@Entity +@TypeDef(name = "json", typeClass = JsonStringType.class) +@Table(name = ModelConstants.RULE_NODE_COLUMN_FAMILY_NAME) +public class RuleNodeEntity extends BaseSqlEntity implements SearchTextEntity { + + @Column(name = ModelConstants.RULE_NODE_TYPE_PROPERTY) + private String type; + + @Column(name = ModelConstants.RULE_NODE_NAME_PROPERTY) + private String name; + + @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) + private String searchText; + + @Type(type = "json") + @Column(name = ModelConstants.RULE_NODE_CONFIGURATION_PROPERTY) + private JsonNode configuration; + + @Type(type = "json") + @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY) + private JsonNode additionalInfo; + + public RuleNodeEntity() { + } + + public RuleNodeEntity(RuleNode ruleNode) { + if (ruleNode.getId() != null) { + this.setId(ruleNode.getUuidId()); + } + this.type = ruleNode.getType(); + this.name = ruleNode.getName(); + this.searchText = ruleNode.getName(); + this.configuration = ruleNode.getConfiguration(); + this.additionalInfo = ruleNode.getAdditionalInfo(); + } + + @Override + public String getSearchTextSource() { + return searchText; + } + + @Override + public void setSearchText(String searchText) { + this.searchText = searchText; + } + + @Override + public RuleNode toData() { + RuleNode ruleNode = new RuleNode(new RuleNodeId(getId())); + ruleNode.setCreatedTime(UUIDs.unixTimestamp(getId())); + ruleNode.setType(type); + ruleNode.setName(name); + ruleNode.setConfiguration(configuration); + ruleNode.setAdditionalInfo(additionalInfo); + return ruleNode; + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraRuleChainDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraRuleChainDao.java new file mode 100644 index 0000000000..863904be65 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraRuleChainDao.java @@ -0,0 +1,60 @@ +/** + * Copyright © 2016-2018 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.rule; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.page.TextPageLink; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.dao.DaoUtil; +import org.thingsboard.server.dao.model.nosql.RuleChainEntity; +import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao; +import org.thingsboard.server.dao.util.NoSqlDao; + +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; +import static org.thingsboard.server.dao.model.ModelConstants.*; + +@Component +@Slf4j +@NoSqlDao +public class CassandraRuleChainDao extends CassandraAbstractSearchTextDao implements RuleChainDao { + + @Override + protected Class getColumnFamilyClass() { + return RuleChainEntity.class; + } + + @Override + protected String getColumnFamilyName() { + return RULE_CHAIN_COLUMN_FAMILY_NAME; + } + + @Override + public List findRuleChainsByTenantId(UUID tenantId, TextPageLink pageLink) { + log.debug("Try to find rule chains by tenantId [{}] and pageLink [{}]", tenantId, pageLink); + List ruleChainEntities = findPageWithTextSearch(RULE_CHAIN_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, + Collections.singletonList(eq(RULE_CHAIN_TENANT_ID_PROPERTY, tenantId)), + pageLink); + + log.trace("Found rule chains [{}] by tenantId [{}] and pageLink [{}]", ruleChainEntities, tenantId, pageLink); + return DaoUtil.convertDataList(ruleChainEntities); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraRuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraRuleNodeDao.java new file mode 100644 index 0000000000..9e34531a71 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraRuleNodeDao.java @@ -0,0 +1,42 @@ +/** + * Copyright © 2016-2018 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.rule; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.rule.RuleNode; +import org.thingsboard.server.dao.model.nosql.RuleNodeEntity; +import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao; +import org.thingsboard.server.dao.util.NoSqlDao; + +import static org.thingsboard.server.dao.model.ModelConstants.RULE_NODE_COLUMN_FAMILY_NAME; + +@Component +@Slf4j +@NoSqlDao +public class CassandraRuleNodeDao extends CassandraAbstractSearchTextDao implements RuleNodeDao { + + @Override + protected Class getColumnFamilyClass() { + return RuleNodeEntity.class; + } + + @Override + protected String getColumnFamilyName() { + return RULE_NODE_COLUMN_FAMILY_NAME; + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java new file mode 100644 index 0000000000..4a7cfaea7c --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java @@ -0,0 +1,40 @@ +/** + * Copyright © 2016-2018 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.rule; + +import org.thingsboard.server.common.data.page.TextPageLink; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.dao.Dao; + +import java.util.List; +import java.util.UUID; + +/** + * Created by igor on 3/12/18. + */ +public interface RuleChainDao extends Dao { + + /** + * Find rule chains by tenantId and page link. + * + * @param tenantId the tenantId + * @param pageLink the page link + * @return the list of rule chain objects + */ + List findRuleChainsByTenantId(UUID tenantId, TextPageLink pageLink); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java new file mode 100644 index 0000000000..c6c947ba9f --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -0,0 +1,28 @@ +/** + * Copyright © 2016-2018 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.rule; + +import org.thingsboard.server.common.data.rule.RuleChain; + +/** + * Created by igor on 3/12/18. + */ +public interface RuleChainService { + + RuleChain saveRuleChain(RuleChain ruleChain); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java new file mode 100644 index 0000000000..7ef4b3e204 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java @@ -0,0 +1,27 @@ +/** + * Copyright © 2016-2018 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.rule; + +import org.thingsboard.server.common.data.rule.RuleNode; +import org.thingsboard.server.dao.Dao; + +/** + * Created by igor on 3/12/18. + */ +public interface RuleNodeDao extends Dao { + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java new file mode 100644 index 0000000000..fb5d20a702 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java @@ -0,0 +1,66 @@ +/** + * Copyright © 2016-2018 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.sql.rule; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.UUIDConverter; +import org.thingsboard.server.common.data.page.TextPageLink; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.dao.DaoUtil; +import org.thingsboard.server.dao.model.sql.RuleChainEntity; +import org.thingsboard.server.dao.rule.RuleChainDao; +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; +import org.thingsboard.server.dao.util.SqlDao; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR; + +@Slf4j +@Component +@SqlDao +public class JpaRuleChainDao extends JpaAbstractSearchTextDao implements RuleChainDao { + + @Autowired + private RuleChainRepository ruleChainRepository; + + @Override + protected Class getEntityClass() { + return RuleChainEntity.class; + } + + @Override + protected CrudRepository getCrudRepository() { + return ruleChainRepository; + } + + @Override + public List findRuleChainsByTenantId(UUID tenantId, TextPageLink pageLink) { + return DaoUtil.convertDataList(ruleChainRepository + .findByTenantId( + UUIDConverter.fromTimeUUID(tenantId), + Objects.toString(pageLink.getTextSearch(), ""), + pageLink.getIdOffset() == null ? NULL_UUID_STR : UUIDConverter.fromTimeUUID(pageLink.getIdOffset()), + new PageRequest(0, pageLink.getLimit()))); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java new file mode 100644 index 0000000000..eec28946a8 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java @@ -0,0 +1,46 @@ +/** + * Copyright © 2016-2018 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.sql.rule; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.rule.RuleNode; +import org.thingsboard.server.dao.model.sql.RuleNodeEntity; +import org.thingsboard.server.dao.rule.RuleNodeDao; +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; +import org.thingsboard.server.dao.util.SqlDao; + +@Slf4j +@Component +@SqlDao +public class JpaRuleNodeDao extends JpaAbstractSearchTextDao implements RuleNodeDao { + + @Autowired + private RuleNodeRepository ruleNodeRepository; + + @Override + protected Class getEntityClass() { + return RuleNodeEntity.class; + } + + @Override + protected CrudRepository getCrudRepository() { + return ruleNodeRepository; + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java new file mode 100644 index 0000000000..58d4aac70b --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java @@ -0,0 +1,38 @@ +/** + * Copyright © 2016-2018 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.sql.rule; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.thingsboard.server.dao.model.sql.RuleChainEntity; +import org.thingsboard.server.dao.util.SqlDao; + +import java.util.List; + +@SqlDao +public interface RuleChainRepository extends CrudRepository { + + @Query("SELECT rc FROM RuleChainEntity rc WHERE rc.tenantId = :tenantId " + + "AND LOWER(rc.searchText) LIKE LOWER(CONCAT(:searchText, '%')) " + + "AND rc.id > :idOffset ORDER BY rc.id") + List findByTenantId(@Param("tenantId") String tenantId, + @Param("searchText") String searchText, + @Param("idOffset") String idOffset, + Pageable pageable); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java new file mode 100644 index 0000000000..574aedf118 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java @@ -0,0 +1,25 @@ +/** + * Copyright © 2016-2018 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.sql.rule; + +import org.springframework.data.repository.CrudRepository; +import org.thingsboard.server.dao.model.sql.RuleNodeEntity; +import org.thingsboard.server.dao.util.SqlDao; + +@SqlDao +public interface RuleNodeRepository extends CrudRepository { + +} diff --git a/dao/src/main/resources/cassandra/schema.cql b/dao/src/main/resources/cassandra/schema.cql index 0c8a644944..6c62c89395 100644 --- a/dao/src/main/resources/cassandra/schema.cql +++ b/dao/src/main/resources/cassandra/schema.cql @@ -542,55 +542,6 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.event_by_id AS PRIMARY KEY ((tenant_id, entity_type, entity_id), id, event_type, event_uid) WITH CLUSTERING ORDER BY (id ASC, event_type ASC, event_uid ASC); -CREATE TABLE IF NOT EXISTS thingsboard.msg_queue ( - node_id timeuuid, - clustered_hash bigint, - partition bigint, - ts bigint, - msg blob, - PRIMARY KEY ((node_id, clustered_hash, partition), ts)) -WITH CLUSTERING ORDER BY (ts DESC) -AND compaction = { - 'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', - 'min_threshold': '5', - 'base_time_seconds': '43200', - 'max_window_size_seconds': '43200', - 'tombstone_threshold': '0.9', - 'unchecked_tombstone_compaction': 'true' -}; - - -CREATE TABLE IF NOT EXISTS thingsboard.msg_ack_queue ( - node_id timeuuid, - clustered_hash bigint, - partition bigint, - msg_id timeuuid, - PRIMARY KEY ((node_id, clustered_hash, partition), msg_id)) -WITH CLUSTERING ORDER BY (msg_id DESC) -AND compaction = { - 'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', - 'min_threshold': '5', - 'base_time_seconds': '43200', - 'max_window_size_seconds': '43200', - 'tombstone_threshold': '0.9', - 'unchecked_tombstone_compaction': 'true' -}; - -CREATE TABLE IF NOT EXISTS thingsboard.processed_msg_partitions ( - node_id timeuuid, - clustered_hash bigint, - partition bigint, - PRIMARY KEY ((node_id, clustered_hash), partition)) -WITH CLUSTERING ORDER BY (partition DESC) -AND compaction = { - 'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', - 'min_threshold': '5', - 'base_time_seconds': '43200', - 'max_window_size_seconds': '43200', - 'tombstone_threshold': '0.9', - 'unchecked_tombstone_compaction': 'true' -}; - CREATE TABLE IF NOT EXISTS thingsboard.audit_log_by_entity_id ( tenant_id timeuuid, id timeuuid, @@ -639,8 +590,6 @@ CREATE TABLE IF NOT EXISTS thingsboard.audit_log_by_user_id ( PRIMARY KEY ((tenant_id, user_id), id) ); - - CREATE TABLE IF NOT EXISTS thingsboard.audit_log_by_tenant_id ( tenant_id timeuuid, id timeuuid, @@ -664,3 +613,80 @@ CREATE TABLE IF NOT EXISTS thingsboard.audit_log_by_tenant_id_partitions ( PRIMARY KEY (( tenant_id ), partition) ) WITH CLUSTERING ORDER BY ( partition ASC ) AND compaction = { 'class' : 'LeveledCompactionStrategy' }; + +CREATE TABLE IF NOT EXISTS thingsboard.msg_queue ( + node_id timeuuid, + clustered_hash bigint, + partition bigint, + ts bigint, + msg blob, + PRIMARY KEY ((node_id, clustered_hash, partition), ts)) +WITH CLUSTERING ORDER BY (ts DESC) +AND compaction = { + 'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', + 'min_threshold': '5', + 'base_time_seconds': '43200', + 'max_window_size_seconds': '43200', + 'tombstone_threshold': '0.9', + 'unchecked_tombstone_compaction': 'true' +}; + +CREATE TABLE IF NOT EXISTS thingsboard.msg_ack_queue ( + node_id timeuuid, + clustered_hash bigint, + partition bigint, + msg_id timeuuid, + PRIMARY KEY ((node_id, clustered_hash, partition), msg_id)) +WITH CLUSTERING ORDER BY (msg_id DESC) +AND compaction = { + 'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', + 'min_threshold': '5', + 'base_time_seconds': '43200', + 'max_window_size_seconds': '43200', + 'tombstone_threshold': '0.9', + 'unchecked_tombstone_compaction': 'true' +}; + +CREATE TABLE IF NOT EXISTS thingsboard.processed_msg_partitions ( + node_id timeuuid, + clustered_hash bigint, + partition bigint, + PRIMARY KEY ((node_id, clustered_hash), partition)) +WITH CLUSTERING ORDER BY (partition DESC) +AND compaction = { + 'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', + 'min_threshold': '5', + 'base_time_seconds': '43200', + 'max_window_size_seconds': '43200', + 'tombstone_threshold': '0.9', + 'unchecked_tombstone_compaction': 'true' +}; + +CREATE TABLE IF NOT EXISTS thingsboard.rule_chain ( + id uuid, + tenant_id uuid, + name text, + search_text text, + first_rule_node_id uuid, + is_root boolean, + configuration text, + additional_info text, + PRIMARY KEY (id, tenant_id) +); + +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 + PRIMARY KEY ( tenant_id, search_text, id ) + WITH CLUSTERING ORDER BY ( search_text ASC, id DESC ); + +CREATE TABLE IF NOT EXISTS thingsboard.rule_node ( + id uuid, + type text, + name text, + search_text text, + configuration text, + additional_info text, + PRIMARY KEY (id) +); \ No newline at end of file diff --git a/dao/src/main/resources/sql/schema.sql b/dao/src/main/resources/sql/schema.sql index 9f03dc8a1b..e525007080 100644 --- a/dao/src/main/resources/sql/schema.sql +++ b/dao/src/main/resources/sql/schema.sql @@ -254,4 +254,24 @@ CREATE TABLE IF NOT EXISTS widgets_bundle ( search_text varchar(255), tenant_id varchar(31), title varchar(255) -); \ No newline at end of file +); + +CREATE TABLE IF NOT EXISTS rule_chain ( + id varchar(31) NOT NULL CONSTRAINT rule_chain_pkey PRIMARY KEY, + additional_info varchar, + configuration varchar(10000000), + name varchar(255), + first_rule_node_id varchar(31), + is_root boolean, + search_text varchar(255), + tenant_id varchar(31) +); + +CREATE TABLE IF NOT EXISTS rule_node ( + id varchar(31) NOT NULL CONSTRAINT rule_node_pkey PRIMARY KEY, + additional_info varchar, + configuration varchar(10000000), + type varchar(255), + name varchar(255), + search_text varchar(255) +);