Showing
19 changed files
with
497 additions
and
2 deletions
@@ -247,7 +247,7 @@ spring: | @@ -247,7 +247,7 @@ spring: | ||
247 | database-platform: "${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.HSQLDialect}" | 247 | database-platform: "${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.HSQLDialect}" |
248 | datasource: | 248 | datasource: |
249 | driverClassName: "${SPRING_DRIVER_CLASS_NAME:org.hsqldb.jdbc.JDBCDriver}" | 249 | driverClassName: "${SPRING_DRIVER_CLASS_NAME:org.hsqldb.jdbc.JDBCDriver}" |
250 | - url: "${SPRING_DATASOURCE_URL:jdbc:hsqldb:file:${SQL_DATA_FOLDER:/tmp}/thingsboardDb;sql.enforce_size=false}" | 250 | + url: "${SPRING_DATASOURCE_URL:jdbc:hsqldb:file:${SQL_DATA_FOLDER:/tmp}/thingsboardDb;sql.enforce_size=false;hsqldb.log_size=5}" |
251 | username: "${SPRING_DATASOURCE_USERNAME:sa}" | 251 | username: "${SPRING_DATASOURCE_USERNAME:sa}" |
252 | password: "${SPRING_DATASOURCE_PASSWORD:}" | 252 | password: "${SPRING_DATASOURCE_PASSWORD:}" |
253 | 253 |
@@ -23,7 +23,6 @@ | @@ -23,7 +23,6 @@ | ||
23 | <version>1.4.0-SNAPSHOT</version> | 23 | <version>1.4.0-SNAPSHOT</version> |
24 | <artifactId>thingsboard</artifactId> | 24 | <artifactId>thingsboard</artifactId> |
25 | </parent> | 25 | </parent> |
26 | - <groupId>org.thingsboard</groupId> | ||
27 | <artifactId>dao</artifactId> | 26 | <artifactId>dao</artifactId> |
28 | <packaging>jar</packaging> | 27 | <packaging>jar</packaging> |
29 | 28 |
@@ -85,6 +85,7 @@ | @@ -85,6 +85,7 @@ | ||
85 | <module>extensions-api</module> | 85 | <module>extensions-api</module> |
86 | <module>extensions-core</module> | 86 | <module>extensions-core</module> |
87 | <module>extensions</module> | 87 | <module>extensions</module> |
88 | + <module>rule-engine</module> | ||
88 | <module>transport</module> | 89 | <module>transport</module> |
89 | <module>ui</module> | 90 | <module>ui</module> |
90 | <module>tools</module> | 91 | <module>tools</module> |
rule-engine/pom.xml
0 → 100644
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2017 The Thingsboard Authors | ||
4 | + | ||
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + you may not use this file except in compliance with the License. | ||
7 | + You may obtain a copy of the License at | ||
8 | + | ||
9 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + | ||
11 | + Unless required by applicable law or agreed to in writing, software | ||
12 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + See the License for the specific language governing permissions and | ||
15 | + limitations under the License. | ||
16 | + | ||
17 | +--> | ||
18 | +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
19 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
20 | + <modelVersion>4.0.0</modelVersion> | ||
21 | + <parent> | ||
22 | + <groupId>org.thingsboard</groupId> | ||
23 | + <version>1.4.0-SNAPSHOT</version> | ||
24 | + <artifactId>thingsboard</artifactId> | ||
25 | + </parent> | ||
26 | + <groupId>org.thingsboard</groupId> | ||
27 | + <artifactId>rule-engine</artifactId> | ||
28 | + <packaging>pom</packaging> | ||
29 | + | ||
30 | + <name>Thingsboard Extensions</name> | ||
31 | + <url>https://thingsboard.io</url> | ||
32 | + | ||
33 | + <properties> | ||
34 | + <main.dir>${basedir}/..</main.dir> | ||
35 | + </properties> | ||
36 | + | ||
37 | + <modules> | ||
38 | + <module>rule-engine-api</module> | ||
39 | + <module>rule-engine-components</module> | ||
40 | + </modules> | ||
41 | + | ||
42 | +</project> |
rule-engine/rule-engine-api/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + | ||
4 | + Copyright © 2016-2017 The Thingsboard Authors | ||
5 | + | ||
6 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | + you may not use this file except in compliance with the License. | ||
8 | + You may obtain a copy of the License at | ||
9 | + | ||
10 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + | ||
12 | + Unless required by applicable law or agreed to in writing, software | ||
13 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | + See the License for the specific language governing permissions and | ||
16 | + limitations under the License. | ||
17 | + | ||
18 | +--> | ||
19 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
20 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
21 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
22 | + <modelVersion>4.0.0</modelVersion> | ||
23 | + <parent> | ||
24 | + <groupId>org.thingsboard</groupId> | ||
25 | + <version>1.4.0-SNAPSHOT</version> | ||
26 | + <artifactId>rule-engine</artifactId> | ||
27 | + </parent> | ||
28 | + <groupId>org.thingsboard.rule-engine</groupId> | ||
29 | + <artifactId>rule-engine-api</artifactId> | ||
30 | + <packaging>jar</packaging> | ||
31 | + | ||
32 | + <name>Thingsboard Rule Engine API</name> | ||
33 | + <url>https://thingsboard.io</url> | ||
34 | + | ||
35 | + <properties> | ||
36 | + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
37 | + <main.dir>${basedir}/../..</main.dir> | ||
38 | + </properties> | ||
39 | + | ||
40 | + <dependencies> | ||
41 | + <dependency> | ||
42 | + <groupId>org.thingsboard.common</groupId> | ||
43 | + <artifactId>message</artifactId> | ||
44 | + <scope>provided</scope> | ||
45 | + </dependency> | ||
46 | + <dependency> | ||
47 | + <groupId>org.thingsboard</groupId> | ||
48 | + <artifactId>extensions-api</artifactId> | ||
49 | + <scope>provided</scope> | ||
50 | + </dependency> | ||
51 | + <dependency> | ||
52 | + <groupId>org.thingsboard</groupId> | ||
53 | + <artifactId>dao</artifactId> | ||
54 | + <scope>provided</scope> | ||
55 | + </dependency> | ||
56 | + <dependency> | ||
57 | + <groupId>ch.qos.logback</groupId> | ||
58 | + <artifactId>logback-core</artifactId> | ||
59 | + <scope>provided</scope> | ||
60 | + </dependency> | ||
61 | + <dependency> | ||
62 | + <groupId>ch.qos.logback</groupId> | ||
63 | + <artifactId>logback-classic</artifactId> | ||
64 | + <scope>provided</scope> | ||
65 | + </dependency> | ||
66 | + </dependencies> | ||
67 | +</project> |
1 | +package org.thingsboard.rule.engine.api; | ||
2 | + | ||
3 | +import org.thingsboard.server.common.msg.cluster.ServerAddress; | ||
4 | +import org.thingsboard.server.dao.attributes.AttributesService; | ||
5 | + | ||
6 | +import java.util.UUID; | ||
7 | + | ||
8 | +/** | ||
9 | + * Created by ashvayka on 13.01.18. | ||
10 | + */ | ||
11 | +public interface TbContext { | ||
12 | + | ||
13 | + void tellNext(TbMsg msg); | ||
14 | + | ||
15 | + void tellNext(TbMsg msg, String relationType); | ||
16 | + | ||
17 | + void tellSelf(TbMsg msg, long delayMs); | ||
18 | + | ||
19 | + void tellOthers(TbMsg msg); | ||
20 | + | ||
21 | + void tellSibling(TbMsg msg, ServerAddress address); | ||
22 | + | ||
23 | + void spawn(TbMsg msg); | ||
24 | + | ||
25 | + void ack(UUID msg); | ||
26 | + | ||
27 | + AttributesService getAttributesService(); | ||
28 | + | ||
29 | +} |
1 | +package org.thingsboard.rule.engine.api; | ||
2 | + | ||
3 | +import lombok.Data; | ||
4 | +import org.thingsboard.server.common.data.id.EntityId; | ||
5 | + | ||
6 | +import java.io.Serializable; | ||
7 | +import java.util.UUID; | ||
8 | + | ||
9 | +/** | ||
10 | + * Created by ashvayka on 13.01.18. | ||
11 | + */ | ||
12 | +@Data | ||
13 | +public final class TbMsg implements Serializable { | ||
14 | + | ||
15 | + private final UUID id; | ||
16 | + private final String type; | ||
17 | + private final EntityId originator; | ||
18 | + private final TbMsgMetaData metaData; | ||
19 | + | ||
20 | + private final byte[] data; | ||
21 | + | ||
22 | +} |
rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbMsgMetaData.java
0 → 100644
1 | +package org.thingsboard.rule.engine.api; | ||
2 | + | ||
3 | +import lombok.Data; | ||
4 | + | ||
5 | +import java.io.Serializable; | ||
6 | +import java.util.Map; | ||
7 | + | ||
8 | +/** | ||
9 | + * Created by ashvayka on 13.01.18. | ||
10 | + */ | ||
11 | +@Data | ||
12 | +public final class TbMsgMetaData implements Serializable { | ||
13 | + | ||
14 | + private Map<String, String> data; | ||
15 | + | ||
16 | + public String getValue(String key) { | ||
17 | + return data.get(key); | ||
18 | + } | ||
19 | + | ||
20 | + public void putValue(String key, String value) { | ||
21 | + data.put(key, value); | ||
22 | + } | ||
23 | + | ||
24 | +} |
1 | +package org.thingsboard.rule.engine.api; | ||
2 | + | ||
3 | +import java.util.concurrent.ExecutionException; | ||
4 | + | ||
5 | +/** | ||
6 | + * Created by ashvayka on 19.01.18. | ||
7 | + */ | ||
8 | +public interface TbNode { | ||
9 | + | ||
10 | + void init(TbNodeConfiguration configuration, TbNodeState state) throws TbNodeException; | ||
11 | + | ||
12 | + void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException; | ||
13 | + | ||
14 | + void destroy(); | ||
15 | + | ||
16 | +} |
rule-engine/rule-engine-components/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + | ||
4 | + Copyright © 2016-2017 The Thingsboard Authors | ||
5 | + | ||
6 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | + you may not use this file except in compliance with the License. | ||
8 | + You may obtain a copy of the License at | ||
9 | + | ||
10 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + | ||
12 | + Unless required by applicable law or agreed to in writing, software | ||
13 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | + See the License for the specific language governing permissions and | ||
16 | + limitations under the License. | ||
17 | + | ||
18 | +--> | ||
19 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
20 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
21 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
22 | + <modelVersion>4.0.0</modelVersion> | ||
23 | + <parent> | ||
24 | + <groupId>org.thingsboard</groupId> | ||
25 | + <version>1.4.0-SNAPSHOT</version> | ||
26 | + <artifactId>rule-engine</artifactId> | ||
27 | + </parent> | ||
28 | + <groupId>org.thingsboard.rule-engine</groupId> | ||
29 | + <artifactId>rule-engine-components</artifactId> | ||
30 | + <packaging>jar</packaging> | ||
31 | + | ||
32 | + <name>Thingsboard Rule Engine Components</name> | ||
33 | + <url>https://thingsboard.io</url> | ||
34 | + | ||
35 | + <properties> | ||
36 | + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
37 | + <main.dir>${basedir}/../..</main.dir> | ||
38 | + </properties> | ||
39 | + | ||
40 | + <dependencies> | ||
41 | + <dependency> | ||
42 | + <groupId>org.thingsboard</groupId> | ||
43 | + <artifactId>dao</artifactId> | ||
44 | + <scope>provided</scope> | ||
45 | + </dependency> | ||
46 | + <dependency> | ||
47 | + <groupId>ch.qos.logback</groupId> | ||
48 | + <artifactId>logback-core</artifactId> | ||
49 | + <scope>provided</scope> | ||
50 | + </dependency> | ||
51 | + <dependency> | ||
52 | + <groupId>ch.qos.logback</groupId> | ||
53 | + <artifactId>logback-classic</artifactId> | ||
54 | + <scope>provided</scope> | ||
55 | + </dependency> | ||
56 | + <dependency> | ||
57 | + <groupId>org.thingsboard</groupId> | ||
58 | + <artifactId>extensions-api</artifactId> | ||
59 | + <scope>provided</scope> | ||
60 | + </dependency> | ||
61 | + <dependency> | ||
62 | + <groupId>org.thingsboard.rule-engine</groupId> | ||
63 | + <artifactId>rule-engine-api</artifactId> | ||
64 | + <version>1.4.0-SNAPSHOT</version> | ||
65 | + </dependency> | ||
66 | + </dependencies> | ||
67 | +</project> |
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/TbNodeUtils.java
0 → 100644
1 | +package org.thingsboard.rule.engine; | ||
2 | + | ||
3 | +import com.fasterxml.jackson.core.JsonProcessingException; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import org.thingsboard.rule.engine.api.TbNodeConfiguration; | ||
6 | +import org.thingsboard.rule.engine.api.TbNodeException; | ||
7 | + | ||
8 | +/** | ||
9 | + * Created by ashvayka on 19.01.18. | ||
10 | + */ | ||
11 | +public class TbNodeUtils { | ||
12 | + | ||
13 | + private static final ObjectMapper mapper = new ObjectMapper(); | ||
14 | + | ||
15 | + public static <T> T convert(TbNodeConfiguration configuration, Class<T> clazz) throws TbNodeException { | ||
16 | + try { | ||
17 | + return mapper.treeToValue(configuration.getData(), clazz); | ||
18 | + } catch (JsonProcessingException e) { | ||
19 | + throw new TbNodeException(e); | ||
20 | + } | ||
21 | + } | ||
22 | + | ||
23 | +} |
1 | +package org.thingsboard.rule.engine.filter; | ||
2 | + | ||
3 | +import lombok.extern.slf4j.Slf4j; | ||
4 | +import org.thingsboard.rule.engine.TbNodeUtils; | ||
5 | +import org.thingsboard.rule.engine.api.*; | ||
6 | +import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; | ||
7 | +import org.thingsboard.server.common.data.DataConstants; | ||
8 | +import org.thingsboard.server.common.data.kv.AttributeKvEntry; | ||
9 | +import org.thingsboard.server.dao.attributes.AttributesService; | ||
10 | + | ||
11 | +import java.util.List; | ||
12 | + | ||
13 | +/** | ||
14 | + * Created by ashvayka on 19.01.18. | ||
15 | + */ | ||
16 | +@Slf4j | ||
17 | +public class TbMsgTypeFilterNode implements TbNode { | ||
18 | + | ||
19 | + TbMsgTypeFilterNodeConfiguration config; | ||
20 | + | ||
21 | + @Override | ||
22 | + public void init(TbNodeConfiguration configuration, TbNodeState state) throws TbNodeException { | ||
23 | + this.config = TbNodeUtils.convert(configuration, TbMsgTypeFilterNodeConfiguration.class); | ||
24 | + } | ||
25 | + | ||
26 | + @Override | ||
27 | + public void onMsg(TbContext ctx, TbMsg msg) throws TbNodeException { | ||
28 | + ctx.tellNext(msg, Boolean.toString(config.getMessageTypes().contains(msg.getType()))); | ||
29 | + } | ||
30 | + | ||
31 | + @Override | ||
32 | + public void destroy() { | ||
33 | + | ||
34 | + } | ||
35 | +} |
1 | +package org.thingsboard.rule.engine.metadata; | ||
2 | + | ||
3 | +import lombok.extern.slf4j.Slf4j; | ||
4 | +import org.thingsboard.rule.engine.TbNodeUtils; | ||
5 | +import org.thingsboard.rule.engine.api.*; | ||
6 | +import org.thingsboard.server.common.data.DataConstants; | ||
7 | +import org.thingsboard.server.common.data.kv.AttributeKvEntry; | ||
8 | +import org.thingsboard.server.dao.attributes.AttributesService; | ||
9 | + | ||
10 | +import java.util.List; | ||
11 | + | ||
12 | +/** | ||
13 | + * Created by ashvayka on 19.01.18. | ||
14 | + */ | ||
15 | +@Slf4j | ||
16 | +public class TbGetAttributesNode implements TbNode { | ||
17 | + | ||
18 | + TbGetAttributesNodeConfiguration config; | ||
19 | + | ||
20 | + @Override | ||
21 | + public void init(TbNodeConfiguration configuration, TbNodeState state) throws TbNodeException { | ||
22 | + this.config = TbNodeUtils.convert(configuration, TbGetAttributesNodeConfiguration.class); | ||
23 | + } | ||
24 | + | ||
25 | + @Override | ||
26 | + public void onMsg(TbContext ctx, TbMsg msg) throws TbNodeException { | ||
27 | + try { | ||
28 | + //TODO: refactor this to work async and fetch attributes from cache. | ||
29 | + AttributesService service = ctx.getAttributesService(); | ||
30 | + fetchAttributes(msg, service, config.getClientAttributeNames(), DataConstants.CLIENT_SCOPE, "cs."); | ||
31 | + fetchAttributes(msg, service, config.getServerAttributeNames(), DataConstants.SERVER_SCOPE, "ss."); | ||
32 | + fetchAttributes(msg, service, config.getSharedAttributeNames(), DataConstants.SHARED_SCOPE, "shared."); | ||
33 | + ctx.tellNext(msg); | ||
34 | + } catch (Exception e) { | ||
35 | + log.warn("[{}][{}] Failed to fetch attributes", msg.getOriginator(), msg.getId(), e); | ||
36 | + throw new TbNodeException(e); | ||
37 | + } | ||
38 | + } | ||
39 | + | ||
40 | + private void fetchAttributes(TbMsg msg, AttributesService service, List<String> attributeNames, String scope, String prefix) throws InterruptedException, java.util.concurrent.ExecutionException { | ||
41 | + if (attributeNames != null && attributeNames.isEmpty()) { | ||
42 | + List<AttributeKvEntry> attributes = service.find(msg.getOriginator(), scope, attributeNames).get(); | ||
43 | + attributes.forEach(attr -> msg.getMetaData().putValue(prefix + attr.getKey(), attr.getValueAsString())); | ||
44 | + } | ||
45 | + } | ||
46 | + | ||
47 | + @Override | ||
48 | + public void destroy() { | ||
49 | + | ||
50 | + } | ||
51 | +} |
1 | +package org.thingsboard.rule.engine.metadata; | ||
2 | + | ||
3 | +import lombok.Data; | ||
4 | + | ||
5 | +import java.util.List; | ||
6 | + | ||
7 | +/** | ||
8 | + * Created by ashvayka on 19.01.18. | ||
9 | + */ | ||
10 | +@Data | ||
11 | +public class TbGetAttributesNodeConfiguration { | ||
12 | + | ||
13 | + private List<String> clientAttributeNames; | ||
14 | + private List<String> sharedAttributeNames; | ||
15 | + private List<String> serverAttributeNames; | ||
16 | + | ||
17 | +} |
1 | +package org.thingsboard.rule.engine.transform; | ||
2 | + | ||
3 | +import lombok.extern.slf4j.Slf4j; | ||
4 | +import org.thingsboard.rule.engine.TbNodeUtils; | ||
5 | +import org.thingsboard.rule.engine.api.*; | ||
6 | +import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; | ||
7 | +import org.thingsboard.server.common.data.DataConstants; | ||
8 | +import org.thingsboard.server.common.data.kv.AttributeKvEntry; | ||
9 | +import org.thingsboard.server.dao.attributes.AttributesService; | ||
10 | + | ||
11 | +import java.util.List; | ||
12 | + | ||
13 | +/** | ||
14 | + * Created by ashvayka on 19.01.18. | ||
15 | + */ | ||
16 | +@Slf4j | ||
17 | +public class TbTransformNode implements TbNode { | ||
18 | + | ||
19 | + TbGetAttributesNodeConfiguration config; | ||
20 | + | ||
21 | + @Override | ||
22 | + public void init(TbNodeConfiguration configuration, TbNodeState state) throws TbNodeException { | ||
23 | + this.config = TbNodeUtils.convert(configuration, TbGetAttributesNodeConfiguration.class); | ||
24 | + } | ||
25 | + | ||
26 | + @Override | ||
27 | + public void onMsg(TbContext ctx, TbMsg msg) throws TbNodeException { | ||
28 | + try { | ||
29 | + //TODO: refactor this to work async and fetch attributes from cache. | ||
30 | + AttributesService service = ctx.getAttributesService(); | ||
31 | + fetchAttributes(msg, service, config.getClientAttributeNames(), DataConstants.CLIENT_SCOPE, "cs."); | ||
32 | + fetchAttributes(msg, service, config.getServerAttributeNames(), DataConstants.SERVER_SCOPE, "ss."); | ||
33 | + fetchAttributes(msg, service, config.getSharedAttributeNames(), DataConstants.SHARED_SCOPE, "shared."); | ||
34 | + ctx.tellNext(msg); | ||
35 | + } catch (Exception e) { | ||
36 | + log.warn("[{}][{}] Failed to fetch attributes", msg.getOriginator(), msg.getId(), e); | ||
37 | + throw new TbNodeException(e); | ||
38 | + } | ||
39 | + } | ||
40 | + | ||
41 | + private void fetchAttributes(TbMsg msg, AttributesService service, List<String> attributeNames, String scope, String prefix) throws InterruptedException, java.util.concurrent.ExecutionException { | ||
42 | + if (attributeNames != null && attributeNames.isEmpty()) { | ||
43 | + List<AttributeKvEntry> attributes = service.find(msg.getOriginator(), scope, attributeNames).get(); | ||
44 | + attributes.forEach(attr -> msg.getMetaData().putValue(prefix + attr.getKey(), attr.getValueAsString())); | ||
45 | + } | ||
46 | + } | ||
47 | + | ||
48 | + @Override | ||
49 | + public void destroy() { | ||
50 | + | ||
51 | + } | ||
52 | +} |