Commit 8869dc0cb0a9a8eb3fb84b3e3045c79b973afd9d

Authored by YevhenBondarenko
1 parent 6436c8a2

added new RPC statuses

... ... @@ -400,6 +400,14 @@ public class ActorSystemContext {
400 400 @Getter
401 401 private String debugPerTenantLimitsConfiguration;
402 402
  403 + @Value("${actors.rpc.sequence.enabled:true}")
  404 + @Getter
  405 + private boolean rpcSequenceEnabled;
  406 +
  407 + @Value("${actors.rpc.persistent.retries:5}")
  408 + @Getter
  409 + private int maxPersistentRpcRetries;
  410 +
403 411 @Getter
404 412 @Setter
405 413 private TbActorSystem actorSystem;
... ...
... ... @@ -121,6 +121,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
121 121 private final Map<UUID, SessionInfo> attributeSubscriptions;
122 122 private final Map<UUID, SessionInfo> rpcSubscriptions;
123 123 private final Map<Integer, ToDeviceRpcRequestMetadata> toDeviceRpcPendingMap;
  124 + private final boolean rpcSequenceEnabled;
124 125
125 126 private int rpcSeq = 0;
126 127 private String deviceName;
... ... @@ -132,6 +133,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
132 133 super(systemContext);
133 134 this.tenantId = tenantId;
134 135 this.deviceId = deviceId;
  136 + this.rpcSequenceEnabled = systemContext.isRpcSequenceEnabled();
135 137 this.attributeSubscriptions = new HashMap<>();
136 138 this.rpcSubscriptions = new HashMap<>();
137 139 this.toDeviceRpcPendingMap = new LinkedHashMap<>();
... ... @@ -185,19 +187,19 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
185 187 if (timeout <= 0) {
186 188 log.debug("[{}][{}] Ignoring message due to exp time reached, {}", deviceId, request.getId(), request.getExpirationTime());
187 189 if (persisted) {
188   - createRpc(request, RpcStatus.TIMEOUT);
  190 + createRpc(request, RpcStatus.EXPIRED);
189 191 }
190 192 return;
191 193 } else if (persisted) {
192 194 createRpc(request, RpcStatus.QUEUED);
193 195 }
194 196
195   - boolean sent;
  197 + boolean sent = false;
196 198 if (systemContext.isEdgesEnabled() && edgeId != null) {
197 199 log.debug("[{}][{}] device is related to edge [{}]. Saving RPC request to edge queue", tenantId, deviceId, edgeId.getId());
198 200 saveRpcRequestToEdgeQueue(request, rpcRequest.getRequestId());
199 201 sent = true;
200   - } else {
  202 + } else if (!rpcSequenceEnabled || toDeviceRpcPendingMap.isEmpty()) {
201 203 sent = rpcSubscriptions.size() > 0;
202 204 Set<UUID> syncSessionSet = new HashSet<>();
203 205 rpcSubscriptions.forEach((key, value) -> {
... ... @@ -292,7 +294,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
292 294 if (requestMd != null) {
293 295 log.debug("[{}] RPC request [{}] timeout detected!", deviceId, msg.getId());
294 296 if (requestMd.getMsg().getMsg().isPersisted()) {
295   - systemContext.getTbRpcService().save(tenantId, new RpcId(requestMd.getMsg().getMsg().getId()), RpcStatus.TIMEOUT, null);
  297 + systemContext.getTbRpcService().save(tenantId, new RpcId(requestMd.getMsg().getMsg().getId()), RpcStatus.EXPIRED, null);
296 298 }
297 299 systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(),
298 300 null, requestMd.isSent() ? RpcError.TIMEOUT : RpcError.NO_ACTIVE_CONNECTION));
... ... @@ -300,7 +302,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
300 302 }
301 303 }
302 304
303   - private void sendPendingRequest(TbActorCtx context, UUID sessionId, String nodeId) {
  305 + private void sendPendingRequests(TbActorCtx context, UUID sessionId, String nodeId) {
304 306 SessionType sessionType = getSessionType(sessionId);
305 307 if (!toDeviceRpcPendingMap.isEmpty()) {
306 308 log.debug("[{}] Pushing {} pending RPC messages to new async session [{}]", deviceId, toDeviceRpcPendingMap.size(), sessionId);
... ... @@ -312,11 +314,34 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
312 314 log.debug("[{}] No pending RPC messages for new async session [{}]", deviceId, sessionId);
313 315 }
314 316 Set<Integer> sentOneWayIds = new HashSet<>();
315   - toDeviceRpcPendingMap.entrySet().stream().findFirst().ifPresent(processPendingRpc(context, sessionId, nodeId, sentOneWayIds));
  317 +
  318 + if (sessionType == SessionType.ASYNC) {
  319 + if (rpcSequenceEnabled) {
  320 + List<Map.Entry<Integer, ToDeviceRpcRequestMetadata>> entries = new ArrayList<>();
  321 + for (Map.Entry<Integer, ToDeviceRpcRequestMetadata> entry : toDeviceRpcPendingMap.entrySet()) {
  322 + if (entry.getValue().isDelivered()) {
  323 + continue;
  324 + }
  325 + entries.add(entry);
  326 + if (entry.getValue().getMsg().getMsg().isPersisted() || entry.getValue().getMsg().getMsg().isOneway()) {
  327 + break;
  328 + }
  329 + }
  330 + entries.forEach(processPendingRpc(context, sessionId, nodeId, sentOneWayIds));
  331 + } else {
  332 + toDeviceRpcPendingMap.entrySet().forEach(processPendingRpc(context, sessionId, nodeId, sentOneWayIds));
  333 + }
  334 + } else {
  335 + toDeviceRpcPendingMap.entrySet().stream().findFirst().ifPresent(processPendingRpc(context, sessionId, nodeId, sentOneWayIds));
  336 + }
  337 +
  338 + sentOneWayIds.stream().filter(id -> !toDeviceRpcPendingMap.get(id).getMsg().getMsg().isPersisted()).forEach(toDeviceRpcPendingMap::remove);
316 339 }
317 340
318 341 private void sendNextPendingRequest(TbActorCtx context) {
319   - rpcSubscriptions.forEach((id, s) -> sendPendingRequest(context, id, s.getNodeId()));
  342 + if (rpcSequenceEnabled) {
  343 + rpcSubscriptions.forEach((id, s) -> sendPendingRequests(context, id, s.getNodeId()));
  344 + }
320 345 }
321 346
322 347 private Consumer<Map.Entry<Integer, ToDeviceRpcRequestMetadata>> processPendingRpc(TbActorCtx context, UUID sessionId, String nodeId, Set<Integer> sentOneWayIds) {
... ... @@ -338,11 +363,6 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
338 363 .setPersisted(request.isPersisted())
339 364 .build();
340 365 sendToTransport(rpcRequest, sessionId, nodeId);
341   -
342   - if (SessionType.ASYNC.equals(getSessionType(sessionId)) && request.isOneway() && !request.isPersisted()) {
343   - toDeviceRpcPendingMap.remove(entry.getKey());
344   - sendPendingRequest(context, sessionId, nodeId);
345   - }
346 366 };
347 367 }
348 368
... ... @@ -361,7 +381,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
361 381 processSubscriptionCommands(context, sessionInfo, msg.getSubscribeToRPC());
362 382 }
363 383 if (msg.hasSendPendingRPC()) {
364   - sendPendingRequest(context, getSessionId(sessionInfo), sessionInfo.getNodeId());
  384 + sendPendingRequests(context, getSessionId(sessionInfo), sessionInfo.getNodeId());
365 385 }
366 386 if (msg.hasGetAttributes()) {
367 387 handleGetAttributesRequest(context, sessionInfo, msg.getGetAttributes());
... ... @@ -559,16 +579,28 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
559 579 private void processPersistedRpcResponses(TbActorCtx context, SessionInfoProto sessionInfo, ToDevicePersistedRpcResponseMsg responseMsg) {
560 580 UUID rpcId = new UUID(responseMsg.getRequestIdMSB(), responseMsg.getRequestIdLSB());
561 581 RpcStatus status = RpcStatus.valueOf(responseMsg.getStatus());
562   -
563   - ToDeviceRpcRequestMetadata md;
564   - if (RpcStatus.DELIVERED.equals(status)) {
565   - md = toDeviceRpcPendingMap.get(responseMsg.getRequestId());
566   - } else {
567   - md = toDeviceRpcPendingMap.remove(responseMsg.getRequestId());
568   - }
  582 + ToDeviceRpcRequestMetadata md = toDeviceRpcPendingMap.get(responseMsg.getRequestId());
569 583
570 584 if (md != null) {
  585 + if (status.equals(RpcStatus.DELIVERED)) {
  586 + if (md.getMsg().getMsg().isOneway()) {
  587 + toDeviceRpcPendingMap.remove(responseMsg.getRequestId());
  588 + } else {
  589 + md.setDelivered(true);
  590 + }
  591 + } else if (status.equals(RpcStatus.TIMEOUT)) {
  592 + if (systemContext.getMaxPersistentRpcRetries() <= md.getRetries()) {
  593 + toDeviceRpcPendingMap.remove(responseMsg.getRequestId());
  594 + status = RpcStatus.FAILED;
  595 + } else {
  596 + md.setRetries(md.getRetries() + 1);
  597 + }
  598 + }
  599 +
571 600 systemContext.getTbRpcService().save(tenantId, new RpcId(rpcId), status, null);
  601 + if (status != RpcStatus.SENT) {
  602 + sendNextPendingRequest(context);
  603 + }
572 604 } else {
573 605 log.info("[{}][{}] Rpc has already removed from pending map.", deviceId, rpcId);
574 606 }
... ... @@ -608,7 +640,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
608 640 sessionMD.setSubscribedToRPC(true);
609 641 log.debug("[{}] Registering rpc subscription for session [{}]", deviceId, sessionId);
610 642 rpcSubscriptions.put(sessionId, sessionMD.getSessionInfo());
611   - sendPendingRequest(context, sessionId, sessionInfo.getNodeId());
  643 + sendPendingRequests(context, sessionId, sessionInfo.getNodeId());
612 644 dumpSessions();
613 645 }
614 646 }
... ... @@ -884,7 +916,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
884 916 ToDeviceRpcRequest msg = JacksonUtil.convertValue(rpc.getRequest(), ToDeviceRpcRequest.class);
885 917 long timeout = rpc.getExpirationTime() - System.currentTimeMillis();
886 918 if (timeout <= 0) {
887   - rpc.setStatus(RpcStatus.TIMEOUT);
  919 + rpc.setStatus(RpcStatus.EXPIRED);
888 920 systemContext.getTbRpcService().save(tenantId, rpc);
889 921 } else {
890 922 registerPendingRpcRequest(ctx, new ToDeviceRpcRequestActorMsg(systemContext.getServiceId(), msg), false, creteToDeviceRpcRequestMsg(msg), timeout);
... ...
... ... @@ -25,4 +25,6 @@ import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg;
25 25 public class ToDeviceRpcRequestMetadata {
26 26 private final ToDeviceRpcRequestActorMsg msg;
27 27 private final boolean sent;
  28 + private int retries;
  29 + private boolean delivered;
28 30 }
... ...
... ... @@ -326,6 +326,11 @@ actors:
326 326 queue_size: "${ACTORS_RULE_TRANSACTION_QUEUE_SIZE:15000}"
327 327 # Time in milliseconds for transaction to complete
328 328 duration: "${ACTORS_RULE_TRANSACTION_DURATION:60000}"
  329 + rpc:
  330 + persistent:
  331 + retries: "${ACTORS_RPC_PERSISTENT_RETRIES:5}"
  332 + sequence:
  333 + enabled: "${ACTORS_RPC_SEQUENCE_ENABLED:true}"
329 334 statistics:
330 335 # Enable/disable actor statistics
331 336 enabled: "${ACTORS_STATISTICS_ENABLED:true}"
... ...
... ... @@ -16,5 +16,5 @@
16 16 package org.thingsboard.server.common.data.rpc;
17 17
18 18 public enum RpcStatus {
19   - QUEUED, DELIVERED, SUCCESSFUL, TIMEOUT, FAILED
  19 + QUEUED, SENT, DELIVERED, SUCCESSFUL, TIMEOUT, EXPIRED, FAILED
20 20 }
... ...
... ... @@ -42,6 +42,7 @@ import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadCo
42 42 import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
43 43 import org.thingsboard.server.common.data.id.DeviceId;
44 44 import org.thingsboard.server.common.data.id.DeviceProfileId;
  45 +import org.thingsboard.server.common.data.rpc.RpcStatus;
45 46 import org.thingsboard.server.common.msg.session.FeatureType;
46 47 import org.thingsboard.server.common.msg.session.SessionMsgType;
47 48 import org.thingsboard.server.common.transport.SessionMsgListener;
... ... @@ -532,7 +533,7 @@ public class DefaultCoapClientContext implements CoapClientContext {
532 533 response.addMessageObserver(new TbCoapMessageObserver(requestId, id -> {
533 534 TransportProtos.ToDeviceRpcRequestMsg rpcRequestMsg = transportContext.getRpcAwaitingAck().remove(id);
534 535 if (rpcRequestMsg != null) {
535   - transportService.process(state.getSession(), rpcRequestMsg, TransportServiceCallback.EMPTY);
  536 + transportService.process(state.getSession(), rpcRequestMsg, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY);
536 537 }
537 538 }, null));
538 539 }
... ... @@ -553,8 +554,12 @@ public class DefaultCoapClientContext implements CoapClientContext {
553 554 transportService.process(state.getSession(),
554 555 TransportProtos.ToDeviceRpcResponseMsg.newBuilder()
555 556 .setRequestId(msg.getRequestId()).setError(error).build(), TransportServiceCallback.EMPTY);
556   - } else if (msg.getPersisted() && !conRequest && sent) {
557   - transportService.process(state.getSession(), msg, TransportServiceCallback.EMPTY);
  557 + } else if (msg.getPersisted() && sent) {
  558 + if (conRequest) {
  559 + transportService.process(state.getSession(), msg, RpcStatus.SENT, TransportServiceCallback.EMPTY);
  560 + } else {
  561 + transportService.process(state.getSession(), msg, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY);
  562 + }
558 563 }
559 564 }
560 565 }
... ...
... ... @@ -409,7 +409,7 @@ public class DeviceApiController implements TbTransportService {
409 409 public void onToDeviceRpcRequest(UUID sessionId, ToDeviceRpcRequestMsg msg) {
410 410 log.trace("[{}] Received RPC command to device", sessionId);
411 411 responseWriter.setResult(new ResponseEntity<>(JsonConverter.toJson(msg, true).toString(), HttpStatus.OK));
412   - transportService.process(sessionInfo, msg, TransportServiceCallback.EMPTY);
  412 + transportService.process(sessionInfo, msg, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY);
413 413 }
414 414
415 415 @Override
... ...
... ... @@ -21,7 +21,9 @@ import org.eclipse.leshan.core.ResponseCode;
21 21 import org.springframework.stereotype.Service;
22 22 import org.thingsboard.common.util.JacksonUtil;
23 23 import org.thingsboard.server.common.data.StringUtils;
  24 +import org.thingsboard.server.common.data.rpc.RpcStatus;
24 25 import org.thingsboard.server.common.transport.TransportService;
  26 +import org.thingsboard.server.common.transport.TransportServiceCallback;
25 27 import org.thingsboard.server.gen.transport.TransportProtos;
26 28 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
27 29 import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
... ... @@ -158,6 +160,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler {
158 160 throw new IllegalArgumentException("Unsupported operation: " + operationType.name());
159 161 }
160 162 }
  163 + transportService.process(client.getSession(), rpcRequest, RpcStatus.SENT, TransportServiceCallback.EMPTY);
161 164 } catch (IllegalArgumentException e) {
162 165 this.sendErrorRpcResponse(sessionInfo, rpcRequest.getRequestId(), ResponseCode.BAD_REQUEST, e.getMessage());
163 166 }
... ...
... ... @@ -19,6 +19,7 @@ import org.eclipse.leshan.core.ResponseCode;
19 19 import org.eclipse.leshan.core.request.exception.ClientSleepingException;
20 20 import org.thingsboard.common.util.JacksonUtil;
21 21 import org.thingsboard.server.common.data.StringUtils;
  22 +import org.thingsboard.server.common.data.rpc.RpcStatus;
22 23 import org.thingsboard.server.common.transport.TransportService;
23 24 import org.thingsboard.server.common.transport.TransportServiceCallback;
24 25 import org.thingsboard.server.gen.transport.TransportProtos;
... ... @@ -44,7 +45,7 @@ public abstract class RpcDownlinkRequestCallbackProxy<R, T> implements DownlinkR
44 45
45 46 @Override
46 47 public void onSuccess(R request, T response) {
47   - transportService.process(client.getSession(), this.request, TransportServiceCallback.EMPTY);
  48 + transportService.process(client.getSession(), this.request, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY);
48 49 sendRpcReplyOnSuccess(response);
49 50 if (callback != null) {
50 51 callback.onSuccess(request, response);
... ... @@ -61,7 +62,9 @@ public abstract class RpcDownlinkRequestCallbackProxy<R, T> implements DownlinkR
61 62
62 63 @Override
63 64 public void onError(String params, Exception e) {
64   - if (!(e instanceof TimeoutException || e instanceof ClientSleepingException)) {
  65 + if (e instanceof TimeoutException) {
  66 + transportService.process(client.getSession(), this.request, RpcStatus.TIMEOUT, TransportServiceCallback.EMPTY);
  67 + } else if (!(e instanceof ClientSleepingException)) {
65 68 sendRpcReplyOnError(e);
66 69 }
67 70 if (callback != null) {
... ...
... ... @@ -50,6 +50,7 @@ import org.thingsboard.server.common.data.TransportPayloadType;
50 50 import org.thingsboard.server.common.data.device.profile.MqttTopics;
51 51 import org.thingsboard.server.common.data.id.OtaPackageId;
52 52 import org.thingsboard.server.common.data.ota.OtaPackageType;
  53 +import org.thingsboard.server.common.data.rpc.RpcStatus;
53 54 import org.thingsboard.server.common.msg.EncryptionUtil;
54 55 import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
55 56 import org.thingsboard.server.common.transport.SessionMsgListener;
... ... @@ -272,7 +273,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
272 273 int msgId = ((MqttPubAckMessage) msg).variableHeader().messageId();
273 274 TransportProtos.ToDeviceRpcRequestMsg rpcRequest = rpcAwaitingAck.remove(msgId);
274 275 if (rpcRequest != null) {
275   - transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, TransportServiceCallback.EMPTY);
  276 + transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY);
276 277 }
277 278 break;
278 279 default:
... ... @@ -856,10 +857,14 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
856 857 }, Math.max(0, rpcRequest.getExpirationTime() - System.currentTimeMillis()), TimeUnit.MILLISECONDS);
857 858 }
858 859 var cf = publish(payload, deviceSessionCtx);
859   - if (rpcRequest.getPersisted() && !isAckExpected(payload)) {
  860 + if (rpcRequest.getPersisted()) {
860 861 cf.addListener(result -> {
861 862 if (result.cause() == null) {
862   - transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, TransportServiceCallback.EMPTY);
  863 + if (isAckExpected(payload)) {
  864 + transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, RpcStatus.SENT, TransportServiceCallback.EMPTY);
  865 + } else {
  866 + transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY);
  867 + }
863 868 }
864 869 });
865 870 }
... ...
... ... @@ -16,8 +16,10 @@
16 16 package org.thingsboard.server.transport.mqtt.session;
17 17
18 18 import io.netty.channel.ChannelFuture;
  19 +import io.netty.handler.codec.mqtt.MqttMessage;
19 20 import lombok.extern.slf4j.Slf4j;
20 21 import org.thingsboard.server.common.data.DeviceProfile;
  22 +import org.thingsboard.server.common.data.rpc.RpcStatus;
21 23 import org.thingsboard.server.common.transport.SessionMsgListener;
22 24 import org.thingsboard.server.common.transport.TransportService;
23 25 import org.thingsboard.server.common.transport.TransportServiceCallback;
... ... @@ -102,9 +104,13 @@ public class GatewayDeviceSessionCtx extends MqttDeviceAwareSessionContext imple
102 104 payload -> {
103 105 ChannelFuture channelFuture = parent.writeAndFlush(payload);
104 106 if (request.getPersisted()) {
105   - channelFuture.addListener(future -> {
106   - if (future.cause() == null) {
107   - transportService.process(getSessionInfo(), request, TransportServiceCallback.EMPTY);
  107 + channelFuture.addListener(result -> {
  108 + if (result.cause() == null) {
  109 + if (isAckExpected(payload)) {
  110 + transportService.process(getSessionInfo(), request, RpcStatus.SENT, TransportServiceCallback.EMPTY);
  111 + } else {
  112 + transportService.process(getSessionInfo(), request, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY);
  113 + }
108 114 }
109 115 });
110 116 }
... ... @@ -129,4 +135,8 @@ public class GatewayDeviceSessionCtx extends MqttDeviceAwareSessionContext imple
129 135 // This feature is not supported in the TB IoT Gateway yet.
130 136 }
131 137
  138 + private boolean isAckExpected(MqttMessage message) {
  139 + return message.fixedHeader().qosLevel().value() > 0;
  140 + }
  141 +
132 142 }
... ...
... ... @@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.DeviceProfile;
26 26 import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration;
27 27 import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration;
28 28 import org.thingsboard.server.common.data.id.DeviceId;
  29 +import org.thingsboard.server.common.data.rpc.RpcStatus;
29 30 import org.thingsboard.server.common.transport.SessionMsgListener;
30 31 import org.thingsboard.server.common.transport.TransportServiceCallback;
31 32 import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext;
... ... @@ -142,7 +143,7 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S
142 143 public void onToDeviceRpcRequest(UUID sessionId, ToDeviceRpcRequestMsg toDeviceRequest) {
143 144 log.trace("[{}] Received RPC command to device", sessionId);
144 145 snmpTransportContext.getSnmpTransportService().onToDeviceRpcRequest(this, toDeviceRequest);
145   - snmpTransportContext.getTransportService().process(getSessionInfo(), toDeviceRequest, TransportServiceCallback.EMPTY);
  146 + snmpTransportContext.getTransportService().process(getSessionInfo(), toDeviceRequest, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY);
146 147 }
147 148
148 149 @Override
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.common.transport;
17 17
18 18 import org.thingsboard.server.common.data.DeviceProfile;
19 19 import org.thingsboard.server.common.data.DeviceTransportType;
  20 +import org.thingsboard.server.common.data.rpc.RpcStatus;
20 21 import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse;
21 22 import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
22 23 import org.thingsboard.server.common.transport.service.SessionMetaData;
... ... @@ -112,7 +113,7 @@ public interface TransportService {
112 113
113 114 void process(SessionInfoProto sessionInfo, ToServerRpcRequestMsg msg, TransportServiceCallback<Void> callback);
114 115
115   - void process(SessionInfoProto sessionInfo, ToDeviceRpcRequestMsg msg, TransportServiceCallback<Void> callback);
  116 + void process(SessionInfoProto sessionInfo, ToDeviceRpcRequestMsg msg, RpcStatus rpcStatus, TransportServiceCallback<Void> callback);
116 117
117 118 void process(SessionInfoProto sessionInfo, SubscriptionInfoProto msg, TransportServiceCallback<Void> callback);
118 119
... ...
... ... @@ -580,15 +580,13 @@ public class DefaultTransportService implements TransportService {
580 580 }
581 581
582 582 @Override
583   - public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDeviceRpcRequestMsg msg, TransportServiceCallback<Void> callback) {
  583 + public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDeviceRpcRequestMsg msg, RpcStatus rpcStatus, TransportServiceCallback<Void> callback) {
584 584 if (msg.getPersisted()) {
585   - RpcStatus status = msg.getOneway() ? RpcStatus.SUCCESSFUL : RpcStatus.DELIVERED;
586   -
587 585 TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder()
588 586 .setRequestId(msg.getRequestId())
589 587 .setRequestIdLSB(msg.getRequestIdLSB())
590 588 .setRequestIdMSB(msg.getRequestIdMSB())
591   - .setStatus(status.name())
  589 + .setStatus(rpcStatus.name())
592 590 .build();
593 591
594 592 if (checkLimits(sessionInfo, responseMsg, callback)) {
... ...