Merge pull request #183 from thingsboard/feature/TB-67
TB-67: Add new filter to rule engine based on device type
This commit is contained in:
		
						commit
						912cffc3b1
					
				@ -19,13 +19,11 @@ import akka.actor.ActorContext;
 | 
			
		||||
import akka.actor.ActorRef;
 | 
			
		||||
import akka.event.LoggingAdapter;
 | 
			
		||||
import org.thingsboard.server.actors.ActorSystemContext;
 | 
			
		||||
import org.thingsboard.server.actors.rule.ChainProcessingContext;
 | 
			
		||||
import org.thingsboard.server.actors.rule.ChainProcessingMetaData;
 | 
			
		||||
import org.thingsboard.server.actors.rule.RuleProcessingMsg;
 | 
			
		||||
import org.thingsboard.server.actors.rule.RulesProcessedMsg;
 | 
			
		||||
import org.thingsboard.server.actors.rule.*;
 | 
			
		||||
import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
 | 
			
		||||
import org.thingsboard.server.actors.tenant.RuleChainDeviceMsg;
 | 
			
		||||
import org.thingsboard.server.common.data.DataConstants;
 | 
			
		||||
import org.thingsboard.server.common.data.Device;
 | 
			
		||||
import org.thingsboard.server.common.data.id.DeviceId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.SessionId;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.AttributeKey;
 | 
			
		||||
@ -42,6 +40,7 @@ import org.thingsboard.server.common.msg.session.ToDeviceMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributes;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceMetaData;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.msg.RpcError;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.msg.TimeoutIntMsg;
 | 
			
		||||
@ -71,6 +70,8 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
 | 
			
		||||
    private final Map<Integer, ToDeviceRpcRequestMetadata> rpcPendingMap;
 | 
			
		||||
 | 
			
		||||
    private int rpcSeq = 0;
 | 
			
		||||
    private String deviceName;
 | 
			
		||||
    private String deviceType;
 | 
			
		||||
    private DeviceAttributes deviceAttributes;
 | 
			
		||||
 | 
			
		||||
    public DeviceActorMessageProcessor(ActorSystemContext systemContext, LoggingAdapter logger, DeviceId deviceId) {
 | 
			
		||||
@ -84,6 +85,10 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initAttributes() {
 | 
			
		||||
        //TODO: add invalidation of deviceType cache.
 | 
			
		||||
        Device device = systemContext.getDeviceService().findDeviceById(deviceId);
 | 
			
		||||
        this.deviceName = device.getName();
 | 
			
		||||
        this.deviceType = device.getType();
 | 
			
		||||
        this.deviceAttributes = new DeviceAttributes(fetchAttributes(DataConstants.CLIENT_SCOPE),
 | 
			
		||||
                fetchAttributes(DataConstants.SERVER_SCOPE), fetchAttributes(DataConstants.SHARED_SCOPE));
 | 
			
		||||
    }
 | 
			
		||||
@ -230,7 +235,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
 | 
			
		||||
 | 
			
		||||
    void process(ActorContext context, RuleChainDeviceMsg srcMsg) {
 | 
			
		||||
        ChainProcessingMetaData md = new ChainProcessingMetaData(srcMsg.getRuleChain(),
 | 
			
		||||
                srcMsg.getToDeviceActorMsg(), deviceAttributes, context.self());
 | 
			
		||||
                srcMsg.getToDeviceActorMsg(), new DeviceMetaData(deviceId, deviceName, deviceType, deviceAttributes), context.self());
 | 
			
		||||
        ChainProcessingContext ctx = new ChainProcessingContext(md);
 | 
			
		||||
        if (ctx.getChainLength() > 0) {
 | 
			
		||||
            RuleProcessingMsg msg = new RuleProcessingMsg(ctx);
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@ import org.thingsboard.server.common.msg.core.RuleEngineErrorMsg;
 | 
			
		||||
import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
 | 
			
		||||
import org.thingsboard.server.common.msg.session.ToDeviceMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributes;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceMetaData;
 | 
			
		||||
 | 
			
		||||
public class ChainProcessingContext {
 | 
			
		||||
 | 
			
		||||
@ -85,8 +86,20 @@ public class ChainProcessingContext {
 | 
			
		||||
        return md.inMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeviceMetaData getDeviceMetaData() {
 | 
			
		||||
        return md.deviceMetaData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getDeviceName() {
 | 
			
		||||
        return md.deviceMetaData.getDeviceName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getDeviceType() {
 | 
			
		||||
        return md.deviceMetaData.getDeviceType();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeviceAttributes getAttributes() {
 | 
			
		||||
        return md.deviceAttributes;
 | 
			
		||||
        return md.deviceMetaData.getDeviceAttributes();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ToDeviceMsg getResponse() {
 | 
			
		||||
 | 
			
		||||
@ -15,10 +15,9 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.actors.rule;
 | 
			
		||||
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributes;
 | 
			
		||||
import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
 | 
			
		||||
 | 
			
		||||
import akka.actor.ActorRef;
 | 
			
		||||
import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceMetaData;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Immutable part of chain processing data;
 | 
			
		||||
@ -30,13 +29,13 @@ public final class ChainProcessingMetaData {
 | 
			
		||||
    final RuleActorChain chain;
 | 
			
		||||
    final ToDeviceActorMsg inMsg;
 | 
			
		||||
    final ActorRef originator;
 | 
			
		||||
    final DeviceAttributes deviceAttributes;
 | 
			
		||||
    final DeviceMetaData deviceMetaData;
 | 
			
		||||
 | 
			
		||||
    public ChainProcessingMetaData(RuleActorChain chain, ToDeviceActorMsg inMsg, DeviceAttributes deviceAttributes, ActorRef originator) {
 | 
			
		||||
    public ChainProcessingMetaData(RuleActorChain chain, ToDeviceActorMsg inMsg, DeviceMetaData deviceMetaData, ActorRef originator) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.chain = chain;
 | 
			
		||||
        this.inMsg = inMsg;
 | 
			
		||||
        this.originator = originator;
 | 
			
		||||
        this.deviceAttributes = deviceAttributes;
 | 
			
		||||
        this.deviceMetaData = deviceMetaData;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -144,7 +144,7 @@ class RuleActorMessageProcessor extends ComponentMsgProcessor<RuleId> {
 | 
			
		||||
        ChainProcessingContext chainCtx = msg.getCtx();
 | 
			
		||||
        ToDeviceActorMsg inMsg = chainCtx.getInMsg();
 | 
			
		||||
 | 
			
		||||
        ruleCtx.update(inMsg, chainCtx.getAttributes());
 | 
			
		||||
        ruleCtx.update(inMsg, chainCtx.getDeviceMetaData());
 | 
			
		||||
 | 
			
		||||
        logger.debug("[{}] Going to filter in msg: {}", entityId, inMsg);
 | 
			
		||||
        for (RuleFilter filter : filters) {
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@ import org.thingsboard.server.dao.event.EventService;
 | 
			
		||||
import org.thingsboard.server.dao.timeseries.TimeseriesService;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributes;
 | 
			
		||||
import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceMetaData;
 | 
			
		||||
import org.thingsboard.server.extensions.api.rules.RuleContext;
 | 
			
		||||
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
@ -34,7 +35,7 @@ public class RuleProcessingContext implements RuleContext {
 | 
			
		||||
    private TenantId tenantId;
 | 
			
		||||
    private CustomerId customerId;
 | 
			
		||||
    private DeviceId deviceId;
 | 
			
		||||
    private DeviceAttributes deviceAttributes;
 | 
			
		||||
    private DeviceMetaData deviceMetaData;
 | 
			
		||||
 | 
			
		||||
    RuleProcessingContext(ActorSystemContext systemContext, RuleId ruleId) {
 | 
			
		||||
        this.tsService = systemContext.getTsService();
 | 
			
		||||
@ -42,11 +43,11 @@ public class RuleProcessingContext implements RuleContext {
 | 
			
		||||
        this.ruleId = ruleId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void update(ToDeviceActorMsg toDeviceActorMsg, DeviceAttributes attributes) {
 | 
			
		||||
    void update(ToDeviceActorMsg toDeviceActorMsg, DeviceMetaData deviceMetaData) {
 | 
			
		||||
        this.tenantId = toDeviceActorMsg.getTenantId();
 | 
			
		||||
        this.customerId = toDeviceActorMsg.getCustomerId();
 | 
			
		||||
        this.deviceId = toDeviceActorMsg.getDeviceId();
 | 
			
		||||
        this.deviceAttributes = attributes;
 | 
			
		||||
        this.deviceMetaData = deviceMetaData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -55,8 +56,8 @@ public class RuleProcessingContext implements RuleContext {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public DeviceAttributes getDeviceAttributes() {
 | 
			
		||||
        return deviceAttributes;
 | 
			
		||||
    public DeviceMetaData getDeviceMetaData() {
 | 
			
		||||
        return deviceMetaData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,34 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2017 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.extensions.api.device;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import org.thingsboard.server.common.data.id.DeviceId;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Contains basic device metadata;
 | 
			
		||||
 *
 | 
			
		||||
 * @author ashvayka
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
public final class DeviceMetaData {
 | 
			
		||||
 | 
			
		||||
    final DeviceId deviceId;
 | 
			
		||||
    final String deviceName;
 | 
			
		||||
    final String deviceType;
 | 
			
		||||
    final DeviceAttributes deviceAttributes;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -18,6 +18,7 @@ package org.thingsboard.server.extensions.api.rules;
 | 
			
		||||
import org.thingsboard.server.common.data.Event;
 | 
			
		||||
import org.thingsboard.server.common.data.id.RuleId;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributes;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceMetaData;
 | 
			
		||||
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
@ -25,7 +26,7 @@ public interface RuleContext {
 | 
			
		||||
 | 
			
		||||
    RuleId getRuleId();
 | 
			
		||||
 | 
			
		||||
    DeviceAttributes getDeviceAttributes();
 | 
			
		||||
    DeviceMetaData getDeviceMetaData();
 | 
			
		||||
 | 
			
		||||
    Event save(Event event);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -71,8 +71,8 @@ public abstract class AbstractTemplatePluginAction<T extends TemplateActionConfi
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected String getMsgBody(RuleContext ctx, ToDeviceActorMsg msg) {
 | 
			
		||||
        log.trace("Creating context for: {} and payload {}", ctx.getDeviceAttributes(), msg.getPayload());
 | 
			
		||||
        VelocityContext context = VelocityUtils.createContext(ctx.getDeviceAttributes(), msg.getPayload());
 | 
			
		||||
        log.trace("Creating context for: {} and payload {}", ctx.getDeviceMetaData(), msg.getPayload());
 | 
			
		||||
        VelocityContext context = VelocityUtils.createContext(ctx.getDeviceMetaData(), msg.getPayload());
 | 
			
		||||
        return VelocityUtils.merge(template, context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,7 @@ public class DeviceAttributesFilter extends BasicJsFilter {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected boolean doFilter(RuleContext ctx, ToDeviceActorMsg msg) throws ScriptException {
 | 
			
		||||
        return evaluator.execute(toBindings(ctx.getDeviceAttributes(), msg != null ? msg.getPayload() : null));
 | 
			
		||||
        return evaluator.execute(toBindings(ctx.getDeviceMetaData().getDeviceAttributes(), msg != null ? msg.getPayload() : null));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Bindings toBindings(DeviceAttributes attributes, FromDeviceMsg msg) {
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,52 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2017 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.extensions.core.filter;
 | 
			
		||||
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.thingsboard.server.common.msg.core.ToServerRpcRequestMsg;
 | 
			
		||||
import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.component.Filter;
 | 
			
		||||
import org.thingsboard.server.extensions.api.rules.RuleContext;
 | 
			
		||||
import org.thingsboard.server.extensions.api.rules.RuleFilter;
 | 
			
		||||
import org.thingsboard.server.extensions.api.rules.SimpleRuleLifecycleComponent;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
import static org.thingsboard.server.common.msg.session.MsgType.TO_SERVER_RPC_REQUEST;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Andrew Shvayka
 | 
			
		||||
 */
 | 
			
		||||
@Filter(name = "Device Type Filter", descriptor = "DeviceTypeFilterDescriptor.json", configuration = DeviceTypeFilterConfiguration.class)
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class DeviceTypeFilter extends SimpleRuleLifecycleComponent implements RuleFilter<DeviceTypeFilterConfiguration> {
 | 
			
		||||
 | 
			
		||||
    private Set<String> deviceTypes;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void init(DeviceTypeFilterConfiguration configuration) {
 | 
			
		||||
        deviceTypes = Arrays.stream(configuration.getDeviceTypes())
 | 
			
		||||
                .map(m -> m.getName())
 | 
			
		||||
                .collect(Collectors.toSet());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean filter(RuleContext ctx, ToDeviceActorMsg msg) {
 | 
			
		||||
        return deviceTypes.contains(ctx.getDeviceMetaData().getDeviceType());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,33 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2017 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.extensions.core.filter;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Andrew Shvayka
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
public class DeviceTypeFilterConfiguration {
 | 
			
		||||
 | 
			
		||||
    private DeviceTypeName[] deviceTypes;
 | 
			
		||||
 | 
			
		||||
    @Data
 | 
			
		||||
    public static class DeviceTypeName {
 | 
			
		||||
        private String name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -59,7 +59,7 @@ public class AlarmDeduplicationProcessor extends SimpleRuleLifecycleComponent
 | 
			
		||||
    @Override
 | 
			
		||||
    public RuleProcessingMetaData process(RuleContext ctx, ToDeviceActorMsg msg) throws RuleException {
 | 
			
		||||
        RuleProcessingMetaData md = new RuleProcessingMetaData();
 | 
			
		||||
        VelocityContext context = VelocityUtils.createContext(ctx.getDeviceAttributes(), msg.getPayload());
 | 
			
		||||
        VelocityContext context = VelocityUtils.createContext(ctx.getDeviceMetaData(), msg.getPayload());
 | 
			
		||||
        String alarmId = VelocityUtils.merge(alarmIdTemplate, context);
 | 
			
		||||
        String alarmBody = VelocityUtils.merge(alarmBodyTemplate, context);
 | 
			
		||||
        Optional<Event> existingEvent = ctx.findEvent(DataConstants.ALARM, alarmId);
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
 | 
			
		||||
import org.thingsboard.server.common.msg.core.TelemetryUploadRequest;
 | 
			
		||||
import org.thingsboard.server.common.msg.session.FromDeviceMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributes;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceMetaData;
 | 
			
		||||
import org.thingsboard.server.extensions.api.rules.RuleProcessingMetaData;
 | 
			
		||||
import org.thingsboard.server.extensions.core.filter.DeviceAttributesFilter;
 | 
			
		||||
 | 
			
		||||
@ -64,9 +65,11 @@ public class VelocityUtils {
 | 
			
		||||
        return context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static VelocityContext createContext(DeviceAttributes deviceAttributes, FromDeviceMsg payload) {
 | 
			
		||||
    public static VelocityContext createContext(DeviceMetaData deviceMetaData, FromDeviceMsg payload) {
 | 
			
		||||
        VelocityContext context = new VelocityContext();
 | 
			
		||||
        context.put("date", new DateTool());
 | 
			
		||||
        DeviceAttributes deviceAttributes = deviceMetaData.getDeviceAttributes();
 | 
			
		||||
 | 
			
		||||
        pushAttributes(context, deviceAttributes.getClientSideAttributes(), DeviceAttributesFilter.CLIENT_SIDE);
 | 
			
		||||
        pushAttributes(context, deviceAttributes.getServerSideAttributes(), DeviceAttributesFilter.SERVER_SIDE);
 | 
			
		||||
        pushAttributes(context, deviceAttributes.getServerSidePublicAttributes(), DeviceAttributesFilter.SHARED);
 | 
			
		||||
@ -77,6 +80,10 @@ public class VelocityUtils {
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        context.put("deviceId", deviceMetaData.getDeviceId().getId().toString());
 | 
			
		||||
        context.put("deviceName", deviceMetaData.getDeviceName());
 | 
			
		||||
        context.put("deviceType", deviceMetaData.getDeviceType());
 | 
			
		||||
 | 
			
		||||
        return context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,28 @@
 | 
			
		||||
{
 | 
			
		||||
  "schema": {
 | 
			
		||||
    "title": "Device Type Filter Configuration",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "properties": {
 | 
			
		||||
      "deviceTypes": {
 | 
			
		||||
        "title": "Device types",
 | 
			
		||||
        "type": "array",
 | 
			
		||||
        "minItems" : 1,
 | 
			
		||||
        "items": {
 | 
			
		||||
          "type": "object",
 | 
			
		||||
          "title": "Device Type",
 | 
			
		||||
          "properties": {
 | 
			
		||||
            "name": {
 | 
			
		||||
              "title": "Device Type",
 | 
			
		||||
              "type": "string"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "uniqueItems": true
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "required": ["deviceTypes"]
 | 
			
		||||
  },
 | 
			
		||||
  "form": [
 | 
			
		||||
    "deviceTypes"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@ -15,11 +15,13 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.extensions.core.filter;
 | 
			
		||||
 | 
			
		||||
import org.thingsboard.server.common.data.id.DeviceId;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.BooleanDataEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.DoubleDataEntry;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributes;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceMetaData;
 | 
			
		||||
import org.thingsboard.server.extensions.api.rules.RuleContext;
 | 
			
		||||
import org.junit.Assert;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
@ -30,6 +32,7 @@ import org.mockito.runners.MockitoJUnitRunner;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Andrew Shvayka
 | 
			
		||||
@ -52,7 +55,7 @@ public class DeviceAttributesFilterTest {
 | 
			
		||||
        clientAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42));
 | 
			
		||||
        DeviceAttributes attributes = new DeviceAttributes(clientAttributes, new ArrayList<>(), new ArrayList<>());
 | 
			
		||||
 | 
			
		||||
        Mockito.when(ruleCtx.getDeviceAttributes()).thenReturn(attributes);
 | 
			
		||||
        Mockito.when(ruleCtx.getDeviceMetaData()).thenReturn(new DeviceMetaData(new DeviceId(UUID.randomUUID()), "A", "A", attributes));
 | 
			
		||||
        Assert.assertTrue(filter.filter(ruleCtx, null));
 | 
			
		||||
        filter.stop();
 | 
			
		||||
    }
 | 
			
		||||
@ -66,7 +69,7 @@ public class DeviceAttributesFilterTest {
 | 
			
		||||
        clientAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42));
 | 
			
		||||
        DeviceAttributes attributes = new DeviceAttributes(clientAttributes, new ArrayList<>(), new ArrayList<>());
 | 
			
		||||
 | 
			
		||||
        Mockito.when(ruleCtx.getDeviceAttributes()).thenReturn(attributes);
 | 
			
		||||
        Mockito.when(ruleCtx.getDeviceMetaData()).thenReturn(new DeviceMetaData(new DeviceId(UUID.randomUUID()), "A", "A", attributes));
 | 
			
		||||
        Assert.assertTrue(filter.filter(ruleCtx, null));
 | 
			
		||||
        filter.stop();
 | 
			
		||||
    }
 | 
			
		||||
@ -81,7 +84,7 @@ public class DeviceAttributesFilterTest {
 | 
			
		||||
        clientAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42));
 | 
			
		||||
        DeviceAttributes attributes = new DeviceAttributes(clientAttributes, new ArrayList<>(), new ArrayList<>());
 | 
			
		||||
 | 
			
		||||
        Mockito.when(ruleCtx.getDeviceAttributes()).thenReturn(attributes);
 | 
			
		||||
        Mockito.when(ruleCtx.getDeviceMetaData()).thenReturn(new DeviceMetaData(new DeviceId(UUID.randomUUID()), "A", "A", attributes));
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < 10000; i++) {
 | 
			
		||||
            Assert.assertTrue(filter.filter(ruleCtx, null));
 | 
			
		||||
@ -99,7 +102,7 @@ public class DeviceAttributesFilterTest {
 | 
			
		||||
        serverAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42));
 | 
			
		||||
        DeviceAttributes attributes = new DeviceAttributes(new ArrayList<>(), serverAttributes, new ArrayList<>());
 | 
			
		||||
 | 
			
		||||
        Mockito.when(ruleCtx.getDeviceAttributes()).thenReturn(attributes);
 | 
			
		||||
        Mockito.when(ruleCtx.getDeviceMetaData()).thenReturn(new DeviceMetaData(new DeviceId(UUID.randomUUID()), "A", "A", attributes));
 | 
			
		||||
        Assert.assertTrue(filter.filter(ruleCtx, null));
 | 
			
		||||
        filter.stop();
 | 
			
		||||
    }
 | 
			
		||||
@ -118,7 +121,7 @@ public class DeviceAttributesFilterTest {
 | 
			
		||||
        serverAttributes.add(new BaseAttributeKvEntry(new BooleanDataEntry("booleanValue", false), 42));
 | 
			
		||||
        DeviceAttributes attributes = new DeviceAttributes(clientAttributes, serverAttributes, new ArrayList<>());
 | 
			
		||||
 | 
			
		||||
        Mockito.when(ruleCtx.getDeviceAttributes()).thenReturn(attributes);
 | 
			
		||||
        Mockito.when(ruleCtx.getDeviceMetaData()).thenReturn(new DeviceMetaData(new DeviceId(UUID.randomUUID()), "A", "A", attributes));
 | 
			
		||||
        Assert.assertTrue(filter.filter(ruleCtx, null));
 | 
			
		||||
        filter.stop();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user