Merge branch 'feature/edge' into develop/3.0-edge
This commit is contained in:
commit
f3aa410c17
@ -0,0 +1,143 @@
|
||||
{
|
||||
"ruleChain": {
|
||||
"additionalInfo": null,
|
||||
"name": "Edge Root Rule Chain",
|
||||
"type": "EDGE",
|
||||
"firstRuleNodeId": null,
|
||||
"root": true,
|
||||
"debugMode": false,
|
||||
"configuration": null
|
||||
},
|
||||
"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
|
||||
}
|
||||
}
|
||||
63
application/src/main/data/upgrade/2.4.x/schema_update.cql
Normal file
63
application/src/main/data/upgrade/2.4.x/schema_update.cql
Normal file
@ -0,0 +1,63 @@
|
||||
--
|
||||
-- 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.
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS thingsboard.edge (
|
||||
id timeuuid,
|
||||
tenant_id timeuuid,
|
||||
customer_id timeuuid,
|
||||
name text,
|
||||
search_text text,
|
||||
configuration text,
|
||||
additional_info text,
|
||||
PRIMARY KEY (id, tenant_id)
|
||||
);
|
||||
|
||||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_name AS
|
||||
SELECT *
|
||||
from thingsboard.edge
|
||||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL
|
||||
PRIMARY KEY ( tenant_id, name, id, customer_id, type)
|
||||
WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC);
|
||||
|
||||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_search_text AS
|
||||
SELECT *
|
||||
from thingsboard.edge
|
||||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL
|
||||
PRIMARY KEY ( tenant_id, search_text, id, customer_id, type)
|
||||
WITH CLUSTERING ORDER BY ( search_text ASC, id DESC, customer_id DESC);
|
||||
|
||||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_by_type_and_search_text AS
|
||||
SELECT *
|
||||
from thingsboard.edge
|
||||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL
|
||||
PRIMARY KEY ( tenant_id, type, search_text, id, customer_id)
|
||||
WITH CLUSTERING ORDER BY ( type ASC, search_text ASC, id DESC, customer_id DESC);
|
||||
|
||||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_customer_and_search_text AS
|
||||
SELECT *
|
||||
from thingsboard.edge
|
||||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL
|
||||
PRIMARY KEY ( customer_id, tenant_id, search_text, id, type )
|
||||
WITH CLUSTERING ORDER BY ( tenant_id DESC, search_text ASC, id DESC );
|
||||
|
||||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_customer_by_type_and_search_text AS
|
||||
SELECT *
|
||||
from thingsboard.edge
|
||||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL
|
||||
PRIMARY KEY ( customer_id, tenant_id, type, search_text, id )
|
||||
WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC );
|
||||
|
||||
-- VOBA ADD changes for the MATERIALIZED view for DEVICE ASSET ENTITY_VIEW RULE_CHAIN
|
||||
30
application/src/main/data/upgrade/2.4.x/schema_update.sql
Normal file
30
application/src/main/data/upgrade/2.4.x/schema_update.sql
Normal file
@ -0,0 +1,30 @@
|
||||
--
|
||||
-- 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.
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS edge (
|
||||
id varchar(31) NOT NULL CONSTRAINT edge_pkey PRIMARY KEY,
|
||||
additional_info varchar,
|
||||
customer_id varchar(31),
|
||||
root_rule_chain_id varchar(31),
|
||||
configuration varchar(10000000),
|
||||
type varchar(255),
|
||||
name varchar(255),
|
||||
label varchar(255),
|
||||
routing_key varchar(255),
|
||||
secret varchar(255),
|
||||
search_text varchar(255),
|
||||
tenant_id varchar(31)
|
||||
);
|
||||
@ -23,6 +23,7 @@ import com.datastax.driver.core.utils.UUIDs;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import org.thingsboard.server.actors.ActorSystemContext;
|
||||
@ -31,6 +32,7 @@ import org.thingsboard.server.actors.service.DefaultActorService;
|
||||
import org.thingsboard.server.actors.shared.ComponentMsgProcessor;
|
||||
import org.thingsboard.server.common.data.DataConstants;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.ShortEdgeInfo;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||
import org.thingsboard.server.common.data.id.RuleNodeId;
|
||||
|
||||
@ -37,7 +37,6 @@ import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
|
||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainType;
|
||||
import org.thingsboard.server.common.msg.TbActorMsg;
|
||||
@ -47,9 +46,6 @@ import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
|
||||
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
||||
import scala.concurrent.duration.Duration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TenantActor extends RuleChainManagerActor {
|
||||
|
||||
private final TenantId tenantId;
|
||||
@ -148,7 +144,6 @@ public class TenantActor extends RuleChainManagerActor {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ActorRef target = getEntityActorRef(msg.getEntityId());
|
||||
if (target != null) {
|
||||
if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN && ruleChain != null) {
|
||||
|
||||
@ -60,6 +60,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;
|
||||
@ -502,6 +503,18 @@ public abstract class BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
Edge checkEdgeId(EdgeId edgeId, Operation operation) throws ThingsboardException {
|
||||
try {
|
||||
validateId(edgeId, "Incorrect edgeId " + edgeId);
|
||||
Edge edge = edgeService.findEdgeById(getTenantId(), edgeId);
|
||||
checkNotNull(edge);
|
||||
accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, operation, edgeId, edge);
|
||||
return edge;
|
||||
} catch (Exception e) {
|
||||
throw handleException(e, false);
|
||||
}
|
||||
}
|
||||
|
||||
DashboardInfo checkDashboardInfoId(DashboardId dashboardId, Operation operation) throws ThingsboardException {
|
||||
try {
|
||||
validateId(dashboardId, "Incorrect dashboardId " + dashboardId);
|
||||
@ -514,28 +527,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);
|
||||
}
|
||||
@ -557,18 +552,6 @@ public abstract class BaseController {
|
||||
return ruleNode;
|
||||
}
|
||||
|
||||
Edge checkEdgeId(EdgeId edgeId, Operation operation) throws ThingsboardException {
|
||||
try {
|
||||
validateId(edgeId, "Incorrect edgeId " + edgeId);
|
||||
Edge edge = edgeService.findEdgeById(getTenantId(), edgeId);
|
||||
checkNotNull(edge);
|
||||
accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, operation, edgeId, edge);
|
||||
return edge;
|
||||
} catch (Exception e) {
|
||||
throw handleException(e, false);
|
||||
}
|
||||
}
|
||||
|
||||
protected String constructBaseUrl(HttpServletRequest request) {
|
||||
String scheme = request.getScheme();
|
||||
|
||||
@ -682,7 +665,7 @@ public abstract class BaseController {
|
||||
String strCustomerName = extractParameter(String.class, 2, additionalInfo);
|
||||
metaData.putValue("unassignedCustomerId", strCustomerId);
|
||||
metaData.putValue("unassignedCustomerName", strCustomerName);
|
||||
} else if (actionType == ActionType.ASSIGNED_TO_EDGE) {
|
||||
} if (actionType == ActionType.ASSIGNED_TO_EDGE) {
|
||||
String strEdgeId = extractParameter(String.class, 1, additionalInfo);
|
||||
metaData.putValue("assignedEdgeId", strEdgeId);
|
||||
} else if (actionType == ActionType.UNASSIGNED_FROM_EDGE) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.thingsboard.server.controller;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
@ -86,9 +86,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);
|
||||
@ -380,4 +380,4 @@ public class EdgeController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,7 +429,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,
|
||||
@ -493,7 +493,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());
|
||||
@ -580,7 +580,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());
|
||||
@ -622,4 +622,22 @@ public class RuleChainController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@ -127,4 +127,4 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase {
|
||||
sessions.remove(edgeId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.grpc.stub.StreamObserver;
|
||||
import lombok.Data;
|
||||
@ -29,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;
|
||||
@ -54,39 +54,29 @@ import org.thingsboard.server.common.data.page.PageData;
|
||||
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;
|
||||
@ -94,7 +84,6 @@ import org.thingsboard.server.gen.edge.UserUpdateMsg;
|
||||
import org.thingsboard.server.service.edge.EdgeContextComponent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@ -146,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()) {
|
||||
@ -169,7 +161,6 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void processHandleMessages() throws ExecutionException, InterruptedException {
|
||||
Long queueStartTs = getQueueStartTs().get();
|
||||
// TODO: this 100 value must be changed properly
|
||||
@ -245,8 +236,8 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
break;
|
||||
}
|
||||
if (entityId != null) {
|
||||
final EntityId finalEntityId = entityId;
|
||||
ListenableFuture<List<AttributeKvEntry>> ssAttrFuture = ctx.getAttributesService().findAll(edge.getTenantId(), entityId, DataConstants.SERVER_SCOPE);
|
||||
EntityId finalEntityId = entityId;
|
||||
Futures.transform(ssAttrFuture, ssAttributes -> {
|
||||
if (ssAttributes != null && !ssAttributes.isEmpty()) {
|
||||
try {
|
||||
@ -276,7 +267,7 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}, MoreExecutors.directExecutor());
|
||||
ListenableFuture<List<AttributeKvEntry>> shAttrFuture = ctx.getAttributesService().findAll(edge.getTenantId(), entityId, DataConstants.SHARED_SCOPE);
|
||||
ListenableFuture<List<AttributeKvEntry>> clAttrFuture = ctx.getAttributesService().findAll(edge.getTenantId(), entityId, DataConstants.CLIENT_SCOPE);
|
||||
}
|
||||
@ -356,13 +347,13 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
ListenableFuture<Optional<AttributeKvEntry>> future =
|
||||
ctx.getAttributesService().find(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, "queueStartTs");
|
||||
return Futures.transform(future, attributeKvEntryOpt -> {
|
||||
if (attributeKvEntryOpt != null && attributeKvEntryOpt.isPresent()) {
|
||||
AttributeKvEntry attributeKvEntry = attributeKvEntryOpt.get();
|
||||
return attributeKvEntry.getLongValue().isPresent() ? attributeKvEntry.getLongValue().get() : 0L;
|
||||
} else {
|
||||
return 0L;
|
||||
}
|
||||
});
|
||||
if (attributeKvEntryOpt != null && attributeKvEntryOpt.isPresent()) {
|
||||
AttributeKvEntry attributeKvEntry = attributeKvEntryOpt.get();
|
||||
return attributeKvEntry.getLongValue().isPresent() ? attributeKvEntry.getLongValue().get() : 0L;
|
||||
} else {
|
||||
return 0L;
|
||||
}
|
||||
}, MoreExecutors.directExecutor());
|
||||
}
|
||||
|
||||
private void onEdgeUpdated(UpdateMsgType msgType, Edge edge) {
|
||||
@ -372,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)
|
||||
@ -381,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)
|
||||
@ -390,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)
|
||||
@ -399,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)
|
||||
@ -407,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)
|
||||
@ -420,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)
|
||||
@ -429,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()) ||
|
||||
@ -492,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)
|
||||
@ -519,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);
|
||||
@ -621,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()) {
|
||||
@ -711,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();
|
||||
}
|
||||
@ -887,4 +707,4 @@ public final class EdgeGrpcSession implements Cloneable {
|
||||
.setType(edge.getType().toString())
|
||||
.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,271 @@
|
||||
/**
|
||||
* 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.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
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 {
|
||||
PageLink pageLink = new PageLink(100);
|
||||
PageData<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 = pageLink.nextPageLink();
|
||||
}
|
||||
} 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 {
|
||||
PageLink pageLink = new PageLink(100);
|
||||
PageData<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 = pageLink.nextPageLink();
|
||||
}
|
||||
} 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 {
|
||||
PageLink pageLink = new PageLink(100);
|
||||
PageData<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 = pageLink.nextPageLink();
|
||||
}
|
||||
} 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);
|
||||
PageData<DashboardInfo> pageData;
|
||||
do {
|
||||
pageData = dashboardService.findDashboardsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
|
||||
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 = pageLink.nextPageLink();
|
||||
}
|
||||
} 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);
|
||||
PageData<RuleChain> pageData;
|
||||
do {
|
||||
pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
|
||||
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 = pageLink.nextPageLink();
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainType;
|
||||
import org.thingsboard.server.common.data.widget.WidgetType;
|
||||
import org.thingsboard.server.common.data.widget.WidgetsBundle;
|
||||
import org.thingsboard.server.dao.dashboard.DashboardService;
|
||||
|
||||
@ -76,8 +76,8 @@ public class AccessValidator {
|
||||
public static final String CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "Customer user is not allowed to perform this operation!";
|
||||
public static final String SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "System administrator is not allowed to perform this operation!";
|
||||
public static final String DEVICE_WITH_REQUESTED_ID_NOT_FOUND = "Device with requested id wasn't found!";
|
||||
public static final String ENTITY_VIEW_WITH_REQUESTED_ID_NOT_FOUND = "Entity-view with requested id wasn't found!";
|
||||
public static final String EDGE_WITH_REQUESTED_ID_NOT_FOUND = "Edge with requested id wasn't found!";
|
||||
public static final String ENTITY_VIEW_WITH_REQUESTED_ID_NOT_FOUND = "Entity-view with requested id wasn't found!";
|
||||
|
||||
@Autowired
|
||||
protected TenantService tenantService;
|
||||
|
||||
@ -41,6 +41,7 @@ public class CustomerUserPermissions extends AbstractPermissions {
|
||||
put(Resource.USER, userPermissionChecker);
|
||||
put(Resource.WIDGETS_BUNDLE, widgetsPermissionChecker);
|
||||
put(Resource.WIDGET_TYPE, widgetsPermissionChecker);
|
||||
put(Resource.EDGE, customerEntityPermissionChecker);
|
||||
}
|
||||
|
||||
private static final PermissionChecker customerEntityPermissionChecker =
|
||||
|
||||
@ -43,6 +43,7 @@ public class TenantAdminPermissions extends AbstractPermissions {
|
||||
put(Resource.USER, userPermissionChecker);
|
||||
put(Resource.WIDGETS_BUNDLE, widgetsPermissionChecker);
|
||||
put(Resource.WIDGET_TYPE, widgetsPermissionChecker);
|
||||
put(Resource.EDGE, tenantEntityPermissionChecker);
|
||||
}
|
||||
|
||||
public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker() {
|
||||
|
||||
@ -65,30 +65,17 @@ public abstract class BaseComponentDescriptorControllerTest extends AbstractCont
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetByClazz() throws Exception {
|
||||
ComponentDescriptor descriptor =
|
||||
doGet("/api/component/" + TbJsFilterNode.class.getName(), ComponentDescriptor.class);
|
||||
|
||||
Assert.assertNotNull(descriptor);
|
||||
Assert.assertNotNull(descriptor.getId());
|
||||
Assert.assertNotNull(descriptor.getName());
|
||||
Assert.assertEquals(ComponentScope.TENANT, descriptor.getScope());
|
||||
Assert.assertEquals(ComponentType.FILTER, descriptor.getType());
|
||||
Assert.assertEquals(descriptor.getClazz(), descriptor.getClazz());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetByType() throws Exception {
|
||||
List<ComponentDescriptor> descriptors = readResponse(
|
||||
doGet("/api/components/" + ComponentType.FILTER).andExpect(status().isOk()), new TypeReference<List<ComponentDescriptor>>() {
|
||||
doGet("/api/components/SYSTEM?componentTypes={componentTypes}", ComponentType.FILTER).andExpect(status().isOk()), new TypeReference<List<ComponentDescriptor>>() {
|
||||
});
|
||||
|
||||
Assert.assertNotNull(descriptors);
|
||||
Assert.assertTrue(descriptors.size() >= AMOUNT_OF_DEFAULT_FILTER_NODES);
|
||||
|
||||
for (ComponentType type : ComponentType.values()) {
|
||||
doGet("/api/components/" + type).andExpect(status().isOk());
|
||||
doGet("/api/components/SYSTEM?componentTypes={componentTypes}", type).andExpect(status().isOk());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* 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,
|
||||
|
||||
@ -70,11 +70,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);
|
||||
|
||||
PageData<RuleChain> findRuleChainsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, PageLink pageLink);
|
||||
|
||||
RuleChain getDefaultRootEdgeRuleChain(TenantId tenantId);
|
||||
|
||||
boolean setDefaultRootEdgeRuleChain(TenantId tenantId, RuleChainId ruleChainId);
|
||||
}
|
||||
|
||||
@ -67,4 +67,5 @@ public class DataConstants {
|
||||
public static final String DURATION_MS_FIELD_NAME = "durationMs";
|
||||
|
||||
public static final String EDGE_QUEUE_EVENT_TYPE = "EDGE_QUEUE";
|
||||
|
||||
}
|
||||
|
||||
@ -47,4 +47,4 @@ public class ShortEdgeInfo {
|
||||
public int hashCode() {
|
||||
return edgeId.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,4 +79,4 @@ public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements H
|
||||
public String getSearchText() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,4 +17,4 @@ package org.thingsboard.server.common.data.edge;
|
||||
|
||||
public enum EdgeQueueEntityType {
|
||||
DASHBOARD, ASSET, DEVICE, ENTITY_VIEW, ALARM, RULE_CHAIN, RULE_CHAIN_METADATA, EDGE, USER, CUSTOMER
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,4 +22,4 @@ public class EdgeQueueEntry {
|
||||
private String type;
|
||||
private EdgeQueueEntityType entityType;
|
||||
private String data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,4 +40,4 @@ public class EdgeSearchQuery {
|
||||
Collections.singletonList(EntityType.EDGE))));
|
||||
return query;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,4 +40,4 @@ public class EdgeId extends UUIDBased implements EntityId {
|
||||
public EntityType getEntityType() {
|
||||
return EntityType.EDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,4 +17,4 @@ package org.thingsboard.server.common.data.rule;
|
||||
|
||||
public enum RuleChainType {
|
||||
SYSTEM, EDGE
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,4 +126,4 @@
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@ -147,4 +147,4 @@ public class EdgeGrpcClient implements EdgeRpcClient {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,4 +36,4 @@ public interface EdgeRpcClient {
|
||||
void disconnect() throws InterruptedException;
|
||||
|
||||
void sendUplinkMsg(UplinkMsg uplinkMsg) throws InterruptedException;
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ package edge;
|
||||
// Interface exported by the ThingsBoard Edge Transport.
|
||||
service EdgeRpcService {
|
||||
|
||||
rpc handleMsgs(stream RequestMsg) returns (stream ResponseMsg) {}
|
||||
rpc handleMsgs(stream RequestMsg) returns (stream ResponseMsg) {}
|
||||
|
||||
}
|
||||
|
||||
@ -32,59 +32,59 @@ service EdgeRpcService {
|
||||
* Data Structures;
|
||||
*/
|
||||
message RequestMsg {
|
||||
RequestMsgType msgType = 1;
|
||||
ConnectRequestMsg connectRequestMsg = 2;
|
||||
UplinkMsg uplinkMsg = 3;
|
||||
RequestMsgType msgType = 1;
|
||||
ConnectRequestMsg connectRequestMsg = 2;
|
||||
UplinkMsg uplinkMsg = 3;
|
||||
}
|
||||
|
||||
message ResponseMsg {
|
||||
ConnectResponseMsg connectResponseMsg = 1;
|
||||
UplinkResponseMsg uplinkResponseMsg = 2;
|
||||
EntityUpdateMsg entityUpdateMsg = 3;
|
||||
DownlinkMsg downlinkMsg = 4;
|
||||
ConnectResponseMsg connectResponseMsg = 1;
|
||||
UplinkResponseMsg uplinkResponseMsg = 2;
|
||||
EntityUpdateMsg entityUpdateMsg = 3;
|
||||
DownlinkMsg downlinkMsg = 4;
|
||||
}
|
||||
|
||||
message EntityUpdateMsg {
|
||||
DeviceUpdateMsg deviceUpdateMsg = 1;
|
||||
RuleChainUpdateMsg ruleChainUpdateMsg = 2;
|
||||
RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = 3;
|
||||
DashboardUpdateMsg dashboardUpdateMsg = 4;
|
||||
AssetUpdateMsg assetUpdateMsg = 5;
|
||||
EntityViewUpdateMsg entityViewUpdateMsg = 6;
|
||||
AlarmUpdateMsg alarmUpdateMsg = 7;
|
||||
UserUpdateMsg userUpdateMsg = 8;
|
||||
CustomerUpdateMsg customerUpdateMsg = 9;
|
||||
DeviceUpdateMsg deviceUpdateMsg = 1;
|
||||
RuleChainUpdateMsg ruleChainUpdateMsg = 2;
|
||||
RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = 3;
|
||||
DashboardUpdateMsg dashboardUpdateMsg = 4;
|
||||
AssetUpdateMsg assetUpdateMsg = 5;
|
||||
EntityViewUpdateMsg entityViewUpdateMsg = 6;
|
||||
AlarmUpdateMsg alarmUpdateMsg = 7;
|
||||
UserUpdateMsg userUpdateMsg = 8;
|
||||
CustomerUpdateMsg customerUpdateMsg = 9;
|
||||
}
|
||||
|
||||
enum RequestMsgType {
|
||||
CONNECT_RPC_MESSAGE = 0;
|
||||
UPLINK_RPC_MESSAGE = 1;
|
||||
CONNECT_RPC_MESSAGE = 0;
|
||||
UPLINK_RPC_MESSAGE = 1;
|
||||
}
|
||||
|
||||
message ConnectRequestMsg {
|
||||
string edgeRoutingKey = 1;
|
||||
string edgeSecret = 2;
|
||||
string edgeRoutingKey = 1;
|
||||
string edgeSecret = 2;
|
||||
}
|
||||
|
||||
enum ConnectResponseCode {
|
||||
ACCEPTED = 0;
|
||||
BAD_CREDENTIALS = 1;
|
||||
SERVER_UNAVAILABLE = 2;
|
||||
ACCEPTED = 0;
|
||||
BAD_CREDENTIALS = 1;
|
||||
SERVER_UNAVAILABLE = 2;
|
||||
}
|
||||
|
||||
message ConnectResponseMsg {
|
||||
ConnectResponseCode responseCode = 1;
|
||||
string errorMsg = 2;
|
||||
EdgeConfiguration configuration = 3;
|
||||
ConnectResponseCode responseCode = 1;
|
||||
string errorMsg = 2;
|
||||
EdgeConfiguration configuration = 3;
|
||||
}
|
||||
|
||||
message EdgeConfiguration {
|
||||
int64 tenantIdMSB = 1;
|
||||
int64 tenantIdLSB = 2;
|
||||
string name = 5;
|
||||
string routingKey = 6;
|
||||
string type = 7;
|
||||
string cloudType = 8;
|
||||
int64 tenantIdMSB = 1;
|
||||
int64 tenantIdLSB = 2;
|
||||
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;
|
||||
@ -234,18 +239,20 @@ enum EntityType {
|
||||
*/
|
||||
|
||||
message UplinkMsg {
|
||||
int32 uplinkMsgId = 1;
|
||||
repeated EntityDataProto entityData = 2;
|
||||
repeated DeviceUpdateMsg deviceUpdateMsg = 3;
|
||||
repeated AlarmUpdateMsg alarmUpdatemsg = 4;
|
||||
int32 uplinkMsgId = 1;
|
||||
repeated EntityDataProto entityData = 2;
|
||||
repeated DeviceUpdateMsg deviceUpdateMsg = 3;
|
||||
repeated AlarmUpdateMsg alarmUpdateMsg = 4;
|
||||
repeated RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg = 5;
|
||||
}
|
||||
|
||||
message UplinkResponseMsg {
|
||||
bool success = 1;
|
||||
string errorMsg = 2;
|
||||
bool success = 1;
|
||||
string errorMsg = 2;
|
||||
}
|
||||
|
||||
message DownlinkMsg {
|
||||
int32 downlinkMsgId = 1;
|
||||
repeated EntityDataProto entityData = 2;
|
||||
}
|
||||
int32 downlinkMsgId = 1;
|
||||
repeated EntityDataProto entityData = 2;
|
||||
}
|
||||
|
||||
|
||||
@ -122,6 +122,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
|
||||
entityViewService.unassignCustomerEntityViews(customer.getTenantId(), customerId);
|
||||
assetService.unassignCustomerAssets(customer.getTenantId(), customerId);
|
||||
deviceService.unassignCustomerDevices(customer.getTenantId(), customerId);
|
||||
edgeService.unassignCustomerEdges(customer.getTenantId(), customerId);
|
||||
userService.deleteCustomerUsers(customer.getTenantId(), customerId);
|
||||
edgeService.unassignCustomerEdges(customer.getTenantId(), customerId);
|
||||
deleteEntityRelations(tenantId, customerId);
|
||||
|
||||
@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
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.dao.customer.CustomerDao;
|
||||
@ -39,6 +40,7 @@ import org.thingsboard.server.dao.entity.AbstractEntityService;
|
||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||
import org.thingsboard.server.dao.service.DataValidator;
|
||||
import org.thingsboard.server.dao.service.PaginatedRemover;
|
||||
import org.thingsboard.server.dao.service.TimePaginatedRemover;
|
||||
import org.thingsboard.server.dao.service.Validator;
|
||||
import org.thingsboard.server.dao.tenant.TenantDao;
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import com.google.common.base.Function;
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.Cache;
|
||||
@ -215,7 +216,7 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic
|
||||
|
||||
dashboardService.unassignEdgeDashboards(tenantId, edgeId);
|
||||
// TODO: validate that rule chains are removed by deleteEntityRelations(tenantId, edgeId); call
|
||||
// ruleChainService.unassignEdgeRuleChains(tenantId, edgeId);
|
||||
ruleChainService.unassignEdgeRuleChains(tenantId, edgeId);
|
||||
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(edge.getTenantId());
|
||||
@ -311,7 +312,7 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic
|
||||
}
|
||||
}
|
||||
return Futures.successfulAsList(futures);
|
||||
});
|
||||
}, MoreExecutors.directExecutor());
|
||||
|
||||
edges = Futures.transform(edges, new Function<List<Edge>, List<Edge>>() {
|
||||
@Nullable
|
||||
@ -319,7 +320,7 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic
|
||||
public List<Edge> apply(@Nullable List<Edge> edgeList) {
|
||||
return edgeList == null ? Collections.emptyList() : edgeList.stream().filter(edge -> query.getEdgeTypes().contains(edge.getType())).collect(Collectors.toList());
|
||||
}
|
||||
});
|
||||
}, MoreExecutors.directExecutor());
|
||||
|
||||
return edges;
|
||||
}
|
||||
@ -333,7 +334,7 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic
|
||||
edgeTypes -> {
|
||||
edgeTypes.sort(Comparator.comparing(EntitySubtype::getType));
|
||||
return edgeTypes;
|
||||
});
|
||||
}, MoreExecutors.directExecutor());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -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!");
|
||||
}
|
||||
|
||||
@ -29,7 +29,12 @@ import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.*;
|
||||
import org.thingsboard.server.common.data.Customer;
|
||||
import org.thingsboard.server.common.data.EntitySubtype;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.EntityView;
|
||||
import org.thingsboard.server.common.data.EntityViewInfo;
|
||||
import org.thingsboard.server.common.data.Tenant;
|
||||
import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
|
||||
import org.thingsboard.server.common.data.id.CustomerId;
|
||||
import org.thingsboard.server.common.data.id.EdgeId;
|
||||
|
||||
@ -345,6 +345,7 @@ public class ModelConstants {
|
||||
public static final String RULE_CHAIN_ASSIGNED_EDGES_PROPERTY = "assigned_edges";
|
||||
|
||||
public static final String RULE_CHAIN_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "rule_chain_by_tenant_and_search_text";
|
||||
public static final String RULE_CHAIN_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "rule_chain_by_tenant_by_type_and_search_text";
|
||||
|
||||
/**
|
||||
* Cassandra rule node constants.
|
||||
|
||||
@ -0,0 +1,145 @@
|
||||
/**
|
||||
* 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.dao.model.nosql;
|
||||
|
||||
import com.datastax.driver.core.utils.UUIDs;
|
||||
import com.datastax.driver.mapping.annotations.ClusteringColumn;
|
||||
import com.datastax.driver.mapping.annotations.Column;
|
||||
import com.datastax.driver.mapping.annotations.PartitionKey;
|
||||
import com.datastax.driver.mapping.annotations.Table;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.Data;
|
||||
import org.thingsboard.server.common.data.edge.Edge;
|
||||
import org.thingsboard.server.common.data.id.CustomerId;
|
||||
import org.thingsboard.server.common.data.id.EdgeId;
|
||||
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.dao.model.SearchTextEntity;
|
||||
import org.thingsboard.server.dao.model.type.JsonCodec;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_ADDITIONAL_INFO_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY_NAME;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CONFIGURATION_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CUSTOMER_ID_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_LABEL_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_NAME_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_ROOT_RULE_CHAIN_ID_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_ROUTING_KEY_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_SECRET_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TENANT_ID_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TYPE_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
|
||||
import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
|
||||
|
||||
@Data
|
||||
@Table(name = EDGE_COLUMN_FAMILY_NAME)
|
||||
public class EdgeEntity implements SearchTextEntity<Edge> {
|
||||
|
||||
@PartitionKey
|
||||
@Column(name = ID_PROPERTY)
|
||||
private UUID id;
|
||||
|
||||
@ClusteringColumn
|
||||
@Column(name = EDGE_TENANT_ID_PROPERTY)
|
||||
private UUID tenantId;
|
||||
|
||||
@ClusteringColumn
|
||||
@Column(name = EDGE_CUSTOMER_ID_PROPERTY)
|
||||
private UUID customerId;
|
||||
|
||||
@Column(name = EDGE_ROOT_RULE_CHAIN_ID_PROPERTY)
|
||||
private UUID rootRuleChainId;
|
||||
|
||||
@Column(name = EDGE_TYPE_PROPERTY)
|
||||
private String type;
|
||||
|
||||
@Column(name = EDGE_NAME_PROPERTY)
|
||||
private String name;
|
||||
|
||||
@Column(name = EDGE_LABEL_PROPERTY)
|
||||
private String label;
|
||||
|
||||
@Column(name = SEARCH_TEXT_PROPERTY)
|
||||
private String searchText;
|
||||
|
||||
@Column(name = EDGE_ROUTING_KEY_PROPERTY)
|
||||
private String routingKey;
|
||||
|
||||
@Column(name = EDGE_SECRET_PROPERTY)
|
||||
private String secret;
|
||||
|
||||
@Column(name = EDGE_CONFIGURATION_PROPERTY, codec = JsonCodec.class)
|
||||
private JsonNode configuration;
|
||||
|
||||
@Column(name = EDGE_ADDITIONAL_INFO_PROPERTY, codec = JsonCodec.class)
|
||||
private JsonNode additionalInfo;
|
||||
|
||||
public EdgeEntity() {
|
||||
super();
|
||||
}
|
||||
|
||||
public EdgeEntity(Edge edge) {
|
||||
if (edge.getId() != null) {
|
||||
this.id = edge.getId().getId();
|
||||
}
|
||||
if (edge.getTenantId() != null) {
|
||||
this.tenantId = edge.getTenantId().getId();
|
||||
}
|
||||
if (edge.getCustomerId() != null) {
|
||||
this.customerId = edge.getCustomerId().getId();
|
||||
}
|
||||
if (edge.getRootRuleChainId() != null) {
|
||||
this.rootRuleChainId = edge.getRootRuleChainId().getId();
|
||||
}
|
||||
this.type = edge.getType();
|
||||
this.name = edge.getName();
|
||||
this.label = edge.getLabel();
|
||||
this.routingKey = edge.getRoutingKey();
|
||||
this.secret = edge.getSecret();
|
||||
this.configuration = edge.getConfiguration();
|
||||
this.additionalInfo = edge.getAdditionalInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSearchTextSource() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Edge toData() {
|
||||
Edge edge = new Edge(new EdgeId(id));
|
||||
edge.setCreatedTime(UUIDs.unixTimestamp(id));
|
||||
if (tenantId != null) {
|
||||
edge.setTenantId(new TenantId(tenantId));
|
||||
}
|
||||
if (customerId != null) {
|
||||
edge.setCustomerId(new CustomerId(customerId));
|
||||
}
|
||||
if (rootRuleChainId != null) {
|
||||
edge.setRootRuleChainId(new RuleChainId(rootRuleChainId));
|
||||
}
|
||||
edge.setType(type);
|
||||
edge.setName(name);
|
||||
edge.setLabel(label);
|
||||
edge.setRoutingKey(routingKey);
|
||||
edge.setSecret(secret);
|
||||
edge.setConfiguration(configuration);
|
||||
edge.setAdditionalInfo(additionalInfo);
|
||||
return edge;
|
||||
}
|
||||
}
|
||||
@ -111,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) {
|
||||
@ -275,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.");
|
||||
@ -405,13 +414,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)) {
|
||||
@ -458,6 +467,33 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
||||
return ruleChainDao.findRuleChainsByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);
|
||||
}
|
||||
|
||||
@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);
|
||||
@ -517,12 +553,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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -555,7 +597,7 @@ 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -70,4 +70,4 @@ public interface EdgeRepository extends CrudRepository<EdgeEntity, String> {
|
||||
List<EdgeEntity> findEdgesByTenantIdAndIdIn(String tenantId, List<String> edgeIds);
|
||||
|
||||
EdgeEntity findByRoutingKey(String routingKey);
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,4 +138,4 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao<EdgeEntity, Edge> imple
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,4 +269,4 @@ CREATE TABLE IF NOT EXISTS edge (
|
||||
secret varchar(255),
|
||||
search_text varchar(255),
|
||||
tenant_id varchar(31)
|
||||
);
|
||||
);
|
||||
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 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.dao.service.nosql;
|
||||
|
||||
import org.thingsboard.server.dao.service.BaseEdgeServiceTest;
|
||||
import org.thingsboard.server.dao.service.DaoNoSqlTest;
|
||||
|
||||
@DaoNoSqlTest
|
||||
public class EdgeServiceNoSqlTest extends BaseEdgeServiceTest {
|
||||
}
|
||||
@ -20,4 +20,4 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
|
||||
|
||||
@DaoSqlTest
|
||||
public class EdgeServiceSqlTest extends BaseEdgeServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,4 +20,4 @@ DROP TABLE IF EXISTS widgets_bundle;
|
||||
DROP TABLE IF EXISTS rule_node;
|
||||
DROP TABLE IF EXISTS rule_chain;
|
||||
DROP TABLE IF EXISTS entity_view;
|
||||
DROP TABLE IF EXISTS edge;
|
||||
DROP TABLE IF EXISTS edge;
|
||||
5
pom.xml
5
pom.xml
@ -423,6 +423,11 @@
|
||||
<artifactId>coap</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thingsboard.common</groupId>
|
||||
<artifactId>edge-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thingsboard</groupId>
|
||||
<artifactId>dao</artifactId>
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -28,6 +28,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.dao.cassandra.CassandraCluster;
|
||||
import org.thingsboard.server.dao.model.type.ComponentLifecycleStateCodec;
|
||||
@ -61,7 +62,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
|
||||
" 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"},
|
||||
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 {
|
||||
|
||||
@ -38,4 +38,4 @@ class PushToEdgeNodeCallback implements FutureCallback<Void> {
|
||||
public void onFailure(Throwable t) {
|
||||
ctx.tellFailure(msg, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -55,4 +57,4 @@ public class TbMsgPushToCloudNode implements TbNode {
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
@ -55,4 +68,4 @@ public class TbMsgPushToEdgeNode implements TbNode {
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"},
|
||||
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"},
|
||||
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"},
|
||||
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"},
|
||||
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"},
|
||||
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"},
|
||||
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 {
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user