Commit 912cffc3b1ad1616cee93f824130e70a3a3bb46c

Authored by Andrew Shvayka
Committed by GitHub
2 parents 65e47393 b603f26f

Merge pull request #183 from thingsboard/feature/TB-67

TB-67: Add new filter to rule engine based on device type
Showing 15 changed files with 205 additions and 29 deletions
@@ -19,13 +19,11 @@ import akka.actor.ActorContext; @@ -19,13 +19,11 @@ import akka.actor.ActorContext;
19 import akka.actor.ActorRef; 19 import akka.actor.ActorRef;
20 import akka.event.LoggingAdapter; 20 import akka.event.LoggingAdapter;
21 import org.thingsboard.server.actors.ActorSystemContext; 21 import org.thingsboard.server.actors.ActorSystemContext;
22 -import org.thingsboard.server.actors.rule.ChainProcessingContext;  
23 -import org.thingsboard.server.actors.rule.ChainProcessingMetaData;  
24 -import org.thingsboard.server.actors.rule.RuleProcessingMsg;  
25 -import org.thingsboard.server.actors.rule.RulesProcessedMsg; 22 +import org.thingsboard.server.actors.rule.*;
26 import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor; 23 import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
27 import org.thingsboard.server.actors.tenant.RuleChainDeviceMsg; 24 import org.thingsboard.server.actors.tenant.RuleChainDeviceMsg;
28 import org.thingsboard.server.common.data.DataConstants; 25 import org.thingsboard.server.common.data.DataConstants;
  26 +import org.thingsboard.server.common.data.Device;
29 import org.thingsboard.server.common.data.id.DeviceId; 27 import org.thingsboard.server.common.data.id.DeviceId;
30 import org.thingsboard.server.common.data.id.SessionId; 28 import org.thingsboard.server.common.data.id.SessionId;
31 import org.thingsboard.server.common.data.kv.AttributeKey; 29 import org.thingsboard.server.common.data.kv.AttributeKey;
@@ -42,6 +40,7 @@ import org.thingsboard.server.common.msg.session.ToDeviceMsg; @@ -42,6 +40,7 @@ import org.thingsboard.server.common.msg.session.ToDeviceMsg;
42 import org.thingsboard.server.extensions.api.device.DeviceAttributes; 40 import org.thingsboard.server.extensions.api.device.DeviceAttributes;
43 import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg; 41 import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
44 import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg; 42 import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg;
  43 +import org.thingsboard.server.extensions.api.device.DeviceMetaData;
45 import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse; 44 import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse;
46 import org.thingsboard.server.extensions.api.plugins.msg.RpcError; 45 import org.thingsboard.server.extensions.api.plugins.msg.RpcError;
47 import org.thingsboard.server.extensions.api.plugins.msg.TimeoutIntMsg; 46 import org.thingsboard.server.extensions.api.plugins.msg.TimeoutIntMsg;
@@ -71,6 +70,8 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso @@ -71,6 +70,8 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
71 private final Map<Integer, ToDeviceRpcRequestMetadata> rpcPendingMap; 70 private final Map<Integer, ToDeviceRpcRequestMetadata> rpcPendingMap;
72 71
73 private int rpcSeq = 0; 72 private int rpcSeq = 0;
  73 + private String deviceName;
  74 + private String deviceType;
74 private DeviceAttributes deviceAttributes; 75 private DeviceAttributes deviceAttributes;
75 76
76 public DeviceActorMessageProcessor(ActorSystemContext systemContext, LoggingAdapter logger, DeviceId deviceId) { 77 public DeviceActorMessageProcessor(ActorSystemContext systemContext, LoggingAdapter logger, DeviceId deviceId) {
@@ -84,6 +85,10 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso @@ -84,6 +85,10 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
84 } 85 }
85 86
86 private void initAttributes() { 87 private void initAttributes() {
  88 + //TODO: add invalidation of deviceType cache.
  89 + Device device = systemContext.getDeviceService().findDeviceById(deviceId);
  90 + this.deviceName = device.getName();
  91 + this.deviceType = device.getType();
87 this.deviceAttributes = new DeviceAttributes(fetchAttributes(DataConstants.CLIENT_SCOPE), 92 this.deviceAttributes = new DeviceAttributes(fetchAttributes(DataConstants.CLIENT_SCOPE),
88 fetchAttributes(DataConstants.SERVER_SCOPE), fetchAttributes(DataConstants.SHARED_SCOPE)); 93 fetchAttributes(DataConstants.SERVER_SCOPE), fetchAttributes(DataConstants.SHARED_SCOPE));
89 } 94 }
@@ -230,7 +235,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso @@ -230,7 +235,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
230 235
231 void process(ActorContext context, RuleChainDeviceMsg srcMsg) { 236 void process(ActorContext context, RuleChainDeviceMsg srcMsg) {
232 ChainProcessingMetaData md = new ChainProcessingMetaData(srcMsg.getRuleChain(), 237 ChainProcessingMetaData md = new ChainProcessingMetaData(srcMsg.getRuleChain(),
233 - srcMsg.getToDeviceActorMsg(), deviceAttributes, context.self()); 238 + srcMsg.getToDeviceActorMsg(), new DeviceMetaData(deviceId, deviceName, deviceType, deviceAttributes), context.self());
234 ChainProcessingContext ctx = new ChainProcessingContext(md); 239 ChainProcessingContext ctx = new ChainProcessingContext(md);
235 if (ctx.getChainLength() > 0) { 240 if (ctx.getChainLength() > 0) {
236 RuleProcessingMsg msg = new RuleProcessingMsg(ctx); 241 RuleProcessingMsg msg = new RuleProcessingMsg(ctx);
@@ -21,6 +21,7 @@ import org.thingsboard.server.common.msg.core.RuleEngineErrorMsg; @@ -21,6 +21,7 @@ import org.thingsboard.server.common.msg.core.RuleEngineErrorMsg;
21 import org.thingsboard.server.common.msg.device.ToDeviceActorMsg; 21 import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
22 import org.thingsboard.server.common.msg.session.ToDeviceMsg; 22 import org.thingsboard.server.common.msg.session.ToDeviceMsg;
23 import org.thingsboard.server.extensions.api.device.DeviceAttributes; 23 import org.thingsboard.server.extensions.api.device.DeviceAttributes;
  24 +import org.thingsboard.server.extensions.api.device.DeviceMetaData;
24 25
25 public class ChainProcessingContext { 26 public class ChainProcessingContext {
26 27
@@ -85,8 +86,20 @@ public class ChainProcessingContext { @@ -85,8 +86,20 @@ public class ChainProcessingContext {
85 return md.inMsg; 86 return md.inMsg;
86 } 87 }
87 88
  89 + public DeviceMetaData getDeviceMetaData() {
  90 + return md.deviceMetaData;
  91 + }
  92 +
  93 + public String getDeviceName() {
  94 + return md.deviceMetaData.getDeviceName();
  95 + }
  96 +
  97 + public String getDeviceType() {
  98 + return md.deviceMetaData.getDeviceType();
  99 + }
  100 +
88 public DeviceAttributes getAttributes() { 101 public DeviceAttributes getAttributes() {
89 - return md.deviceAttributes; 102 + return md.deviceMetaData.getDeviceAttributes();
90 } 103 }
91 104
92 public ToDeviceMsg getResponse() { 105 public ToDeviceMsg getResponse() {
@@ -15,10 +15,9 @@ @@ -15,10 +15,9 @@
15 */ 15 */
16 package org.thingsboard.server.actors.rule; 16 package org.thingsboard.server.actors.rule;
17 17
18 -import org.thingsboard.server.extensions.api.device.DeviceAttributes;  
19 -import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;  
20 -  
21 import akka.actor.ActorRef; 18 import akka.actor.ActorRef;
  19 +import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
  20 +import org.thingsboard.server.extensions.api.device.DeviceMetaData;
22 21
23 /** 22 /**
24 * Immutable part of chain processing data; 23 * Immutable part of chain processing data;
@@ -30,13 +29,13 @@ public final class ChainProcessingMetaData { @@ -30,13 +29,13 @@ public final class ChainProcessingMetaData {
30 final RuleActorChain chain; 29 final RuleActorChain chain;
31 final ToDeviceActorMsg inMsg; 30 final ToDeviceActorMsg inMsg;
32 final ActorRef originator; 31 final ActorRef originator;
33 - final DeviceAttributes deviceAttributes; 32 + final DeviceMetaData deviceMetaData;
34 33
35 - public ChainProcessingMetaData(RuleActorChain chain, ToDeviceActorMsg inMsg, DeviceAttributes deviceAttributes, ActorRef originator) { 34 + public ChainProcessingMetaData(RuleActorChain chain, ToDeviceActorMsg inMsg, DeviceMetaData deviceMetaData, ActorRef originator) {
36 super(); 35 super();
37 this.chain = chain; 36 this.chain = chain;
38 this.inMsg = inMsg; 37 this.inMsg = inMsg;
39 this.originator = originator; 38 this.originator = originator;
40 - this.deviceAttributes = deviceAttributes; 39 + this.deviceMetaData = deviceMetaData;
41 } 40 }
42 } 41 }
@@ -144,7 +144,7 @@ class RuleActorMessageProcessor extends ComponentMsgProcessor<RuleId> { @@ -144,7 +144,7 @@ class RuleActorMessageProcessor extends ComponentMsgProcessor<RuleId> {
144 ChainProcessingContext chainCtx = msg.getCtx(); 144 ChainProcessingContext chainCtx = msg.getCtx();
145 ToDeviceActorMsg inMsg = chainCtx.getInMsg(); 145 ToDeviceActorMsg inMsg = chainCtx.getInMsg();
146 146
147 - ruleCtx.update(inMsg, chainCtx.getAttributes()); 147 + ruleCtx.update(inMsg, chainCtx.getDeviceMetaData());
148 148
149 logger.debug("[{}] Going to filter in msg: {}", entityId, inMsg); 149 logger.debug("[{}] Going to filter in msg: {}", entityId, inMsg);
150 for (RuleFilter filter : filters) { 150 for (RuleFilter filter : filters) {
@@ -22,6 +22,7 @@ import org.thingsboard.server.dao.event.EventService; @@ -22,6 +22,7 @@ import org.thingsboard.server.dao.event.EventService;
22 import org.thingsboard.server.dao.timeseries.TimeseriesService; 22 import org.thingsboard.server.dao.timeseries.TimeseriesService;
23 import org.thingsboard.server.extensions.api.device.DeviceAttributes; 23 import org.thingsboard.server.extensions.api.device.DeviceAttributes;
24 import org.thingsboard.server.common.msg.device.ToDeviceActorMsg; 24 import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
  25 +import org.thingsboard.server.extensions.api.device.DeviceMetaData;
25 import org.thingsboard.server.extensions.api.rules.RuleContext; 26 import org.thingsboard.server.extensions.api.rules.RuleContext;
26 27
27 import java.util.Optional; 28 import java.util.Optional;
@@ -34,7 +35,7 @@ public class RuleProcessingContext implements RuleContext { @@ -34,7 +35,7 @@ public class RuleProcessingContext implements RuleContext {
34 private TenantId tenantId; 35 private TenantId tenantId;
35 private CustomerId customerId; 36 private CustomerId customerId;
36 private DeviceId deviceId; 37 private DeviceId deviceId;
37 - private DeviceAttributes deviceAttributes; 38 + private DeviceMetaData deviceMetaData;
38 39
39 RuleProcessingContext(ActorSystemContext systemContext, RuleId ruleId) { 40 RuleProcessingContext(ActorSystemContext systemContext, RuleId ruleId) {
40 this.tsService = systemContext.getTsService(); 41 this.tsService = systemContext.getTsService();
@@ -42,11 +43,11 @@ public class RuleProcessingContext implements RuleContext { @@ -42,11 +43,11 @@ public class RuleProcessingContext implements RuleContext {
42 this.ruleId = ruleId; 43 this.ruleId = ruleId;
43 } 44 }
44 45
45 - void update(ToDeviceActorMsg toDeviceActorMsg, DeviceAttributes attributes) { 46 + void update(ToDeviceActorMsg toDeviceActorMsg, DeviceMetaData deviceMetaData) {
46 this.tenantId = toDeviceActorMsg.getTenantId(); 47 this.tenantId = toDeviceActorMsg.getTenantId();
47 this.customerId = toDeviceActorMsg.getCustomerId(); 48 this.customerId = toDeviceActorMsg.getCustomerId();
48 this.deviceId = toDeviceActorMsg.getDeviceId(); 49 this.deviceId = toDeviceActorMsg.getDeviceId();
49 - this.deviceAttributes = attributes; 50 + this.deviceMetaData = deviceMetaData;
50 } 51 }
51 52
52 @Override 53 @Override
@@ -55,8 +56,8 @@ public class RuleProcessingContext implements RuleContext { @@ -55,8 +56,8 @@ public class RuleProcessingContext implements RuleContext {
55 } 56 }
56 57
57 @Override 58 @Override
58 - public DeviceAttributes getDeviceAttributes() {  
59 - return deviceAttributes; 59 + public DeviceMetaData getDeviceMetaData() {
  60 + return deviceMetaData;
60 } 61 }
61 62
62 @Override 63 @Override
  1 +/**
  2 + * Copyright © 2016-2017 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.extensions.api.device;
  17 +
  18 +import lombok.Data;
  19 +import org.thingsboard.server.common.data.id.DeviceId;
  20 +
  21 +/**
  22 + * Contains basic device metadata;
  23 + *
  24 + * @author ashvayka
  25 + */
  26 +@Data
  27 +public final class DeviceMetaData {
  28 +
  29 + final DeviceId deviceId;
  30 + final String deviceName;
  31 + final String deviceType;
  32 + final DeviceAttributes deviceAttributes;
  33 +
  34 +}
@@ -18,6 +18,7 @@ package org.thingsboard.server.extensions.api.rules; @@ -18,6 +18,7 @@ package org.thingsboard.server.extensions.api.rules;
18 import org.thingsboard.server.common.data.Event; 18 import org.thingsboard.server.common.data.Event;
19 import org.thingsboard.server.common.data.id.RuleId; 19 import org.thingsboard.server.common.data.id.RuleId;
20 import org.thingsboard.server.extensions.api.device.DeviceAttributes; 20 import org.thingsboard.server.extensions.api.device.DeviceAttributes;
  21 +import org.thingsboard.server.extensions.api.device.DeviceMetaData;
21 22
22 import java.util.Optional; 23 import java.util.Optional;
23 24
@@ -25,7 +26,7 @@ public interface RuleContext { @@ -25,7 +26,7 @@ public interface RuleContext {
25 26
26 RuleId getRuleId(); 27 RuleId getRuleId();
27 28
28 - DeviceAttributes getDeviceAttributes(); 29 + DeviceMetaData getDeviceMetaData();
29 30
30 Event save(Event event); 31 Event save(Event event);
31 32
@@ -71,8 +71,8 @@ public abstract class AbstractTemplatePluginAction<T extends TemplateActionConfi @@ -71,8 +71,8 @@ public abstract class AbstractTemplatePluginAction<T extends TemplateActionConfi
71 } 71 }
72 72
73 protected String getMsgBody(RuleContext ctx, ToDeviceActorMsg msg) { 73 protected String getMsgBody(RuleContext ctx, ToDeviceActorMsg msg) {
74 - log.trace("Creating context for: {} and payload {}", ctx.getDeviceAttributes(), msg.getPayload());  
75 - VelocityContext context = VelocityUtils.createContext(ctx.getDeviceAttributes(), msg.getPayload()); 74 + log.trace("Creating context for: {} and payload {}", ctx.getDeviceMetaData(), msg.getPayload());
  75 + VelocityContext context = VelocityUtils.createContext(ctx.getDeviceMetaData(), msg.getPayload());
76 return VelocityUtils.merge(template, context); 76 return VelocityUtils.merge(template, context);
77 } 77 }
78 78
@@ -46,7 +46,7 @@ public class DeviceAttributesFilter extends BasicJsFilter { @@ -46,7 +46,7 @@ public class DeviceAttributesFilter extends BasicJsFilter {
46 46
47 @Override 47 @Override
48 protected boolean doFilter(RuleContext ctx, ToDeviceActorMsg msg) throws ScriptException { 48 protected boolean doFilter(RuleContext ctx, ToDeviceActorMsg msg) throws ScriptException {
49 - return evaluator.execute(toBindings(ctx.getDeviceAttributes(), msg != null ? msg.getPayload() : null)); 49 + return evaluator.execute(toBindings(ctx.getDeviceMetaData().getDeviceAttributes(), msg != null ? msg.getPayload() : null));
50 } 50 }
51 51
52 private Bindings toBindings(DeviceAttributes attributes, FromDeviceMsg msg) { 52 private Bindings toBindings(DeviceAttributes attributes, FromDeviceMsg msg) {
  1 +/**
  2 + * Copyright © 2016-2017 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.extensions.core.filter;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.thingsboard.server.common.msg.core.ToServerRpcRequestMsg;
  20 +import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
  21 +import org.thingsboard.server.extensions.api.component.Filter;
  22 +import org.thingsboard.server.extensions.api.rules.RuleContext;
  23 +import org.thingsboard.server.extensions.api.rules.RuleFilter;
  24 +import org.thingsboard.server.extensions.api.rules.SimpleRuleLifecycleComponent;
  25 +
  26 +import java.util.Arrays;
  27 +import java.util.Set;
  28 +import java.util.stream.Collectors;
  29 +
  30 +import static org.thingsboard.server.common.msg.session.MsgType.TO_SERVER_RPC_REQUEST;
  31 +
  32 +/**
  33 + * @author Andrew Shvayka
  34 + */
  35 +@Filter(name = "Device Type Filter", descriptor = "DeviceTypeFilterDescriptor.json", configuration = DeviceTypeFilterConfiguration.class)
  36 +@Slf4j
  37 +public class DeviceTypeFilter extends SimpleRuleLifecycleComponent implements RuleFilter<DeviceTypeFilterConfiguration> {
  38 +
  39 + private Set<String> deviceTypes;
  40 +
  41 + @Override
  42 + public void init(DeviceTypeFilterConfiguration configuration) {
  43 + deviceTypes = Arrays.stream(configuration.getDeviceTypes())
  44 + .map(m -> m.getName())
  45 + .collect(Collectors.toSet());
  46 + }
  47 +
  48 + @Override
  49 + public boolean filter(RuleContext ctx, ToDeviceActorMsg msg) {
  50 + return deviceTypes.contains(ctx.getDeviceMetaData().getDeviceType());
  51 + }
  52 +}
  1 +/**
  2 + * Copyright © 2016-2017 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.extensions.core.filter;
  17 +
  18 +import lombok.Data;
  19 +
  20 +/**
  21 + * @author Andrew Shvayka
  22 + */
  23 +@Data
  24 +public class DeviceTypeFilterConfiguration {
  25 +
  26 + private DeviceTypeName[] deviceTypes;
  27 +
  28 + @Data
  29 + public static class DeviceTypeName {
  30 + private String name;
  31 + }
  32 +
  33 +}
@@ -59,7 +59,7 @@ public class AlarmDeduplicationProcessor extends SimpleRuleLifecycleComponent @@ -59,7 +59,7 @@ public class AlarmDeduplicationProcessor extends SimpleRuleLifecycleComponent
59 @Override 59 @Override
60 public RuleProcessingMetaData process(RuleContext ctx, ToDeviceActorMsg msg) throws RuleException { 60 public RuleProcessingMetaData process(RuleContext ctx, ToDeviceActorMsg msg) throws RuleException {
61 RuleProcessingMetaData md = new RuleProcessingMetaData(); 61 RuleProcessingMetaData md = new RuleProcessingMetaData();
62 - VelocityContext context = VelocityUtils.createContext(ctx.getDeviceAttributes(), msg.getPayload()); 62 + VelocityContext context = VelocityUtils.createContext(ctx.getDeviceMetaData(), msg.getPayload());
63 String alarmId = VelocityUtils.merge(alarmIdTemplate, context); 63 String alarmId = VelocityUtils.merge(alarmIdTemplate, context);
64 String alarmBody = VelocityUtils.merge(alarmBodyTemplate, context); 64 String alarmBody = VelocityUtils.merge(alarmBodyTemplate, context);
65 Optional<Event> existingEvent = ctx.findEvent(DataConstants.ALARM, alarmId); 65 Optional<Event> existingEvent = ctx.findEvent(DataConstants.ALARM, alarmId);
@@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry; @@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
27 import org.thingsboard.server.common.msg.core.TelemetryUploadRequest; 27 import org.thingsboard.server.common.msg.core.TelemetryUploadRequest;
28 import org.thingsboard.server.common.msg.session.FromDeviceMsg; 28 import org.thingsboard.server.common.msg.session.FromDeviceMsg;
29 import org.thingsboard.server.extensions.api.device.DeviceAttributes; 29 import org.thingsboard.server.extensions.api.device.DeviceAttributes;
  30 +import org.thingsboard.server.extensions.api.device.DeviceMetaData;
30 import org.thingsboard.server.extensions.api.rules.RuleProcessingMetaData; 31 import org.thingsboard.server.extensions.api.rules.RuleProcessingMetaData;
31 import org.thingsboard.server.extensions.core.filter.DeviceAttributesFilter; 32 import org.thingsboard.server.extensions.core.filter.DeviceAttributesFilter;
32 33
@@ -64,9 +65,11 @@ public class VelocityUtils { @@ -64,9 +65,11 @@ public class VelocityUtils {
64 return context; 65 return context;
65 } 66 }
66 67
67 - public static VelocityContext createContext(DeviceAttributes deviceAttributes, FromDeviceMsg payload) { 68 + public static VelocityContext createContext(DeviceMetaData deviceMetaData, FromDeviceMsg payload) {
68 VelocityContext context = new VelocityContext(); 69 VelocityContext context = new VelocityContext();
69 context.put("date", new DateTool()); 70 context.put("date", new DateTool());
  71 + DeviceAttributes deviceAttributes = deviceMetaData.getDeviceAttributes();
  72 +
70 pushAttributes(context, deviceAttributes.getClientSideAttributes(), DeviceAttributesFilter.CLIENT_SIDE); 73 pushAttributes(context, deviceAttributes.getClientSideAttributes(), DeviceAttributesFilter.CLIENT_SIDE);
71 pushAttributes(context, deviceAttributes.getServerSideAttributes(), DeviceAttributesFilter.SERVER_SIDE); 74 pushAttributes(context, deviceAttributes.getServerSideAttributes(), DeviceAttributesFilter.SERVER_SIDE);
72 pushAttributes(context, deviceAttributes.getServerSidePublicAttributes(), DeviceAttributesFilter.SHARED); 75 pushAttributes(context, deviceAttributes.getServerSidePublicAttributes(), DeviceAttributesFilter.SHARED);
@@ -77,6 +80,10 @@ public class VelocityUtils { @@ -77,6 +80,10 @@ public class VelocityUtils {
77 break; 80 break;
78 } 81 }
79 82
  83 + context.put("deviceId", deviceMetaData.getDeviceId().getId().toString());
  84 + context.put("deviceName", deviceMetaData.getDeviceName());
  85 + context.put("deviceType", deviceMetaData.getDeviceType());
  86 +
80 return context; 87 return context;
81 } 88 }
82 89
  1 +{
  2 + "schema": {
  3 + "title": "Device Type Filter Configuration",
  4 + "type": "object",
  5 + "properties": {
  6 + "deviceTypes": {
  7 + "title": "Device types",
  8 + "type": "array",
  9 + "minItems" : 1,
  10 + "items": {
  11 + "type": "object",
  12 + "title": "Device Type",
  13 + "properties": {
  14 + "name": {
  15 + "title": "Device Type",
  16 + "type": "string"
  17 + }
  18 + }
  19 + },
  20 + "uniqueItems": true
  21 + }
  22 + },
  23 + "required": ["deviceTypes"]
  24 + },
  25 + "form": [
  26 + "deviceTypes"
  27 + ]
  28 +}
@@ -15,11 +15,13 @@ @@ -15,11 +15,13 @@
15 */ 15 */
16 package org.thingsboard.server.extensions.core.filter; 16 package org.thingsboard.server.extensions.core.filter;
17 17
  18 +import org.thingsboard.server.common.data.id.DeviceId;
18 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 19 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
19 import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; 20 import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
20 import org.thingsboard.server.common.data.kv.BooleanDataEntry; 21 import org.thingsboard.server.common.data.kv.BooleanDataEntry;
21 import org.thingsboard.server.common.data.kv.DoubleDataEntry; 22 import org.thingsboard.server.common.data.kv.DoubleDataEntry;
22 import org.thingsboard.server.extensions.api.device.DeviceAttributes; 23 import org.thingsboard.server.extensions.api.device.DeviceAttributes;
  24 +import org.thingsboard.server.extensions.api.device.DeviceMetaData;
23 import org.thingsboard.server.extensions.api.rules.RuleContext; 25 import org.thingsboard.server.extensions.api.rules.RuleContext;
24 import org.junit.Assert; 26 import org.junit.Assert;
25 import org.junit.Test; 27 import org.junit.Test;
@@ -30,6 +32,7 @@ import org.mockito.runners.MockitoJUnitRunner; @@ -30,6 +32,7 @@ import org.mockito.runners.MockitoJUnitRunner;
30 32
31 import java.util.ArrayList; 33 import java.util.ArrayList;
32 import java.util.List; 34 import java.util.List;
  35 +import java.util.UUID;
33 36
34 /** 37 /**
35 * @author Andrew Shvayka 38 * @author Andrew Shvayka
@@ -52,7 +55,7 @@ public class DeviceAttributesFilterTest { @@ -52,7 +55,7 @@ public class DeviceAttributesFilterTest {
52 clientAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42)); 55 clientAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42));
53 DeviceAttributes attributes = new DeviceAttributes(clientAttributes, new ArrayList<>(), new ArrayList<>()); 56 DeviceAttributes attributes = new DeviceAttributes(clientAttributes, new ArrayList<>(), new ArrayList<>());
54 57
55 - Mockito.when(ruleCtx.getDeviceAttributes()).thenReturn(attributes); 58 + Mockito.when(ruleCtx.getDeviceMetaData()).thenReturn(new DeviceMetaData(new DeviceId(UUID.randomUUID()), "A", "A", attributes));
56 Assert.assertTrue(filter.filter(ruleCtx, null)); 59 Assert.assertTrue(filter.filter(ruleCtx, null));
57 filter.stop(); 60 filter.stop();
58 } 61 }
@@ -66,7 +69,7 @@ public class DeviceAttributesFilterTest { @@ -66,7 +69,7 @@ public class DeviceAttributesFilterTest {
66 clientAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42)); 69 clientAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42));
67 DeviceAttributes attributes = new DeviceAttributes(clientAttributes, new ArrayList<>(), new ArrayList<>()); 70 DeviceAttributes attributes = new DeviceAttributes(clientAttributes, new ArrayList<>(), new ArrayList<>());
68 71
69 - Mockito.when(ruleCtx.getDeviceAttributes()).thenReturn(attributes); 72 + Mockito.when(ruleCtx.getDeviceMetaData()).thenReturn(new DeviceMetaData(new DeviceId(UUID.randomUUID()), "A", "A", attributes));
70 Assert.assertTrue(filter.filter(ruleCtx, null)); 73 Assert.assertTrue(filter.filter(ruleCtx, null));
71 filter.stop(); 74 filter.stop();
72 } 75 }
@@ -81,7 +84,7 @@ public class DeviceAttributesFilterTest { @@ -81,7 +84,7 @@ public class DeviceAttributesFilterTest {
81 clientAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42)); 84 clientAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42));
82 DeviceAttributes attributes = new DeviceAttributes(clientAttributes, new ArrayList<>(), new ArrayList<>()); 85 DeviceAttributes attributes = new DeviceAttributes(clientAttributes, new ArrayList<>(), new ArrayList<>());
83 86
84 - Mockito.when(ruleCtx.getDeviceAttributes()).thenReturn(attributes); 87 + Mockito.when(ruleCtx.getDeviceMetaData()).thenReturn(new DeviceMetaData(new DeviceId(UUID.randomUUID()), "A", "A", attributes));
85 88
86 for (int i = 0; i < 10000; i++) { 89 for (int i = 0; i < 10000; i++) {
87 Assert.assertTrue(filter.filter(ruleCtx, null)); 90 Assert.assertTrue(filter.filter(ruleCtx, null));
@@ -99,7 +102,7 @@ public class DeviceAttributesFilterTest { @@ -99,7 +102,7 @@ public class DeviceAttributesFilterTest {
99 serverAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42)); 102 serverAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42));
100 DeviceAttributes attributes = new DeviceAttributes(new ArrayList<>(), serverAttributes, new ArrayList<>()); 103 DeviceAttributes attributes = new DeviceAttributes(new ArrayList<>(), serverAttributes, new ArrayList<>());
101 104
102 - Mockito.when(ruleCtx.getDeviceAttributes()).thenReturn(attributes); 105 + Mockito.when(ruleCtx.getDeviceMetaData()).thenReturn(new DeviceMetaData(new DeviceId(UUID.randomUUID()), "A", "A", attributes));
103 Assert.assertTrue(filter.filter(ruleCtx, null)); 106 Assert.assertTrue(filter.filter(ruleCtx, null));
104 filter.stop(); 107 filter.stop();
105 } 108 }
@@ -118,7 +121,7 @@ public class DeviceAttributesFilterTest { @@ -118,7 +121,7 @@ public class DeviceAttributesFilterTest {
118 serverAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42)); 121 serverAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42));
119 DeviceAttributes attributes = new DeviceAttributes(clientAttributes, serverAttributes, new ArrayList<>()); 122 DeviceAttributes attributes = new DeviceAttributes(clientAttributes, serverAttributes, new ArrayList<>());
120 123
121 - Mockito.when(ruleCtx.getDeviceAttributes()).thenReturn(attributes); 124 + Mockito.when(ruleCtx.getDeviceMetaData()).thenReturn(new DeviceMetaData(new DeviceId(UUID.randomUUID()), "A", "A", attributes));
122 Assert.assertTrue(filter.filter(ruleCtx, null)); 125 Assert.assertTrue(filter.filter(ruleCtx, null));
123 filter.stop(); 126 filter.stop();
124 } 127 }