Browse Source

Updated edge root rule chain. Fixed handling of failed rpc messages

pull/4918/head
Volodymyr Babak 5 years ago
parent
commit
0465781303
  1. 15
      application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json
  2. 15
      application/src/main/data/json/tenant/edge_management/rule_chains/edge_root_rule_chain.json
  3. 59
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java
  4. 1
      application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java

15
application/src/main/data/json/demo/edge_management/rule_chains/edge_root_rule_chain.json

@ -14,8 +14,8 @@
{ {
"additionalInfo": { "additionalInfo": {
"description": "Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \"Success\" relation type.", "description": "Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \"Success\" relation type.",
"layoutX": 203, "layoutX": 187,
"layoutY": 259 "layoutY": 468
}, },
"type": "org.thingsboard.rule.engine.profile.TbDeviceProfileNode", "type": "org.thingsboard.rule.engine.profile.TbDeviceProfileNode",
"name": "Device Profile Node", "name": "Device Profile Node",
@ -99,14 +99,14 @@
}, },
{ {
"additionalInfo": { "additionalInfo": {
"layoutX": 1134, "layoutX": 1129,
"layoutY": 132 "layoutY": 52
}, },
"type": "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode", "type": "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode",
"name": "Push to cloud", "name": "Push to cloud",
"debugMode": false, "debugMode": false,
"configuration": { "configuration": {
"version": 0 "scope": "SERVER_SCOPE"
} }
} }
], ],
@ -151,6 +151,11 @@
"toIndex": 4, "toIndex": 4,
"type": "RPC Request from Device" "type": "RPC Request from Device"
}, },
{
"fromIndex": 3,
"toIndex": 7,
"type": "Attributes Updated"
},
{ {
"fromIndex": 4, "fromIndex": 4,
"toIndex": 7, "toIndex": 7,

15
application/src/main/data/json/tenant/edge_management/rule_chains/edge_root_rule_chain.json

@ -14,8 +14,8 @@
{ {
"additionalInfo": { "additionalInfo": {
"description": "Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \"Success\" relation type.", "description": "Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \"Success\" relation type.",
"layoutX": 203, "layoutX": 187,
"layoutY": 259 "layoutY": 468
}, },
"type": "org.thingsboard.rule.engine.profile.TbDeviceProfileNode", "type": "org.thingsboard.rule.engine.profile.TbDeviceProfileNode",
"name": "Device Profile Node", "name": "Device Profile Node",
@ -99,14 +99,14 @@
}, },
{ {
"additionalInfo": { "additionalInfo": {
"layoutX": 1134, "layoutX": 1129,
"layoutY": 132 "layoutY": 52
}, },
"type": "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode", "type": "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode",
"name": "Push to cloud", "name": "Push to cloud",
"debugMode": false, "debugMode": false,
"configuration": { "configuration": {
"version": 0 "scope": "SERVER_SCOPE"
} }
} }
], ],
@ -151,6 +151,11 @@
"toIndex": 4, "toIndex": 4,
"type": "RPC Request from Device" "type": "RPC Request from Device"
}, },
{
"fromIndex": 3,
"toIndex": 7,
"type": "Attributes Updated"
},
{ {
"fromIndex": 4, "fromIndex": 4,
"toIndex": 7, "toIndex": 7,

59
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java

@ -83,8 +83,10 @@ import org.thingsboard.server.service.edge.rpc.fetch.TenantWidgetsBundlesEdgeEve
import java.io.Closeable; import java.io.Closeable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -103,6 +105,7 @@ import java.util.stream.Collectors;
public final class EdgeGrpcSession implements Closeable { public final class EdgeGrpcSession implements Closeable {
private static final ReentrantLock downlinkMsgLock = new ReentrantLock(); private static final ReentrantLock downlinkMsgLock = new ReentrantLock();
private static final ReentrantLock downlinkMsgsPackLock = new ReentrantLock();
private static final String QUEUE_START_TS_ATTR_KEY = "queueStartTs"; private static final String QUEUE_START_TS_ATTR_KEY = "queueStartTs";
@ -111,7 +114,7 @@ public final class EdgeGrpcSession implements Closeable {
private final Consumer<EdgeId> sessionCloseListener; private final Consumer<EdgeId> sessionCloseListener;
private final ObjectMapper mapper; private final ObjectMapper mapper;
private final Map<Integer, DownlinkMsg> pendingMsgsMap; private final Map<Integer, DownlinkMsg> pendingMsgsMap = new HashMap<>();
private EdgeContextComponent ctx; private EdgeContextComponent ctx;
private Edge edge; private Edge edge;
@ -133,7 +136,6 @@ public final class EdgeGrpcSession implements Closeable {
this.sessionCloseListener = sessionCloseListener; this.sessionCloseListener = sessionCloseListener;
this.mapper = mapper; this.mapper = mapper;
this.syncExecutorService = syncExecutorService; this.syncExecutorService = syncExecutorService;
this.pendingMsgsMap = new HashMap<>();
initInputStream(); initInputStream();
} }
@ -197,6 +199,7 @@ public final class EdgeGrpcSession implements Closeable {
public void startSyncProcess(TenantId tenantId, EdgeId edgeId) { public void startSyncProcess(TenantId tenantId, EdgeId edgeId) {
log.trace("[{}][{}] Staring edge sync process", tenantId, edgeId); log.trace("[{}][{}] Staring edge sync process", tenantId, edgeId);
syncCompleted = false;
syncExecutorService.submit(() -> { syncExecutorService.submit(() -> {
try { try {
startProcessingEdgeEvents(new SystemWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService())); startProcessingEdgeEvents(new SystemWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService()));
@ -336,30 +339,36 @@ public final class EdgeGrpcSession implements Closeable {
} }
private boolean sendDownlinkMsgsPack(List<DownlinkMsg> downlinkMsgsPack) throws InterruptedException { private boolean sendDownlinkMsgsPack(List<DownlinkMsg> downlinkMsgsPack) throws InterruptedException {
boolean success; try {
pendingMsgsMap.clear(); downlinkMsgsPackLock.lock();
downlinkMsgsPack.forEach(msg -> pendingMsgsMap.put(msg.getDownlinkMsgId(), msg)); boolean success;
do { pendingMsgsMap.clear();
log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, pendingMsgsMap.values().size()); downlinkMsgsPack.forEach(msg -> pendingMsgsMap.put(msg.getDownlinkMsgId(), msg));
latch = new CountDownLatch(pendingMsgsMap.values().size()); do {
for (DownlinkMsg downlinkMsg : pendingMsgsMap.values()) { log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, pendingMsgsMap.values().size());
sendDownlinkMsg(ResponseMsg.newBuilder() latch = new CountDownLatch(pendingMsgsMap.values().size());
.setDownlinkMsg(downlinkMsg) Collection<DownlinkMsg> copy = new ArrayList<>(pendingMsgsMap.values());
.build()); for (DownlinkMsg downlinkMsg : copy) {
} sendDownlinkMsg(ResponseMsg.newBuilder()
success = latch.await(10, TimeUnit.SECONDS); .setDownlinkMsg(downlinkMsg)
if (!success) { .build());
log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, pendingMsgsMap.values());
}
if (isConnected() && !success) {
try {
Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches());
} catch (InterruptedException e) {
log.error("[{}] Error during sleep between next send of single downlink msg", this.sessionId, e);
} }
} success = latch.await(10, TimeUnit.SECONDS);
} while (isConnected() && !success); if (!success || pendingMsgsMap.values().size() > 0) {
return success; log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, pendingMsgsMap.values());
}
if (isConnected() && (!success || pendingMsgsMap.values().size() > 0)) {
try {
Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches());
} catch (InterruptedException e) {
log.error("[{}] Error during sleep between batches", this.sessionId, e);
}
}
} while (isConnected() && (!success || pendingMsgsMap.values().size() > 0));
return success;
} finally {
downlinkMsgsPackLock.unlock();
}
} }
private DownlinkMsg convertToDownlinkMsg(EdgeEvent edgeEvent) { private DownlinkMsg convertToDownlinkMsg(EdgeEvent edgeEvent) {

1
application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java

@ -232,6 +232,7 @@ public class InstallScripts {
try { try {
createDefaultRuleChains(tenantId); createDefaultRuleChains(tenantId);
createDefaultRuleChain(tenantId, "Thermostat"); createDefaultRuleChain(tenantId, "Thermostat");
createDefaultEdgeRuleChains(tenantId);
} catch (Exception e) { } catch (Exception e) {
log.error("Unable to load dashboard from json", e); log.error("Unable to load dashboard from json", e);
throw new RuntimeException("Unable to load dashboard from json", e); throw new RuntimeException("Unable to load dashboard from json", e);

Loading…
Cancel
Save