Transport Implementation
This commit is contained in:
parent
fa9194c1c1
commit
c4c53bfbd8
@ -67,7 +67,6 @@ import org.thingsboard.server.dao.user.UserService;
|
|||||||
import org.thingsboard.server.kafka.TbNodeIdProvider;
|
import org.thingsboard.server.kafka.TbNodeIdProvider;
|
||||||
import org.thingsboard.server.service.cluster.discovery.DiscoveryService;
|
import org.thingsboard.server.service.cluster.discovery.DiscoveryService;
|
||||||
import org.thingsboard.server.service.cluster.routing.ClusterRoutingService;
|
import org.thingsboard.server.service.cluster.routing.ClusterRoutingService;
|
||||||
import org.thingsboard.server.service.cluster.rpc.ClusterRpcService;
|
|
||||||
import org.thingsboard.server.service.component.ComponentDiscoveryService;
|
import org.thingsboard.server.service.component.ComponentDiscoveryService;
|
||||||
import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
|
import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
|
||||||
import org.thingsboard.server.service.executors.ClusterRpcCallbackExecutorService;
|
import org.thingsboard.server.service.executors.ClusterRpcCallbackExecutorService;
|
||||||
@ -81,7 +80,7 @@ import org.thingsboard.server.service.script.JsInvokeService;
|
|||||||
import org.thingsboard.server.service.session.DeviceSessionCacheService;
|
import org.thingsboard.server.service.session.DeviceSessionCacheService;
|
||||||
import org.thingsboard.server.service.state.DeviceStateService;
|
import org.thingsboard.server.service.state.DeviceStateService;
|
||||||
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
||||||
import org.thingsboard.server.service.transport.RuleEngineTransportService;
|
import org.thingsboard.server.service.transport.TbCoreToTransportService;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -122,10 +121,6 @@ public class ActorSystemContext {
|
|||||||
@Getter
|
@Getter
|
||||||
private ClusterRoutingService routingService;
|
private ClusterRoutingService routingService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
@Getter
|
|
||||||
private ClusterRpcService rpcService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Getter
|
@Getter
|
||||||
private DataDecodingEncodingService encodingService;
|
private DataDecodingEncodingService encodingService;
|
||||||
@ -241,7 +236,7 @@ public class ActorSystemContext {
|
|||||||
@Lazy
|
@Lazy
|
||||||
@Autowired
|
@Autowired
|
||||||
@Getter
|
@Getter
|
||||||
private RuleEngineTransportService ruleEngineTransportService;
|
private TbCoreToTransportService tbCoreToTransportService;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@ -234,24 +234,24 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
|
|||||||
if (msg.hasSubscribeToRPC()) {
|
if (msg.hasSubscribeToRPC()) {
|
||||||
processSubscriptionCommands(context, msg.getSessionInfo(), msg.getSubscribeToRPC());
|
processSubscriptionCommands(context, msg.getSessionInfo(), msg.getSubscribeToRPC());
|
||||||
}
|
}
|
||||||
if (msg.hasPostAttributes()) {
|
// if (msg.hasPostAttributes()) {
|
||||||
handlePostAttributesRequest(context, msg.getSessionInfo(), msg.getPostAttributes());
|
// handlePostAttributesRequest(context, msg.getSessionInfo(), msg.getPostAttributes());
|
||||||
reportDeviceActivity = true;
|
// reportDeviceActivity = true;
|
||||||
}
|
// }
|
||||||
if (msg.hasPostTelemetry()) {
|
// if (msg.hasPostTelemetry()) {
|
||||||
handlePostTelemetryRequest(context, msg.getSessionInfo(), msg.getPostTelemetry());
|
// handlePostTelemetryRequest(context, msg.getSessionInfo(), msg.getPostTelemetry());
|
||||||
reportDeviceActivity = true;
|
// reportDeviceActivity = true;
|
||||||
}
|
// }
|
||||||
if (msg.hasGetAttributes()) {
|
if (msg.hasGetAttributes()) {
|
||||||
handleGetAttributesRequest(context, msg.getSessionInfo(), msg.getGetAttributes());
|
handleGetAttributesRequest(context, msg.getSessionInfo(), msg.getGetAttributes());
|
||||||
}
|
}
|
||||||
if (msg.hasToDeviceRPCCallResponse()) {
|
if (msg.hasToDeviceRPCCallResponse()) {
|
||||||
processRpcResponses(context, msg.getSessionInfo(), msg.getToDeviceRPCCallResponse());
|
processRpcResponses(context, msg.getSessionInfo(), msg.getToDeviceRPCCallResponse());
|
||||||
}
|
}
|
||||||
if (msg.hasToServerRPCCallRequest()) {
|
// if (msg.hasToServerRPCCallRequest()) {
|
||||||
handleClientSideRPCRequest(context, msg.getSessionInfo(), msg.getToServerRPCCallRequest());
|
// handleClientSideRPCRequest(context, msg.getSessionInfo(), msg.getToServerRPCCallRequest());
|
||||||
reportDeviceActivity = true;
|
// reportDeviceActivity = true;
|
||||||
}
|
// }
|
||||||
if (msg.hasSubscriptionInfo()) {
|
if (msg.hasSubscriptionInfo()) {
|
||||||
handleSessionActivity(context, msg.getSessionInfo(), msg.getSubscriptionInfo());
|
handleSessionActivity(context, msg.getSessionInfo(), msg.getSubscriptionInfo());
|
||||||
}
|
}
|
||||||
@ -260,6 +260,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: 2.5 move this as a notification to the queue;
|
||||||
private void reportLogicalDeviceActivity() {
|
private void reportLogicalDeviceActivity() {
|
||||||
systemContext.getDeviceStateService().onDeviceActivity(deviceId);
|
systemContext.getDeviceStateService().onDeviceActivity(deviceId);
|
||||||
}
|
}
|
||||||
@ -540,7 +541,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
|
|||||||
.setSessionIdMSB(sessionId.getMostSignificantBits())
|
.setSessionIdMSB(sessionId.getMostSignificantBits())
|
||||||
.setSessionIdLSB(sessionId.getLeastSignificantBits())
|
.setSessionIdLSB(sessionId.getLeastSignificantBits())
|
||||||
.setSessionCloseNotification(SessionCloseNotificationProto.getDefaultInstance()).build();
|
.setSessionCloseNotification(SessionCloseNotificationProto.getDefaultInstance()).build();
|
||||||
systemContext.getRuleEngineTransportService().process(sessionMd.getSessionInfo().getNodeId(), msg);
|
systemContext.getTbCoreToTransportService().process(sessionMd.getSessionInfo().getNodeId(), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void processNameOrTypeUpdate(DeviceNameOrTypeUpdateMsg msg) {
|
void processNameOrTypeUpdate(DeviceNameOrTypeUpdateMsg msg) {
|
||||||
@ -556,7 +557,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
|
|||||||
.setSessionIdMSB(sessionInfo.getSessionIdMSB())
|
.setSessionIdMSB(sessionInfo.getSessionIdMSB())
|
||||||
.setSessionIdLSB(sessionInfo.getSessionIdLSB())
|
.setSessionIdLSB(sessionInfo.getSessionIdLSB())
|
||||||
.setGetAttributesResponse(responseMsg).build();
|
.setGetAttributesResponse(responseMsg).build();
|
||||||
systemContext.getRuleEngineTransportService().process(sessionInfo.getNodeId(), msg);
|
systemContext.getTbCoreToTransportService().process(sessionInfo.getNodeId(), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendToTransport(AttributeUpdateNotificationMsg notificationMsg, UUID sessionId, String nodeId) {
|
private void sendToTransport(AttributeUpdateNotificationMsg notificationMsg, UUID sessionId, String nodeId) {
|
||||||
@ -564,7 +565,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
|
|||||||
.setSessionIdMSB(sessionId.getMostSignificantBits())
|
.setSessionIdMSB(sessionId.getMostSignificantBits())
|
||||||
.setSessionIdLSB(sessionId.getLeastSignificantBits())
|
.setSessionIdLSB(sessionId.getLeastSignificantBits())
|
||||||
.setAttributeUpdateNotification(notificationMsg).build();
|
.setAttributeUpdateNotification(notificationMsg).build();
|
||||||
systemContext.getRuleEngineTransportService().process(nodeId, msg);
|
systemContext.getTbCoreToTransportService().process(nodeId, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendToTransport(ToDeviceRpcRequestMsg rpcMsg, UUID sessionId, String nodeId) {
|
private void sendToTransport(ToDeviceRpcRequestMsg rpcMsg, UUID sessionId, String nodeId) {
|
||||||
@ -572,7 +573,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
|
|||||||
.setSessionIdMSB(sessionId.getMostSignificantBits())
|
.setSessionIdMSB(sessionId.getMostSignificantBits())
|
||||||
.setSessionIdLSB(sessionId.getLeastSignificantBits())
|
.setSessionIdLSB(sessionId.getLeastSignificantBits())
|
||||||
.setToDeviceRequest(rpcMsg).build();
|
.setToDeviceRequest(rpcMsg).build();
|
||||||
systemContext.getRuleEngineTransportService().process(nodeId, msg);
|
systemContext.getTbCoreToTransportService().process(nodeId, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendToTransport(TransportProtos.ToServerRpcResponseMsg rpcMsg, UUID sessionId, String nodeId) {
|
private void sendToTransport(TransportProtos.ToServerRpcResponseMsg rpcMsg, UUID sessionId, String nodeId) {
|
||||||
@ -580,7 +581,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
|
|||||||
.setSessionIdMSB(sessionId.getMostSignificantBits())
|
.setSessionIdMSB(sessionId.getMostSignificantBits())
|
||||||
.setSessionIdLSB(sessionId.getLeastSignificantBits())
|
.setSessionIdLSB(sessionId.getLeastSignificantBits())
|
||||||
.setToServerResponse(rpcMsg).build();
|
.setToServerResponse(rpcMsg).build();
|
||||||
systemContext.getRuleEngineTransportService().process(nodeId, msg);
|
systemContext.getTbCoreToTransportService().process(nodeId, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -52,15 +52,12 @@ import org.thingsboard.server.service.cluster.discovery.DiscoveryService;
|
|||||||
import org.thingsboard.server.service.cluster.discovery.ServerInstance;
|
import org.thingsboard.server.service.cluster.discovery.ServerInstance;
|
||||||
import org.thingsboard.server.service.cluster.rpc.ClusterRpcService;
|
import org.thingsboard.server.service.cluster.rpc.ClusterRpcService;
|
||||||
import org.thingsboard.server.service.state.DeviceStateService;
|
import org.thingsboard.server.service.state.DeviceStateService;
|
||||||
import org.thingsboard.server.service.transport.RuleEngineStats;
|
|
||||||
import scala.concurrent.Await;
|
import scala.concurrent.Await;
|
||||||
import scala.concurrent.Future;
|
import scala.concurrent.Future;
|
||||||
import scala.concurrent.duration.Duration;
|
import scala.concurrent.duration.Duration;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import static org.thingsboard.server.gen.cluster.ClusterAPIProtos.MessageType.CLUSTER_ACTOR_MESSAGE;
|
import static org.thingsboard.server.gen.cluster.ClusterAPIProtos.MessageType.CLUSTER_ACTOR_MESSAGE;
|
||||||
|
|||||||
@ -1,161 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.cluster.rpc;
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
import io.grpc.Server;
|
|
||||||
import io.grpc.ServerBuilder;
|
|
||||||
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.actors.rpc.RpcBroadcastMsg;
|
|
||||||
import org.thingsboard.server.actors.rpc.RpcSessionCreateRequestMsg;
|
|
||||||
import org.thingsboard.server.common.msg.TbActorMsg;
|
|
||||||
import org.thingsboard.server.common.msg.cluster.ServerAddress;
|
|
||||||
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
|
|
||||||
import org.thingsboard.server.gen.cluster.ClusterRpcServiceGrpc;
|
|
||||||
import org.thingsboard.server.service.cluster.discovery.ServerInstance;
|
|
||||||
import org.thingsboard.server.service.cluster.discovery.ServerInstanceService;
|
|
||||||
import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
|
|
||||||
|
|
||||||
import javax.annotation.PreDestroy;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrew Shvayka
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@Slf4j
|
|
||||||
public class ClusterGrpcService extends ClusterRpcServiceGrpc.ClusterRpcServiceImplBase implements ClusterRpcService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ServerInstanceService instanceService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DataDecodingEncodingService encodingService;
|
|
||||||
|
|
||||||
private RpcMsgListener listener;
|
|
||||||
|
|
||||||
private Server server;
|
|
||||||
|
|
||||||
private ServerInstance instance;
|
|
||||||
|
|
||||||
private ConcurrentMap<UUID, BlockingQueue<StreamObserver<ClusterAPIProtos.ClusterMessage>>> pendingSessionMap =
|
|
||||||
new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public void init(RpcMsgListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
log.info("Initializing RPC service!");
|
|
||||||
instance = instanceService.getSelf();
|
|
||||||
server = ServerBuilder.forPort(instance.getPort()).addService(this).build();
|
|
||||||
log.info("Going to start RPC server using port: {}", instance.getPort());
|
|
||||||
try {
|
|
||||||
server.start();
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Failed to start RPC server!", e);
|
|
||||||
throw new RuntimeException("Failed to start RPC server!");
|
|
||||||
}
|
|
||||||
log.info("RPC service initialized!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSessionCreated(UUID msgUid, StreamObserver<ClusterAPIProtos.ClusterMessage> inputStream) {
|
|
||||||
BlockingQueue<StreamObserver<ClusterAPIProtos.ClusterMessage>> queue = pendingSessionMap.remove(msgUid);
|
|
||||||
if (queue != null) {
|
|
||||||
try {
|
|
||||||
queue.put(inputStream);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
log.warn("Failed to report created session!");
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("Failed to lookup pending session!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StreamObserver<ClusterAPIProtos.ClusterMessage> handleMsgs(
|
|
||||||
StreamObserver<ClusterAPIProtos.ClusterMessage> responseObserver) {
|
|
||||||
log.info("Processing new session.");
|
|
||||||
return createSession(new RpcSessionCreateRequestMsg(UUID.randomUUID(), null, responseObserver));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@PreDestroy
|
|
||||||
public void stop() {
|
|
||||||
if (server != null) {
|
|
||||||
log.info("Going to onStop RPC server");
|
|
||||||
server.shutdownNow();
|
|
||||||
try {
|
|
||||||
server.awaitTermination();
|
|
||||||
log.info("RPC server stopped!");
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
log.warn("Failed to onStop RPC server!");
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void broadcast(RpcBroadcastMsg msg) {
|
|
||||||
listener.onBroadcastMsg(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
private StreamObserver<ClusterAPIProtos.ClusterMessage> createSession(RpcSessionCreateRequestMsg msg) {
|
|
||||||
BlockingQueue<StreamObserver<ClusterAPIProtos.ClusterMessage>> queue = new ArrayBlockingQueue<>(1);
|
|
||||||
pendingSessionMap.put(msg.getMsgUid(), queue);
|
|
||||||
listener.onRpcSessionCreateRequestMsg(msg);
|
|
||||||
try {
|
|
||||||
StreamObserver<ClusterAPIProtos.ClusterMessage> observer = queue.take();
|
|
||||||
log.info("Processed new session.");
|
|
||||||
return observer;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.info("Failed to process session.", e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tell(ClusterAPIProtos.ClusterMessage message) {
|
|
||||||
listener.onSendMsg(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tell(ServerAddress serverAddress, TbActorMsg actorMsg) {
|
|
||||||
listener.onSendMsg(encodingService.convertToProtoDataMessage(serverAddress, actorMsg));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tell(ServerAddress serverAddress, ClusterAPIProtos.MessageType msgType, byte[] data) {
|
|
||||||
ClusterAPIProtos.ClusterMessage msg = ClusterAPIProtos.ClusterMessage
|
|
||||||
.newBuilder()
|
|
||||||
.setServerAddress(ClusterAPIProtos.ServerAddress
|
|
||||||
.newBuilder()
|
|
||||||
.setHost(serverAddress.getHost())
|
|
||||||
.setPort(serverAddress.getPort())
|
|
||||||
.build())
|
|
||||||
.setMessageType(msgType)
|
|
||||||
.setPayload(ByteString.copyFrom(data)).build();
|
|
||||||
listener.onSendMsg(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.cluster.rpc;
|
|
||||||
|
|
||||||
import io.grpc.stub.StreamObserver;
|
|
||||||
import org.thingsboard.server.actors.rpc.RpcBroadcastMsg;
|
|
||||||
import org.thingsboard.server.common.msg.TbActorMsg;
|
|
||||||
import org.thingsboard.server.common.msg.cluster.ServerAddress;
|
|
||||||
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrew Shvayka
|
|
||||||
*/
|
|
||||||
public interface ClusterRpcService {
|
|
||||||
|
|
||||||
void init(RpcMsgListener listener);
|
|
||||||
|
|
||||||
void broadcast(RpcBroadcastMsg msg);
|
|
||||||
|
|
||||||
void onSessionCreated(UUID msgUid, StreamObserver<ClusterAPIProtos.ClusterMessage> inputStream);
|
|
||||||
|
|
||||||
void tell(ClusterAPIProtos.ClusterMessage message);
|
|
||||||
|
|
||||||
void tell(ServerAddress serverAddress, TbActorMsg actorMsg);
|
|
||||||
|
|
||||||
void tell(ServerAddress serverAddress, ClusterAPIProtos.MessageType msgType, byte[] data);
|
|
||||||
}
|
|
||||||
@ -1,125 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.cluster.rpc;
|
|
||||||
|
|
||||||
import io.grpc.Channel;
|
|
||||||
import io.grpc.ManagedChannel;
|
|
||||||
import io.grpc.stub.StreamObserver;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.thingsboard.server.common.msg.cluster.ServerAddress;
|
|
||||||
import org.thingsboard.server.common.msg.cluster.ServerType;
|
|
||||||
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
|
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrew Shvayka
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Slf4j
|
|
||||||
public final class GrpcSession implements Closeable {
|
|
||||||
private final UUID sessionId;
|
|
||||||
private final boolean client;
|
|
||||||
private final GrpcSessionListener listener;
|
|
||||||
private final ManagedChannel channel;
|
|
||||||
private StreamObserver<ClusterAPIProtos.ClusterMessage> inputStream;
|
|
||||||
private StreamObserver<ClusterAPIProtos.ClusterMessage> outputStream;
|
|
||||||
|
|
||||||
private boolean connected;
|
|
||||||
private ServerAddress remoteServer;
|
|
||||||
|
|
||||||
public GrpcSession(GrpcSessionListener listener) {
|
|
||||||
this(null, listener, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GrpcSession(ServerAddress remoteServer, GrpcSessionListener listener, ManagedChannel channel) {
|
|
||||||
this.sessionId = UUID.randomUUID();
|
|
||||||
this.listener = listener;
|
|
||||||
if (remoteServer != null) {
|
|
||||||
this.client = true;
|
|
||||||
this.connected = true;
|
|
||||||
this.remoteServer = remoteServer;
|
|
||||||
} else {
|
|
||||||
this.client = false;
|
|
||||||
}
|
|
||||||
this.channel = channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initInputStream() {
|
|
||||||
this.inputStream = new StreamObserver<ClusterAPIProtos.ClusterMessage>() {
|
|
||||||
@Override
|
|
||||||
public void onNext(ClusterAPIProtos.ClusterMessage clusterMessage) {
|
|
||||||
if (!connected && clusterMessage.getMessageType() == ClusterAPIProtos.MessageType.CONNECT_RPC_MESSAGE) {
|
|
||||||
connected = true;
|
|
||||||
ServerAddress rpcAddress = new ServerAddress(clusterMessage.getServerAddress().getHost(), clusterMessage.getServerAddress().getPort(), ServerType.CORE);
|
|
||||||
remoteServer = new ServerAddress(rpcAddress.getHost(), rpcAddress.getPort(), ServerType.CORE);
|
|
||||||
listener.onConnected(GrpcSession.this);
|
|
||||||
}
|
|
||||||
if (connected) {
|
|
||||||
listener.onReceiveClusterGrpcMsg(GrpcSession.this, clusterMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable t) {
|
|
||||||
listener.onError(GrpcSession.this, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCompleted() {
|
|
||||||
outputStream.onCompleted();
|
|
||||||
listener.onDisconnected(GrpcSession.this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initOutputStream() {
|
|
||||||
if (client) {
|
|
||||||
listener.onConnected(GrpcSession.this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendMsg(ClusterAPIProtos.ClusterMessage msg) {
|
|
||||||
if (connected) {
|
|
||||||
try {
|
|
||||||
outputStream.onNext(msg);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
try {
|
|
||||||
outputStream.onError(t);
|
|
||||||
} catch (Throwable t2) {
|
|
||||||
}
|
|
||||||
listener.onError(GrpcSession.this, t);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("[{}] Failed to send message due to closed session!", sessionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
connected = false;
|
|
||||||
try {
|
|
||||||
outputStream.onCompleted();
|
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
log.debug("[{}] Failed to close output stream: {}", sessionId, e.getMessage());
|
|
||||||
}
|
|
||||||
if (channel != null) {
|
|
||||||
channel.shutdownNow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.cluster.rpc;
|
|
||||||
|
|
||||||
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrew Shvayka
|
|
||||||
*/
|
|
||||||
public interface GrpcSessionListener {
|
|
||||||
|
|
||||||
void onConnected(GrpcSession session);
|
|
||||||
|
|
||||||
void onDisconnected(GrpcSession session);
|
|
||||||
|
|
||||||
void onReceiveClusterGrpcMsg(GrpcSession session, ClusterAPIProtos.ClusterMessage clusterMessage);
|
|
||||||
|
|
||||||
void onError(GrpcSession session, Throwable t);
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.cluster.rpc;
|
|
||||||
|
|
||||||
import org.thingsboard.server.actors.rpc.RpcBroadcastMsg;
|
|
||||||
import org.thingsboard.server.actors.rpc.RpcSessionCreateRequestMsg;
|
|
||||||
import org.thingsboard.server.common.msg.cluster.ServerAddress;
|
|
||||||
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrew Shvayka
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface RpcMsgListener {
|
|
||||||
void onReceivedMsg(ServerAddress remoteServer, ClusterAPIProtos.ClusterMessage msg);
|
|
||||||
void onSendMsg(ClusterAPIProtos.ClusterMessage msg);
|
|
||||||
void onRpcSessionCreateRequestMsg(RpcSessionCreateRequestMsg msg);
|
|
||||||
void onBroadcastMsg(RpcBroadcastMsg msg);
|
|
||||||
}
|
|
||||||
@ -15,7 +15,6 @@ import org.thingsboard.server.common.TbProtoQueueMsg;
|
|||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
|
||||||
import org.thingsboard.server.provider.TbCoreQueueProvider;
|
import org.thingsboard.server.provider.TbCoreQueueProvider;
|
||||||
import org.thingsboard.server.service.transport.RuleEngineStats;
|
|
||||||
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
|
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@ -44,7 +43,7 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
|
|||||||
|
|
||||||
private final ActorSystemContext actorContext;
|
private final ActorSystemContext actorContext;
|
||||||
private final TbQueueConsumer<TbProtoQueueMsg<ToCoreMsg>> consumer;
|
private final TbQueueConsumer<TbProtoQueueMsg<ToCoreMsg>> consumer;
|
||||||
private final RuleEngineStats stats = new RuleEngineStats();
|
private final TbCoreConsumerStats stats = new TbCoreConsumerStats();
|
||||||
private volatile ExecutorService mainConsumerExecutor;
|
private volatile ExecutorService mainConsumerExecutor;
|
||||||
private volatile boolean stopped = false;
|
private volatile boolean stopped = false;
|
||||||
|
|
||||||
@ -71,10 +70,10 @@ public class DefaultTbCoreConsumerService implements TbCoreConsumerService {
|
|||||||
ackMap.forEach((id, msg) -> {
|
ackMap.forEach((id, msg) -> {
|
||||||
TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, ackMap);
|
TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, ackMap);
|
||||||
try {
|
try {
|
||||||
ToCoreMsg toRuleEngineMsg = msg.getValue();
|
ToCoreMsg toCoreMsg = msg.getValue();
|
||||||
log.trace("Forwarding message to rule engine {}", toRuleEngineMsg);
|
log.trace("Forwarding message to rule engine {}", toCoreMsg);
|
||||||
if (toRuleEngineMsg.hasToDeviceActorMsg()) {
|
if (toCoreMsg.hasToDeviceActorMsg()) {
|
||||||
forwardToDeviceActor(toRuleEngineMsg.getToDeviceActorMsg(), callback);
|
forwardToDeviceActor(toCoreMsg.getToDeviceActorMsg(), callback);
|
||||||
} else {
|
} else {
|
||||||
callback.onSuccess();
|
callback.onSuccess();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,124 @@
|
|||||||
|
package org.thingsboard.server.service.queue;
|
||||||
|
|
||||||
|
import akka.actor.ActorRef;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.thingsboard.common.util.ThingsBoardThreadFactory;
|
||||||
|
import org.thingsboard.server.TbQueueConsumer;
|
||||||
|
import org.thingsboard.server.actors.ActorSystemContext;
|
||||||
|
import org.thingsboard.server.common.TbProtoQueueMsg;
|
||||||
|
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||||
|
import org.thingsboard.server.provider.TbCoreQueueProvider;
|
||||||
|
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.annotation.PreDestroy;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-rule-engine')")
|
||||||
|
@Slf4j
|
||||||
|
public class DefaultTbRuleEngineConsumerService implements TbRuleEngineConsumerService {
|
||||||
|
|
||||||
|
|
||||||
|
@Value("${queue.rule-engine.poll_interval}")
|
||||||
|
private long pollDuration;
|
||||||
|
@Value("${queue.rule-engine.pack_processing_timeout}")
|
||||||
|
private long packProcessingTimeout;
|
||||||
|
@Value("${queue.rule-engine.stats.enabled:false}")
|
||||||
|
private boolean statsEnabled;
|
||||||
|
|
||||||
|
private final ActorSystemContext actorContext;
|
||||||
|
private final TbQueueConsumer<TbProtoQueueMsg<TransportProtos.ToCoreMsg>> consumer;
|
||||||
|
private final TbCoreConsumerStats stats = new TbCoreConsumerStats();
|
||||||
|
private volatile ExecutorService mainConsumerExecutor;
|
||||||
|
private volatile boolean stopped = false;
|
||||||
|
|
||||||
|
public DefaultTbRuleEngineConsumerService(TbCoreQueueProvider tbCoreQueueProvider, ActorSystemContext actorContext) {
|
||||||
|
this.consumer = tbCoreQueueProvider.getToCoreMsgConsumer();
|
||||||
|
this.actorContext = actorContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
this.consumer.subscribe();
|
||||||
|
this.mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("tb-core-consumer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
|
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||||
|
mainConsumerExecutor.execute(() -> {
|
||||||
|
while (!stopped) {
|
||||||
|
try {
|
||||||
|
List<TbProtoQueueMsg<TransportProtos.ToCoreMsg>> msgs = consumer.poll(pollDuration);
|
||||||
|
ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToCoreMsg>> ackMap = msgs.stream().collect(
|
||||||
|
Collectors.toConcurrentMap(s -> UUID.randomUUID(), Function.identity()));
|
||||||
|
CountDownLatch processingTimeoutLatch = new CountDownLatch(1);
|
||||||
|
ackMap.forEach((id, msg) -> {
|
||||||
|
TbMsgCallback callback = new MsgPackCallback<>(id, processingTimeoutLatch, ackMap);
|
||||||
|
try {
|
||||||
|
TransportProtos.ToCoreMsg toCoreMsg = msg.getValue();
|
||||||
|
log.trace("Forwarding message to rule engine {}", toCoreMsg);
|
||||||
|
if (toCoreMsg.hasToDeviceActorMsg()) {
|
||||||
|
forwardToDeviceActor(toCoreMsg.getToDeviceActorMsg(), callback);
|
||||||
|
} else {
|
||||||
|
callback.onSuccess();
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
callback.onFailure(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!processingTimeoutLatch.await(packProcessingTimeout, TimeUnit.MILLISECONDS)) {
|
||||||
|
ackMap.forEach((id, msg) -> log.warn("[{}] Timeout to process message: {}", id, msg.getValue()));
|
||||||
|
}
|
||||||
|
consumer.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Failed to obtain messages from queue.", e);
|
||||||
|
try {
|
||||||
|
Thread.sleep(pollDuration);
|
||||||
|
} catch (InterruptedException e2) {
|
||||||
|
log.trace("Failed to wait until the server has capacity to handle new requests", e2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void forwardToDeviceActor(TransportProtos.TransportToDeviceActorMsg toDeviceActorMsg, TbMsgCallback callback) {
|
||||||
|
if (statsEnabled) {
|
||||||
|
stats.log(toDeviceActorMsg);
|
||||||
|
}
|
||||||
|
actorContext.getAppActor().tell(new TransportToDeviceActorMsgWrapper(toDeviceActorMsg, callback), ActorRef.noSender());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(fixedDelayString = "${queue.core.stats.print_interval_ms}")
|
||||||
|
public void printStats() {
|
||||||
|
if (statsEnabled) {
|
||||||
|
stats.printStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreDestroy
|
||||||
|
public void destroy() {
|
||||||
|
stopped = true;
|
||||||
|
if (consumer != null) {
|
||||||
|
consumer.unsubscribe();
|
||||||
|
}
|
||||||
|
if (mainConsumerExecutor != null) {
|
||||||
|
mainConsumerExecutor.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* 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.queue;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class TbCoreConsumerStats {
|
||||||
|
|
||||||
|
private final AtomicInteger totalCounter = new AtomicInteger(0);
|
||||||
|
private final AtomicInteger sessionEventCounter = new AtomicInteger(0);
|
||||||
|
private final AtomicInteger getAttributesCounter = new AtomicInteger(0);
|
||||||
|
private final AtomicInteger subscribeToAttributesCounter = new AtomicInteger(0);
|
||||||
|
private final AtomicInteger subscribeToRPCCounter = new AtomicInteger(0);
|
||||||
|
private final AtomicInteger toDeviceRPCCallResponseCounter = new AtomicInteger(0);
|
||||||
|
private final AtomicInteger subscriptionInfoCounter = new AtomicInteger(0);
|
||||||
|
private final AtomicInteger claimDeviceCounter = new AtomicInteger(0);
|
||||||
|
|
||||||
|
public void log(TransportProtos.TransportToDeviceActorMsg msg) {
|
||||||
|
totalCounter.incrementAndGet();
|
||||||
|
if (msg.hasSessionEvent()) {
|
||||||
|
sessionEventCounter.incrementAndGet();
|
||||||
|
}
|
||||||
|
if (msg.hasGetAttributes()) {
|
||||||
|
getAttributesCounter.incrementAndGet();
|
||||||
|
}
|
||||||
|
if (msg.hasSubscribeToAttributes()) {
|
||||||
|
subscribeToAttributesCounter.incrementAndGet();
|
||||||
|
}
|
||||||
|
if (msg.hasSubscribeToRPC()) {
|
||||||
|
subscribeToRPCCounter.incrementAndGet();
|
||||||
|
}
|
||||||
|
if (msg.hasToDeviceRPCCallResponse()) {
|
||||||
|
toDeviceRPCCallResponseCounter.incrementAndGet();
|
||||||
|
}
|
||||||
|
if (msg.hasSubscriptionInfo()) {
|
||||||
|
subscriptionInfoCounter.incrementAndGet();
|
||||||
|
}
|
||||||
|
if (msg.hasClaimDevice()) {
|
||||||
|
claimDeviceCounter.incrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printStats() {
|
||||||
|
int total = totalCounter.getAndSet(0);
|
||||||
|
if (total > 0) {
|
||||||
|
log.info("Transport total [{}] sessionEvents [{}] getAttr [{}] subToAttr [{}] subToRpc [{}] toDevRpc [{}] subInfo [{}] claimDevice [{}]",
|
||||||
|
total, sessionEventCounter.getAndSet(0),
|
||||||
|
getAttributesCounter.getAndSet(0), subscribeToAttributesCounter.getAndSet(0),
|
||||||
|
subscribeToRPCCounter.getAndSet(0), toDeviceRPCCallResponseCounter.getAndSet(0),
|
||||||
|
subscriptionInfoCounter.getAndSet(0), claimDeviceCounter.getAndSet(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package org.thingsboard.server.service.queue;
|
||||||
|
|
||||||
|
public interface TbRuleEngineConsumerService {
|
||||||
|
|
||||||
|
}
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.thingsboard.server.service.transport;
|
package org.thingsboard.server.service.queue;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||||
@ -21,7 +21,7 @@ import org.thingsboard.server.gen.transport.TransportProtos;
|
|||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class RuleEngineStats {
|
public class TbRuleEngineConsumerStats {
|
||||||
|
|
||||||
private final AtomicInteger totalCounter = new AtomicInteger(0);
|
private final AtomicInteger totalCounter = new AtomicInteger(0);
|
||||||
private final AtomicInteger sessionEventCounter = new AtomicInteger(0);
|
private final AtomicInteger sessionEventCounter = new AtomicInteger(0);
|
||||||
@ -45,6 +45,7 @@ import org.thingsboard.server.kafka.TbNodeIdProvider;
|
|||||||
import org.thingsboard.server.service.cluster.routing.ClusterRoutingService;
|
import org.thingsboard.server.service.cluster.routing.ClusterRoutingService;
|
||||||
import org.thingsboard.server.service.cluster.rpc.ClusterRpcService;
|
import org.thingsboard.server.service.cluster.rpc.ClusterRpcService;
|
||||||
import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
|
import org.thingsboard.server.service.encoding.DataDecodingEncodingService;
|
||||||
|
import org.thingsboard.server.service.queue.TbCoreConsumerStats;
|
||||||
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
|
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@ -109,7 +110,7 @@ public class RemoteRuleEngineTransportService implements RuleEngineTransportServ
|
|||||||
|
|
||||||
private volatile boolean stopped = false;
|
private volatile boolean stopped = false;
|
||||||
|
|
||||||
private final RuleEngineStats stats = new RuleEngineStats();
|
private final TbCoreConsumerStats stats = new TbCoreConsumerStats();
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
|
|||||||
@ -23,7 +23,7 @@ option java_outer_classname = "TransportProtos";
|
|||||||
* Transport Service Data Structures;
|
* Transport Service Data Structures;
|
||||||
*/
|
*/
|
||||||
message SessionInfoProto {
|
message SessionInfoProto {
|
||||||
string ServiceId = 1;
|
string nodeId = 1;
|
||||||
int64 sessionIdMSB = 2;
|
int64 sessionIdMSB = 2;
|
||||||
int64 sessionIdLSB = 3;
|
int64 sessionIdLSB = 3;
|
||||||
int64 tenantIdMSB = 4;
|
int64 tenantIdMSB = 4;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user