Fix to RPC logic
This commit is contained in:
parent
35e91d27c9
commit
aa4787e989
@ -41,7 +41,6 @@ import org.thingsboard.server.common.msg.TbMsg;
|
|||||||
import org.thingsboard.server.common.msg.TbMsgDataType;
|
import org.thingsboard.server.common.msg.TbMsgDataType;
|
||||||
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
||||||
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
|
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
|
||||||
import org.thingsboard.server.common.msg.cluster.ServerAddress;
|
|
||||||
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
|
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
|
||||||
import org.thingsboard.server.common.msg.session.SessionMsgType;
|
import org.thingsboard.server.common.msg.session.SessionMsgType;
|
||||||
import org.thingsboard.server.common.msg.timeout.DeviceActorClientSideRpcTimeoutMsg;
|
import org.thingsboard.server.common.msg.timeout.DeviceActorClientSideRpcTimeoutMsg;
|
||||||
@ -152,7 +151,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
|
|||||||
|
|
||||||
if (request.isOneway() && sent) {
|
if (request.isOneway() && sent) {
|
||||||
logger.debug("[{}] Rpc command response sent [{}]!", deviceId, request.getId());
|
logger.debug("[{}] Rpc command response sent [{}]!", deviceId, request.getId());
|
||||||
systemContext.getDeviceRpcService().processRpcResponseFromDevice(new FromDeviceRpcResponse(msg.getMsg().getId(), msg.getServerAddress(), null, null));
|
systemContext.getDeviceRpcService().processResponseToServerSideRPCRequestFromDeviceActor(new FromDeviceRpcResponse(msg.getMsg().getId(), null, null));
|
||||||
} else {
|
} else {
|
||||||
registerPendingRpcRequest(context, msg, sent, rpcRequest, timeout);
|
registerPendingRpcRequest(context, msg, sent, rpcRequest, timeout);
|
||||||
}
|
}
|
||||||
@ -174,8 +173,8 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
|
|||||||
ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(msg.getId());
|
ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(msg.getId());
|
||||||
if (requestMd != null) {
|
if (requestMd != null) {
|
||||||
logger.debug("[{}] RPC request [{}] timeout detected!", deviceId, msg.getId());
|
logger.debug("[{}] RPC request [{}] timeout detected!", deviceId, msg.getId());
|
||||||
systemContext.getDeviceRpcService().processRpcResponseFromDevice(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(),
|
systemContext.getDeviceRpcService().processResponseToServerSideRPCRequestFromDeviceActor(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(),
|
||||||
requestMd.getMsg().getServerAddress(), null, requestMd.isSent() ? RpcError.TIMEOUT : RpcError.NO_ACTIVE_CONNECTION));
|
null, requestMd.isSent() ? RpcError.TIMEOUT : RpcError.NO_ACTIVE_CONNECTION));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +206,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
|
|||||||
ToDeviceRpcRequestBody body = request.getBody();
|
ToDeviceRpcRequestBody body = request.getBody();
|
||||||
if (request.isOneway()) {
|
if (request.isOneway()) {
|
||||||
sentOneWayIds.add(entry.getKey());
|
sentOneWayIds.add(entry.getKey());
|
||||||
systemContext.getDeviceRpcService().processRpcResponseFromDevice(new FromDeviceRpcResponse(request.getId(), requestActorMsg.getServerAddress(), null, null));
|
systemContext.getDeviceRpcService().processResponseToServerSideRPCRequestFromDeviceActor(new FromDeviceRpcResponse(request.getId(), null, null));
|
||||||
}
|
}
|
||||||
ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder().setRequestId(
|
ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder().setRequestId(
|
||||||
entry.getKey()).setMethodName(body.getMethod()).setParams(body.getParams()).build();
|
entry.getKey()).setMethodName(body.getMethod()).setParams(body.getParams()).build();
|
||||||
@ -400,8 +399,8 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
|
|||||||
ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId());
|
ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId());
|
||||||
boolean success = requestMd != null;
|
boolean success = requestMd != null;
|
||||||
if (success) {
|
if (success) {
|
||||||
systemContext.getDeviceRpcService().processRpcResponseFromDevice(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(),
|
systemContext.getDeviceRpcService().processResponseToServerSideRPCRequestFromDeviceActor(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(),
|
||||||
requestMd.getMsg().getServerAddress(), responseMsg.getPayload(), null));
|
responseMsg.getPayload(), null));
|
||||||
} else {
|
} else {
|
||||||
logger.debug("[{}] Rpc command response [{}] is stale!", deviceId, responseMsg.getRequestId());
|
logger.debug("[{}] Rpc command response [{}] is stale!", deviceId, responseMsg.getRequestId());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ package org.thingsboard.server.actors.ruleChain;
|
|||||||
|
|
||||||
import akka.actor.ActorRef;
|
import akka.actor.ActorRef;
|
||||||
import com.datastax.driver.core.utils.UUIDs;
|
import com.datastax.driver.core.utils.UUIDs;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
import org.thingsboard.rule.engine.api.ListeningExecutor;
|
import org.thingsboard.rule.engine.api.ListeningExecutor;
|
||||||
import org.thingsboard.rule.engine.api.MailService;
|
import org.thingsboard.rule.engine.api.MailService;
|
||||||
import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcRequest;
|
import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcRequest;
|
||||||
@ -35,6 +36,8 @@ import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
|
|||||||
import org.thingsboard.server.common.data.rule.RuleNode;
|
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||||
import org.thingsboard.server.common.msg.TbMsg;
|
import org.thingsboard.server.common.msg.TbMsg;
|
||||||
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
||||||
|
import org.thingsboard.server.common.msg.cluster.ServerAddress;
|
||||||
|
import org.thingsboard.server.common.msg.cluster.ServerType;
|
||||||
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
|
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
|
||||||
import org.thingsboard.server.dao.alarm.AlarmService;
|
import org.thingsboard.server.dao.alarm.AlarmService;
|
||||||
import org.thingsboard.server.dao.asset.AssetService;
|
import org.thingsboard.server.dao.asset.AssetService;
|
||||||
@ -232,16 +235,22 @@ class DefaultTbContext implements TbContext {
|
|||||||
return new RuleEngineRpcService() {
|
return new RuleEngineRpcService() {
|
||||||
@Override
|
@Override
|
||||||
public void sendRpcReply(DeviceId deviceId, int requestId, String body) {
|
public void sendRpcReply(DeviceId deviceId, int requestId, String body) {
|
||||||
mainCtx.getDeviceRpcService().sendRpcReplyToDevice(nodeCtx.getTenantId(), deviceId, requestId, body);
|
mainCtx.getDeviceRpcService().sendReplyToRpcCallFromDevice(nodeCtx.getTenantId(), deviceId, requestId, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendRpcRequest(RuleEngineDeviceRpcRequest src, Consumer<RuleEngineDeviceRpcResponse> consumer) {
|
public void sendRpcRequest(RuleEngineDeviceRpcRequest src, Consumer<RuleEngineDeviceRpcResponse> consumer) {
|
||||||
ToDeviceRpcRequest request = new ToDeviceRpcRequest(src.getRequestUUID(), nodeCtx.getTenantId(), src.getDeviceId(),
|
ToDeviceRpcRequest request = new ToDeviceRpcRequest(src.getRequestUUID(), nodeCtx.getTenantId(), src.getDeviceId(),
|
||||||
src.isOneway(), src.getExpirationTime(), new ToDeviceRpcRequestBody(src.getMethod(), src.getBody()));
|
src.isOneway(), src.getExpirationTime(), new ToDeviceRpcRequestBody(src.getMethod(), src.getBody()));
|
||||||
mainCtx.getDeviceRpcService().processRpcRequestToDevice(request, response -> {
|
mainCtx.getDeviceRpcService().forwardServerSideRPCRequestToDeviceActor(request, response -> {
|
||||||
if (src.isRestApiCall()) {
|
if (src.isRestApiCall()) {
|
||||||
mainCtx.getDeviceRpcService().processRestAPIRpcResponseFromRuleEngine(response);
|
ServerAddress requestOriginAddress;
|
||||||
|
if (!StringUtils.isEmpty(src.getOriginHost())) {
|
||||||
|
requestOriginAddress = new ServerAddress(src.getOriginHost(), src.getOriginPort(), ServerType.CORE);
|
||||||
|
} else {
|
||||||
|
requestOriginAddress = mainCtx.getRoutingService().getCurrentServer();
|
||||||
|
}
|
||||||
|
mainCtx.getDeviceRpcService().processResponseToServerSideRPCRequestFromRuleEngine(requestOriginAddress, response);
|
||||||
}
|
}
|
||||||
consumer.accept(RuleEngineDeviceRpcResponse.builder()
|
consumer.accept(RuleEngineDeviceRpcResponse.builder()
|
||||||
.deviceId(src.getDeviceId())
|
.deviceId(src.getDeviceId())
|
||||||
|
|||||||
@ -35,5 +35,4 @@ public interface ActorService extends SessionMsgProcessor, RpcMsgListener, Disco
|
|||||||
|
|
||||||
void onDeviceNameOrTypeUpdate(TenantId tenantId, DeviceId deviceId, String deviceName, String deviceType);
|
void onDeviceNameOrTypeUpdate(TenantId tenantId, DeviceId deviceId, String deviceName, String deviceType);
|
||||||
|
|
||||||
void onMsg(ServiceToRuleEngineMsg serviceToRuleEngineMsg);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,6 @@ import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
|
|||||||
import org.thingsboard.server.common.msg.cluster.ServerAddress;
|
import org.thingsboard.server.common.msg.cluster.ServerAddress;
|
||||||
import org.thingsboard.server.common.msg.cluster.ToAllNodesMsg;
|
import org.thingsboard.server.common.msg.cluster.ToAllNodesMsg;
|
||||||
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
|
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
|
||||||
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
|
||||||
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
|
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
|
||||||
import org.thingsboard.server.service.cluster.discovery.DiscoveryService;
|
import org.thingsboard.server.service.cluster.discovery.DiscoveryService;
|
||||||
import org.thingsboard.server.service.cluster.discovery.ServerInstance;
|
import org.thingsboard.server.service.cluster.discovery.ServerInstance;
|
||||||
@ -159,11 +158,6 @@ public class DefaultActorService implements ActorService {
|
|||||||
appActor.tell(new SendToClusterMsg(deviceId, msg), ActorRef.noSender());
|
appActor.tell(new SendToClusterMsg(deviceId, msg), ActorRef.noSender());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMsg(ServiceToRuleEngineMsg msg) {
|
|
||||||
appActor.tell(msg, ActorRef.noSender());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void broadcast(ToAllNodesMsg msg) {
|
public void broadcast(ToAllNodesMsg msg) {
|
||||||
actorContext.getEncodingService().encode(msg);
|
actorContext.getEncodingService().encode(msg);
|
||||||
rpcService.broadcast(new RpcBroadcastMsg(ClusterAPIProtos.ClusterMessage
|
rpcService.broadcast(new RpcBroadcastMsg(ClusterAPIProtos.ClusterMessage
|
||||||
@ -185,7 +179,7 @@ public class DefaultActorService implements ActorService {
|
|||||||
ServerAddress serverAddress = new ServerAddress(source.getHost(), source.getPort(), source.getServerType());
|
ServerAddress serverAddress = new ServerAddress(source.getHost(), source.getPort(), source.getServerType());
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.info("Received msg [{}] from [{}]", msg.getMessageType().name(), serverAddress);
|
log.info("Received msg [{}] from [{}]", msg.getMessageType().name(), serverAddress);
|
||||||
log.info("MSG: ", msg);
|
log.info("MSG: {}", msg);
|
||||||
}
|
}
|
||||||
switch (msg.getMessageType()) {
|
switch (msg.getMessageType()) {
|
||||||
case CLUSTER_ACTOR_MESSAGE:
|
case CLUSTER_ACTOR_MESSAGE:
|
||||||
@ -219,7 +213,7 @@ public class DefaultActorService implements ActorService {
|
|||||||
actorContext.getTsSubService().onRemoteTsUpdate(serverAddress, msg.getPayload().toByteArray());
|
actorContext.getTsSubService().onRemoteTsUpdate(serverAddress, msg.getPayload().toByteArray());
|
||||||
break;
|
break;
|
||||||
case CLUSTER_RPC_FROM_DEVICE_RESPONSE_MESSAGE:
|
case CLUSTER_RPC_FROM_DEVICE_RESPONSE_MESSAGE:
|
||||||
actorContext.getDeviceRpcService().processRemoteResponseFromDevice(serverAddress, msg.getPayload().toByteArray());
|
actorContext.getDeviceRpcService().processResponseToServerSideRPCRequestFromRemoteServer(serverAddress, msg.getPayload().toByteArray());
|
||||||
break;
|
break;
|
||||||
case CLUSTER_DEVICE_STATE_SERVICE_MESSAGE:
|
case CLUSTER_DEVICE_STATE_SERVICE_MESSAGE:
|
||||||
actorContext.getDeviceStateService().onRemoteMsg(serverAddress, msg.getPayload().toByteArray());
|
actorContext.getDeviceStateService().onRemoteMsg(serverAddress, msg.getPayload().toByteArray());
|
||||||
|
|||||||
@ -48,6 +48,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle;
|
|||||||
import org.thingsboard.server.common.msg.TbMsg;
|
import org.thingsboard.server.common.msg.TbMsg;
|
||||||
import org.thingsboard.server.common.msg.TbMsgDataType;
|
import org.thingsboard.server.common.msg.TbMsgDataType;
|
||||||
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
||||||
|
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
|
||||||
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
||||||
import org.thingsboard.server.dao.alarm.AlarmService;
|
import org.thingsboard.server.dao.alarm.AlarmService;
|
||||||
import org.thingsboard.server.dao.asset.AssetService;
|
import org.thingsboard.server.dao.asset.AssetService;
|
||||||
@ -673,7 +674,7 @@ public abstract class BaseController {
|
|||||||
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), msgType, entityId, metaData, TbMsgDataType.JSON
|
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), msgType, entityId, metaData, TbMsgDataType.JSON
|
||||||
, json.writeValueAsString(entityNode)
|
, json.writeValueAsString(entityNode)
|
||||||
, null, null, 0L);
|
, null, null, 0L);
|
||||||
actorService.onMsg(new ServiceToRuleEngineMsg(user.getTenantId(), tbMsg));
|
actorService.onMsg(new SendToClusterMsg(entityId, new ServiceToRuleEngineMsg(user.getTenantId(), tbMsg)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e);
|
log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,7 +90,7 @@ public class DefaultDeviceRpcService implements DeviceRpcService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processRestAPIRpcRequestToRuleEngine(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer) {
|
public void processRestAPIRpcRequestToRuleEngine(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer) {
|
||||||
log.trace("[{}][{}] Processing local rpc call to rule engine [{}]", request.getTenantId(), request.getId(), request.getDeviceId());
|
log.trace("[{}][{}] Processing REST API call to rule engine [{}]", request.getTenantId(), request.getId(), request.getDeviceId());
|
||||||
UUID requestId = request.getId();
|
UUID requestId = request.getId();
|
||||||
localToRuleEngineRpcRequests.put(requestId, responseConsumer);
|
localToRuleEngineRpcRequests.put(requestId, responseConsumer);
|
||||||
sendRpcRequestToRuleEngine(request);
|
sendRpcRequestToRuleEngine(request);
|
||||||
@ -98,7 +98,9 @@ public class DefaultDeviceRpcService implements DeviceRpcService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processRestAPIRpcResponseFromRuleEngine(FromDeviceRpcResponse response) {
|
public void processResponseToServerSideRPCRequestFromRuleEngine(ServerAddress requestOriginAddress, FromDeviceRpcResponse response) {
|
||||||
|
log.trace("[{}] Received response to server-side RPC request from rule engine: [{}]", response.getId(), requestOriginAddress);
|
||||||
|
if (routingService.getCurrentServer().equals(requestOriginAddress)) {
|
||||||
UUID requestId = response.getId();
|
UUID requestId = response.getId();
|
||||||
Consumer<FromDeviceRpcResponse> consumer = localToRuleEngineRpcRequests.remove(requestId);
|
Consumer<FromDeviceRpcResponse> consumer = localToRuleEngineRpcRequests.remove(requestId);
|
||||||
if (consumer != null) {
|
if (consumer != null) {
|
||||||
@ -106,28 +108,6 @@ public class DefaultDeviceRpcService implements DeviceRpcService {
|
|||||||
} else {
|
} else {
|
||||||
log.trace("[{}] Unknown or stale rpc response received [{}]", requestId, response);
|
log.trace("[{}] Unknown or stale rpc response received [{}]", requestId, response);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processRpcRequestToDevice(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer) {
|
|
||||||
log.trace("[{}][{}] Processing local rpc call to device [{}]", request.getTenantId(), request.getId(), request.getDeviceId());
|
|
||||||
UUID requestId = request.getId();
|
|
||||||
localToDeviceRpcRequests.put(requestId, responseConsumer);
|
|
||||||
sendRpcRequestToDevice(request);
|
|
||||||
scheduleTimeout(request, requestId, localToDeviceRpcRequests);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processRpcResponseFromDevice(FromDeviceRpcResponse response) {
|
|
||||||
log.trace("[{}] Received device RPC response from server: [{}]", response.getId(), response.getServerAddress());
|
|
||||||
if (routingService.getCurrentServer().equals(response.getServerAddress())) {
|
|
||||||
UUID requestId = response.getId();
|
|
||||||
Consumer<FromDeviceRpcResponse> consumer = localToDeviceRpcRequests.remove(requestId);
|
|
||||||
if (consumer != null) {
|
|
||||||
consumer.accept(response);
|
|
||||||
} else {
|
|
||||||
log.trace("[{}] Unknown or stale rpc response received [{}]", requestId, response);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ClusterAPIProtos.FromDeviceRPCResponseProto.Builder builder = ClusterAPIProtos.FromDeviceRPCResponseProto.newBuilder();
|
ClusterAPIProtos.FromDeviceRPCResponseProto.Builder builder = ClusterAPIProtos.FromDeviceRPCResponseProto.newBuilder();
|
||||||
builder.setRequestIdMSB(response.getId().getMostSignificantBits());
|
builder.setRequestIdMSB(response.getId().getMostSignificantBits());
|
||||||
@ -138,12 +118,33 @@ public class DefaultDeviceRpcService implements DeviceRpcService {
|
|||||||
} else {
|
} else {
|
||||||
builder.setError(-1);
|
builder.setError(-1);
|
||||||
}
|
}
|
||||||
rpcService.tell(response.getServerAddress(), ClusterAPIProtos.MessageType.CLUSTER_RPC_FROM_DEVICE_RESPONSE_MESSAGE, builder.build().toByteArray());
|
rpcService.tell(requestOriginAddress, ClusterAPIProtos.MessageType.CLUSTER_RPC_FROM_DEVICE_RESPONSE_MESSAGE, builder.build().toByteArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processRemoteResponseFromDevice(ServerAddress serverAddress, byte[] data) {
|
public void forwardServerSideRPCRequestToDeviceActor(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer) {
|
||||||
|
log.trace("[{}][{}] Processing local rpc call to device actor [{}]", request.getTenantId(), request.getId(), request.getDeviceId());
|
||||||
|
UUID requestId = request.getId();
|
||||||
|
localToDeviceRpcRequests.put(requestId, responseConsumer);
|
||||||
|
sendRpcRequestToDevice(request);
|
||||||
|
scheduleTimeout(request, requestId, localToDeviceRpcRequests);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processResponseToServerSideRPCRequestFromDeviceActor(FromDeviceRpcResponse response) {
|
||||||
|
log.trace("[{}] Received response to server-side RPC request from device actor.", response.getId());
|
||||||
|
UUID requestId = response.getId();
|
||||||
|
Consumer<FromDeviceRpcResponse> consumer = localToDeviceRpcRequests.remove(requestId);
|
||||||
|
if (consumer != null) {
|
||||||
|
consumer.accept(response);
|
||||||
|
} else {
|
||||||
|
log.trace("[{}] Unknown or stale rpc response received [{}]", requestId, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processResponseToServerSideRPCRequestFromRemoteServer(ServerAddress serverAddress, byte[] data) {
|
||||||
ClusterAPIProtos.FromDeviceRPCResponseProto proto;
|
ClusterAPIProtos.FromDeviceRPCResponseProto proto;
|
||||||
try {
|
try {
|
||||||
proto = ClusterAPIProtos.FromDeviceRPCResponseProto.parseFrom(data);
|
proto = ClusterAPIProtos.FromDeviceRPCResponseProto.parseFrom(data);
|
||||||
@ -151,13 +152,12 @@ public class DefaultDeviceRpcService implements DeviceRpcService {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
RpcError error = proto.getError() > 0 ? RpcError.values()[proto.getError()] : null;
|
RpcError error = proto.getError() > 0 ? RpcError.values()[proto.getError()] : null;
|
||||||
FromDeviceRpcResponse response = new FromDeviceRpcResponse(new UUID(proto.getRequestIdMSB(), proto.getRequestIdLSB()), serverAddress,
|
FromDeviceRpcResponse response = new FromDeviceRpcResponse(new UUID(proto.getRequestIdMSB(), proto.getRequestIdLSB()), proto.getResponse(), error);
|
||||||
proto.getResponse(), error);
|
processResponseToServerSideRPCRequestFromRuleEngine(routingService.getCurrentServer(), response);
|
||||||
processRpcResponseFromDevice(response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendRpcReplyToDevice(TenantId tenantId, DeviceId deviceId, int requestId, String body) {
|
public void sendReplyToRpcCallFromDevice(TenantId tenantId, DeviceId deviceId, int requestId, String body) {
|
||||||
ToServerRpcResponseActorMsg rpcMsg = new ToServerRpcResponseActorMsg(tenantId, deviceId, new ToServerRpcResponseMsg(requestId, body));
|
ToServerRpcResponseActorMsg rpcMsg = new ToServerRpcResponseActorMsg(tenantId, deviceId, new ToServerRpcResponseMsg(requestId, body));
|
||||||
forward(deviceId, rpcMsg);
|
forward(deviceId, rpcMsg);
|
||||||
}
|
}
|
||||||
@ -166,6 +166,8 @@ public class DefaultDeviceRpcService implements DeviceRpcService {
|
|||||||
ObjectNode entityNode = json.createObjectNode();
|
ObjectNode entityNode = json.createObjectNode();
|
||||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||||
metaData.putValue("requestUUID", msg.getId().toString());
|
metaData.putValue("requestUUID", msg.getId().toString());
|
||||||
|
metaData.putValue("originHost", routingService.getCurrentServer().getHost());
|
||||||
|
metaData.putValue("originPort", Integer.toString(routingService.getCurrentServer().getPort()));
|
||||||
metaData.putValue("expirationTime", Long.toString(msg.getExpirationTime()));
|
metaData.putValue("expirationTime", Long.toString(msg.getExpirationTime()));
|
||||||
metaData.putValue("oneway", Boolean.toString(msg.isOneway()));
|
metaData.putValue("oneway", Boolean.toString(msg.isOneway()));
|
||||||
|
|
||||||
@ -176,7 +178,7 @@ public class DefaultDeviceRpcService implements DeviceRpcService {
|
|||||||
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), metaData, TbMsgDataType.JSON
|
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), metaData, TbMsgDataType.JSON
|
||||||
, json.writeValueAsString(entityNode)
|
, json.writeValueAsString(entityNode)
|
||||||
, null, null, 0L);
|
, null, null, 0L);
|
||||||
actorService.onMsg(new ServiceToRuleEngineMsg(msg.getTenantId(), tbMsg));
|
actorService.onMsg(new SendToClusterMsg(msg.getDeviceId(), new ServiceToRuleEngineMsg(msg.getTenantId(), tbMsg)));
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -199,7 +201,7 @@ public class DefaultDeviceRpcService implements DeviceRpcService {
|
|||||||
log.trace("[{}] timeout the request: [{}]", this.hashCode(), requestId);
|
log.trace("[{}] timeout the request: [{}]", this.hashCode(), requestId);
|
||||||
Consumer<FromDeviceRpcResponse> consumer = requestsMap.remove(requestId);
|
Consumer<FromDeviceRpcResponse> consumer = requestsMap.remove(requestId);
|
||||||
if (consumer != null) {
|
if (consumer != null) {
|
||||||
consumer.accept(new FromDeviceRpcResponse(requestId, null, null, RpcError.TIMEOUT));
|
consumer.accept(new FromDeviceRpcResponse(requestId, null, RpcError.TIMEOUT));
|
||||||
}
|
}
|
||||||
}, timeout, TimeUnit.MILLISECONDS);
|
}, timeout, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,13 +29,13 @@ public interface DeviceRpcService {
|
|||||||
|
|
||||||
void processRestAPIRpcRequestToRuleEngine(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer);
|
void processRestAPIRpcRequestToRuleEngine(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer);
|
||||||
|
|
||||||
void processRestAPIRpcResponseFromRuleEngine(FromDeviceRpcResponse response);
|
void processResponseToServerSideRPCRequestFromRuleEngine(ServerAddress requestOriginAddress, FromDeviceRpcResponse response);
|
||||||
|
|
||||||
void processRpcRequestToDevice(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer);
|
void forwardServerSideRPCRequestToDeviceActor(ToDeviceRpcRequest request, Consumer<FromDeviceRpcResponse> responseConsumer);
|
||||||
|
|
||||||
void processRpcResponseFromDevice(FromDeviceRpcResponse response);
|
void processResponseToServerSideRPCRequestFromDeviceActor(FromDeviceRpcResponse response);
|
||||||
|
|
||||||
void sendRpcReplyToDevice(TenantId tenantId, DeviceId deviceId, int requestId, String body);
|
void processResponseToServerSideRPCRequestFromRemoteServer(ServerAddress serverAddress, byte[] data);
|
||||||
|
|
||||||
void processRemoteResponseFromDevice(ServerAddress serverAddress, byte[] bytes);
|
void sendReplyToRpcCallFromDevice(TenantId tenantId, DeviceId deviceId, int requestId, String body);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,8 +32,6 @@ import java.util.UUID;
|
|||||||
public class FromDeviceRpcResponse {
|
public class FromDeviceRpcResponse {
|
||||||
@Getter
|
@Getter
|
||||||
private final UUID id;
|
private final UUID id;
|
||||||
@Getter
|
|
||||||
private final ServerAddress serverAddress;
|
|
||||||
private final String response;
|
private final String response;
|
||||||
private final RpcError error;
|
private final RpcError error;
|
||||||
|
|
||||||
|
|||||||
@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
|
|||||||
import org.thingsboard.server.common.msg.TbMsg;
|
import org.thingsboard.server.common.msg.TbMsg;
|
||||||
import org.thingsboard.server.common.msg.TbMsgDataType;
|
import org.thingsboard.server.common.msg.TbMsgDataType;
|
||||||
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
||||||
|
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
|
||||||
import org.thingsboard.server.common.msg.cluster.ServerAddress;
|
import org.thingsboard.server.common.msg.cluster.ServerAddress;
|
||||||
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
||||||
import org.thingsboard.server.dao.attributes.AttributesService;
|
import org.thingsboard.server.dao.attributes.AttributesService;
|
||||||
@ -457,7 +458,7 @@ public class DefaultDeviceStateService implements DeviceStateService {
|
|||||||
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), msgType, stateData.getDeviceId(), stateData.getMetaData().copy(), TbMsgDataType.JSON
|
TbMsg tbMsg = new TbMsg(UUIDs.timeBased(), msgType, stateData.getDeviceId(), stateData.getMetaData().copy(), TbMsgDataType.JSON
|
||||||
, json.writeValueAsString(state)
|
, json.writeValueAsString(state)
|
||||||
, null, null, 0L);
|
, null, null, 0L);
|
||||||
actorService.onMsg(new ServiceToRuleEngineMsg(stateData.getTenantId(), tbMsg));
|
actorService.onMsg(new SendToClusterMsg(stateData.getDeviceId(), new ServiceToRuleEngineMsg(stateData.getTenantId(), tbMsg)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("[{}] Failed to push inactivity alarm: {}", stateData.getDeviceId(), state, e);
|
log.warn("[{}] Failed to push inactivity alarm: {}", stateData.getDeviceId(), state, e);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ option java_outer_classname = "ClusterAPIProtos";
|
|||||||
service ClusterRpcService {
|
service ClusterRpcService {
|
||||||
rpc handleMsgs(stream ClusterMessage) returns (stream ClusterMessage) {}
|
rpc handleMsgs(stream ClusterMessage) returns (stream ClusterMessage) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
message ClusterMessage {
|
message ClusterMessage {
|
||||||
MessageType messageType = 1;
|
MessageType messageType = 1;
|
||||||
MessageMataInfo messageMetaInfo = 2;
|
MessageMataInfo messageMetaInfo = 2;
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.rule.RuleNode;
|
|||||||
import org.thingsboard.server.common.data.security.Authority;
|
import org.thingsboard.server.common.data.security.Authority;
|
||||||
import org.thingsboard.server.common.msg.TbMsg;
|
import org.thingsboard.server.common.msg.TbMsg;
|
||||||
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
||||||
|
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
|
||||||
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
||||||
import org.thingsboard.server.controller.AbstractRuleEngineControllerTest;
|
import org.thingsboard.server.controller.AbstractRuleEngineControllerTest;
|
||||||
import org.thingsboard.server.dao.attributes.AttributesService;
|
import org.thingsboard.server.dao.attributes.AttributesService;
|
||||||
@ -155,7 +156,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
|
|||||||
device.getId(),
|
device.getId(),
|
||||||
new TbMsgMetaData(),
|
new TbMsgMetaData(),
|
||||||
"{}", null, null, 0L);
|
"{}", null, null, 0L);
|
||||||
actorService.onMsg(new ServiceToRuleEngineMsg(savedTenant.getId(), tbMsg));
|
actorService.onMsg(new SendToClusterMsg(device.getId(), new ServiceToRuleEngineMsg(savedTenant.getId(), tbMsg)));
|
||||||
|
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
|
|
||||||
@ -270,7 +271,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
|
|||||||
device.getId(),
|
device.getId(),
|
||||||
new TbMsgMetaData(),
|
new TbMsgMetaData(),
|
||||||
"{}", null, null, 0L);
|
"{}", null, null, 0L);
|
||||||
actorService.onMsg(new ServiceToRuleEngineMsg(savedTenant.getId(), tbMsg));
|
actorService.onMsg(new SendToClusterMsg(device.getId(), new ServiceToRuleEngineMsg(savedTenant.getId(), tbMsg)));
|
||||||
|
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
|
|
||||||
|
|||||||
@ -39,6 +39,7 @@ import org.thingsboard.server.common.data.rule.RuleNode;
|
|||||||
import org.thingsboard.server.common.data.security.Authority;
|
import org.thingsboard.server.common.data.security.Authority;
|
||||||
import org.thingsboard.server.common.msg.TbMsg;
|
import org.thingsboard.server.common.msg.TbMsg;
|
||||||
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
||||||
|
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
|
||||||
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
|
||||||
import org.thingsboard.server.controller.AbstractRuleEngineControllerTest;
|
import org.thingsboard.server.controller.AbstractRuleEngineControllerTest;
|
||||||
import org.thingsboard.server.dao.attributes.AttributesService;
|
import org.thingsboard.server.dao.attributes.AttributesService;
|
||||||
@ -142,7 +143,7 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac
|
|||||||
new TbMsgMetaData(),
|
new TbMsgMetaData(),
|
||||||
"{}",
|
"{}",
|
||||||
null, null, 0L);
|
null, null, 0L);
|
||||||
actorService.onMsg(new ServiceToRuleEngineMsg(savedTenant.getId(), tbMsg));
|
actorService.onMsg(new SendToClusterMsg(device.getId(), new ServiceToRuleEngineMsg(savedTenant.getId(), tbMsg)));
|
||||||
|
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
|
|
||||||
|
|||||||
@ -21,11 +21,13 @@ import org.thingsboard.server.common.msg.MsgType;
|
|||||||
import org.thingsboard.server.common.msg.TbActorMsg;
|
import org.thingsboard.server.common.msg.TbActorMsg;
|
||||||
import org.thingsboard.server.common.msg.TbMsg;
|
import org.thingsboard.server.common.msg.TbMsg;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ashvayka on 15.03.18.
|
* Created by ashvayka on 15.03.18.
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public final class ServiceToRuleEngineMsg implements TbActorMsg {
|
public final class ServiceToRuleEngineMsg implements TbActorMsg, Serializable {
|
||||||
|
|
||||||
private final TenantId tenantId;
|
private final TenantId tenantId;
|
||||||
private final TbMsg tbMsg;
|
private final TbMsg tbMsg;
|
||||||
|
|||||||
@ -172,6 +172,22 @@ message ToServerRpcResponseMsg {
|
|||||||
string error = 3;
|
string error = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Used to report session state to tb-node and persist this state in the cache on the tb-node level.
|
||||||
|
message SubscriptionInfoProto {
|
||||||
|
int64 lastActivityTime = 1;
|
||||||
|
bool attributeSubscription = 2;
|
||||||
|
bool rpcSubscription = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SessionSubscriptionInfoProto {
|
||||||
|
SessionInfoProto sessionInfo = 1;
|
||||||
|
SubscriptionInfoProto subscriptionInfo = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeviceSessionsCacheEntry {
|
||||||
|
repeated SessionSubscriptionInfoProto sessions = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message TransportToDeviceActorMsg {
|
message TransportToDeviceActorMsg {
|
||||||
SessionInfoProto sessionInfo = 1;
|
SessionInfoProto sessionInfo = 1;
|
||||||
SessionEventMsg sessionEvent = 2;
|
SessionEventMsg sessionEvent = 2;
|
||||||
@ -182,6 +198,7 @@ message TransportToDeviceActorMsg {
|
|||||||
SubscribeToRPCMsg subscribeToRPC = 7;
|
SubscribeToRPCMsg subscribeToRPC = 7;
|
||||||
ToDeviceRpcResponseMsg toDeviceRPCCallResponse = 8;
|
ToDeviceRpcResponseMsg toDeviceRPCCallResponse = 8;
|
||||||
ToServerRpcRequestMsg toServerRPCCallRequest = 9;
|
ToServerRpcRequestMsg toServerRPCCallRequest = 9;
|
||||||
|
SubscriptionInfoProto subscriptionInfo = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeviceActorToTransportMsg {
|
message DeviceActorToTransportMsg {
|
||||||
|
|||||||
@ -23,7 +23,6 @@
|
|||||||
<version>2.2.0-SNAPSHOT</version>
|
<version>2.2.0-SNAPSHOT</version>
|
||||||
<artifactId>thingsboard</artifactId>
|
<artifactId>thingsboard</artifactId>
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>org.thingsboard</groupId>
|
|
||||||
<artifactId>msa</artifactId>
|
<artifactId>msa</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,8 @@ public final class RuleEngineDeviceRpcRequest {
|
|||||||
private final DeviceId deviceId;
|
private final DeviceId deviceId;
|
||||||
private final int requestId;
|
private final int requestId;
|
||||||
private final UUID requestUUID;
|
private final UUID requestUUID;
|
||||||
|
private final String originHost;
|
||||||
|
private final int originPort;
|
||||||
private final boolean oneway;
|
private final boolean oneway;
|
||||||
private final String method;
|
private final String method;
|
||||||
private final String body;
|
private final String body;
|
||||||
|
|||||||
@ -86,6 +86,10 @@ public class TbSendRPCRequestNode implements TbNode {
|
|||||||
|
|
||||||
tmp = msg.getMetaData().getValue("requestUUID");
|
tmp = msg.getMetaData().getValue("requestUUID");
|
||||||
UUID requestUUID = !StringUtils.isEmpty(tmp) ? UUID.fromString(tmp) : UUIDs.timeBased();
|
UUID requestUUID = !StringUtils.isEmpty(tmp) ? UUID.fromString(tmp) : UUIDs.timeBased();
|
||||||
|
tmp = msg.getMetaData().getValue("originHost");
|
||||||
|
String originHost = !StringUtils.isEmpty(tmp) ? tmp : null;
|
||||||
|
tmp = msg.getMetaData().getValue("originPort");
|
||||||
|
int originPort = !StringUtils.isEmpty(tmp) ? Integer.parseInt(tmp) : 0;
|
||||||
|
|
||||||
tmp = msg.getMetaData().getValue("expirationTime");
|
tmp = msg.getMetaData().getValue("expirationTime");
|
||||||
long expirationTime = !StringUtils.isEmpty(tmp) ? Long.parseLong(tmp) : (System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(config.getTimeoutInSeconds()));
|
long expirationTime = !StringUtils.isEmpty(tmp) ? Long.parseLong(tmp) : (System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(config.getTimeoutInSeconds()));
|
||||||
@ -105,6 +109,8 @@ public class TbSendRPCRequestNode implements TbNode {
|
|||||||
.deviceId(new DeviceId(msg.getOriginator().getId()))
|
.deviceId(new DeviceId(msg.getOriginator().getId()))
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.requestUUID(requestUUID)
|
.requestUUID(requestUUID)
|
||||||
|
.originHost(originHost)
|
||||||
|
.originPort(originPort)
|
||||||
.expirationTime(expirationTime)
|
.expirationTime(expirationTime)
|
||||||
.restApiCall(restApiCall)
|
.restApiCall(restApiCall)
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user