Merge branch 'feature/edge-last-week' into feature/edge
This commit is contained in:
commit
bb95ce99f8
@ -0,0 +1,145 @@
|
||||
{
|
||||
"ruleChain": {
|
||||
"additionalInfo": null,
|
||||
"name": "Edge Root Rule Chain",
|
||||
"type": "EDGE",
|
||||
"firstRuleNodeId": null,
|
||||
"root": true,
|
||||
"debugMode": false,
|
||||
"configuration": null,
|
||||
"assignedEdges": [],
|
||||
"assignedEdgesIds": []
|
||||
},
|
||||
"metadata": {
|
||||
"firstNodeIndex": 2,
|
||||
"nodes": [
|
||||
{
|
||||
"additionalInfo": {
|
||||
"layoutX": 823,
|
||||
"layoutY": 157
|
||||
},
|
||||
"type": "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode",
|
||||
"name": "Save Timeseries",
|
||||
"debugMode": false,
|
||||
"configuration": {
|
||||
"defaultTTL": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"additionalInfo": {
|
||||
"layoutX": 824,
|
||||
"layoutY": 52
|
||||
},
|
||||
"type": "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode",
|
||||
"name": "Save Client Attributes",
|
||||
"debugMode": false,
|
||||
"configuration": {
|
||||
"scope": "CLIENT_SCOPE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"additionalInfo": {
|
||||
"layoutX": 347,
|
||||
"layoutY": 149
|
||||
},
|
||||
"type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode",
|
||||
"name": "Message Type Switch",
|
||||
"debugMode": false,
|
||||
"configuration": {
|
||||
"version": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"additionalInfo": {
|
||||
"layoutX": 825,
|
||||
"layoutY": 266
|
||||
},
|
||||
"type": "org.thingsboard.rule.engine.action.TbLogNode",
|
||||
"name": "Log RPC from Device",
|
||||
"debugMode": false,
|
||||
"configuration": {
|
||||
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
|
||||
}
|
||||
},
|
||||
{
|
||||
"additionalInfo": {
|
||||
"layoutX": 824,
|
||||
"layoutY": 378
|
||||
},
|
||||
"type": "org.thingsboard.rule.engine.action.TbLogNode",
|
||||
"name": "Log Other",
|
||||
"debugMode": false,
|
||||
"configuration": {
|
||||
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
|
||||
}
|
||||
},
|
||||
{
|
||||
"additionalInfo": {
|
||||
"layoutX": 824,
|
||||
"layoutY": 466
|
||||
},
|
||||
"type": "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode",
|
||||
"name": "RPC Call Request",
|
||||
"debugMode": false,
|
||||
"configuration": {
|
||||
"timeoutInSeconds": 60
|
||||
}
|
||||
},
|
||||
{
|
||||
"additionalInfo": {
|
||||
"layoutX": 1134,
|
||||
"layoutY": 132
|
||||
},
|
||||
"type": "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode",
|
||||
"name": "Push to cloud",
|
||||
"debugMode": false,
|
||||
"configuration": {
|
||||
"version": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"fromIndex": 0,
|
||||
"toIndex": 6,
|
||||
"type": "Success"
|
||||
},
|
||||
{
|
||||
"fromIndex": 1,
|
||||
"toIndex": 6,
|
||||
"type": "Success"
|
||||
},
|
||||
{
|
||||
"fromIndex": 2,
|
||||
"toIndex": 4,
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"fromIndex": 2,
|
||||
"toIndex": 1,
|
||||
"type": "Post attributes"
|
||||
},
|
||||
{
|
||||
"fromIndex": 2,
|
||||
"toIndex": 0,
|
||||
"type": "Post telemetry"
|
||||
},
|
||||
{
|
||||
"fromIndex": 2,
|
||||
"toIndex": 3,
|
||||
"type": "RPC Request from Device"
|
||||
},
|
||||
{
|
||||
"fromIndex": 2,
|
||||
"toIndex": 5,
|
||||
"type": "RPC Request to Device"
|
||||
},
|
||||
{
|
||||
"fromIndex": 3,
|
||||
"toIndex": 6,
|
||||
"type": "Success"
|
||||
}
|
||||
],
|
||||
"ruleChainConnections": null
|
||||
}
|
||||
}
|
||||
@ -2,9 +2,9 @@
|
||||
"ruleChain": {
|
||||
"additionalInfo": null,
|
||||
"name": "Root Rule Chain",
|
||||
"type": "SYSTEM",
|
||||
"firstRuleNodeId": null,
|
||||
"root": true,
|
||||
"type": "SYSTEM",
|
||||
"debugMode": false,
|
||||
"configuration": null
|
||||
},
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
@RequestMapping(value = "/components/{ruleChainType}", params = {"componentTypes"}, 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)
|
||||
@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);
|
||||
}
|
||||
|
||||
@ -90,9 +90,9 @@ public class EdgeController extends BaseController {
|
||||
Edge result = checkNotNull(edgeService.saveEdge(edge));
|
||||
|
||||
if (created) {
|
||||
RuleChain rootTenantRuleChain = ruleChainService.getRootTenantRuleChain(tenantId);
|
||||
ruleChainService.assignRuleChainToEdge(tenantId, rootTenantRuleChain.getId(), result.getId());
|
||||
edgeService.setRootRuleChain(tenantId, result, rootTenantRuleChain.getId());
|
||||
RuleChain defaultRootEdgeRuleChain = ruleChainService.getDefaultRootEdgeRuleChain(tenantId);
|
||||
ruleChainService.assignRuleChainToEdge(tenantId, defaultRootEdgeRuleChain.getId(), result.getId());
|
||||
edgeService.setRootRuleChain(tenantId, result, defaultRootEdgeRuleChain.getId());
|
||||
}
|
||||
|
||||
logEntityAction(result.getId(), result, null, created ? ActionType.ADDED : ActionType.UPDATED, null);
|
||||
|
||||
@ -430,7 +430,7 @@ public class RuleChainController extends BaseController {
|
||||
RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId));
|
||||
RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.UNASSIGN_FROM_EDGE);
|
||||
|
||||
RuleChain savedRuleChain = checkNotNull(ruleChainService.unassignRuleChainFromEdge(getCurrentUser().getTenantId(), ruleChainId, edgeId));
|
||||
RuleChain savedRuleChain = checkNotNull(ruleChainService.unassignRuleChainFromEdge(getCurrentUser().getTenantId(), ruleChainId, edgeId, false));
|
||||
|
||||
logEntityAction(ruleChainId, ruleChain,
|
||||
null,
|
||||
@ -494,7 +494,7 @@ public class RuleChainController extends BaseController {
|
||||
}
|
||||
for (EdgeId edgeId : removedEdgeIds) {
|
||||
ShortEdgeInfo edgeInfo = ruleChain.getAssignedEdgeInfo(edgeId);
|
||||
savedRuleChain = checkNotNull(ruleChainService.unassignRuleChainFromEdge(getCurrentUser().getTenantId(), ruleChainId, edgeId));
|
||||
savedRuleChain = checkNotNull(ruleChainService.unassignRuleChainFromEdge(getCurrentUser().getTenantId(), ruleChainId, edgeId, false));
|
||||
logEntityAction(ruleChainId, ruleChain,
|
||||
null,
|
||||
ActionType.UNASSIGNED_FROM_EDGE, null, strRuleChainId, edgeId.toString(), edgeInfo.getTitle());
|
||||
@ -581,7 +581,7 @@ public class RuleChainController extends BaseController {
|
||||
RuleChain savedRuleChain = null;
|
||||
for (EdgeId edgeId : edgeIds) {
|
||||
ShortEdgeInfo edgeInfo = ruleChain.getAssignedEdgeInfo(edgeId);
|
||||
savedRuleChain = checkNotNull(ruleChainService.unassignRuleChainFromEdge(getCurrentUser().getTenantId(), ruleChainId, edgeId));
|
||||
savedRuleChain = checkNotNull(ruleChainService.unassignRuleChainFromEdge(getCurrentUser().getTenantId(), ruleChainId, edgeId, false));
|
||||
logEntityAction(ruleChainId, ruleChain,
|
||||
null,
|
||||
ActionType.UNASSIGNED_FROM_EDGE, null, strRuleChainId, edgeId.toString(), edgeInfo.getTitle());
|
||||
@ -620,4 +620,23 @@ public class RuleChainController extends BaseController {
|
||||
throw handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
|
||||
@RequestMapping(value = "/ruleChain/{ruleChainId}/defaultRootEdge", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public RuleChain setDefaultRootEdgeRuleChain(@PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException {
|
||||
checkParameter(RULE_CHAIN_ID, strRuleChainId);
|
||||
try {
|
||||
RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId));
|
||||
RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.WRITE);
|
||||
ruleChainService.setDefaultRootEdgeRuleChain(getTenantId(), ruleChainId);
|
||||
return ruleChain;
|
||||
} catch (Exception e) {
|
||||
logEntityAction(emptyId(EntityType.RULE_CHAIN),
|
||||
null,
|
||||
null,
|
||||
ActionType.UPDATED, e, strRuleChainId);
|
||||
throw handleException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 List<ComponentDescriptor> persist(Set<BeanDefinition> filterDefs, ComponentType type) {
|
||||
List<ComponentDescriptor> result = new ArrayList<>();
|
||||
for (BeanDefinition def : filterDefs) {
|
||||
result.add(scanAndPersistComponent(def, type));
|
||||
private void putComponentIntoMaps(ComponentType type, RuleNode ruleNodeAnnotation, ComponentDescriptor component) {
|
||||
if (ruleChainTypeContainsArray(RuleChainType.SYSTEM, ruleNodeAnnotation.ruleChainTypes())) {
|
||||
systemComponentsMap.computeIfAbsent(type, k -> new ArrayList<>()).add(component);
|
||||
}
|
||||
return result;
|
||||
if (ruleChainTypeContainsArray(RuleChainType.EDGE, ruleNodeAnnotation.ruleChainTypes())) {
|
||||
edgeComponentsMap.computeIfAbsent(type, k -> new ArrayList<>()).add(component);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean ruleChainTypeContainsArray(RuleChainType ruleChainType, RuleChainType[] array) {
|
||||
for (RuleChainType tmp : array) {
|
||||
if (ruleChainType.equals(tmp)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -29,6 +29,13 @@ import org.thingsboard.server.dao.device.DeviceService;
|
||||
import org.thingsboard.server.dao.edge.EdgeService;
|
||||
import org.thingsboard.server.dao.entityview.EntityViewService;
|
||||
import org.thingsboard.server.dao.relation.RelationService;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.AlarmUpdateMsgConstructor;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.AssetUpdateMsgConstructor;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.DashboardUpdateMsgConstructor;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.DeviceUpdateMsgConstructor;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.EntityViewUpdateMsgConstructor;
|
||||
import org.thingsboard.server.service.edge.rpc.init.InitEdgeService;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.RuleChainUpdateMsgConstructor;
|
||||
|
||||
@Component
|
||||
@Data
|
||||
@ -73,4 +80,32 @@ public class EdgeContextComponent {
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ActorService actorService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private InitEdgeService initEdgeService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private RuleChainUpdateMsgConstructor ruleChainUpdateMsgConstructor;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private AlarmUpdateMsgConstructor alarmUpdateMsgConstructor;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private DeviceUpdateMsgConstructor deviceUpdateMsgConstructor;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private AssetUpdateMsgConstructor assetUpdateMsgConstructor;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private EntityViewUpdateMsgConstructor entityViewUpdateMsgConstructor;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private DashboardUpdateMsgConstructor dashboardUpdateMsgConstructor;
|
||||
}
|
||||
|
||||
@ -30,7 +30,6 @@ import org.thingsboard.server.common.data.Customer;
|
||||
import org.thingsboard.server.common.data.Dashboard;
|
||||
import org.thingsboard.server.common.data.DataConstants;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.EntityView;
|
||||
import org.thingsboard.server.common.data.Event;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
@ -38,7 +37,6 @@ import org.thingsboard.server.common.data.alarm.Alarm;
|
||||
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
||||
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.common.data.audit.ActionType;
|
||||
import org.thingsboard.server.common.data.edge.Edge;
|
||||
import org.thingsboard.server.common.data.edge.EdgeQueueEntry;
|
||||
import org.thingsboard.server.common.data.id.AssetId;
|
||||
@ -46,7 +44,6 @@ import org.thingsboard.server.common.data.id.CustomerId;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.common.data.id.EdgeId;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
||||
import org.thingsboard.server.common.data.id.EntityViewId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
|
||||
@ -57,48 +54,36 @@ import org.thingsboard.server.common.data.page.TimePageData;
|
||||
import org.thingsboard.server.common.data.page.TimePageLink;
|
||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||
import org.thingsboard.server.common.data.rule.NodeConnectionInfo;
|
||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||
import org.thingsboard.server.common.msg.TbMsg;
|
||||
import org.thingsboard.server.common.msg.TbMsgDataType;
|
||||
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
||||
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
|
||||
import org.thingsboard.server.common.msg.session.SessionMsgType;
|
||||
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
||||
import org.thingsboard.server.dao.util.mapping.JacksonUtil;
|
||||
import org.thingsboard.server.gen.edge.AlarmUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.AssetUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.ConnectRequestMsg;
|
||||
import org.thingsboard.server.gen.edge.ConnectResponseCode;
|
||||
import org.thingsboard.server.gen.edge.ConnectResponseMsg;
|
||||
import org.thingsboard.server.gen.edge.CustomerUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.DashboardUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.DeviceUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.DownlinkMsg;
|
||||
import org.thingsboard.server.gen.edge.EdgeConfiguration;
|
||||
import org.thingsboard.server.gen.edge.EntityDataProto;
|
||||
import org.thingsboard.server.gen.edge.EntityUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.EntityViewUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.NodeConnectionInfoProto;
|
||||
import org.thingsboard.server.gen.edge.RequestMsg;
|
||||
import org.thingsboard.server.gen.edge.RequestMsgType;
|
||||
import org.thingsboard.server.gen.edge.ResponseMsg;
|
||||
import org.thingsboard.server.gen.edge.RuleChainConnectionInfoProto;
|
||||
import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg;
|
||||
import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.RuleChainUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.RuleNodeProto;
|
||||
import org.thingsboard.server.gen.edge.UpdateMsgType;
|
||||
import org.thingsboard.server.gen.edge.UplinkMsg;
|
||||
import org.thingsboard.server.gen.edge.UplinkResponseMsg;
|
||||
import org.thingsboard.server.gen.edge.UserUpdateMsg;
|
||||
import org.thingsboard.server.service.edge.EdgeContextComponent;
|
||||
|
||||
import javax.swing.text.html.parser.Entity;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@ -109,7 +94,6 @@ import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.thingsboard.server.gen.edge.UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE;
|
||||
import static org.thingsboard.server.gen.edge.UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE;
|
||||
|
||||
@Slf4j
|
||||
@Data
|
||||
@ -151,6 +135,9 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
if (ConnectResponseCode.ACCEPTED != responseMsg.getResponseCode()) {
|
||||
outputStream.onError(new RuntimeException(responseMsg.getErrorMsg()));
|
||||
}
|
||||
if (ConnectResponseCode.ACCEPTED == responseMsg.getResponseCode()) {
|
||||
ctx.getInitEdgeService().init(edge, outputStream);
|
||||
}
|
||||
}
|
||||
if (connected) {
|
||||
if (requestMsg.getMsgType().equals(RequestMsgType.UPLINK_RPC_MESSAGE) && requestMsg.hasUplinkMsg()) {
|
||||
@ -174,15 +161,14 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void processHandleMessages() throws ExecutionException, InterruptedException {
|
||||
Long queueStartTs = getQueueStartTs().get();
|
||||
// TODO: this 100 value must be changed properly
|
||||
TimePageLink pageLink = new TimePageLink(30, queueStartTs + 1000);
|
||||
TimePageLink pageLink = new TimePageLink(30, queueStartTs + 1000, null, true);
|
||||
TimePageData<Event> pageData;
|
||||
UUID ifOffset = null;
|
||||
do {
|
||||
pageData = ctx.getEdgeService().findQueueEvents(edge.getTenantId(), edge.getId(), pageLink);
|
||||
pageData = ctx.getEdgeService().findQueueEvents(edge.getTenantId(), edge.getId(), pageLink);
|
||||
if (!pageData.getData().isEmpty()) {
|
||||
log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size());
|
||||
for (Event event : pageData.getData()) {
|
||||
@ -377,7 +363,7 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
|
||||
private void onDeviceUpdated(UpdateMsgType msgType, Device device) {
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setDeviceUpdateMsg(constructDeviceUpdatedMsg(msgType, device))
|
||||
.setDeviceUpdateMsg(ctx.getDeviceUpdateMsgConstructor().constructDeviceUpdatedMsg(msgType, device))
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
@ -386,7 +372,7 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
|
||||
private void onAssetUpdated(UpdateMsgType msgType, Asset asset) {
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setAssetUpdateMsg(constructAssetUpdatedMsg(msgType, asset))
|
||||
.setAssetUpdateMsg(ctx.getAssetUpdateMsgConstructor().constructAssetUpdatedMsg(msgType, asset))
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
@ -395,7 +381,7 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
|
||||
private void onEntityViewUpdated(UpdateMsgType msgType, EntityView entityView) {
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setEntityViewUpdateMsg(constructEntityViewUpdatedMsg(msgType, entityView))
|
||||
.setEntityViewUpdateMsg(ctx.getEntityViewUpdateMsgConstructor().constructEntityViewUpdatedMsg(msgType, entityView))
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
@ -404,7 +390,7 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
|
||||
private void onRuleChainUpdated(UpdateMsgType msgType, RuleChain ruleChain) {
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setRuleChainUpdateMsg(constructRuleChainUpdatedMsg(msgType, ruleChain))
|
||||
.setRuleChainUpdateMsg(ctx.getRuleChainUpdateMsgConstructor().constructRuleChainUpdatedMsg(edge, msgType, ruleChain))
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
@ -412,7 +398,8 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
}
|
||||
|
||||
private void onRuleChainMetadataUpdated(UpdateMsgType msgType, RuleChainMetaData ruleChainMetaData) {
|
||||
RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = constructRuleChainMetadataUpdatedMsg(msgType, ruleChainMetaData);
|
||||
RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg =
|
||||
ctx.getRuleChainUpdateMsgConstructor().constructRuleChainMetadataUpdatedMsg(msgType, ruleChainMetaData);
|
||||
if (ruleChainMetadataUpdateMsg != null) {
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setRuleChainMetadataUpdateMsg(ruleChainMetadataUpdateMsg)
|
||||
@ -425,7 +412,7 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
|
||||
private void onDashboardUpdated(UpdateMsgType msgType, Dashboard dashboard) {
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setDashboardUpdateMsg(constructDashboardUpdatedMsg(msgType, dashboard))
|
||||
.setDashboardUpdateMsg(ctx.getDashboardUpdateMsgConstructor().constructDashboardUpdatedMsg(msgType, dashboard))
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
@ -434,43 +421,13 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
|
||||
private void onAlarmUpdated(UpdateMsgType msgType, Alarm alarm) {
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setAlarmUpdateMsg(constructAlarmUpdatedMsg(msgType, alarm))
|
||||
.setAlarmUpdateMsg(ctx.getAlarmUpdateMsgConstructor().constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm))
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
.build());
|
||||
}
|
||||
|
||||
private AlarmUpdateMsg constructAlarmUpdatedMsg(UpdateMsgType msgType, Alarm alarm) {
|
||||
String entityName = null;
|
||||
switch (alarm.getOriginator().getEntityType()) {
|
||||
case DEVICE:
|
||||
entityName = ctx.getDeviceService().findDeviceById(edge.getTenantId(), new DeviceId(alarm.getOriginator().getId())).getName();
|
||||
break;
|
||||
case ASSET:
|
||||
entityName = ctx.getAssetService().findAssetById(edge.getTenantId(), new AssetId(alarm.getOriginator().getId())).getName();
|
||||
break;
|
||||
case ENTITY_VIEW:
|
||||
entityName = ctx.getEntityViewService().findEntityViewById(edge.getTenantId(), new EntityViewId(alarm.getOriginator().getId())).getName();
|
||||
break;
|
||||
}
|
||||
AlarmUpdateMsg.Builder builder = AlarmUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setName(alarm.getName())
|
||||
.setType(alarm.getType())
|
||||
.setOriginatorName(entityName)
|
||||
.setOriginatorType(alarm.getOriginator().getEntityType().name())
|
||||
.setSeverity(alarm.getSeverity().name())
|
||||
.setStatus(alarm.getStatus().name())
|
||||
.setStartTs(alarm.getStartTs())
|
||||
.setEndTs(alarm.getEndTs())
|
||||
.setAckTs(alarm.getAckTs())
|
||||
.setClearTs(alarm.getClearTs())
|
||||
.setDetails(JacksonUtil.toString(alarm.getDetails()))
|
||||
.setPropagate(alarm.isPropagate());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private UpdateMsgType getResponseMsgType(String msgType) {
|
||||
if (msgType.equals(SessionMsgType.POST_TELEMETRY_REQUEST.name()) ||
|
||||
msgType.equals(SessionMsgType.POST_ATTRIBUTES_REQUEST.name()) ||
|
||||
@ -497,22 +454,6 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
private RuleChainUpdateMsg constructRuleChainUpdatedMsg(UpdateMsgType msgType, RuleChain ruleChain) {
|
||||
RuleChainUpdateMsg.Builder builder = RuleChainUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setIdMSB(ruleChain.getId().getId().getMostSignificantBits())
|
||||
.setIdLSB(ruleChain.getId().getId().getLeastSignificantBits())
|
||||
.setName(ruleChain.getName())
|
||||
.setRoot(ruleChain.getId().equals(edge.getRootRuleChainId()))
|
||||
.setDebugMode(ruleChain.isDebugMode())
|
||||
.setConfiguration(JacksonUtil.toString(ruleChain.getConfiguration()));
|
||||
if (ruleChain.getFirstRuleNodeId() != null) {
|
||||
builder.setFirstRuleNodeIdMSB(ruleChain.getFirstRuleNodeId().getId().getMostSignificantBits())
|
||||
.setFirstRuleNodeIdLSB(ruleChain.getFirstRuleNodeId().getId().getLeastSignificantBits());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private DownlinkMsg constructDownlinkEntityDataMsg(String entityName, TbMsg tbMsg) {
|
||||
EntityDataProto entityData = EntityDataProto.newBuilder()
|
||||
.setEntityName(entityName)
|
||||
@ -524,96 +465,6 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private RuleChainMetadataUpdateMsg constructRuleChainMetadataUpdatedMsg(UpdateMsgType msgType, RuleChainMetaData ruleChainMetaData) {
|
||||
try {
|
||||
RuleChainMetadataUpdateMsg.Builder builder = RuleChainMetadataUpdateMsg.newBuilder()
|
||||
.setRuleChainIdMSB(ruleChainMetaData.getRuleChainId().getId().getMostSignificantBits())
|
||||
.setRuleChainIdLSB(ruleChainMetaData.getRuleChainId().getId().getLeastSignificantBits())
|
||||
.addAllNodes(constructNodes(ruleChainMetaData.getNodes()))
|
||||
.addAllConnections(constructConnections(ruleChainMetaData.getConnections()))
|
||||
.addAllRuleChainConnections(constructRuleChainConnections(ruleChainMetaData.getRuleChainConnections()));
|
||||
if (ruleChainMetaData.getFirstNodeIndex() != null) {
|
||||
builder.setFirstNodeIndex(ruleChainMetaData.getFirstNodeIndex());
|
||||
}
|
||||
builder.setMsgType(msgType);
|
||||
return builder.build();
|
||||
} catch (JsonProcessingException ex) {
|
||||
log.error("Can't construct RuleChainMetadataUpdateMsg", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<RuleChainConnectionInfoProto> constructRuleChainConnections(List<RuleChainConnectionInfo> ruleChainConnections) throws JsonProcessingException {
|
||||
List<RuleChainConnectionInfoProto> result = new ArrayList<>();
|
||||
if (ruleChainConnections != null && !ruleChainConnections.isEmpty()) {
|
||||
for (RuleChainConnectionInfo ruleChainConnectionInfo : ruleChainConnections) {
|
||||
result.add(constructRuleChainConnection(ruleChainConnectionInfo));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private RuleChainConnectionInfoProto constructRuleChainConnection(RuleChainConnectionInfo ruleChainConnectionInfo) throws JsonProcessingException {
|
||||
return RuleChainConnectionInfoProto.newBuilder()
|
||||
.setFromIndex(ruleChainConnectionInfo.getFromIndex())
|
||||
.setTargetRuleChainIdMSB(ruleChainConnectionInfo.getTargetRuleChainId().getId().getMostSignificantBits())
|
||||
.setTargetRuleChainIdLSB(ruleChainConnectionInfo.getTargetRuleChainId().getId().getLeastSignificantBits())
|
||||
.setType(ruleChainConnectionInfo.getType())
|
||||
.setAdditionalInfo(objectMapper.writeValueAsString(ruleChainConnectionInfo.getAdditionalInfo()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<NodeConnectionInfoProto> constructConnections(List<NodeConnectionInfo> connections) {
|
||||
List<NodeConnectionInfoProto> result = new ArrayList<>();
|
||||
if (connections != null && !connections.isEmpty()) {
|
||||
for (NodeConnectionInfo connection : connections) {
|
||||
result.add(constructConnection(connection));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private NodeConnectionInfoProto constructConnection(NodeConnectionInfo connection) {
|
||||
return NodeConnectionInfoProto.newBuilder()
|
||||
.setFromIndex(connection.getFromIndex())
|
||||
.setToIndex(connection.getToIndex())
|
||||
.setType(connection.getType())
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<RuleNodeProto> constructNodes(List<RuleNode> nodes) throws JsonProcessingException {
|
||||
List<RuleNodeProto> result = new ArrayList<>();
|
||||
if (nodes != null && !nodes.isEmpty()) {
|
||||
for (RuleNode node : nodes) {
|
||||
result.add(constructNode(node));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private RuleNodeProto constructNode(RuleNode node) throws JsonProcessingException {
|
||||
return RuleNodeProto.newBuilder()
|
||||
.setIdMSB(node.getId().getId().getMostSignificantBits())
|
||||
.setIdLSB(node.getId().getId().getLeastSignificantBits())
|
||||
.setType(node.getType())
|
||||
.setName(node.getName())
|
||||
.setDebugMode(node.isDebugMode())
|
||||
.setConfiguration(objectMapper.writeValueAsString(node.getConfiguration()))
|
||||
.setAdditionalInfo(objectMapper.writeValueAsString(node.getAdditionalInfo()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private DashboardUpdateMsg constructDashboardUpdatedMsg(UpdateMsgType msgType, Dashboard dashboard) {
|
||||
dashboard = ctx.getDashboardService().findDashboardById(edge.getTenantId(), dashboard.getId());
|
||||
DashboardUpdateMsg.Builder builder = DashboardUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setIdMSB(dashboard.getId().getId().getMostSignificantBits())
|
||||
.setIdLSB(dashboard.getId().getId().getLeastSignificantBits())
|
||||
.setTitle(dashboard.getTitle())
|
||||
.setConfiguration(JacksonUtil.toString(dashboard.getConfiguration()));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private CustomerUpdateMsg constructCustomerUpdatedMsg(UpdateMsgType msgType, Customer customer) {
|
||||
CustomerUpdateMsg.Builder builder = CustomerUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType);
|
||||
@ -626,47 +477,6 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private DeviceUpdateMsg constructDeviceUpdatedMsg(UpdateMsgType msgType, Device device) {
|
||||
DeviceUpdateMsg.Builder builder = DeviceUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setName(device.getName())
|
||||
.setType(device.getType());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private AssetUpdateMsg constructAssetUpdatedMsg(UpdateMsgType msgType, Asset asset) {
|
||||
AssetUpdateMsg.Builder builder = AssetUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setName(asset.getName())
|
||||
.setType(asset.getType());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private EntityViewUpdateMsg constructEntityViewUpdatedMsg(UpdateMsgType msgType, EntityView entityView) {
|
||||
String relatedName;
|
||||
String relatedType;
|
||||
org.thingsboard.server.gen.edge.EntityType relatedEntityType;
|
||||
if (entityView.getEntityId().getEntityType().equals(EntityType.DEVICE)) {
|
||||
Device device = ctx.getDeviceService().findDeviceById(entityView.getTenantId(), new DeviceId(entityView.getEntityId().getId()));
|
||||
relatedName = device.getName();
|
||||
relatedType = device.getType();
|
||||
relatedEntityType = org.thingsboard.server.gen.edge.EntityType.DEVICE;
|
||||
} else {
|
||||
Asset asset = ctx.getAssetService().findAssetById(entityView.getTenantId(), new AssetId(entityView.getEntityId().getId()));
|
||||
relatedName = asset.getName();
|
||||
relatedType = asset.getType();
|
||||
relatedEntityType = org.thingsboard.server.gen.edge.EntityType.ASSET;
|
||||
}
|
||||
EntityViewUpdateMsg.Builder builder = EntityViewUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setName(entityView.getName())
|
||||
.setType(entityView.getType())
|
||||
.setRelatedName(relatedName)
|
||||
.setRelatedType(relatedType)
|
||||
.setRelatedEntityType(relatedEntityType);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private UplinkResponseMsg processUplinkMsg(UplinkMsg uplinkMsg) {
|
||||
try {
|
||||
if (uplinkMsg.getEntityDataList() != null && !uplinkMsg.getEntityDataList().isEmpty()) {
|
||||
@ -716,11 +526,16 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uplinkMsg.getAlarmUpdatemsgList() != null && !uplinkMsg.getAlarmUpdatemsgList().isEmpty()) {
|
||||
for (AlarmUpdateMsg alarmUpdateMsg : uplinkMsg.getAlarmUpdatemsgList()) {
|
||||
if (uplinkMsg.getAlarmUpdateMsgList() != null && !uplinkMsg.getAlarmUpdateMsgList().isEmpty()) {
|
||||
for (AlarmUpdateMsg alarmUpdateMsg : uplinkMsg.getAlarmUpdateMsgList()) {
|
||||
onAlarmUpdate(alarmUpdateMsg);
|
||||
}
|
||||
}
|
||||
if (uplinkMsg.getRuleChainMetadataRequestMsgList() != null && !uplinkMsg.getRuleChainMetadataRequestMsgList().isEmpty()) {
|
||||
for (RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg : uplinkMsg.getRuleChainMetadataRequestMsgList()) {
|
||||
ctx.getInitEdgeService().initRuleChainMetadata(edge, ruleChainMetadataRequestMsg, outputStream);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return UplinkResponseMsg.newBuilder().setSuccess(false).setErrorMsg(e.getMessage()).build();
|
||||
}
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright © 2016-2020 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.service.edge.rpc.constructor;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bouncycastle.jcajce.provider.symmetric.DES;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.alarm.Alarm;
|
||||
import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
|
||||
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.id.TenantId;
|
||||
import org.thingsboard.server.dao.asset.AssetService;
|
||||
import org.thingsboard.server.dao.device.DeviceService;
|
||||
import org.thingsboard.server.dao.entityview.EntityViewService;
|
||||
import org.thingsboard.server.dao.util.mapping.JacksonUtil;
|
||||
import org.thingsboard.server.gen.edge.AlarmUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.UpdateMsgType;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AlarmUpdateMsgConstructor {
|
||||
|
||||
@Autowired
|
||||
private DeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private AssetService assetService;
|
||||
|
||||
@Autowired
|
||||
private EntityViewService entityViewService;
|
||||
|
||||
public AlarmUpdateMsg constructAlarmUpdatedMsg(TenantId tenantId, UpdateMsgType msgType, Alarm alarm) {
|
||||
String entityName = null;
|
||||
switch (alarm.getOriginator().getEntityType()) {
|
||||
case DEVICE:
|
||||
entityName = deviceService.findDeviceById(tenantId, new DeviceId(alarm.getOriginator().getId())).getName();
|
||||
break;
|
||||
case ASSET:
|
||||
entityName = assetService.findAssetById(tenantId, new AssetId(alarm.getOriginator().getId())).getName();
|
||||
break;
|
||||
case ENTITY_VIEW:
|
||||
entityName = entityViewService.findEntityViewById(tenantId, new EntityViewId(alarm.getOriginator().getId())).getName();
|
||||
break;
|
||||
}
|
||||
AlarmUpdateMsg.Builder builder = AlarmUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setName(alarm.getName())
|
||||
.setType(alarm.getType())
|
||||
.setOriginatorName(entityName)
|
||||
.setOriginatorType(alarm.getOriginator().getEntityType().name())
|
||||
.setSeverity(alarm.getSeverity().name())
|
||||
.setStatus(alarm.getStatus().name())
|
||||
.setStartTs(alarm.getStartTs())
|
||||
.setEndTs(alarm.getEndTs())
|
||||
.setAckTs(alarm.getAckTs())
|
||||
.setClearTs(alarm.getClearTs())
|
||||
.setDetails(JacksonUtil.toString(alarm.getDetails()))
|
||||
.setPropagate(alarm.isPropagate());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright © 2016-2020 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.service.edge.rpc.constructor;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.gen.edge.AssetUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.UpdateMsgType;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AssetUpdateMsgConstructor {
|
||||
|
||||
public AssetUpdateMsg constructAssetUpdatedMsg(UpdateMsgType msgType, Asset asset) {
|
||||
AssetUpdateMsg.Builder builder = AssetUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setName(asset.getName())
|
||||
.setType(asset.getType());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright © 2016-2020 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.service.edge.rpc.constructor;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.Dashboard;
|
||||
import org.thingsboard.server.dao.dashboard.DashboardService;
|
||||
import org.thingsboard.server.dao.util.mapping.JacksonUtil;
|
||||
import org.thingsboard.server.gen.edge.DashboardUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.UpdateMsgType;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DashboardUpdateMsgConstructor {
|
||||
|
||||
@Autowired
|
||||
private DashboardService dashboardService;
|
||||
|
||||
public DashboardUpdateMsg constructDashboardUpdatedMsg(UpdateMsgType msgType, Dashboard dashboard) {
|
||||
dashboard = dashboardService.findDashboardById(dashboard.getTenantId(), dashboard.getId());
|
||||
DashboardUpdateMsg.Builder builder = DashboardUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setIdMSB(dashboard.getId().getId().getMostSignificantBits())
|
||||
.setIdLSB(dashboard.getId().getId().getLeastSignificantBits())
|
||||
.setTitle(dashboard.getTitle())
|
||||
.setConfiguration(JacksonUtil.toString(dashboard.getConfiguration()));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright © 2016-2020 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.service.edge.rpc.constructor;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.gen.edge.DeviceUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.UpdateMsgType;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DeviceUpdateMsgConstructor {
|
||||
|
||||
public DeviceUpdateMsg constructDeviceUpdatedMsg(UpdateMsgType msgType, Device device) {
|
||||
DeviceUpdateMsg.Builder builder = DeviceUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setName(device.getName())
|
||||
.setType(device.getType());
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright © 2016-2020 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.service.edge.rpc.constructor;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.EntityView;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.common.data.id.AssetId;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.dao.asset.AssetService;
|
||||
import org.thingsboard.server.dao.device.DeviceService;
|
||||
import org.thingsboard.server.gen.edge.EntityViewUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.UpdateMsgType;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class EntityViewUpdateMsgConstructor {
|
||||
|
||||
@Autowired
|
||||
private DeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private AssetService assetService;
|
||||
|
||||
public EntityViewUpdateMsg constructEntityViewUpdatedMsg(UpdateMsgType msgType, EntityView entityView) {
|
||||
String relatedName;
|
||||
String relatedType;
|
||||
org.thingsboard.server.gen.edge.EntityType relatedEntityType;
|
||||
if (entityView.getEntityId().getEntityType().equals(EntityType.DEVICE)) {
|
||||
Device device = deviceService.findDeviceById(entityView.getTenantId(), new DeviceId(entityView.getEntityId().getId()));
|
||||
relatedName = device.getName();
|
||||
relatedType = device.getType();
|
||||
relatedEntityType = org.thingsboard.server.gen.edge.EntityType.DEVICE;
|
||||
} else {
|
||||
Asset asset = assetService.findAssetById(entityView.getTenantId(), new AssetId(entityView.getEntityId().getId()));
|
||||
relatedName = asset.getName();
|
||||
relatedType = asset.getType();
|
||||
relatedEntityType = org.thingsboard.server.gen.edge.EntityType.ASSET;
|
||||
}
|
||||
EntityViewUpdateMsg.Builder builder = EntityViewUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setName(entityView.getName())
|
||||
.setType(entityView.getType())
|
||||
.setRelatedName(relatedName)
|
||||
.setRelatedType(relatedType)
|
||||
.setRelatedEntityType(relatedEntityType);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Copyright © 2016-2020 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.service.edge.rpc.constructor;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.edge.Edge;
|
||||
import org.thingsboard.server.common.data.rule.NodeConnectionInfo;
|
||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||
import org.thingsboard.server.dao.util.mapping.JacksonUtil;
|
||||
import org.thingsboard.server.gen.edge.NodeConnectionInfoProto;
|
||||
import org.thingsboard.server.gen.edge.RuleChainConnectionInfoProto;
|
||||
import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.RuleChainUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.RuleNodeProto;
|
||||
import org.thingsboard.server.gen.edge.UpdateMsgType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RuleChainUpdateMsgConstructor {
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public RuleChainUpdateMsg constructRuleChainUpdatedMsg(Edge edge, UpdateMsgType msgType, RuleChain ruleChain) {
|
||||
RuleChainUpdateMsg.Builder builder = RuleChainUpdateMsg.newBuilder()
|
||||
.setMsgType(msgType)
|
||||
.setIdMSB(ruleChain.getId().getId().getMostSignificantBits())
|
||||
.setIdLSB(ruleChain.getId().getId().getLeastSignificantBits())
|
||||
.setName(ruleChain.getName())
|
||||
.setRoot(ruleChain.getId().equals(edge.getRootRuleChainId()))
|
||||
.setDebugMode(ruleChain.isDebugMode())
|
||||
.setConfiguration(JacksonUtil.toString(ruleChain.getConfiguration()));
|
||||
if (ruleChain.getFirstRuleNodeId() != null) {
|
||||
builder.setFirstRuleNodeIdMSB(ruleChain.getFirstRuleNodeId().getId().getMostSignificantBits())
|
||||
.setFirstRuleNodeIdLSB(ruleChain.getFirstRuleNodeId().getId().getLeastSignificantBits());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public RuleChainMetadataUpdateMsg constructRuleChainMetadataUpdatedMsg(UpdateMsgType msgType, RuleChainMetaData ruleChainMetaData) {
|
||||
try {
|
||||
RuleChainMetadataUpdateMsg.Builder builder = RuleChainMetadataUpdateMsg.newBuilder()
|
||||
.setRuleChainIdMSB(ruleChainMetaData.getRuleChainId().getId().getMostSignificantBits())
|
||||
.setRuleChainIdLSB(ruleChainMetaData.getRuleChainId().getId().getLeastSignificantBits())
|
||||
.addAllNodes(constructNodes(ruleChainMetaData.getNodes()))
|
||||
.addAllConnections(constructConnections(ruleChainMetaData.getConnections()))
|
||||
.addAllRuleChainConnections(constructRuleChainConnections(ruleChainMetaData.getRuleChainConnections()));
|
||||
if (ruleChainMetaData.getFirstNodeIndex() != null) {
|
||||
builder.setFirstNodeIndex(ruleChainMetaData.getFirstNodeIndex());
|
||||
}
|
||||
builder.setMsgType(msgType);
|
||||
return builder.build();
|
||||
} catch (JsonProcessingException ex) {
|
||||
log.error("Can't construct RuleChainMetadataUpdateMsg", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<NodeConnectionInfoProto> constructConnections(List<NodeConnectionInfo> connections) {
|
||||
List<NodeConnectionInfoProto> result = new ArrayList<>();
|
||||
if (connections != null && !connections.isEmpty()) {
|
||||
for (NodeConnectionInfo connection : connections) {
|
||||
result.add(constructConnection(connection));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private NodeConnectionInfoProto constructConnection(NodeConnectionInfo connection) {
|
||||
return NodeConnectionInfoProto.newBuilder()
|
||||
.setFromIndex(connection.getFromIndex())
|
||||
.setToIndex(connection.getToIndex())
|
||||
.setType(connection.getType())
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<RuleNodeProto> constructNodes(List<RuleNode> nodes) throws JsonProcessingException {
|
||||
List<RuleNodeProto> result = new ArrayList<>();
|
||||
if (nodes != null && !nodes.isEmpty()) {
|
||||
for (RuleNode node : nodes) {
|
||||
result.add(constructNode(node));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<RuleChainConnectionInfoProto> constructRuleChainConnections(List<RuleChainConnectionInfo> ruleChainConnections) throws JsonProcessingException {
|
||||
List<RuleChainConnectionInfoProto> result = new ArrayList<>();
|
||||
if (ruleChainConnections != null && !ruleChainConnections.isEmpty()) {
|
||||
for (RuleChainConnectionInfo ruleChainConnectionInfo : ruleChainConnections) {
|
||||
result.add(constructRuleChainConnection(ruleChainConnectionInfo));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private RuleChainConnectionInfoProto constructRuleChainConnection(RuleChainConnectionInfo ruleChainConnectionInfo) throws JsonProcessingException {
|
||||
return RuleChainConnectionInfoProto.newBuilder()
|
||||
.setFromIndex(ruleChainConnectionInfo.getFromIndex())
|
||||
.setTargetRuleChainIdMSB(ruleChainConnectionInfo.getTargetRuleChainId().getId().getMostSignificantBits())
|
||||
.setTargetRuleChainIdLSB(ruleChainConnectionInfo.getTargetRuleChainId().getId().getLeastSignificantBits())
|
||||
.setType(ruleChainConnectionInfo.getType())
|
||||
.setAdditionalInfo(objectMapper.writeValueAsString(ruleChainConnectionInfo.getAdditionalInfo()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
private RuleNodeProto constructNode(RuleNode node) throws JsonProcessingException {
|
||||
return RuleNodeProto.newBuilder()
|
||||
.setIdMSB(node.getId().getId().getMostSignificantBits())
|
||||
.setIdLSB(node.getId().getId().getLeastSignificantBits())
|
||||
.setType(node.getType())
|
||||
.setName(node.getName())
|
||||
.setDebugMode(node.isDebugMode())
|
||||
.setConfiguration(objectMapper.writeValueAsString(node.getConfiguration()))
|
||||
.setAdditionalInfo(objectMapper.writeValueAsString(node.getAdditionalInfo()))
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,272 @@
|
||||
/**
|
||||
* Copyright © 2016-2020 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.service.edge.rpc.init;
|
||||
|
||||
import io.grpc.stub.StreamObserver;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.Dashboard;
|
||||
import org.thingsboard.server.common.data.DashboardInfo;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.EntityView;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.common.data.edge.Edge;
|
||||
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||
import org.thingsboard.server.common.data.page.TextPageData;
|
||||
import org.thingsboard.server.common.data.page.TextPageLink;
|
||||
import org.thingsboard.server.common.data.page.TimePageData;
|
||||
import org.thingsboard.server.common.data.page.TimePageLink;
|
||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||
import org.thingsboard.server.dao.asset.AssetService;
|
||||
import org.thingsboard.server.dao.dashboard.DashboardService;
|
||||
import org.thingsboard.server.dao.device.DeviceService;
|
||||
import org.thingsboard.server.dao.entityview.EntityViewService;
|
||||
import org.thingsboard.server.dao.rule.RuleChainService;
|
||||
import org.thingsboard.server.gen.edge.AssetUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.DashboardUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.DeviceUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.EntityUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.EntityViewUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.ResponseMsg;
|
||||
import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg;
|
||||
import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.RuleChainUpdateMsg;
|
||||
import org.thingsboard.server.gen.edge.UpdateMsgType;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.AssetUpdateMsgConstructor;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.DashboardUpdateMsgConstructor;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.DeviceUpdateMsgConstructor;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.EntityViewUpdateMsgConstructor;
|
||||
import org.thingsboard.server.service.edge.rpc.constructor.RuleChainUpdateMsgConstructor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class DefaultInitEdgeService implements InitEdgeService {
|
||||
|
||||
@Autowired
|
||||
private RuleChainService ruleChainService;
|
||||
|
||||
@Autowired
|
||||
private DeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private AssetService assetService;
|
||||
|
||||
@Autowired
|
||||
private EntityViewService entityViewService;
|
||||
|
||||
@Autowired
|
||||
private DashboardService dashboardService;
|
||||
|
||||
@Autowired
|
||||
private RuleChainUpdateMsgConstructor ruleChainUpdateMsgConstructor;
|
||||
|
||||
@Autowired
|
||||
private DeviceUpdateMsgConstructor deviceUpdateMsgConstructor;
|
||||
|
||||
@Autowired
|
||||
private AssetUpdateMsgConstructor assetUpdateMsgConstructor;
|
||||
|
||||
@Autowired
|
||||
private EntityViewUpdateMsgConstructor entityViewUpdateMsgConstructor;
|
||||
|
||||
@Autowired
|
||||
private DashboardUpdateMsgConstructor dashboardUpdateMsgConstructor;
|
||||
|
||||
@Override
|
||||
public void init(Edge edge, StreamObserver<ResponseMsg> outputStream) {
|
||||
initRuleChains(edge, outputStream);
|
||||
initDevices(edge, outputStream);
|
||||
initAssets(edge, outputStream);
|
||||
initEntityViews(edge, outputStream);
|
||||
initDashboards(edge, outputStream);
|
||||
}
|
||||
|
||||
private void initDevices(Edge edge, StreamObserver<ResponseMsg> outputStream) {
|
||||
try {
|
||||
TextPageLink pageLink = new TextPageLink(100);
|
||||
TextPageData<Device> pageData;
|
||||
do {
|
||||
pageData = deviceService.findDevicesByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
|
||||
if (!pageData.getData().isEmpty()) {
|
||||
log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
|
||||
for (Device device : pageData.getData()) {
|
||||
DeviceUpdateMsg deviceUpdateMsg =
|
||||
deviceUpdateMsgConstructor.constructDeviceUpdatedMsg(
|
||||
UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE,
|
||||
device);
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setDeviceUpdateMsg(deviceUpdateMsg)
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
if (pageData.hasNext()) {
|
||||
pageLink = pageData.getNextPageLink();
|
||||
}
|
||||
} while (pageData.hasNext());
|
||||
} catch (Exception e) {
|
||||
log.error("Exception during loading edge device(s) on init!");
|
||||
}
|
||||
}
|
||||
|
||||
private void initAssets(Edge edge, StreamObserver<ResponseMsg> outputStream) {
|
||||
try {
|
||||
TextPageLink pageLink = new TextPageLink(100);
|
||||
TextPageData<Asset> pageData;
|
||||
do {
|
||||
pageData = assetService.findAssetsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
|
||||
if (!pageData.getData().isEmpty()) {
|
||||
log.trace("[{}] [{}] asset(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
|
||||
for (Asset asset : pageData.getData()) {
|
||||
AssetUpdateMsg assetUpdateMsg =
|
||||
assetUpdateMsgConstructor.constructAssetUpdatedMsg(
|
||||
UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE,
|
||||
asset);
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setAssetUpdateMsg(assetUpdateMsg)
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
if (pageData.hasNext()) {
|
||||
pageLink = pageData.getNextPageLink();
|
||||
}
|
||||
} while (pageData.hasNext());
|
||||
} catch (Exception e) {
|
||||
log.error("Exception during loading edge asset(s) on init!");
|
||||
}
|
||||
}
|
||||
|
||||
private void initEntityViews(Edge edge, StreamObserver<ResponseMsg> outputStream) {
|
||||
try {
|
||||
TextPageLink pageLink = new TextPageLink(100);
|
||||
TextPageData<EntityView> pageData;
|
||||
do {
|
||||
pageData = entityViewService.findEntityViewsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
|
||||
if (!pageData.getData().isEmpty()) {
|
||||
log.trace("[{}] [{}] entity view(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
|
||||
for (EntityView entityView : pageData.getData()) {
|
||||
EntityViewUpdateMsg entityViewUpdateMsg =
|
||||
entityViewUpdateMsgConstructor.constructEntityViewUpdatedMsg(
|
||||
UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE,
|
||||
entityView);
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setEntityViewUpdateMsg(entityViewUpdateMsg)
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
if (pageData.hasNext()) {
|
||||
pageLink = pageData.getNextPageLink();
|
||||
}
|
||||
} while (pageData.hasNext());
|
||||
} catch (Exception e) {
|
||||
log.error("Exception during loading edge entity view(s) on init!");
|
||||
}
|
||||
}
|
||||
|
||||
private void initDashboards(Edge edge, StreamObserver<ResponseMsg> outputStream) {
|
||||
try {
|
||||
TimePageLink pageLink = new TimePageLink(100);
|
||||
TimePageData<DashboardInfo> pageData;
|
||||
do {
|
||||
pageData = dashboardService.findDashboardsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink).get();
|
||||
if (!pageData.getData().isEmpty()) {
|
||||
log.trace("[{}] [{}] dashboard(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
|
||||
for (DashboardInfo dashboardInfo : pageData.getData()) {
|
||||
Dashboard dashboard = dashboardService.findDashboardById(edge.getTenantId(), dashboardInfo.getId());
|
||||
DashboardUpdateMsg dashboardUpdateMsg =
|
||||
dashboardUpdateMsgConstructor.constructDashboardUpdatedMsg(
|
||||
UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE,
|
||||
dashboard);
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setDashboardUpdateMsg(dashboardUpdateMsg)
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
if (pageData.hasNext()) {
|
||||
pageLink = pageData.getNextPageLink();
|
||||
}
|
||||
} while (pageData.hasNext());
|
||||
} catch (Exception e) {
|
||||
log.error("Exception during loading edge dashboard(s) on init!");
|
||||
}
|
||||
}
|
||||
|
||||
private void initRuleChains(Edge edge, StreamObserver<ResponseMsg> outputStream) {
|
||||
try {
|
||||
TimePageLink pageLink = new TimePageLink(100);
|
||||
TimePageData<RuleChain> pageData;
|
||||
do {
|
||||
pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink).get();
|
||||
if (!pageData.getData().isEmpty()) {
|
||||
log.trace("[{}] [{}] rule chains(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
|
||||
for (RuleChain ruleChain : pageData.getData()) {
|
||||
RuleChainUpdateMsg ruleChainUpdateMsg =
|
||||
ruleChainUpdateMsgConstructor.constructRuleChainUpdatedMsg(
|
||||
edge,
|
||||
UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE,
|
||||
ruleChain);
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setRuleChainUpdateMsg(ruleChainUpdateMsg)
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
if (pageData.hasNext()) {
|
||||
pageLink = pageData.getNextPageLink();
|
||||
}
|
||||
} while (pageData.hasNext());
|
||||
} catch (Exception e) {
|
||||
log.error("Exception during loading edge rule chain(s) on init!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initRuleChainMetadata(Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg, StreamObserver<ResponseMsg> outputStream) {
|
||||
if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) {
|
||||
RuleChainId ruleChainId = new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB()));
|
||||
RuleChainMetaData ruleChainMetaData = ruleChainService.loadRuleChainMetaData(edge.getTenantId(), ruleChainId);
|
||||
RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg =
|
||||
ruleChainUpdateMsgConstructor.constructRuleChainMetadataUpdatedMsg(
|
||||
UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE,
|
||||
ruleChainMetaData);
|
||||
if (ruleChainMetadataUpdateMsg != null) {
|
||||
EntityUpdateMsg entityUpdateMsg = EntityUpdateMsg.newBuilder()
|
||||
.setRuleChainMetadataUpdateMsg(ruleChainMetadataUpdateMsg)
|
||||
.build();
|
||||
outputStream.onNext(ResponseMsg.newBuilder()
|
||||
.setEntityUpdateMsg(entityUpdateMsg)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright © 2016-2020 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.service.edge.rpc.init;
|
||||
|
||||
import io.grpc.stub.StreamObserver;
|
||||
import org.thingsboard.server.common.data.edge.Edge;
|
||||
import org.thingsboard.server.gen.edge.ResponseMsg;
|
||||
import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg;
|
||||
|
||||
public interface InitEdgeService {
|
||||
|
||||
void init(Edge edge, StreamObserver<ResponseMsg> outputStream);
|
||||
|
||||
void initRuleChainMetadata(Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg, StreamObserver<ResponseMsg> outputStream);
|
||||
}
|
||||
@ -115,7 +115,6 @@ public class InstallScripts {
|
||||
RuleChainMetaData ruleChainMetaData = objectMapper.treeToValue(ruleChainJson.get("metadata"), RuleChainMetaData.class);
|
||||
|
||||
ruleChain.setTenantId(tenantId);
|
||||
ruleChain.setType(RuleChainType.SYSTEM);
|
||||
ruleChain = ruleChainService.saveRuleChain(ruleChain);
|
||||
|
||||
ruleChainMetaData.setRuleChainId(ruleChain.getId());
|
||||
|
||||
@ -71,11 +71,15 @@ public interface RuleChainService {
|
||||
|
||||
RuleChain assignRuleChainToEdge(TenantId tenantId, RuleChainId ruleChainId, EdgeId edgeId);
|
||||
|
||||
RuleChain unassignRuleChainFromEdge(TenantId tenantId, RuleChainId ruleChainId, EdgeId edgeId);
|
||||
RuleChain unassignRuleChainFromEdge(TenantId tenantId, RuleChainId ruleChainId, EdgeId edgeId, boolean remove);
|
||||
|
||||
void unassignEdgeRuleChains(TenantId tenantId, EdgeId edgeId);
|
||||
|
||||
void updateEdgeRuleChains(TenantId tenantId, EdgeId edgeId);
|
||||
|
||||
ListenableFuture<TimePageData<RuleChain>> findRuleChainsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
|
||||
|
||||
RuleChain getDefaultRootEdgeRuleChain(TenantId tenantId);
|
||||
|
||||
boolean setDefaultRootEdgeRuleChain(TenantId tenantId, RuleChainId ruleChainId);
|
||||
}
|
||||
|
||||
@ -81,10 +81,10 @@ message ConnectResponseMsg {
|
||||
message EdgeConfiguration {
|
||||
int64 tenantIdMSB = 1;
|
||||
int64 tenantIdLSB = 2;
|
||||
string name = 5;
|
||||
string routingKey = 6;
|
||||
string type = 7;
|
||||
string cloudType = 8;
|
||||
string name = 3;
|
||||
string routingKey = 4;
|
||||
string type = 5;
|
||||
string cloudType = 6;
|
||||
}
|
||||
|
||||
enum UpdateMsgType {
|
||||
@ -224,6 +224,11 @@ message UserUpdateMsg {
|
||||
string password = 13;
|
||||
}
|
||||
|
||||
message RuleChainMetadataRequestMsg {
|
||||
int64 ruleChainIdMSB = 1;
|
||||
int64 ruleChainIdLSB = 2;
|
||||
}
|
||||
|
||||
enum EntityType {
|
||||
DEVICE = 0;
|
||||
ASSET = 1;
|
||||
@ -237,7 +242,8 @@ message UplinkMsg {
|
||||
int32 uplinkMsgId = 1;
|
||||
repeated EntityDataProto entityData = 2;
|
||||
repeated DeviceUpdateMsg deviceUpdateMsg = 3;
|
||||
repeated AlarmUpdateMsg alarmUpdatemsg = 4;
|
||||
repeated AlarmUpdateMsg alarmUpdateMsg = 4;
|
||||
repeated RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg = 5;
|
||||
}
|
||||
|
||||
message UplinkResponseMsg {
|
||||
|
||||
@ -216,7 +216,8 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic
|
||||
Edge edge = edgeDao.findById(tenantId, edgeId.getId());
|
||||
|
||||
dashboardService.unassignEdgeDashboards(tenantId, edgeId);
|
||||
ruleChainService.unassignEdgeRuleChains(tenantId, edgeId);
|
||||
// TODO: validate that rule chains are removed by deleteEntityRelations(tenantId, edgeId); call
|
||||
ruleChainService.unassignEdgeRuleChains(tenantId, edgeId);
|
||||
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(edge.getTenantId());
|
||||
|
||||
@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.id.AssetId;
|
||||
import org.thingsboard.server.common.data.id.CustomerId;
|
||||
import org.thingsboard.server.common.data.id.DashboardId;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.common.data.id.EdgeId;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.EntityViewId;
|
||||
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||
@ -38,6 +39,7 @@ import org.thingsboard.server.dao.asset.AssetService;
|
||||
import org.thingsboard.server.dao.customer.CustomerService;
|
||||
import org.thingsboard.server.dao.dashboard.DashboardService;
|
||||
import org.thingsboard.server.dao.device.DeviceService;
|
||||
import org.thingsboard.server.dao.edge.EdgeService;
|
||||
import org.thingsboard.server.dao.entityview.EntityViewService;
|
||||
import org.thingsboard.server.dao.rule.RuleChainService;
|
||||
import org.thingsboard.server.dao.tenant.TenantService;
|
||||
@ -77,6 +79,9 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
|
||||
@Autowired
|
||||
private RuleChainService ruleChainService;
|
||||
|
||||
@Autowired
|
||||
private EdgeService edgeService;
|
||||
|
||||
@Override
|
||||
public void deleteEntityRelations(TenantId tenantId, EntityId entityId) {
|
||||
super.deleteEntityRelations(tenantId, entityId);
|
||||
@ -115,6 +120,9 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
|
||||
case RULE_CHAIN:
|
||||
hasName = ruleChainService.findRuleChainByIdAsync(tenantId, new RuleChainId(entityId.getId()));
|
||||
break;
|
||||
case EDGE:
|
||||
hasName = edgeService.findEdgeByIdAsync(tenantId, new EdgeId(entityId.getId()));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Not Implemented!");
|
||||
}
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.thingsboard.server.dao.rule;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
@ -47,7 +46,6 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainType;
|
||||
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||
import org.thingsboard.server.dao.edge.EdgeDao;
|
||||
import org.thingsboard.server.dao.edge.EdgeService;
|
||||
import org.thingsboard.server.dao.entity.AbstractEntityService;
|
||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||
import org.thingsboard.server.dao.service.DataValidator;
|
||||
@ -62,9 +60,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.thingsboard.server.dao.service.Validator.validateString;
|
||||
|
||||
/**
|
||||
* Created by igor on 3/12/18.
|
||||
@ -73,8 +68,6 @@ import static org.thingsboard.server.dao.service.Validator.validateString;
|
||||
@Slf4j
|
||||
public class BaseRuleChainService extends AbstractEntityService implements RuleChainService {
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@Autowired
|
||||
private RuleChainDao ruleChainDao;
|
||||
|
||||
@ -87,9 +80,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
||||
@Autowired
|
||||
private EdgeDao edgeDao;
|
||||
|
||||
@Autowired
|
||||
private EdgeService edgeService;
|
||||
|
||||
@Override
|
||||
public RuleChain saveRuleChain(RuleChain ruleChain) {
|
||||
ruleChainValidator.validate(ruleChain, RuleChain::getTenantId);
|
||||
@ -121,7 +111,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
||||
createRelation(tenantId, new EntityRelation(ruleChain.getTenantId(), ruleChain.getId(),
|
||||
EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
|
||||
ruleChain.setRoot(true);
|
||||
ruleChain.setType(RuleChainType.SYSTEM);
|
||||
ruleChainDao.save(tenantId, ruleChain);
|
||||
return true;
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
@ -285,17 +274,27 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
||||
|
||||
@Override
|
||||
public RuleChain getRootTenantRuleChain(TenantId tenantId) {
|
||||
return getRootRuleChainByType(tenantId, RuleChainType.SYSTEM);
|
||||
}
|
||||
|
||||
private RuleChain getRootRuleChainByType(TenantId tenantId, RuleChainType type) {
|
||||
Validator.validateId(tenantId, "Incorrect tenant id for search request.");
|
||||
List<EntityRelation> relations = relationService.findByFrom(tenantId, tenantId, RelationTypeGroup.RULE_CHAIN);
|
||||
if (relations != null && !relations.isEmpty()) {
|
||||
EntityRelation relation = relations.get(0);
|
||||
RuleChainId ruleChainId = new RuleChainId(relation.getTo().getId());
|
||||
return findRuleChainById(tenantId, ruleChainId);
|
||||
for (EntityRelation relation : relations) {
|
||||
RuleChainId ruleChainId = new RuleChainId(relation.getTo().getId());
|
||||
RuleChain ruleChainById = findRuleChainById(tenantId, ruleChainId);
|
||||
if (type.equals(ruleChainById.getType())) {
|
||||
return ruleChainById;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<RuleNode> getRuleChainNodes(TenantId tenantId, RuleChainId ruleChainId) {
|
||||
Validator.validateId(ruleChainId, "Incorrect rule chain id for search request.");
|
||||
@ -417,13 +416,13 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuleChain unassignRuleChainFromEdge(TenantId tenantId, RuleChainId ruleChainId, EdgeId edgeId) {
|
||||
public RuleChain unassignRuleChainFromEdge(TenantId tenantId, RuleChainId ruleChainId, EdgeId edgeId, boolean remove) {
|
||||
RuleChain ruleChain = findRuleChainById(tenantId, ruleChainId);
|
||||
Edge edge = edgeDao.findById(tenantId, edgeId.getId());
|
||||
if (edge == null) {
|
||||
throw new DataValidationException("Can't unassign rule chain from non-existent edge!");
|
||||
}
|
||||
if (edge.getRootRuleChainId() != null && edge.getRootRuleChainId().equals(ruleChainId)) {
|
||||
if (!remove && edge.getRootRuleChainId() != null && edge.getRootRuleChainId().equals(ruleChainId)) {
|
||||
throw new DataValidationException("Can't unassign root rule chain from edge [" + edge.getName() + "]. Please assign another root rule chain first!");
|
||||
}
|
||||
if (ruleChain.removeAssignedEdge(edge)) {
|
||||
@ -479,6 +478,34 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
||||
}, MoreExecutors.directExecutor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuleChain getDefaultRootEdgeRuleChain(TenantId tenantId) {
|
||||
return getRootRuleChainByType(tenantId, RuleChainType.EDGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDefaultRootEdgeRuleChain(TenantId tenantId, RuleChainId ruleChainId) {
|
||||
RuleChain ruleChain = ruleChainDao.findById(tenantId, ruleChainId.getId());
|
||||
RuleChain previousDefaultRootEdgeRuleChain = getDefaultRootEdgeRuleChain(ruleChain.getTenantId());
|
||||
if (!previousDefaultRootEdgeRuleChain.getId().equals(ruleChain.getId())) {
|
||||
try {
|
||||
deleteRelation(tenantId, new EntityRelation(previousDefaultRootEdgeRuleChain.getTenantId(), previousDefaultRootEdgeRuleChain.getId(),
|
||||
EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
|
||||
previousDefaultRootEdgeRuleChain.setRoot(false);
|
||||
ruleChainDao.save(tenantId, previousDefaultRootEdgeRuleChain);
|
||||
createRelation(tenantId, new EntityRelation(ruleChain.getTenantId(), ruleChain.getId(),
|
||||
EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
|
||||
ruleChain.setRoot(true);
|
||||
ruleChainDao.save(tenantId, ruleChain);
|
||||
return true;
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
log.warn("[{}] Failed to set default root edge rule chain, ruleChainId: [{}]", ruleChainId);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void checkRuleNodesAndDelete(TenantId tenantId, RuleChainId ruleChainId) {
|
||||
List<EntityRelation> nodeRelations = getRuleChainToNodeRelations(tenantId, ruleChainId);
|
||||
for (EntityRelation relation : nodeRelations) {
|
||||
@ -537,12 +564,18 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
||||
if (tenant == null) {
|
||||
throw new DataValidationException("Rule chain is referencing to non-existent tenant!");
|
||||
}
|
||||
if (ruleChain.isRoot()) {
|
||||
if (ruleChain.isRoot() && RuleChainType.SYSTEM.equals(ruleChain.getType())) {
|
||||
RuleChain rootRuleChain = getRootTenantRuleChain(ruleChain.getTenantId());
|
||||
if (rootRuleChain != null && !rootRuleChain.getId().equals(ruleChain.getId())) {
|
||||
throw new DataValidationException("Another root rule chain is present in scope of current tenant!");
|
||||
}
|
||||
}
|
||||
if (ruleChain.isRoot() && RuleChainType.EDGE.equals(ruleChain.getType())) {
|
||||
RuleChain defaultRootEdgeRuleChain = getDefaultRootEdgeRuleChain(ruleChain.getTenantId());
|
||||
if (defaultRootEdgeRuleChain != null && !defaultRootEdgeRuleChain.getId().equals(ruleChain.getId())) {
|
||||
throw new DataValidationException("Another default root edge rule chain is present in scope of current tenant!");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -580,9 +613,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
||||
|
||||
@Override
|
||||
protected void removeEntity(TenantId tenantId, RuleChain entity) {
|
||||
unassignRuleChainFromEdge(edge.getTenantId(), new RuleChainId(entity.getUuidId()), this.edge.getId());
|
||||
unassignRuleChainFromEdge(edge.getTenantId(), new RuleChainId(entity.getUuidId()), this.edge.getId(), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class EdgeRuleChainsUpdater extends TimePaginatedRemover<Edge, RuleChain> {
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -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> {
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils;
|
||||
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
|
||||
@ -44,7 +45,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> {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -31,6 +31,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;
|
||||
@ -50,7 +51,8 @@ import java.util.List;
|
||||
"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> {
|
||||
|
||||
|
||||
@ -34,6 +34,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;
|
||||
@ -53,7 +54,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> {
|
||||
|
||||
|
||||
@ -28,6 +28,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;
|
||||
@ -44,7 +45,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> {
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import org.thingsboard.common.util.ListeningExecutor;
|
||||
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;
|
||||
@ -36,7 +37,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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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_";
|
||||
|
||||
@ -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> {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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.plugin.ComponentType;
|
||||
import org.thingsboard.server.common.msg.TbMsg;
|
||||
import org.thingsboard.server.common.msg.session.SessionMsgType;
|
||||
|
||||
@Slf4j
|
||||
@RuleNode(
|
||||
@ -39,6 +40,11 @@ import org.thingsboard.server.common.msg.TbMsg;
|
||||
)
|
||||
public class TbMsgPushToEdgeNode implements TbNode {
|
||||
|
||||
private static final String CLOUD_MSG_SOURCE = "cloud";
|
||||
private static final String EDGE_MSG_SOURCE = "edge";
|
||||
private static final String MSG_SOURCE_KEY = "source";
|
||||
private static final String TS_METADATA_KEY = "ts";
|
||||
|
||||
private EmptyNodeConfiguration config;
|
||||
|
||||
@Override
|
||||
@ -48,6 +54,13 @@ public class TbMsgPushToEdgeNode implements TbNode {
|
||||
|
||||
@Override
|
||||
public void onMsg(TbContext ctx, TbMsg msg) {
|
||||
if (EDGE_MSG_SOURCE.equalsIgnoreCase(msg.getMetaData().getValue(MSG_SOURCE_KEY))) {
|
||||
return;
|
||||
}
|
||||
if (msg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name())) {
|
||||
msg.getMetaData().putValue(TS_METADATA_KEY, Long.toString(System.currentTimeMillis()));
|
||||
}
|
||||
msg.getMetaData().putValue(MSG_SOURCE_KEY, CLOUD_MSG_SOURCE);
|
||||
ctx.getEdgeService().pushEventToEdge(ctx.getTenantId(), msg, new PushToEdgeNodeCallback(ctx, msg));
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -31,6 +31,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;
|
||||
@ -51,7 +52,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;
|
||||
|
||||
@ -20,6 +20,7 @@ import org.thingsboard.common.util.ListeningExecutor;
|
||||
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;
|
||||
@ -36,7 +37,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 {
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import org.thingsboard.common.util.ListeningExecutor;
|
||||
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;
|
||||
@ -39,7 +40,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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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<>();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -24,6 +24,7 @@ import org.apache.kafka.common.header.internals.RecordHeaders;
|
||||
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;
|
||||
|
||||
@ -43,7 +44,8 @@ import java.util.concurrent.ExecutionException;
|
||||
" 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 {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -27,6 +27,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 javax.mail.internet.MimeMessage;
|
||||
@ -47,7 +48,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 {
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -30,6 +30,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
|
||||
@ -41,7 +42,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_";
|
||||
|
||||
@ -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
|
||||
|
||||
@ -28,6 +28,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.common.util.DonAsynchron.withCallback;
|
||||
@ -43,7 +44,9 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
|
||||
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;
|
||||
|
||||
@ -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> {
|
||||
|
||||
|
||||
@ -38,6 +38,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.io.IOException;
|
||||
@ -66,7 +67,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";
|
||||
|
||||
@ -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
|
||||
|
||||
@ -26,6 +26,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
|
||||
@ -37,7 +38,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_";
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -23,6 +23,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;
|
||||
@ -41,7 +42,8 @@ import java.util.concurrent.ExecutionException;
|
||||
"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 {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE;
|
||||
@ -37,7 +38,9 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
|
||||
"<code>{ msg: <i style=\"color: #666;\">new payload</i>,<br/>   metadata: <i style=\"color: #666;\">new metadata</i>,<br/>   msgType: <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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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,
|
||||
@ -40,13 +40,15 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
|
||||
addRuleChainEdges: addRuleChainEdges,
|
||||
removeRuleChainEdges: removeRuleChainEdges,
|
||||
getEdgeRuleChains: getEdgeRuleChains,
|
||||
getEdgesRuleChains: getEdgesRuleChains,
|
||||
assignRuleChainToEdge: assignRuleChainToEdge,
|
||||
unassignRuleChainFromEdge: unassignRuleChainFromEdge
|
||||
unassignRuleChainFromEdge: unassignRuleChainFromEdge,
|
||||
setDefaultRootEdgeRuleChain: setDefaultRootEdgeRuleChain
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
function getRuleChains (pageLink, config, type) {
|
||||
function getRuleChains(pageLink, config, type) {
|
||||
var deferred = $q.defer();
|
||||
var url = '/api/ruleChains?limit=' + pageLink.limit;
|
||||
if (angular.isDefined(pageLink.textSearch)) {
|
||||
@ -152,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) {
|
||||
@ -174,7 +176,7 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
|
||||
return result;
|
||||
}
|
||||
);
|
||||
deferred.resolve(ruleNodeComponents);
|
||||
deferred.resolve(ruleNodeComponents[ruleChainType]);
|
||||
},
|
||||
() => {
|
||||
deferred.reject();
|
||||
@ -231,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];
|
||||
}
|
||||
@ -282,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) {
|
||||
@ -341,6 +343,10 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function getEdgesRuleChains(pageLink, config) {
|
||||
return getRuleChains(pageLink, config, types.edgeRuleChainType);
|
||||
}
|
||||
|
||||
function getEdgeRuleChains(edgeId, pageLink, config) {
|
||||
var deferred = $q.defer();
|
||||
var url = '/api/edge/' + edgeId + '/ruleChains?limit=' + pageLink.limit;
|
||||
@ -381,6 +387,17 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function setDefaultRootEdgeRuleChain(ruleChainId) {
|
||||
var deferred = $q.defer();
|
||||
var url = '/api/ruleChain/' + ruleChainId + '/defaultRootEdge';
|
||||
$http.post(url).then(function success(response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function fail() {
|
||||
deferred.reject();
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function prepareRuleChains(ruleChainsData) {
|
||||
if (ruleChainsData.data) {
|
||||
for (var i = 0; i < ruleChainsData.data.length; i++) {
|
||||
|
||||
@ -258,6 +258,8 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
|
||||
}
|
||||
ruleChain.root = false;
|
||||
delete ruleChain.assignedEdgesText;
|
||||
delete ruleChain.assignedEdges;
|
||||
delete ruleChain.assignedEdgesIds;
|
||||
return ruleChain;
|
||||
}
|
||||
|
||||
@ -279,13 +281,16 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
|
||||
toast.showError($translate.instant('rulechain.export-failed-error', {error: message}));
|
||||
}
|
||||
|
||||
function importRuleChain($event) {
|
||||
function importRuleChain($event, expectedRuleChainType) {
|
||||
var deferred = $q.defer();
|
||||
openImportDialog($event, 'rulechain.import', 'rulechain.rulechain-file').then(
|
||||
function success(ruleChainImport) {
|
||||
if (!validateImportedRuleChain(ruleChainImport)) {
|
||||
toast.showError($translate.instant('rulechain.invalid-rulechain-file-error'));
|
||||
deferred.reject();
|
||||
} else if (ruleChainImport.ruleChain.type !== expectedRuleChainType) {
|
||||
toast.showError($translate.instant('rulechain.invalid-rulechain-type-error', {expectedRuleChainType: expectedRuleChainType}));
|
||||
deferred.reject();
|
||||
} else {
|
||||
deferred.resolve(ruleChainImport);
|
||||
}
|
||||
@ -307,6 +312,9 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
|
||||
if (angular.isUndefined(ruleChainImport.ruleChain.name)) {
|
||||
return false;
|
||||
}
|
||||
if (angular.isUndefined(ruleChainImport.ruleChain.type)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1559,7 +1559,11 @@
|
||||
"assign-to-edges-text": "Please select the edges to assign the rulechain(s)",
|
||||
"unassign-from-edges": "Unassign Rule Chain(s) From Edges",
|
||||
"unassign-from-edges-text": "Please select the edges to unassign from the rulechain(s)",
|
||||
"assigned-to-edges": "Assigned to edges"
|
||||
"assigned-to-edges": "Assigned to edges",
|
||||
"set-default-root-edge": "Make rule chain default root",
|
||||
"set-default-root-edge-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' default edge root?",
|
||||
"set-default-root-edge-rulechain-text": "After the confirmation the rule chain will become default edge root and will handle all incoming transport messages.",
|
||||
"invalid-rulechain-type-error": "Unable to import rule chain: Invalid rule chain type. Expected type is {{expectedRuleChainType}}."
|
||||
},
|
||||
"rulenode": {
|
||||
"details": "Details",
|
||||
|
||||
@ -52,7 +52,7 @@ export default function AddRuleChainsToEdgeController(ruleChainService, $mdDialo
|
||||
fetchMoreItems_: function () {
|
||||
if (vm.ruleChains.hasNext && !vm.ruleChains.pending) {
|
||||
vm.ruleChains.pending = true;
|
||||
ruleChainService.getRuleChains(vm.ruleChains.nextPageLink).then(
|
||||
ruleChainService.getEdgesRuleChains(vm.ruleChains.nextPageLink).then(
|
||||
function success(ruleChains) {
|
||||
vm.ruleChains.data = ruleChains.data;
|
||||
vm.ruleChains.nextPageLink = ruleChains.nextPageLink;
|
||||
|
||||
@ -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;
|
||||
@ -1269,7 +1269,11 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
||||
vm.isDirty = false;
|
||||
vm.isImport = false;
|
||||
$mdUtil.nextTick(() => {
|
||||
$state.go('home.ruleChains.ruleChain', {ruleChainId: vm.ruleChain.id.id});
|
||||
if (vm.ruleChain.type === vm.types.systemRuleChainType) {
|
||||
$state.go('home.ruleChains.system.ruleChain', {ruleChainId: vm.ruleChain.id.id});
|
||||
} else {
|
||||
$state.go('home.ruleChains.edge.ruleChain', {ruleChainId: vm.ruleChain.id.id});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
prepareRuleChain();
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -56,7 +56,7 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
|
||||
ncyBreadcrumb: {
|
||||
label: '{"icon": "settings_ethernet", "label": "rulechain.system-rulechains"}'
|
||||
}
|
||||
}).state('home.ruleChains.ruleChain', {
|
||||
}).state('home.ruleChains.system.ruleChain', {
|
||||
url: '/:ruleChainId',
|
||||
reloadOnSearch: false,
|
||||
module: 'private',
|
||||
@ -82,7 +82,7 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
|
||||
ruleNodeComponents:
|
||||
/*@ngInject*/
|
||||
function($stateParams, ruleChainService) {
|
||||
return ruleChainService.getRuleNodeComponents();
|
||||
return ruleChainService.getRuleNodeComponents(types.systemRuleChainType);
|
||||
}
|
||||
},
|
||||
data: {
|
||||
@ -106,7 +106,8 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
|
||||
}
|
||||
},
|
||||
params: {
|
||||
ruleChainImport: {}
|
||||
ruleChainImport: {},
|
||||
ruleChainType: {}
|
||||
},
|
||||
resolve: {
|
||||
ruleChain:
|
||||
@ -122,7 +123,7 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
|
||||
ruleNodeComponents:
|
||||
/*@ngInject*/
|
||||
function($stateParams, ruleChainService) {
|
||||
return ruleChainService.getRuleNodeComponents();
|
||||
return ruleChainService.getRuleNodeComponents($stateParams.ruleChainType);
|
||||
}
|
||||
},
|
||||
data: {
|
||||
@ -179,7 +180,7 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
|
||||
ruleNodeComponents:
|
||||
/*@ngInject*/
|
||||
function($stateParams, ruleChainService) {
|
||||
return ruleChainService.getRuleNodeComponents();
|
||||
return ruleChainService.getRuleNodeComponents(types.edgeRuleChainType);
|
||||
}
|
||||
},
|
||||
data: {
|
||||
@ -236,7 +237,7 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
|
||||
ruleNodeComponents:
|
||||
/*@ngInject*/
|
||||
function($stateParams, ruleChainService) {
|
||||
return ruleChainService.getRuleNodeComponents();
|
||||
return ruleChainService.getRuleNodeComponents(types.edgeRuleChainType);
|
||||
}
|
||||
},
|
||||
data: {
|
||||
|
||||
@ -164,9 +164,9 @@ export default function RuleChainsController(ruleChainService, userService, edge
|
||||
});
|
||||
vm.ruleChainGridConfig.addItemActions.push({
|
||||
onAction: function ($event) {
|
||||
importExport.importRuleChain($event).then(
|
||||
importExport.importRuleChain($event, types.systemRuleChainType).then(
|
||||
function(ruleChainImport) {
|
||||
$state.go('home.ruleChains.importRuleChain', {ruleChainImport:ruleChainImport});
|
||||
$state.go('home.ruleChains.importRuleChain', {ruleChainImport:ruleChainImport, ruleChainType: types.systemRuleChainType});
|
||||
}
|
||||
);
|
||||
},
|
||||
@ -202,6 +202,16 @@ export default function RuleChainsController(ruleChainService, userService, edge
|
||||
isEnabled: isNonRootRuleChain
|
||||
});
|
||||
|
||||
ruleChainActionsList.push({
|
||||
onAction: function ($event, item) {
|
||||
setDefaultRootEdgeRuleChain($event, item);
|
||||
},
|
||||
name: function() { return $translate.instant('rulechain.set-default-root-edge') },
|
||||
details: function() { return $translate.instant('rulechain.set-default-root-edge') },
|
||||
icon: "flag",
|
||||
isEnabled: isNonRootRuleChain
|
||||
});
|
||||
|
||||
ruleChainGroupActionsList.push(
|
||||
{
|
||||
onAction: function ($event, items) {
|
||||
@ -250,9 +260,9 @@ export default function RuleChainsController(ruleChainService, userService, edge
|
||||
});
|
||||
vm.ruleChainGridConfig.addItemActions.push({
|
||||
onAction: function ($event) {
|
||||
importExport.importRuleChain($event).then(
|
||||
importExport.importRuleChain($event, types.edgeRuleChainType).then(
|
||||
function(ruleChainImport) {
|
||||
$state.go('home.ruleChains.importRuleChain', {ruleChainImport:ruleChainImport});
|
||||
$state.go('home.ruleChains.importRuleChain', {ruleChainImport:ruleChainImport, ruleChainType: types.edgeRuleChainType});
|
||||
}
|
||||
);
|
||||
},
|
||||
@ -366,7 +376,7 @@ export default function RuleChainsController(ruleChainService, userService, edge
|
||||
} else if (vm.ruleChainsScope === 'edges') {
|
||||
$state.go('home.ruleChains.edge.ruleChain', {ruleChainId: ruleChain.id.id});
|
||||
} else {
|
||||
$state.go('home.ruleChains.ruleChain', {ruleChainId: ruleChain.id.id});
|
||||
$state.go('home.ruleChains.system.ruleChain', {ruleChainId: ruleChain.id.id});
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,6 +436,24 @@ export default function RuleChainsController(ruleChainService, userService, edge
|
||||
});
|
||||
}
|
||||
|
||||
function setDefaultRootEdgeRuleChain($event, ruleChain) {
|
||||
$event.stopPropagation();
|
||||
var confirm = $mdDialog.confirm()
|
||||
.targetEvent($event)
|
||||
.title($translate.instant('rulechain.set-default-root-edge-rulechain-title', {ruleChainName: ruleChain.name}))
|
||||
.htmlContent($translate.instant('rulechain.set-default-root-edge-rulechain-text'))
|
||||
.ariaLabel($translate.instant('rulechain.set-root-rulechain-text'))
|
||||
.cancel($translate.instant('action.no'))
|
||||
.ok($translate.instant('action.yes'));
|
||||
$mdDialog.show(confirm).then(function () {
|
||||
ruleChainService.setDefaultRootEdgeRuleChain(ruleChain.id.id).then(
|
||||
() => {
|
||||
vm.grid.refreshList();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function manageAssignedEdges($event, ruleChain) {
|
||||
showManageAssignedEdgesDialog($event, [ruleChain.id.id], 'manage', ruleChain.assignedEdgesIds);
|
||||
}
|
||||
@ -488,7 +516,7 @@ export default function RuleChainsController(ruleChainService, userService, edge
|
||||
$event.stopPropagation();
|
||||
}
|
||||
var pageSize = 10;
|
||||
ruleChainService.getRuleChains({limit: pageSize, textSearch: ''}).then(
|
||||
ruleChainService.getEdgesRuleChains({limit: pageSize, textSearch: ''}).then(
|
||||
function success(_ruleChains) {
|
||||
var ruleChains = {
|
||||
pageSize: pageSize,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -231,12 +231,12 @@ function Menu(userService, $state, $rootScope) {
|
||||
{
|
||||
name: 'rulechain.system-rulechains',
|
||||
icon: 'settings_ethernet',
|
||||
state: 'home.ruleChains'
|
||||
state: 'home.ruleChains.system'
|
||||
},
|
||||
{
|
||||
name: 'rulechain.edge-rulechains',
|
||||
icon: 'router',
|
||||
state: 'home.edgesRuleChains'
|
||||
state: 'home.ruleChains.edge'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user