Browse Source

Added rule chain type definition into rule node

pull/2818/head
Volodymyr Babak 7 years ago
parent
commit
24d4aed56c
  1. 23
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  2. 33
      application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java
  3. 54
      application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java
  4. 8
      application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java
  5. 3
      rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java
  6. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNode.java
  7. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java
  8. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java
  9. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java
  10. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java
  11. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java
  12. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java
  13. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java
  14. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbSaveToCustomCassandraTableNode.java
  15. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNode.java
  16. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sns/TbSnsNode.java
  17. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java
  18. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java
  19. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java
  20. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToCloudNode.java
  21. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckMessageNode.java
  22. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java
  23. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsFilterNode.java
  24. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java
  25. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeFilterNode.java
  26. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeSwitchNode.java
  27. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java
  28. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java
  29. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/gcp/pubsub/TbPubSubNode.java
  30. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNode.java
  31. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNode.java
  32. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java
  33. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java
  34. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java
  35. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java
  36. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java
  37. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java
  38. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java
  39. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java
  40. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java
  41. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java
  42. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java
  43. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java
  44. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java
  45. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java
  46. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java
  47. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java
  48. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java
  49. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java
  50. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java
  51. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java
  52. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationEndNode.java
  53. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java
  54. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java
  55. 73
      ui/src/app/api/component-descriptor.service.js
  56. 26
      ui/src/app/api/rule-chain.service.js
  57. 4
      ui/src/app/rulechain/rulechain.controller.js
  58. 10
      ui/src/app/rulechain/rulechain.routes.js
  59. 4
      ui/src/app/services/item-buffer.service.js

23
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -67,6 +67,7 @@ import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
@ -491,28 +492,10 @@ public abstract class BaseController {
}
}
ComponentDescriptor checkComponentDescriptorByClazz(String clazz) throws ThingsboardException {
try {
log.debug("[{}] Lookup component descriptor", clazz);
return checkNotNull(componentDescriptorService.getComponent(clazz));
} catch (Exception e) {
throw handleException(e, false);
}
}
List<ComponentDescriptor> checkComponentDescriptorsByType(ComponentType type) throws ThingsboardException {
try {
log.debug("[{}] Lookup component descriptors", type);
return componentDescriptorService.getComponents(type);
} catch (Exception e) {
throw handleException(e, false);
}
}
List<ComponentDescriptor> checkComponentDescriptorsByTypes(Set<ComponentType> types) throws ThingsboardException {
List<ComponentDescriptor> checkComponentDescriptorsByTypes(Set<ComponentType> types, RuleChainType ruleChainType) throws ThingsboardException {
try {
log.debug("[{}] Lookup component descriptors", types);
return componentDescriptorService.getComponents(types);
return componentDescriptorService.getComponents(types, ruleChainType);
} catch (Exception e) {
throw handleException(e, false);
}

33
application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java

@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import java.util.HashSet;
import java.util.List;
@ -34,41 +35,21 @@ import java.util.Set;
@RequestMapping("/api")
public class ComponentDescriptorController extends BaseController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
@RequestMapping(value = "/component/{componentDescriptorClazz:.+}", method = RequestMethod.GET)
@ResponseBody
public ComponentDescriptor getComponentDescriptorByClazz(@PathVariable("componentDescriptorClazz") String strComponentDescriptorClazz) throws ThingsboardException {
checkParameter("strComponentDescriptorClazz", strComponentDescriptorClazz);
try {
return checkComponentDescriptorByClazz(strComponentDescriptorClazz);
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
@RequestMapping(value = "/components/{componentType}", method = RequestMethod.GET)
@ResponseBody
public List<ComponentDescriptor> getComponentDescriptorsByType(@PathVariable("componentType") String strComponentType) throws ThingsboardException {
checkParameter("componentType", strComponentType);
try {
return checkComponentDescriptorsByType(ComponentType.valueOf(strComponentType));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
@RequestMapping(value = "/components", params = {"componentTypes"}, method = RequestMethod.GET)
@RequestMapping(value = "/components/{ruleChainType}", params = {"componentTypes"}, method = RequestMethod.GET)
@ResponseBody
public List<ComponentDescriptor> getComponentDescriptorsByTypes(@RequestParam("componentTypes") String[] strComponentTypes) throws ThingsboardException {
public List<ComponentDescriptor> getComponentDescriptorsByTypes(@PathVariable("ruleChainType") String strRuleChainType,
@RequestParam("componentTypes") String[] strComponentTypes) throws ThingsboardException {
checkArrayParameter("componentTypes", strComponentTypes);
checkParameter("ruleChainType", strRuleChainType);
try {
RuleChainType ruleChainType = RuleChainType.valueOf(strRuleChainType);
Set<ComponentType> componentTypes = new HashSet<>();
for (String strComponentType : strComponentTypes) {
componentTypes.add(ComponentType.valueOf(strComponentType));
}
return checkComponentDescriptorsByTypes(componentTypes);
return checkComponentDescriptorsByTypes(componentTypes, ruleChainType);
} catch (Exception e) {
throw handleException(e);
}

54
application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java

@ -33,6 +33,7 @@ import org.thingsboard.rule.engine.api.TbRelationTypes;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.dao.component.ComponentDescriptorService;
import javax.annotation.PostConstruct;
@ -64,7 +65,9 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
private Map<String, ComponentDescriptor> components = new HashMap<>();
private Map<ComponentType, List<ComponentDescriptor>> componentsMap = new HashMap<>();
private Map<ComponentType, List<ComponentDescriptor>> systemComponentsMap = new HashMap<>();
private Map<ComponentType, List<ComponentDescriptor>> edgeComponentsMap = new HashMap<>();
private ObjectMapper mapper = new ObjectMapper();
@ -92,7 +95,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
ComponentType type = ruleNodeAnnotation.type();
ComponentDescriptor component = scanAndPersistComponent(def, type);
components.put(component.getClazz(), component);
componentsMap.computeIfAbsent(type, k -> new ArrayList<>()).add(component);
putComponentIntoMaps(type, ruleNodeAnnotation, component);
break;
} catch (Exception e) {
log.trace("Can't initialize component {}, due to {}", def.getBeanClassName(), e.getMessage(), e);
@ -112,22 +115,22 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
}
}
private void registerComponents(ComponentType type, Class<? extends Annotation> annotation) {
List<ComponentDescriptor> components = persist(getBeanDefinitions(annotation), type);
componentsMap.put(type, components);
registerComponents(components);
}
private void registerComponents(Collection<ComponentDescriptor> comps) {
comps.forEach(c -> components.put(c.getClazz(), c));
private void putComponentIntoMaps(ComponentType type, RuleNode ruleNodeAnnotation, ComponentDescriptor component) {
if (ruleChainTypeContainsArray(RuleChainType.SYSTEM, ruleNodeAnnotation.ruleChainTypes())) {
systemComponentsMap.computeIfAbsent(type, k -> new ArrayList<>()).add(component);
}
if (ruleChainTypeContainsArray(RuleChainType.EDGE, ruleNodeAnnotation.ruleChainTypes())) {
edgeComponentsMap.computeIfAbsent(type, k -> new ArrayList<>()).add(component);
}
}
private List<ComponentDescriptor> persist(Set<BeanDefinition> filterDefs, ComponentType type) {
List<ComponentDescriptor> result = new ArrayList<>();
for (BeanDefinition def : filterDefs) {
result.add(scanAndPersistComponent(def, type));
private boolean ruleChainTypeContainsArray(RuleChainType ruleChainType, RuleChainType[] array) {
for (RuleChainType tmp : array) {
if (ruleChainType.equals(tmp)) {
return true;
}
}
return result;
return false;
}
private ComponentDescriptor scanAndPersistComponent(BeanDefinition def, ComponentType type) {
@ -221,25 +224,22 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
}
@Override
public List<ComponentDescriptor> getComponents(ComponentType type) {
if (componentsMap.containsKey(type)) {
return Collections.unmodifiableList(componentsMap.get(type));
public List<ComponentDescriptor> getComponents(Set<ComponentType> types, RuleChainType ruleChainType) {
if (RuleChainType.SYSTEM.equals(ruleChainType)) {
return getComponents(types, systemComponentsMap);
} else if (RuleChainType.EDGE.equals(ruleChainType)) {
return getComponents(types, edgeComponentsMap);
} else {
return Collections.emptyList();
log.error("Unsupported rule chain type {}", ruleChainType);
throw new RuntimeException("Unsupported rule chain type " + ruleChainType);
}
}
@Override
public List<ComponentDescriptor> getComponents(Set<ComponentType> types) {
private List<ComponentDescriptor> getComponents(Set<ComponentType> types, Map<ComponentType, List<ComponentDescriptor>> componentsMap) {
List<ComponentDescriptor> result = new ArrayList<>();
types.stream().filter(type -> componentsMap.containsKey(type)).forEach(type -> {
types.stream().filter(componentsMap::containsKey).forEach(type -> {
result.addAll(componentsMap.get(type));
});
return Collections.unmodifiableList(result);
}
@Override
public Optional<ComponentDescriptor> getComponent(String clazz) {
return Optional.ofNullable(components.get(clazz));
}
}

8
application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java

@ -17,9 +17,9 @@ package org.thingsboard.server.service.component;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
@ -29,10 +29,6 @@ public interface ComponentDiscoveryService {
void discoverComponents();
List<ComponentDescriptor> getComponents(ComponentType type);
List<ComponentDescriptor> getComponents(Set<ComponentType> types);
Optional<ComponentDescriptor> getComponent(String clazz);
List<ComponentDescriptor> getComponents(Set<ComponentType> types, RuleChainType ruleChainType);
}

3
rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java

@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.api;
import org.thingsboard.server.common.data.plugin.ComponentScope;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@ -57,4 +58,6 @@ public @interface RuleNode {
boolean customRelations() default false;
RuleChainType[] ruleChainTypes() default RuleChainType.SYSTEM;
}

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNode.java

@ -24,6 +24,7 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@Slf4j
@ -36,7 +37,8 @@ import org.thingsboard.server.common.msg.TbMsg;
"Will create new Customer if it doesn't exists and 'Create new Customer if not exists' is set to true.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeAssignToCustomerConfig",
icon = "add_circle"
icon = "add_circle",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbAssignToCustomerNode extends TbAbstractCustomerActionNode<TbAssignToCustomerNodeConfiguration> {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java

@ -27,6 +27,7 @@ import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@Slf4j
@ -43,7 +44,8 @@ import org.thingsboard.server.common.msg.TbMsg;
"Message metadata can be accessed via <code>metadata</code> property. For example <code>'name = ' + metadata.customerName;</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeClearAlarmConfig",
icon = "notifications_off"
icon = "notifications_off",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfiguration> {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java

@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
@ -56,7 +57,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
"Changes message originator to related entity view and produces new messages according to count of updated entity views",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbNodeEmptyConfig",
icon = "content_copy"
icon = "content_copy",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbCopyAttributesToEntityViewNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java

@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.io.IOException;
@ -48,7 +49,8 @@ import java.io.IOException;
"Message metadata can be accessed via <code>metadata</code> property. For example <code>'name = ' + metadata.customerName;</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeCreateAlarmConfig",
icon = "notifications_active"
icon = "notifications_active",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConfiguration> {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java

@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.ArrayList;
@ -52,7 +53,8 @@ import java.util.List;
nodeDetails = "If the relation already exists or successfully created - Message send via <b>Success</b> chain, otherwise <b>Failure</b> chain will be used.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeCreateRelationConfig",
icon = "add_circle"
icon = "add_circle",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateRelationNodeConfiguration> {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java

@ -27,6 +27,7 @@ import org.thingsboard.rule.engine.util.EntityContainer;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.ArrayList;
@ -43,7 +44,8 @@ import java.util.List;
nodeDetails = "If the relation(s) successfully deleted - Message send via <b>Success</b> chain, otherwise <b>Failure</b> chain will be used.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeDeleteRelationConfig",
icon = "remove_circle"
icon = "remove_circle",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteRelationNodeConfiguration> {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java

@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import static org.thingsboard.common.util.DonAsynchron.withCallback;
@ -35,7 +36,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
"Message metadata can be accessed via <code>metadata</code> property. For example <code>'name = ' + metadata.customerName;</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeLogConfig",
icon = "menu"
icon = "menu",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbLogNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java

@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -42,7 +43,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
nodeDetails = "Count incoming messages for specified interval and produces POST_TELEMETRY_REQUEST msg with messages count",
icon = "functions",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeMsgCountConfig"
configDirective = "tbActionNodeMsgCountConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbMsgCountNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbSaveToCustomCassandraTableNode.java

@ -40,6 +40,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.dao.cassandra.CassandraCluster;
import org.thingsboard.server.dao.model.type.AuthorityCodec;
@ -77,7 +78,8 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
" otherwise, the message will be routed via <b>success</b> chain.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeCustomTableConfig",
icon = "file_upload")
icon = "file_upload"
)
public class TbSaveToCustomCassandraTableNode implements TbNode {
private static final String TABLE_PREFIX = "cs_tb_";

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNode.java

@ -23,6 +23,7 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@RuleNode(
@ -33,7 +34,8 @@ import org.thingsboard.server.common.msg.TbMsg;
nodeDetails = "Finds target Entity Customer by Customer name pattern and then unassign Originator Entity from this customer.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeUnAssignToCustomerConfig",
icon = "remove_circle"
icon = "remove_circle",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbUnassignFromCustomerNode extends TbAbstractCustomerActionNode<TbUnassignFromCustomerNodeConfiguration> {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sns/TbSnsNode.java

@ -27,6 +27,7 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -45,7 +46,8 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
"For example <b>requestId</b> field can be accessed with <code>metadata.requestId</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeSnsConfig",
iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ij48cGF0aCBkPSJNMTMuMjMgMTAuNTZWMTBjLTEuOTQgMC0zLjk5LjM5LTMuOTkgMi42NyAwIDEuMTYuNjEgMS45NSAxLjYzIDEuOTUuNzYgMCAxLjQzLS40NyAxLjg2LTEuMjIuNTItLjkzLjUtMS44LjUtMi44NG0yLjcgNi41M2MtLjE4LjE2LS40My4xNy0uNjMuMDYtLjg5LS43NC0xLjA1LTEuMDgtMS41NC0xLjc5LTEuNDcgMS41LTIuNTEgMS45NS00LjQyIDEuOTUtMi4yNSAwLTQuMDEtMS4zOS00LjAxLTQuMTcgMC0yLjE4IDEuMTctMy42NCAyLjg2LTQuMzggMS40Ni0uNjQgMy40OS0uNzYgNS4wNC0uOTNWNy41YzAtLjY2LjA1LTEuNDEtLjMzLTEuOTYtLjMyLS40OS0uOTUtLjctMS41LS43LTEuMDIgMC0xLjkzLjUzLTIuMTUgMS42MS0uMDUuMjQtLjI1LjQ4LS40Ny40OWwtMi42LS4yOGMtLjIyLS4wNS0uNDYtLjIyLS40LS41Ni42LTMuMTUgMy40NS00LjEgNi00LjEgMS4zIDAgMyAuMzUgNC4wMyAxLjMzQzE3LjExIDQuNTUgMTcgNi4xOCAxNyA3Ljk1djQuMTdjMCAxLjI1LjUgMS44MSAxIDIuNDguMTcuMjUuMjEuNTQgMCAuNzFsLTIuMDYgMS43OGgtLjAxIj48L3BhdGg+PHBhdGggZD0iTTIwLjE2IDE5LjU0QzE4IDIxLjE0IDE0LjgyIDIyIDEyLjEgMjJjLTMuODEgMC03LjI1LTEuNDEtOS44NS0zLjc2LS4yLS4xOC0uMDItLjQzLjI1LS4yOSAyLjc4IDEuNjMgNi4yNSAyLjYxIDkuODMgMi42MSAyLjQxIDAgNS4wNy0uNSA3LjUxLTEuNTMuMzctLjE2LjY2LjI0LjMyLjUxIj48L3BhdGg+PHBhdGggZD0iTTIxLjA3IDE4LjVjLS4yOC0uMzYtMS44NS0uMTctMi41Ny0uMDgtLjE5LjAyLS4yMi0uMTYtLjAzLS4zIDEuMjQtLjg4IDMuMjktLjYyIDMuNTMtLjMzLjI0LjMtLjA3IDIuMzUtMS4yNCAzLjMyLS4xOC4xNi0uMzUuMDctLjI2LS4xMS4yNi0uNjcuODUtMi4xNC41Ny0yLjV6Ij48L3BhdGg+PC9zdmc+"
iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ij48cGF0aCBkPSJNMTMuMjMgMTAuNTZWMTBjLTEuOTQgMC0zLjk5LjM5LTMuOTkgMi42NyAwIDEuMTYuNjEgMS45NSAxLjYzIDEuOTUuNzYgMCAxLjQzLS40NyAxLjg2LTEuMjIuNTItLjkzLjUtMS44LjUtMi44NG0yLjcgNi41M2MtLjE4LjE2LS40My4xNy0uNjMuMDYtLjg5LS43NC0xLjA1LTEuMDgtMS41NC0xLjc5LTEuNDcgMS41LTIuNTEgMS45NS00LjQyIDEuOTUtMi4yNSAwLTQuMDEtMS4zOS00LjAxLTQuMTcgMC0yLjE4IDEuMTctMy42NCAyLjg2LTQuMzggMS40Ni0uNjQgMy40OS0uNzYgNS4wNC0uOTNWNy41YzAtLjY2LjA1LTEuNDEtLjMzLTEuOTYtLjMyLS40OS0uOTUtLjctMS41LS43LTEuMDIgMC0xLjkzLjUzLTIuMTUgMS42MS0uMDUuMjQtLjI1LjQ4LS40Ny40OWwtMi42LS4yOGMtLjIyLS4wNS0uNDYtLjIyLS40LS41Ni42LTMuMTUgMy40NS00LjEgNi00LjEgMS4zIDAgMyAuMzUgNC4wMyAxLjMzQzE3LjExIDQuNTUgMTcgNi4xOCAxNyA3Ljk1djQuMTdjMCAxLjI1LjUgMS44MSAxIDIuNDguMTcuMjUuMjEuNTQgMCAuNzFsLTIuMDYgMS43OGgtLjAxIj48L3BhdGg+PHBhdGggZD0iTTIwLjE2IDE5LjU0QzE4IDIxLjE0IDE0LjgyIDIyIDEyLjEgMjJjLTMuODEgMC03LjI1LTEuNDEtOS44NS0zLjc2LS4yLS4xOC0uMDItLjQzLjI1LS4yOSAyLjc4IDEuNjMgNi4yNSAyLjYxIDkuODMgMi42MSAyLjQxIDAgNS4wNy0uNSA3LjUxLTEuNTMuMzctLjE2LjY2LjI0LjMyLjUxIj48L3BhdGg+PHBhdGggZD0iTTIxLjA3IDE4LjVjLS4yOC0uMzYtMS44NS0uMTctMi41Ny0uMDgtLjE5LjAyLS4yMi0uMTYtLjAzLS4zIDEuMjQtLjg4IDMuMjktLjYyIDMuNTMtLjMzLjI0LjMtLjA3IDIuMzUtMS4yNCAzLjMyLS4xOC4xNi0uMzUuMDctLjI2LS4xMS4yNi0uNjcuODUtMi4xNC41Ny0yLjV6Ij48L3BhdGg+PC9zdmc+",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbSnsNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java

@ -29,6 +29,7 @@ import org.apache.commons.lang3.StringUtils;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -50,7 +51,8 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
" For example <b>requestId</b> field can be accessed with <code>metadata.requestId</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeSqsConfig",
iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ij48cGF0aCBkPSJNMTMuMjMgMTAuNTZWMTBjLTEuOTQgMC0zLjk5LjM5LTMuOTkgMi42NyAwIDEuMTYuNjEgMS45NSAxLjYzIDEuOTUuNzYgMCAxLjQzLS40NyAxLjg2LTEuMjIuNTItLjkzLjUtMS44LjUtMi44NG0yLjcgNi41M2MtLjE4LjE2LS40My4xNy0uNjMuMDYtLjg5LS43NC0xLjA1LTEuMDgtMS41NC0xLjc5LTEuNDcgMS41LTIuNTEgMS45NS00LjQyIDEuOTUtMi4yNSAwLTQuMDEtMS4zOS00LjAxLTQuMTcgMC0yLjE4IDEuMTctMy42NCAyLjg2LTQuMzggMS40Ni0uNjQgMy40OS0uNzYgNS4wNC0uOTNWNy41YzAtLjY2LjA1LTEuNDEtLjMzLTEuOTYtLjMyLS40OS0uOTUtLjctMS41LS43LTEuMDIgMC0xLjkzLjUzLTIuMTUgMS42MS0uMDUuMjQtLjI1LjQ4LS40Ny40OWwtMi42LS4yOGMtLjIyLS4wNS0uNDYtLjIyLS40LS41Ni42LTMuMTUgMy40NS00LjEgNi00LjEgMS4zIDAgMyAuMzUgNC4wMyAxLjMzQzE3LjExIDQuNTUgMTcgNi4xOCAxNyA3Ljk1djQuMTdjMCAxLjI1LjUgMS44MSAxIDIuNDguMTcuMjUuMjEuNTQgMCAuNzFsLTIuMDYgMS43OGgtLjAxIj48L3BhdGg+PHBhdGggZD0iTTIwLjE2IDE5LjU0QzE4IDIxLjE0IDE0LjgyIDIyIDEyLjEgMjJjLTMuODEgMC03LjI1LTEuNDEtOS44NS0zLjc2LS4yLS4xOC0uMDItLjQzLjI1LS4yOSAyLjc4IDEuNjMgNi4yNSAyLjYxIDkuODMgMi42MSAyLjQxIDAgNS4wNy0uNSA3LjUxLTEuNTMuMzctLjE2LjY2LjI0LjMyLjUxIj48L3BhdGg+PHBhdGggZD0iTTIxLjA3IDE4LjVjLS4yOC0uMzYtMS44NS0uMTctMi41Ny0uMDgtLjE5LjAyLS4yMi0uMTYtLjAzLS4zIDEuMjQtLjg4IDMuMjktLjYyIDMuNTMtLjMzLjI0LjMtLjA3IDIuMzUtMS4yNCAzLjMyLS4xOC4xNi0uMzUuMDctLjI2LS4xMS4yNi0uNjcuODUtMi4xNC41Ny0yLjV6Ij48L3BhdGg+PC9zdmc+"
iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ij48cGF0aCBkPSJNMTMuMjMgMTAuNTZWMTBjLTEuOTQgMC0zLjk5LjM5LTMuOTkgMi42NyAwIDEuMTYuNjEgMS45NSAxLjYzIDEuOTUuNzYgMCAxLjQzLS40NyAxLjg2LTEuMjIuNTItLjkzLjUtMS44LjUtMi44NG0yLjcgNi41M2MtLjE4LjE2LS40My4xNy0uNjMuMDYtLjg5LS43NC0xLjA1LTEuMDgtMS41NC0xLjc5LTEuNDcgMS41LTIuNTEgMS45NS00LjQyIDEuOTUtMi4yNSAwLTQuMDEtMS4zOS00LjAxLTQuMTcgMC0yLjE4IDEuMTctMy42NCAyLjg2LTQuMzggMS40Ni0uNjQgMy40OS0uNzYgNS4wNC0uOTNWNy41YzAtLjY2LjA1LTEuNDEtLjMzLTEuOTYtLjMyLS40OS0uOTUtLjctMS41LS43LTEuMDIgMC0xLjkzLjUzLTIuMTUgMS42MS0uMDUuMjQtLjI1LjQ4LS40Ny40OWwtMi42LS4yOGMtLjIyLS4wNS0uNDYtLjIyLS40LS41Ni42LTMuMTUgMy40NS00LjEgNi00LjEgMS4zIDAgMyAuMzUgNC4wMyAxLjMzQzE3LjExIDQuNTUgMTcgNi4xOCAxNyA3Ljk1djQuMTdjMCAxLjI1LjUgMS44MSAxIDIuNDguMTcuMjUuMjEuNTQgMCAuNzFsLTIuMDYgMS43OGgtLjAxIj48L3BhdGg+PHBhdGggZD0iTTIwLjE2IDE5LjU0QzE4IDIxLjE0IDE0LjgyIDIyIDEyLjEgMjJjLTMuODEgMC03LjI1LTEuNDEtOS44NS0zLjc2LS4yLS4xOC0uMDItLjQzLjI1LS4yOSAyLjc4IDEuNjMgNi4yNSAyLjYxIDkuODMgMi42MSAyLjQxIDAgNS4wNy0uNSA3LjUxLTEuNTMuMzctLjE2LjY2LjI0LjMyLjUxIj48L3BhdGg+PHBhdGggZD0iTTIxLjA3IDE4LjVjLS4yOC0uMzYtMS44NS0uMTctMi41Ny0uMDgtLjE5LjAyLS4yMi0uMTYtLjAzLS4zIDEuMjQtLjg4IDMuMjktLjYyIDMuNTMtLjMzLjI0LjMtLjA3IDIuMzUtMS4yNCAzLjMyLS4xOC4xNi0uMzUuMDctLjI2LS4xMS4yNi0uNjcuODUtMi4xNC41Ny0yLjV6Ij48L3BhdGg+PC9zdmc+",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbSqsNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java

@ -23,6 +23,7 @@ import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
@ -43,7 +44,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
inEnabled = false,
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbActionNodeGeneratorConfig",
icon = "repeat"
icon = "repeat",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbMsgGeneratorNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java

@ -24,6 +24,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -44,7 +45,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
nodeDetails = "Delays messages for configurable period.",
icon = "pause",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeMsgDelayConfig"
configDirective = "tbActionNodeMsgDelayConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbMsgDelayNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToCloudNode.java

@ -24,6 +24,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@Slf4j
@ -35,7 +36,8 @@ import org.thingsboard.server.common.msg.TbMsg;
nodeDetails = "Pushes messages to cloud. This node is used only on Edge instances to push messages from Edge to Cloud.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbNodeEmptyConfig",
icon = "cloud_upload"
icon = "cloud_upload",
ruleChainTypes = RuleChainType.EDGE
)
public class TbMsgPushToCloudNode implements TbNode {

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckMessageNode.java

@ -24,6 +24,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.List;
@ -39,7 +40,9 @@ import java.util.Map;
nodeDetails = "If selected checkbox 'Check that all selected keys are present'\" and all keys in message data and metadata are exist - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.\n" +
"Else if the checkbox is not selected, and at least one of the keys from data or metadata of the message exists - send Message via <b>True</b> chain, otherwise, <b>False</b> chain is used. ",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbFilterNodeCheckMessageConfig")
configDirective = "tbFilterNodeCheckMessageConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbCheckMessageNode implements TbNode {
private static final Gson gson = new Gson();

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java

@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.List;
@ -50,7 +51,9 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
" any relation to the originator of the message by type and direction.",
nodeDetails = "If at least one relation exists - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbFilterNodeCheckRelationConfig")
configDirective = "tbFilterNodeCheckRelationConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbCheckRelationNode implements TbNode {
private TbCheckRelationNodeConfiguration config;

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsFilterNode.java

@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import static org.thingsboard.common.util.DonAsynchron.withCallback;
@ -35,7 +36,9 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
"Message metadata can be accessed via <code>metadata</code> property. For example <code>metadata.customerName === 'John';</code><br/>" +
"Message type can be accessed via <code>msgType</code> property.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbFilterNodeScriptConfig")
configDirective = "tbFilterNodeScriptConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbJsFilterNode implements TbNode {

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java

@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.Set;
@ -38,7 +39,9 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
"Message metadata can be accessed via <code>metadata</code> property. For example <code>metadata.customerName === 'John';</code><br/>" +
"Message type can be accessed via <code>msgType</code> property.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbFilterNodeSwitchConfig")
configDirective = "tbFilterNodeSwitchConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbJsSwitchNode implements TbNode {
private TbJsSwitchNodeConfiguration config;

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeFilterNode.java

@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
/**
@ -33,7 +34,9 @@ import org.thingsboard.server.common.msg.TbMsg;
nodeDescription = "Filter incoming messages by Message Type",
nodeDetails = "If incoming MessageType is expected - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbFilterNodeMessageTypeConfig")
configDirective = "tbFilterNodeMessageTypeConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbMsgTypeFilterNode implements TbNode {
TbMsgTypeFilterNodeConfiguration config;

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeSwitchNode.java

@ -20,6 +20,7 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.session.SessionMsgType;
@ -34,7 +35,9 @@ import org.thingsboard.server.common.msg.session.SessionMsgType;
nodeDescription = "Route incoming messages by Message Type",
nodeDetails = "Sends messages with message types <b>\"Post attributes\", \"Post telemetry\", \"RPC Request\"</b> etc. via corresponding chain, otherwise <b>Other</b> chain is used.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbNodeEmptyConfig")
configDirective = "tbNodeEmptyConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbMsgTypeSwitchNode implements TbNode {
EmptyNodeConfiguration config;

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java

@ -20,6 +20,7 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@Slf4j
@ -31,7 +32,9 @@ import org.thingsboard.server.common.msg.TbMsg;
nodeDescription = "Filter incoming messages by message Originator Type",
nodeDetails = "If Originator Type of incoming message is expected - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbFilterNodeOriginatorTypeConfig")
configDirective = "tbFilterNodeOriginatorTypeConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbOriginatorTypeFilterNode implements TbNode {
TbOriginatorTypeFilterNodeConfiguration config;

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java

@ -20,6 +20,7 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@Slf4j
@ -31,7 +32,9 @@ import org.thingsboard.server.common.msg.TbMsg;
nodeDescription = "Route incoming messages by Message Originator Type",
nodeDetails = "Routes messages to chain according to the originator type ('Device', 'Asset', etc.).",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbNodeEmptyConfig")
configDirective = "tbNodeEmptyConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbOriginatorTypeSwitchNode implements TbNode {
EmptyNodeConfiguration config;

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/gcp/pubsub/TbPubSubNode.java

@ -29,6 +29,7 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -49,7 +50,8 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
"<b>messageId</b> field can be accessed with <code>metadata.messageId</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodePubSubConfig",
iconUrl = "data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgMTI4IDEyOCI+Cjx0aXRsZT5DbG91ZCBQdWJTdWI8L3RpdGxlPgo8Zz4KPHBhdGggZD0iTTEyNi40Nyw1OC4xMmwtMjYuMy00NS43NEExMS41NiwxMS41NiwwLDAsMCw5MC4zMSw2LjVIMzcuN2ExMS41NSwxMS41NSwwLDAsMC05Ljg2LDUuODhMMS41Myw1OGExMS40OCwxMS40OCwwLDAsMCwwLDExLjQ0bDI2LjMsNDZhMTEuNzcsMTEuNzcsMCwwLDAsOS44Niw2LjA5SDkwLjNhMTEuNzMsMTEuNzMsMCwwLDAsOS44Ny02LjA2bDI2LjMtNDUuNzRBMTEuNzMsMTEuNzMsMCwwLDAsMTI2LjQ3LDU4LjEyWiIgc3R5bGU9ImZpbGw6ICM3MzViMmYiLz4KPHBhdGggZD0iTTg5LjIyLDQ3Ljc0LDgzLjM2LDQ5bC0xNC42LTE0LjZMNjQuMDksNDMuMSw2MS41NSw1My4ybDQuMjksNC4yOUw1Ny42LDU5LjE4LDQ2LjMsNDcuODhsLTcuNjcsNy4zOEw1Mi43Niw2OS4zN2wtMTUsMTEuOUw3OCwxMjEuNUg5MC4zYTExLjczLDExLjczLDAsMCwwLDkuODctNi4wNmwyMC43Mi0zNloiIHN0eWxlPSJvcGFjaXR5OiAwLjA3MDAwMDAwMDI5ODAyMztpc29sYXRpb246IGlzb2xhdGUiLz4KPHBhdGggZD0iTTgyLjg2LDQ3YTUuMzIsNS4zMiwwLDEsMS0xLjk1LDcuMjdBNS4zMiw1LjMyLDAsMCwxLDgyLjg2LDQ3IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNMzkuODIsNTYuMThhNS4zMiw1LjMyLDAsMSwxLDcuMjctMS45NSw1LjMyLDUuMzIsMCwwLDEtNy4yNywxLjk1IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNNjkuMzIsODguODVBNS4zMiw1LjMyLDAsMSwxLDY0LDgzLjUyYTUuMzIsNS4zMiwwLDAsMSw1LjMyLDUuMzIiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxnPgo8cGF0aCBkPSJNNjQsNTIuOTRhMTEuMDYsMTEuMDYsMCwwLDEsMi40Ni4yOFYzOS4xNUg2MS41NFY1My4yMkExMS4wNiwxMS4wNiwwLDAsMSw2NCw1Mi45NFoiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxwYXRoIGQ9Ik03NC41Nyw2Ny4yNmExMSwxMSwwLDAsMS0yLjQ3LDQuMjVsMTIuMTksNywyLjQ2LTQuMjZaIiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNNTMuNDMsNjcuMjZsLTEyLjE4LDcsMi40Niw0LjI2LDEyLjE5LTdBMTEsMTEsMCwwLDEsNTMuNDMsNjcuMjZaIiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi42LDY0QTguNiw4LjYsMCwxLDEsNjQsNTUuNCw4LjYsOC42LDAsMCwxLDcyLjYsNjQiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxwYXRoIGQ9Ik0zOS4xLDcwLjU3YTYuNzYsNi43NiwwLDEsMS0yLjQ3LDkuMjMsNi43Niw2Ljc2LDAsMCwxLDIuNDctOS4yMyIgc3R5bGU9ImZpbGw6ICNmZmYiLz4KPHBhdGggZD0iTTgyLjE0LDgyLjI3YTYuNzYsNi43NiwwLDEsMSw5LjIzLTIuNDcsNi43NSw2Ljc1LDAsMCwxLTkuMjMsMi40NyIgc3R5bGU9ImZpbGw6ICNmZmYiLz4KPHBhdGggZD0iTTcwLjc2LDM5LjE1QTYuNzYsNi43NiwwLDEsMSw2NCwzMi4zOWE2Ljc2LDYuNzYsMCwwLDEsNi43Niw2Ljc2IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8L2c+Cjwvc3ZnPgo="
iconUrl = "data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgMTI4IDEyOCI+Cjx0aXRsZT5DbG91ZCBQdWJTdWI8L3RpdGxlPgo8Zz4KPHBhdGggZD0iTTEyNi40Nyw1OC4xMmwtMjYuMy00NS43NEExMS41NiwxMS41NiwwLDAsMCw5MC4zMSw2LjVIMzcuN2ExMS41NSwxMS41NSwwLDAsMC05Ljg2LDUuODhMMS41Myw1OGExMS40OCwxMS40OCwwLDAsMCwwLDExLjQ0bDI2LjMsNDZhMTEuNzcsMTEuNzcsMCwwLDAsOS44Niw2LjA5SDkwLjNhMTEuNzMsMTEuNzMsMCwwLDAsOS44Ny02LjA2bDI2LjMtNDUuNzRBMTEuNzMsMTEuNzMsMCwwLDAsMTI2LjQ3LDU4LjEyWiIgc3R5bGU9ImZpbGw6ICM3MzViMmYiLz4KPHBhdGggZD0iTTg5LjIyLDQ3Ljc0LDgzLjM2LDQ5bC0xNC42LTE0LjZMNjQuMDksNDMuMSw2MS41NSw1My4ybDQuMjksNC4yOUw1Ny42LDU5LjE4LDQ2LjMsNDcuODhsLTcuNjcsNy4zOEw1Mi43Niw2OS4zN2wtMTUsMTEuOUw3OCwxMjEuNUg5MC4zYTExLjczLDExLjczLDAsMCwwLDkuODctNi4wNmwyMC43Mi0zNloiIHN0eWxlPSJvcGFjaXR5OiAwLjA3MDAwMDAwMDI5ODAyMztpc29sYXRpb246IGlzb2xhdGUiLz4KPHBhdGggZD0iTTgyLjg2LDQ3YTUuMzIsNS4zMiwwLDEsMS0xLjk1LDcuMjdBNS4zMiw1LjMyLDAsMCwxLDgyLjg2LDQ3IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNMzkuODIsNTYuMThhNS4zMiw1LjMyLDAsMSwxLDcuMjctMS45NSw1LjMyLDUuMzIsMCwwLDEtNy4yNywxLjk1IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNNjkuMzIsODguODVBNS4zMiw1LjMyLDAsMSwxLDY0LDgzLjUyYTUuMzIsNS4zMiwwLDAsMSw1LjMyLDUuMzIiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxnPgo8cGF0aCBkPSJNNjQsNTIuOTRhMTEuMDYsMTEuMDYsMCwwLDEsMi40Ni4yOFYzOS4xNUg2MS41NFY1My4yMkExMS4wNiwxMS4wNiwwLDAsMSw2NCw1Mi45NFoiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxwYXRoIGQ9Ik03NC41Nyw2Ny4yNmExMSwxMSwwLDAsMS0yLjQ3LDQuMjVsMTIuMTksNywyLjQ2LTQuMjZaIiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNNTMuNDMsNjcuMjZsLTEyLjE4LDcsMi40Niw0LjI2LDEyLjE5LTdBMTEsMTEsMCwwLDEsNTMuNDMsNjcuMjZaIiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi42LDY0QTguNiw4LjYsMCwxLDEsNjQsNTUuNCw4LjYsOC42LDAsMCwxLDcyLjYsNjQiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxwYXRoIGQ9Ik0zOS4xLDcwLjU3YTYuNzYsNi43NiwwLDEsMS0yLjQ3LDkuMjMsNi43Niw2Ljc2LDAsMCwxLDIuNDctOS4yMyIgc3R5bGU9ImZpbGw6ICNmZmYiLz4KPHBhdGggZD0iTTgyLjE0LDgyLjI3YTYuNzYsNi43NiwwLDEsMSw5LjIzLTIuNDcsNi43NSw2Ljc1LDAsMCwxLTkuMjMsMi40NyIgc3R5bGU9ImZpbGw6ICNmZmYiLz4KPHBhdGggZD0iTTcwLjc2LDM5LjE1QTYuNzYsNi43NiwwLDEsMSw2NCwzMi4zOWE2Ljc2LDYuNzYsMCwwLDEsNi43Niw2Ljc2IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8L2c+Cjwvc3ZnPgo=",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbPubSubNode implements TbNode {

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNode.java

@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.Collections;
@ -51,7 +52,9 @@ import java.util.concurrent.TimeoutException;
nodeDescription = "Produces incoming messages using GPS based geofencing",
nodeDetails = "Extracts latitude and longitude parameters from incoming message and returns different events based on configuration parameters",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeGpsGeofencingConfig")
configDirective = "tbActionNodeGpsGeofencingConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGpsGeofencingActionNode extends AbstractGeofencingNode<TbGpsGeofencingActionNodeConfiguration> {
private final Map<EntityId, EntityGeofencingState> entityStates = new HashMap<>();

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNode.java

@ -35,6 +35,7 @@ import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.filter.TbMsgTypeFilterNodeConfiguration;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.Collections;
@ -52,7 +53,9 @@ import java.util.List;
nodeDescription = "Filter incoming messages by GPS based geofencing",
nodeDetails = "Extracts latitude and longitude parameters from incoming message and returns 'True' if they are inside configured perimeters, 'False' otherwise.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbFilterNodeGpsGeofencingConfig")
configDirective = "tbFilterNodeGpsGeofencingConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGpsGeofencingFilterNode extends AbstractGeofencingNode<TbGpsGeofencingFilterNodeConfiguration> {
@Override

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java

@ -20,6 +20,7 @@ import org.apache.kafka.clients.producer.*;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -38,7 +39,8 @@ import java.util.concurrent.atomic.AtomicInteger;
" from the Kafka in the Message Metadata. For example <b>partition</b> field can be accessed with <code>metadata.partition</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeKafkaConfig",
iconUrl = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUzOCIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMjU2IDQxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZD0iTTIwMS44MTYgMjMwLjIxNmMtMTYuMTg2IDAtMzAuNjk3IDcuMTcxLTQwLjYzNCAxOC40NjFsLTI1LjQ2My0xOC4wMjZjMi43MDMtNy40NDIgNC4yNTUtMTUuNDMzIDQuMjU1LTIzLjc5NyAwLTguMjE5LTEuNDk4LTE2LjA3Ni00LjExMi0yMy40MDhsMjUuNDA2LTE3LjgzNWM5LjkzNiAxMS4yMzMgMjQuNDA5IDE4LjM2NSA0MC41NDggMTguMzY1IDI5Ljg3NSAwIDU0LjE4NC0yNC4zMDUgNTQuMTg0LTU0LjE4NCAwLTI5Ljg3OS0yNC4zMDktNTQuMTg0LTU0LjE4NC01NC4xODQtMjkuODc1IDAtNTQuMTg0IDI0LjMwNS01NC4xODQgNTQuMTg0IDAgNS4zNDguODA4IDEwLjUwNSAyLjI1OCAxNS4zODlsLTI1LjQyMyAxNy44NDRjLTEwLjYyLTEzLjE3NS0yNS45MTEtMjIuMzc0LTQzLjMzMy0yNS4xODJ2LTMwLjY0YzI0LjU0NC01LjE1NSA0My4wMzctMjYuOTYyIDQzLjAzNy01My4wMTlDMTI0LjE3MSAyNC4zMDUgOTkuODYyIDAgNjkuOTg3IDAgNDAuMTEyIDAgMTUuODAzIDI0LjMwNSAxNS44MDMgNTQuMTg0YzAgMjUuNzA4IDE4LjAxNCA0Ny4yNDYgNDIuMDY3IDUyLjc2OXYzMS4wMzhDMjUuMDQ0IDE0My43NTMgMCAxNzIuNDAxIDAgMjA2Ljg1NGMwIDM0LjYyMSAyNS4yOTIgNjMuMzc0IDU4LjM1NSA2OC45NHYzMi43NzRjLTI0LjI5OSA1LjM0MS00Mi41NTIgMjcuMDExLTQyLjU1MiA1Mi44OTQgMCAyOS44NzkgMjQuMzA5IDU0LjE4NCA1NC4xODQgNTQuMTg0IDI5Ljg3NSAwIDU0LjE4NC0yNC4zMDUgNTQuMTg0LTU0LjE4NCAwLTI1Ljg4My0xOC4yNTMtNDcuNTUzLTQyLjU1Mi01Mi44OTR2LTMyLjc3NWE2OS45NjUgNjkuOTY1IDAgMCAwIDQyLjYtMjQuNzc2bDI1LjYzMyAxOC4xNDNjLTEuNDIzIDQuODQtMi4yMiA5Ljk0Ni0yLjIyIDE1LjI0IDAgMjkuODc5IDI0LjMwOSA1NC4xODQgNTQuMTg0IDU0LjE4NCAyOS44NzUgMCA1NC4xODQtMjQuMzA1IDU0LjE4NC01NC4xODQgMC0yOS44NzktMjQuMzA5LTU0LjE4NC01NC4xODQtNTQuMTg0em0wLTEyNi42OTVjMTQuNDg3IDAgMjYuMjcgMTEuNzg4IDI2LjI3IDI2LjI3MXMtMTEuNzgzIDI2LjI3LTI2LjI3IDI2LjI3LTI2LjI3LTExLjc4Ny0yNi4yNy0yNi4yN2MwLTE0LjQ4MyAxMS43ODMtMjYuMjcxIDI2LjI3LTI2LjI3MXptLTE1OC4xLTQ5LjMzN2MwLTE0LjQ4MyAxMS43ODQtMjYuMjcgMjYuMjcxLTI2LjI3czI2LjI3IDExLjc4NyAyNi4yNyAyNi4yN2MwIDE0LjQ4My0xMS43ODMgMjYuMjctMjYuMjcgMjYuMjdzLTI2LjI3MS0xMS43ODctMjYuMjcxLTI2LjI3em01Mi41NDEgMzA3LjI3OGMwIDE0LjQ4My0xMS43ODMgMjYuMjctMjYuMjcgMjYuMjdzLTI2LjI3MS0xMS43ODctMjYuMjcxLTI2LjI3YzAtMTQuNDgzIDExLjc4NC0yNi4yNyAyNi4yNzEtMjYuMjdzMjYuMjcgMTEuNzg3IDI2LjI3IDI2LjI3em0tMjYuMjcyLTExNy45N2MtMjAuMjA1IDAtMzYuNjQyLTE2LjQzNC0zNi42NDItMzYuNjM4IDAtMjAuMjA1IDE2LjQzNy0zNi42NDIgMzYuNjQyLTM2LjY0MiAyMC4yMDQgMCAzNi42NDEgMTYuNDM3IDM2LjY0MSAzNi42NDIgMCAyMC4yMDQtMTYuNDM3IDM2LjYzOC0zNi42NDEgMzYuNjM4em0xMzEuODMxIDY3LjE3OWMtMTQuNDg3IDAtMjYuMjctMTEuNzg4LTI2LjI3LTI2LjI3MXMxMS43ODMtMjYuMjcgMjYuMjctMjYuMjcgMjYuMjcgMTEuNzg3IDI2LjI3IDI2LjI3YzAgMTQuNDgzLTExLjc4MyAyNi4yNzEtMjYuMjcgMjYuMjcxeiIvPjwvc3ZnPg=="
iconUrl = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUzOCIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMjU2IDQxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZD0iTTIwMS44MTYgMjMwLjIxNmMtMTYuMTg2IDAtMzAuNjk3IDcuMTcxLTQwLjYzNCAxOC40NjFsLTI1LjQ2My0xOC4wMjZjMi43MDMtNy40NDIgNC4yNTUtMTUuNDMzIDQuMjU1LTIzLjc5NyAwLTguMjE5LTEuNDk4LTE2LjA3Ni00LjExMi0yMy40MDhsMjUuNDA2LTE3LjgzNWM5LjkzNiAxMS4yMzMgMjQuNDA5IDE4LjM2NSA0MC41NDggMTguMzY1IDI5Ljg3NSAwIDU0LjE4NC0yNC4zMDUgNTQuMTg0LTU0LjE4NCAwLTI5Ljg3OS0yNC4zMDktNTQuMTg0LTU0LjE4NC01NC4xODQtMjkuODc1IDAtNTQuMTg0IDI0LjMwNS01NC4xODQgNTQuMTg0IDAgNS4zNDguODA4IDEwLjUwNSAyLjI1OCAxNS4zODlsLTI1LjQyMyAxNy44NDRjLTEwLjYyLTEzLjE3NS0yNS45MTEtMjIuMzc0LTQzLjMzMy0yNS4xODJ2LTMwLjY0YzI0LjU0NC01LjE1NSA0My4wMzctMjYuOTYyIDQzLjAzNy01My4wMTlDMTI0LjE3MSAyNC4zMDUgOTkuODYyIDAgNjkuOTg3IDAgNDAuMTEyIDAgMTUuODAzIDI0LjMwNSAxNS44MDMgNTQuMTg0YzAgMjUuNzA4IDE4LjAxNCA0Ny4yNDYgNDIuMDY3IDUyLjc2OXYzMS4wMzhDMjUuMDQ0IDE0My43NTMgMCAxNzIuNDAxIDAgMjA2Ljg1NGMwIDM0LjYyMSAyNS4yOTIgNjMuMzc0IDU4LjM1NSA2OC45NHYzMi43NzRjLTI0LjI5OSA1LjM0MS00Mi41NTIgMjcuMDExLTQyLjU1MiA1Mi44OTQgMCAyOS44NzkgMjQuMzA5IDU0LjE4NCA1NC4xODQgNTQuMTg0IDI5Ljg3NSAwIDU0LjE4NC0yNC4zMDUgNTQuMTg0LTU0LjE4NCAwLTI1Ljg4My0xOC4yNTMtNDcuNTUzLTQyLjU1Mi01Mi44OTR2LTMyLjc3NWE2OS45NjUgNjkuOTY1IDAgMCAwIDQyLjYtMjQuNzc2bDI1LjYzMyAxOC4xNDNjLTEuNDIzIDQuODQtMi4yMiA5Ljk0Ni0yLjIyIDE1LjI0IDAgMjkuODc5IDI0LjMwOSA1NC4xODQgNTQuMTg0IDU0LjE4NCAyOS44NzUgMCA1NC4xODQtMjQuMzA1IDU0LjE4NC01NC4xODQgMC0yOS44NzktMjQuMzA5LTU0LjE4NC01NC4xODQtNTQuMTg0em0wLTEyNi42OTVjMTQuNDg3IDAgMjYuMjcgMTEuNzg4IDI2LjI3IDI2LjI3MXMtMTEuNzgzIDI2LjI3LTI2LjI3IDI2LjI3LTI2LjI3LTExLjc4Ny0yNi4yNy0yNi4yN2MwLTE0LjQ4MyAxMS43ODMtMjYuMjcxIDI2LjI3LTI2LjI3MXptLTE1OC4xLTQ5LjMzN2MwLTE0LjQ4MyAxMS43ODQtMjYuMjcgMjYuMjcxLTI2LjI3czI2LjI3IDExLjc4NyAyNi4yNyAyNi4yN2MwIDE0LjQ4My0xMS43ODMgMjYuMjctMjYuMjcgMjYuMjdzLTI2LjI3MS0xMS43ODctMjYuMjcxLTI2LjI3em01Mi41NDEgMzA3LjI3OGMwIDE0LjQ4My0xMS43ODMgMjYuMjctMjYuMjcgMjYuMjdzLTI2LjI3MS0xMS43ODctMjYuMjcxLTI2LjI3YzAtMTQuNDgzIDExLjc4NC0yNi4yNyAyNi4yNzEtMjYuMjdzMjYuMjcgMTEuNzg3IDI2LjI3IDI2LjI3em0tMjYuMjcyLTExNy45N2MtMjAuMjA1IDAtMzYuNjQyLTE2LjQzNC0zNi42NDItMzYuNjM4IDAtMjAuMjA1IDE2LjQzNy0zNi42NDIgMzYuNjQyLTM2LjY0MiAyMC4yMDQgMCAzNi42NDEgMTYuNDM3IDM2LjY0MSAzNi42NDIgMCAyMC4yMDQtMTYuNDM3IDM2LjYzOC0zNi42NDEgMzYuNjM4em0xMzEuODMxIDY3LjE3OWMtMTQuNDg3IDAtMjYuMjctMTEuNzg4LTI2LjI3LTI2LjI3MXMxMS43ODMtMjYuMjcgMjYuMjctMjYuMjcgMjYuMjcgMTEuNzg3IDI2LjI3IDI2LjI3YzAgMTQuNDgzLTExLjc4MyAyNi4yNzEtMjYuMjcgMjYuMjcxeiIvPjwvc3ZnPg==",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbKafkaNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java

@ -22,6 +22,7 @@ import org.springframework.util.StringUtils;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -40,7 +41,8 @@ import static org.thingsboard.rule.engine.mail.TbSendEmailNode.SEND_EMAIL_TYPE;
"Set 'SEND_EMAIL' output message type.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbTransformationNodeToEmailConfig",
icon = "email"
icon = "email",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbMsgToEmailNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java

@ -23,6 +23,7 @@ import org.springframework.mail.javamail.MimeMessageHelper;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import javax.mail.internet.MimeMessage;
@ -43,7 +44,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
"with <code>to Email</code> Node using <code>Successful</code> chain.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeSendEmailConfig",
icon = "send"
icon = "send",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbSendEmailNode implements TbNode {

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java

@ -25,6 +25,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
/**
@ -40,7 +41,9 @@ import org.thingsboard.server.common.msg.TbMsg;
"To access those attributes in other nodes this template can be used " +
"<code>metadata.cs_temperature</code> or <code>metadata.shared_limit</code> ",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeOriginatorAttributesConfig")
configDirective = "tbEnrichmentNodeOriginatorAttributesConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGetAttributesNode extends TbAbstractGetAttributesNode<TbGetAttributesNodeConfiguration, EntityId> {
@Override

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java

@ -22,6 +22,7 @@ import org.thingsboard.rule.engine.util.EntitiesCustomerIdAsyncLoader;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
@RuleNode(
type = ComponentType.ENRICHMENT,
@ -33,7 +34,9 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
"To access those attributes in other nodes this template can be used " +
"<code>metadata.temperature</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbEnrichmentNodeCustomerAttributesConfig")
configDirective = "tbEnrichmentNodeCustomerAttributesConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGetCustomerAttributeNode extends TbEntityGetAttrNode<CustomerId> {
@Override

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java

@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@Slf4j
@ -40,7 +41,9 @@ import org.thingsboard.server.common.msg.TbMsg;
"<b>Note:</b> only Device, Asset, and Entity View type are allowed.<br><br>" +
"If the originator of the message is not assigned to Customer, or originator type is not supported - Message will be forwarded to <b>Failure</b> chain, otherwise, <b>Success</b> chain will be used.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeEntityDetailsConfig")
configDirective = "tbEnrichmentNodeEntityDetailsConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbGetCustomerDetailsNodeConfiguration> {
private static final String CUSTOMER_PREFIX = "customer_";

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java

@ -26,6 +26,7 @@ import org.thingsboard.rule.engine.util.EntitiesRelatedDeviceIdAsyncLoader;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@Slf4j
@ -38,7 +39,9 @@ import org.thingsboard.server.common.msg.TbMsg;
"To access those attributes in other nodes this template can be used " +
"<code>metadata.cs_temperature</code> or <code>metadata.shared_limit</code> ",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeDeviceAttributesConfig")
configDirective = "tbEnrichmentNodeDeviceAttributesConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode<TbGetDeviceAttrNodeConfiguration, DeviceId> {
@Override

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java

@ -23,6 +23,7 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
@ -38,7 +39,9 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
nodeDescription = "Add Message Originator fields values into Message Metadata",
nodeDetails = "Will fetch fields values specified in mapping. If specified field is not part of originator fields it will be ignored.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeOriginatorFieldsConfig")
configDirective = "tbEnrichmentNodeOriginatorFieldsConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGetOriginatorFieldsNode implements TbNode {
private TbGetOriginatorFieldsConfiguration config;

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java

@ -22,6 +22,7 @@ import org.thingsboard.rule.engine.util.EntitiesRelatedEntityIdAsyncLoader;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
@RuleNode(
type = ComponentType.ENRICHMENT,
@ -35,7 +36,9 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
"To access those attributes in other nodes this template can be used " +
"<code>metadata.temperature</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbEnrichmentNodeRelatedAttributesConfig")
configDirective = "tbEnrichmentNodeRelatedAttributesConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGetRelatedAttributeNode extends TbEntityGetAttrNode<EntityId> {

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java

@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.List;
@ -64,7 +65,9 @@ import static org.thingsboard.server.common.data.kv.Aggregation.NONE;
"Also, the rule node allows you to select telemetry sampling order: <b>ASC</b> or <b>DESC</b>. </br>" +
"<b>Note</b>: The maximum size of the fetched array is 1000 records.\n ",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeGetTelemetryFromDatabase")
configDirective = "tbEnrichmentNodeGetTelemetryFromDatabase",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGetTelemetryNode implements TbNode {
private static final String DESC_ORDER = "DESC";

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java

@ -23,6 +23,7 @@ import org.thingsboard.rule.engine.util.EntitiesTenantIdAsyncLoader;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
@Slf4j
@RuleNode(
@ -35,7 +36,9 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
"To access those attributes in other nodes this template can be used " +
"<code>metadata.temperature</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbEnrichmentNodeTenantAttributesConfig")
configDirective = "tbEnrichmentNodeTenantAttributesConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGetTenantAttributeNode extends TbEntityGetAttrNode<TenantId> {
@Override

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java

@ -25,6 +25,7 @@ import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.ContactBased;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@Slf4j
@ -36,7 +37,9 @@ import org.thingsboard.server.common.msg.TbMsg;
"<b>Note:</b> only Device, Asset, and Entity View type are allowed.<br><br>" +
"If the originator of the message is not assigned to Tenant, or originator type is not supported - Message will be forwarded to <b>Failure</b> chain, otherwise, <b>Success</b> chain will be used.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeEntityDetailsConfig")
configDirective = "tbEnrichmentNodeEntityDetailsConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode<TbGetTenantDetailsNodeConfiguration> {
private static final String TENANT_PREFIX = "tenant_";

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java

@ -30,6 +30,7 @@ import org.springframework.util.StringUtils;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -49,7 +50,8 @@ import java.util.concurrent.TimeoutException;
nodeDetails = "Will publish message payload to the MQTT broker with QoS <b>AT_LEAST_ONCE</b>.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbActionNodeMqttConfig",
icon = "call_split"
icon = "call_split",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbMqttNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java

@ -22,6 +22,7 @@ import org.apache.commons.lang3.StringUtils;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -39,7 +40,8 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
nodeDetails = "Will publish message payload to RabbitMQ queue.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeRabbitMqConfig",
iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHZpZXdCb3g9IjAgMCAxMDAwIDEwMDAiPjxwYXRoIHN0cm9rZS13aWR0aD0iLjg0OTU2IiBkPSJtODYwLjQ3IDQxNi4zMmgtMjYyLjAxYy0xMi45MTMgMC0yMy42MTgtMTAuNzA0LTIzLjYxOC0yMy42MTh2LTI3Mi43MWMwLTIwLjMwNS0xNi4yMjctMzYuMjc2LTM2LjI3Ni0zNi4yNzZoLTkzLjc5MmMtMjAuMzA1IDAtMzYuMjc2IDE2LjIyNy0zNi4yNzYgMzYuMjc2djI3MC44NGMtMC4yNTQ4NyAxNC4xMDMtMTEuNDY5IDI1LjU3Mi0yNS43NDIgMjUuNTcybC04NS42MzYgMC42Nzk2NWMtMTQuMTAzIDAtMjUuNTcyLTExLjQ2OS0yNS41NzItMjUuNTcybDAuNjc5NjUtMjcxLjUyYzAtMjAuMzA1LTE2LjIyNy0zNi4yNzYtMzYuMjc2LTM2LjI3NmgtOTMuNTM3Yy0yMC4zMDUgMC0zNi4yNzYgMTYuMjI3LTM2LjI3NiAzNi4yNzZ2NzYzLjg0YzAgMTguMDk2IDE0Ljc4MiAzMi40NTMgMzIuNDUzIDMyLjQ1M2g3MjIuODFjMTguMDk2IDAgMzIuNDUzLTE0Ljc4MiAzMi40NTMtMzIuNDUzdi00MzUuMzFjLTEuMTg5NC0xOC4xODEtMTUuMjkyLTMyLjE5OC0zMy4zODgtMzIuMTk4em0tMTIyLjY4IDI4Ny4wN2MwIDIzLjYxOC0xOC44NiA0Mi40NzgtNDIuNDc4IDQyLjQ3OGgtNzMuOTk3Yy0yMy42MTggMC00Mi40NzgtMTguODYtNDIuNDc4LTQyLjQ3OHYtNzQuMjUyYzAtMjMuNjE4IDE4Ljg2LTQyLjQ3OCA0Mi40NzgtNDIuNDc4aDczLjk5N2MyMy42MTggMCA0Mi40NzggMTguODYgNDIuNDc4IDQyLjQ3OHoiLz48L3N2Zz4="
iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHZpZXdCb3g9IjAgMCAxMDAwIDEwMDAiPjxwYXRoIHN0cm9rZS13aWR0aD0iLjg0OTU2IiBkPSJtODYwLjQ3IDQxNi4zMmgtMjYyLjAxYy0xMi45MTMgMC0yMy42MTgtMTAuNzA0LTIzLjYxOC0yMy42MTh2LTI3Mi43MWMwLTIwLjMwNS0xNi4yMjctMzYuMjc2LTM2LjI3Ni0zNi4yNzZoLTkzLjc5MmMtMjAuMzA1IDAtMzYuMjc2IDE2LjIyNy0zNi4yNzYgMzYuMjc2djI3MC44NGMtMC4yNTQ4NyAxNC4xMDMtMTEuNDY5IDI1LjU3Mi0yNS43NDIgMjUuNTcybC04NS42MzYgMC42Nzk2NWMtMTQuMTAzIDAtMjUuNTcyLTExLjQ2OS0yNS41NzItMjUuNTcybDAuNjc5NjUtMjcxLjUyYzAtMjAuMzA1LTE2LjIyNy0zNi4yNzYtMzYuMjc2LTM2LjI3NmgtOTMuNTM3Yy0yMC4zMDUgMC0zNi4yNzYgMTYuMjI3LTM2LjI3NiAzNi4yNzZ2NzYzLjg0YzAgMTguMDk2IDE0Ljc4MiAzMi40NTMgMzIuNDUzIDMyLjQ1M2g3MjIuODFjMTguMDk2IDAgMzIuNDUzLTE0Ljc4MiAzMi40NTMtMzIuNDUzdi00MzUuMzFjLTEuMTg5NC0xOC4xODEtMTUuMjkyLTMyLjE5OC0zMy4zODgtMzIuMTk4em0tMTIyLjY4IDI4Ny4wN2MwIDIzLjYxOC0xOC44NiA0Mi40NzgtNDIuNDc4IDQyLjQ3OGgtNzMuOTk3Yy0yMy42MTggMC00Mi40NzgtMTguODYtNDIuNDc4LTQyLjQ3OHYtNzQuMjUyYzAtMjMuNjE4IDE4Ljg2LTQyLjQ3OCA0Mi40NzgtNDIuNDc4aDczLjk5N2MyMy42MTggMCA0Mi40NzggMTguODYgNDIuNDc4IDQyLjQ3OHoiLz48L3N2Zz4=",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbRabbitMqNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java

@ -31,6 +31,7 @@ import org.springframework.web.client.HttpClientErrorException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -52,7 +53,8 @@ import java.util.concurrent.TimeUnit;
"For example <b>statusCode</b> field can be accessed with <code>metadata.statusCode</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeRestApiCallConfig",
iconUrl = "data:image/svg+xml;base64,PHN2ZyBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB2ZXJzaW9uPSIxLjEiIHk9IjBweCIgeD0iMHB4Ij48ZyB0cmFuc2Zvcm09Im1hdHJpeCguOTQ5NzUgMCAwIC45NDk3NSAxNy4xMiAyNi40OTIpIj48cGF0aCBkPSJtMTY5LjExIDEwOC41NGMtOS45MDY2IDAuMDczNC0xOS4wMTQgNi41NzI0LTIyLjAxNCAxNi40NjlsLTY5Ljk5MyAyMzEuMDhjLTMuNjkwNCAxMi4xODEgMy4yODkyIDI1LjIyIDE1LjQ2OSAyOC45MSAyLjIyNTkgMC42NzQ4MSA0LjQ5NjkgMSA2LjcyODUgMSA5Ljk3MjEgMCAxOS4xNjUtNi41MTUzIDIyLjE4Mi0xNi40NjdhNi41MjI0IDYuNTIyNCAwIDAgMCAwLjAwMiAtMC4wMDJsNjkuOTktMjMxLjA3YTYuNTIyNCA2LjUyMjQgMCAwIDAgMCAtMC4wMDJjMy42ODU1LTEyLjE4MS0zLjI4Ny0yNS4yMjUtMTUuNDcxLTI4LjkxMi0yLjI4MjUtMC42OTE0NS00LjYxMTYtMS4wMTY5LTYuODk4NC0xem04NC45ODggMGMtOS45MDQ4IDAuMDczNC0xOS4wMTggNi41Njc1LTIyLjAxOCAxNi40NjlsLTY5Ljk4NiAyMzEuMDhjLTMuNjg5OCAxMi4xNzkgMy4yODUzIDI1LjIxNyAxNS40NjUgMjguOTA4IDIuMjI5NyAwLjY3NjQ3IDQuNTAwOCAxLjAwMiA2LjczMjQgMS4wMDIgOS45NzIxIDAgMTkuMTY1LTYuNTE1MyAyMi4xODItMTYuNDY3YTYuNTIyNCA2LjUyMjQgMCAwIDAgMC4wMDIgLTAuMDAybDY5Ljk4OC0yMzEuMDdjMy42OTA4LTEyLjE4MS0zLjI4NTItMjUuMjIzLTE1LjQ2Ny0yOC45MTItMi4yODE0LTAuNjkyMzEtNC42MTA4LTEuMDE4OS02Ljg5ODQtMS4wMDJ6bS0yMTcuMjkgNDIuMjNjLTEyLjcyOS0wLjAwMDg3LTIzLjE4OCAxMC40NTYtMjMuMTg4IDIzLjE4NiAwLjAwMSAxMi43MjggMTAuNDU5IDIzLjE4NiAyMy4xODggMjMuMTg2IDEyLjcyNy0wLjAwMSAyMy4xODMtMTAuNDU5IDIzLjE4NC0yMy4xODYgMC4wMDA4NzYtMTIuNzI4LTEwLjQ1Ni0yMy4xODUtMjMuMTg0LTIzLjE4NnptMCAxNDYuNjRjLTEyLjcyNy0wLjAwMDg3LTIzLjE4NiAxMC40NTUtMjMuMTg4IDIzLjE4NC0wLjAwMDg3MyAxMi43MjkgMTAuNDU4IDIzLjE4OCAyMy4xODggMjMuMTg4IDEyLjcyOC0wLjAwMSAyMy4xODQtMTAuNDYgMjMuMTg0LTIzLjE4OC0wLjAwMS0xMi43MjYtMTAuNDU3LTIzLjE4My0yMy4xODQtMjMuMTg0em0yNzAuNzkgNDIuMjExYy0xMi43MjcgMC0yMy4xODQgMTAuNDU3LTIzLjE4NCAyMy4xODRzMTAuNDU1IDIzLjE4OCAyMy4xODQgMjMuMTg4aDE1NC45OGMxMi43MjkgMCAyMy4xODYtMTAuNDYgMjMuMTg2LTIzLjE4OCAwLjAwMS0xMi43MjgtMTAuNDU4LTIzLjE4NC0yMy4xODYtMjMuMTg0eiIgdHJhbnNmb3JtPSJtYXRyaXgoMS4wMzc2IDAgMCAxLjAzNzYgLTcuNTY3NiAtMTQuOTI1KSIgc3Ryb2tlLXdpZHRoPSIxLjI2OTMiLz48L2c+PC9zdmc+"
iconUrl = "data:image/svg+xml;base64,PHN2ZyBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB2ZXJzaW9uPSIxLjEiIHk9IjBweCIgeD0iMHB4Ij48ZyB0cmFuc2Zvcm09Im1hdHJpeCguOTQ5NzUgMCAwIC45NDk3NSAxNy4xMiAyNi40OTIpIj48cGF0aCBkPSJtMTY5LjExIDEwOC41NGMtOS45MDY2IDAuMDczNC0xOS4wMTQgNi41NzI0LTIyLjAxNCAxNi40NjlsLTY5Ljk5MyAyMzEuMDhjLTMuNjkwNCAxMi4xODEgMy4yODkyIDI1LjIyIDE1LjQ2OSAyOC45MSAyLjIyNTkgMC42NzQ4MSA0LjQ5NjkgMSA2LjcyODUgMSA5Ljk3MjEgMCAxOS4xNjUtNi41MTUzIDIyLjE4Mi0xNi40NjdhNi41MjI0IDYuNTIyNCAwIDAgMCAwLjAwMiAtMC4wMDJsNjkuOTktMjMxLjA3YTYuNTIyNCA2LjUyMjQgMCAwIDAgMCAtMC4wMDJjMy42ODU1LTEyLjE4MS0zLjI4Ny0yNS4yMjUtMTUuNDcxLTI4LjkxMi0yLjI4MjUtMC42OTE0NS00LjYxMTYtMS4wMTY5LTYuODk4NC0xem04NC45ODggMGMtOS45MDQ4IDAuMDczNC0xOS4wMTggNi41Njc1LTIyLjAxOCAxNi40NjlsLTY5Ljk4NiAyMzEuMDhjLTMuNjg5OCAxMi4xNzkgMy4yODUzIDI1LjIxNyAxNS40NjUgMjguOTA4IDIuMjI5NyAwLjY3NjQ3IDQuNTAwOCAxLjAwMiA2LjczMjQgMS4wMDIgOS45NzIxIDAgMTkuMTY1LTYuNTE1MyAyMi4xODItMTYuNDY3YTYuNTIyNCA2LjUyMjQgMCAwIDAgMC4wMDIgLTAuMDAybDY5Ljk4OC0yMzEuMDdjMy42OTA4LTEyLjE4MS0zLjI4NTItMjUuMjIzLTE1LjQ2Ny0yOC45MTItMi4yODE0LTAuNjkyMzEtNC42MTA4LTEuMDE4OS02Ljg5ODQtMS4wMDJ6bS0yMTcuMjkgNDIuMjNjLTEyLjcyOS0wLjAwMDg3LTIzLjE4OCAxMC40NTYtMjMuMTg4IDIzLjE4NiAwLjAwMSAxMi43MjggMTAuNDU5IDIzLjE4NiAyMy4xODggMjMuMTg2IDEyLjcyNy0wLjAwMSAyMy4xODMtMTAuNDU5IDIzLjE4NC0yMy4xODYgMC4wMDA4NzYtMTIuNzI4LTEwLjQ1Ni0yMy4xODUtMjMuMTg0LTIzLjE4NnptMCAxNDYuNjRjLTEyLjcyNy0wLjAwMDg3LTIzLjE4NiAxMC40NTUtMjMuMTg4IDIzLjE4NC0wLjAwMDg3MyAxMi43MjkgMTAuNDU4IDIzLjE4OCAyMy4xODggMjMuMTg4IDEyLjcyOC0wLjAwMSAyMy4xODQtMTAuNDYgMjMuMTg0LTIzLjE4OC0wLjAwMS0xMi43MjYtMTAuNDU3LTIzLjE4My0yMy4xODQtMjMuMTg0em0yNzAuNzkgNDIuMjExYy0xMi43MjcgMC0yMy4xODQgMTAuNDU3LTIzLjE4NCAyMy4xODRzMTAuNDU1IDIzLjE4OCAyMy4xODQgMjMuMTg4aDE1NC45OGMxMi43MjkgMCAyMy4xODYtMTAuNDYgMjMuMTg2LTIzLjE4OCAwLjAwMS0xMi43MjgtMTAuNDU4LTIzLjE4NC0yMy4xODYtMjMuMTg0eiIgdHJhbnNmb3JtPSJtYXRyaXgoMS4wMzc2IDAgMCAxLjAzNzYgLTcuNTY3NiAtMTQuOTI1KSIgc3Ryb2tlLXdpZHRoPSIxLjI2OTMiLz48L2c+PC9zdmc+",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbRestApiCallNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java

@ -26,6 +26,7 @@ import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@Slf4j
@ -37,7 +38,8 @@ import org.thingsboard.server.common.msg.TbMsg;
nodeDetails = "Expects messages with any message type. Will forward message body to the device.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeRpcReplyConfig",
icon = "call_merge"
icon = "call_merge",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbSendRPCReplyNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java

@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.io.IOException;
@ -53,7 +54,8 @@ import java.util.concurrent.TimeUnit;
"If the RPC call request is originated by REST API call from user, will forward the response to user immediately.",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeRpcRequestConfig",
icon = "call_made"
icon = "call_made",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbSendRPCRequestNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java

@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
@ -44,7 +45,8 @@ import java.util.Set;
nodeDetails = "Saves entity attributes based on configurable scope parameter. Expects messages with 'POST_ATTRIBUTES_REQUEST' message type",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbActionNodeAttributesConfig",
icon = "file_upload"
icon = "file_upload",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbMsgAttributesNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java

@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
import org.thingsboard.server.common.data.kv.KvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
@ -45,7 +46,8 @@ import java.util.Map;
nodeDetails = "Saves timeseries telemetry data based on configurable TTL parameter. Expects messages with 'POST_TELEMETRY_REQUEST' message type",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbActionNodeTimeseriesConfig",
icon = "file_upload"
icon = "file_upload",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbMsgTimeseriesNode implements TbNode {

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java

@ -24,6 +24,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgTransactionData;
@ -42,7 +43,9 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
"Subsequent messages will not be processed until the previous message processing is completed or timeout event occurs.\n" +
"Size of the queue per originator and timeout values are configurable on a system level",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbNodeEmptyConfig")
configDirective = "tbNodeEmptyConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbSynchronizationBeginNode implements TbNode {
private EmptyNodeConfiguration config;

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationEndNode.java

@ -24,6 +24,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.concurrent.ExecutionException;
@ -38,7 +39,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
nodeDescription = "Stops synchronization of message processing based on message originator",
nodeDetails = "",
uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = ("tbNodeEmptyConfig")
configDirective = ("tbNodeEmptyConfig"),
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbSynchronizationEndNode implements TbNode {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java

@ -31,6 +31,7 @@ import org.thingsboard.rule.engine.util.EntitiesRelatedEntityIdAsyncLoader;
import org.thingsboard.rule.engine.util.EntitiesTenantIdAsyncLoader;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.HashSet;
@ -46,7 +47,8 @@ import java.util.HashSet;
"Alarm Originator found only in case original Originator is <code>Alarm</code> entity.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbTransformationNodeChangeOriginatorConfig",
icon = "find_replace"
icon = "find_replace",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbChangeOriginatorNode extends TbAbstractTransformNode {

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java

@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg;
@RuleNode(
@ -34,7 +35,9 @@ import org.thingsboard.server.common.msg.TbMsg;
"<code>{ msg: <i style=\"color: #666;\">new payload</i>,<br/>&nbsp&nbsp&nbspmetadata: <i style=\"color: #666;\">new metadata</i>,<br/>&nbsp&nbsp&nbspmsgType: <i style=\"color: #666;\">new msgType</i> }</code><br/>" +
"All fields in resulting object are optional and will be taken from original message if not specified.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbTransformationNodeScriptConfig")
configDirective = "tbTransformationNodeScriptConfig",
ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
)
public class TbTransformMsgNode extends TbAbstractTransformNode {
private TbTransformMsgNodeConfiguration config;

73
ui/src/app/api/component-descriptor.service.js

@ -21,60 +21,38 @@ function ComponentDescriptorService($http, $q) {
var componentsByType = {};
var componentsByClazz = {};
var actionsByPlugin = {};
var service = {
getComponentDescriptorsByType: getComponentDescriptorsByType,
getComponentDescriptorByClazz: getComponentDescriptorByClazz,
getPluginActionsByPluginClazz: getPluginActionsByPluginClazz,
getComponentDescriptorsByTypes: getComponentDescriptorsByTypes
}
return service;
function getComponentDescriptorsByType(componentType) {
var deferred = $q.defer();
if (componentsByType[componentType]) {
deferred.resolve(componentsByType[componentType]);
} else {
var url = '/api/components/' + componentType;
$http.get(url, null).then(function success(response) {
componentsByType[componentType] = response.data;
for (var i = 0; i < componentsByType[componentType].length; i++) {
var component = componentsByType[componentType][i];
componentsByClazz[component.clazz] = component;
}
deferred.resolve(componentsByType[componentType]);
}, function fail() {
deferred.reject();
});
}
return deferred.promise;
}
function getComponentDescriptorsByTypes(componentTypes) {
function getComponentDescriptorsByTypes(componentTypes, ruleChainType) {
var deferred = $q.defer();
var result = [];
if (!componentsByType[ruleChainType]) {
componentsByType[ruleChainType] = {};
}
for (var i=componentTypes.length-1;i>=0;i--) {
var componentType = componentTypes[i];
if (componentsByType[componentType]) {
result = result.concat(componentsByType[componentType]);
if (componentsByType[ruleChainType][componentType]) {
result = result.concat(componentsByType[ruleChainType][componentType]);
componentTypes.splice(i, 1);
}
}
if (!componentTypes.length) {
deferred.resolve(result);
} else {
var url = '/api/components?componentTypes=' + componentTypes.join(',');
var url = '/api/components/' + ruleChainType + '?componentTypes=' + componentTypes.join(',');
$http.get(url, null).then(function success(response) {
var components = response.data;
for (var i = 0; i < components.length; i++) {
var component = components[i];
var componentsList = componentsByType[component.type];
var componentsList = componentsByType[ruleChainType][component.type];
if (!componentsList) {
componentsList = [];
componentsByType[component.type] = componentsList;
componentsByType[ruleChainType][component.type] = componentsList;
}
componentsList.push(component);
componentsByClazz[component.clazz] = component;
@ -87,37 +65,4 @@ function ComponentDescriptorService($http, $q) {
}
return deferred.promise;
}
function getComponentDescriptorByClazz(componentDescriptorClazz) {
var deferred = $q.defer();
if (componentsByClazz[componentDescriptorClazz]) {
deferred.resolve(componentsByClazz[componentDescriptorClazz]);
} else {
var url = '/api/component/' + componentDescriptorClazz;
$http.get(url, null).then(function success(response) {
componentsByClazz[componentDescriptorClazz] = response.data;
deferred.resolve(componentsByClazz[componentDescriptorClazz]);
}, function fail() {
deferred.reject();
});
}
return deferred.promise;
}
function getPluginActionsByPluginClazz(pluginClazz) {
var deferred = $q.defer();
if (actionsByPlugin[pluginClazz]) {
deferred.resolve(actionsByPlugin[pluginClazz]);
} else {
var url = '/api/components/actions/' + pluginClazz;
$http.get(url, null).then(function success(response) {
actionsByPlugin[pluginClazz] = response.data;
deferred.resolve(actionsByPlugin[pluginClazz]);
}, function fail() {
deferred.reject();
});
}
return deferred.promise;
}
}

26
ui/src/app/api/rule-chain.service.js

@ -19,7 +19,7 @@ export default angular.module('thingsboard.api.ruleChain', [])
/*@ngInject*/
function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, componentDescriptorService) {
var ruleNodeComponents = null;
var ruleNodeComponents = {};
var service = {
getRuleChains: getRuleChains,
@ -154,20 +154,20 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
return component.configurationDescriptor.nodeDefinition.customRelations;
}
function getRuleNodeComponents() {
function getRuleNodeComponents(ruleChainType) {
var deferred = $q.defer();
if (ruleNodeComponents) {
deferred.resolve(ruleNodeComponents);
if (ruleNodeComponents[ruleChainType]) {
deferred.resolve(ruleNodeComponents[ruleChainType]);
} else {
loadRuleNodeComponents().then(
loadRuleNodeComponents(ruleChainType).then(
(components) => {
resolveRuleNodeComponentsUiResources(components).then(
(components) => {
ruleNodeComponents = components;
ruleNodeComponents.push(
ruleNodeComponents[ruleChainType] = components;
ruleNodeComponents[ruleChainType].push(
types.ruleChainNodeComponent
);
ruleNodeComponents.sort(
ruleNodeComponents[ruleChainType].sort(
(comp1, comp2) => {
var result = comp1.type.localeCompare(comp2.type);
if (result == 0) {
@ -176,7 +176,7 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
return result;
}
);
deferred.resolve(ruleNodeComponents);
deferred.resolve(ruleNodeComponents[ruleChainType]);
},
() => {
deferred.reject();
@ -233,8 +233,8 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
return deferred.promise;
}
function getRuleNodeComponentByClazz(clazz) {
var res = $filter('filter')(ruleNodeComponents, {clazz: clazz}, true);
function getRuleNodeComponentByClazz(clazz, ruleNodeType) {
var res = $filter('filter')(ruleNodeComponents[ruleNodeType], {clazz: clazz}, true);
if (res && res.length) {
return res[0];
}
@ -284,8 +284,8 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
return deferred.promise;
}
function loadRuleNodeComponents() {
return componentDescriptorService.getComponentDescriptorsByTypes(types.ruleNodeTypeComponentTypes);
function loadRuleNodeComponents(ruleChainType) {
return componentDescriptorService.getComponentDescriptorsByTypes(types.ruleNodeTypeComponentTypes, ruleChainType);
}
function testScript(inputParams) {

4
ui/src/app/rulechain/rulechain.controller.js

@ -774,7 +774,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
x = scrollLeft + scrollParent.width()/2;
y = scrollTop + scrollParent.height()/2;
}
var ruleNodes = itembuffer.pasteRuleNodes(x, y, event);
var ruleNodes = itembuffer.pasteRuleNodes(vm.ruleChain.type, x, y);
if (ruleNodes) {
vm.modelservice.deselectAll();
var nodes = [];
@ -972,7 +972,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
var nodes = [];
for (var i=0;i<vm.ruleChainMetaData.nodes.length;i++) {
var ruleNode = vm.ruleChainMetaData.nodes[i];
var component = ruleChainService.getRuleNodeComponentByClazz(ruleNode.type);
var component = ruleChainService.getRuleNodeComponentByClazz(ruleNode.type, vm.ruleChain.type);
if (component) {
var icon = vm.types.ruleNodeType[component.type].icon;
var iconUrl = null;

10
ui/src/app/rulechain/rulechain.routes.js

@ -22,7 +22,7 @@ import ruleChainTemplate from './rulechain.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/
export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider) {
export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider, types) {
NodeTemplatePathProvider.setTemplatePath(ruleNodeTemplate);
@ -82,7 +82,7 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
ruleNodeComponents:
/*@ngInject*/
function($stateParams, ruleChainService) {
return ruleChainService.getRuleNodeComponents();
return ruleChainService.getRuleNodeComponents(types.systemRuleChainType);
}
},
data: {
@ -122,7 +122,7 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
ruleNodeComponents:
/*@ngInject*/
function($stateParams, ruleChainService) {
return ruleChainService.getRuleNodeComponents();
return ruleChainService.getRuleNodeComponents(types.systemRuleChainType);
}
},
data: {
@ -179,7 +179,7 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
ruleNodeComponents:
/*@ngInject*/
function($stateParams, ruleChainService) {
return ruleChainService.getRuleNodeComponents();
return ruleChainService.getRuleNodeComponents(types.edgeRuleChainType);
}
},
data: {
@ -236,7 +236,7 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
ruleNodeComponents:
/*@ngInject*/
function($stateParams, ruleChainService) {
return ruleChainService.getRuleNodeComponents();
return ruleChainService.getRuleNodeComponents(types.edgeRuleChainType);
}
},
data: {

4
ui/src/app/services/item-buffer.service.js

@ -204,7 +204,7 @@ function ItemBuffer($q, bufferStore, types, utils, dashboardUtils, ruleChainServ
return bufferStore.get(RULE_NODES);
}
function pasteRuleNodes(x, y) {
function pasteRuleNodes(ruleChainType, x, y) {
var ruleNodesJson = bufferStore.get(RULE_NODES);
if (ruleNodesJson) {
var ruleNodes = angular.fromJson(ruleNodesJson);
@ -212,7 +212,7 @@ function ItemBuffer($q, bufferStore, types, utils, dashboardUtils, ruleChainServ
var deltaY = y - ruleNodes.originY;
for (var i=0;i<ruleNodes.nodes.length;i++) {
var node = ruleNodes.nodes[i];
var component = ruleChainService.getRuleNodeComponentByClazz(node.componentClazz);
var component = ruleChainService.getRuleNodeComponentByClazz(node.componentClazz, ruleChainType);
if (component) {
var icon = types.ruleNodeType[component.type].icon;
var iconUrl = null;

Loading…
Cancel
Save