|
|
|
@ -21,6 +21,8 @@ import com.google.common.util.concurrent.MoreExecutors; |
|
|
|
import jakarta.annotation.PostConstruct; |
|
|
|
import jakarta.annotation.PreDestroy; |
|
|
|
import lombok.Data; |
|
|
|
import lombok.Getter; |
|
|
|
import lombok.Setter; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
|
import org.springframework.context.ApplicationEventPublisher; |
|
|
|
@ -32,12 +34,19 @@ import org.thingsboard.server.common.data.id.CalculatedFieldId; |
|
|
|
import org.thingsboard.server.common.data.id.EntityIdFactory; |
|
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
|
import org.thingsboard.server.common.data.queue.QueueConfig; |
|
|
|
import org.thingsboard.server.common.msg.MsgType; |
|
|
|
import org.thingsboard.server.common.msg.TbActorMsg; |
|
|
|
import org.thingsboard.server.common.msg.queue.ServiceType; |
|
|
|
import org.thingsboard.server.common.msg.queue.TbCallback; |
|
|
|
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequestActorMsg; |
|
|
|
import org.thingsboard.server.common.util.ProtoUtils; |
|
|
|
import org.thingsboard.server.dao.tenant.TbTenantProfileCache; |
|
|
|
import org.thingsboard.server.gen.transport.TransportProtos; |
|
|
|
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldLinkedTelemetryMsgProto; |
|
|
|
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldTelemetryMsgProto; |
|
|
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldMsg; |
|
|
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldNotificationMsg; |
|
|
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; |
|
|
|
import org.thingsboard.server.queue.TbQueueConsumer; |
|
|
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
|
|
|
import org.thingsboard.server.queue.discovery.PartitionService; |
|
|
|
@ -50,12 +59,20 @@ import org.thingsboard.server.service.cf.CalculatedFieldCache; |
|
|
|
import org.thingsboard.server.service.cf.CalculatedFieldExecutionService; |
|
|
|
import org.thingsboard.server.service.profile.TbAssetProfileCache; |
|
|
|
import org.thingsboard.server.service.profile.TbDeviceProfileCache; |
|
|
|
import org.thingsboard.server.service.queue.DefaultTbCoreConsumerService.PendingMsgHolder; |
|
|
|
import org.thingsboard.server.service.queue.consumer.MainQueueConsumerManager; |
|
|
|
import org.thingsboard.server.service.queue.processing.AbstractConsumerService; |
|
|
|
import org.thingsboard.server.service.queue.processing.IdMsgPair; |
|
|
|
import org.thingsboard.server.service.security.auth.jwt.settings.JwtSettingsService; |
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
import java.util.UUID; |
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
import java.util.concurrent.ConcurrentMap; |
|
|
|
import java.util.concurrent.CountDownLatch; |
|
|
|
import java.util.concurrent.Future; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
@Service |
|
|
|
@TbRuleEngineComponent |
|
|
|
@ -132,7 +149,46 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer |
|
|
|
} |
|
|
|
|
|
|
|
private void processMsgs(List<TbProtoQueueMsg<ToCalculatedFieldMsg>> msgs, TbQueueConsumer<TbProtoQueueMsg<ToCalculatedFieldMsg>> consumer, CalculatedFieldQueueConfig config) throws Exception { |
|
|
|
|
|
|
|
List<IdMsgPair<ToCalculatedFieldMsg>> orderedMsgList = msgs.stream().map(msg -> new IdMsgPair<>(UUID.randomUUID(), msg)).toList(); |
|
|
|
ConcurrentMap<UUID, TbProtoQueueMsg<ToCalculatedFieldMsg>> pendingMap = orderedMsgList.stream().collect( |
|
|
|
Collectors.toConcurrentMap(IdMsgPair::getUuid, IdMsgPair::getMsg)); |
|
|
|
CountDownLatch processingTimeoutLatch = new CountDownLatch(1); |
|
|
|
TbPackProcessingContext<TbProtoQueueMsg<ToCalculatedFieldMsg>> ctx = new TbPackProcessingContext<>( |
|
|
|
processingTimeoutLatch, pendingMap, new ConcurrentHashMap<>()); |
|
|
|
PendingMsgHolder<ToCalculatedFieldMsg> pendingMsgHolder = new PendingMsgHolder<>(); |
|
|
|
Future<?> packSubmitFuture = consumersExecutor.submit(() -> { |
|
|
|
orderedMsgList.forEach((element) -> { |
|
|
|
UUID id = element.getUuid(); |
|
|
|
TbProtoQueueMsg<ToCalculatedFieldMsg> msg = element.getMsg(); |
|
|
|
log.trace("[{}] Creating main callback for message: {}", id, msg.getValue()); |
|
|
|
TbCallback callback = new TbPackCallback<>(id, ctx); |
|
|
|
try { |
|
|
|
ToCalculatedFieldMsg toCfMsg = msg.getValue(); |
|
|
|
pendingMsgHolder.setMsg(toCfMsg); |
|
|
|
if (toCfMsg.hasTelemetryMsg()) { |
|
|
|
log.trace("[{}] Forwarding regular telemetry message for processing {}", id, toCfMsg.getTelemetryMsg()); |
|
|
|
forwardToCalculatedFieldService(toCfMsg.getTelemetryMsg(), callback); |
|
|
|
} else if (toCfMsg.hasLinkedTelemetryMsg()) { |
|
|
|
log.trace("[{}] Forwarding linked telemetry message for processing {}", id, toCfMsg.getLinkedTelemetryMsg()); |
|
|
|
forwardToCalculatedFieldService(toCfMsg.getLinkedTelemetryMsg(), callback); |
|
|
|
} |
|
|
|
} catch (Throwable e) { |
|
|
|
log.warn("[{}] Failed to process message: {}", id, msg, e); |
|
|
|
callback.onFailure(e); |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
if (!processingTimeoutLatch.await(packProcessingTimeout, TimeUnit.MILLISECONDS)) { |
|
|
|
if (!packSubmitFuture.isDone()) { |
|
|
|
packSubmitFuture.cancel(true); |
|
|
|
log.info("Timeout to process message: {}", pendingMsgHolder.getMsg()); |
|
|
|
} |
|
|
|
if (log.isDebugEnabled()) { |
|
|
|
ctx.getAckMap().forEach((id, msg) -> log.debug("[{}] Timeout to process message: {}", id, msg.getValue())); |
|
|
|
} |
|
|
|
ctx.getFailedMap().forEach((id, msg) -> log.warn("[{}] Failed to process message: {}", id, msg.getValue())); |
|
|
|
} |
|
|
|
consumer.commit(); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
@ -193,6 +249,33 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer |
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
|
|
|
|
private void forwardToCalculatedFieldService(CalculatedFieldLinkedTelemetryMsgProto linkedMsg, TbCallback callback) { |
|
|
|
var msg = linkedMsg.getMsg(); |
|
|
|
var tenantId = toTenantId(msg.getTenantIdMSB(), msg.getTenantIdLSB()); |
|
|
|
var calculatedFieldId = new CalculatedFieldId(new UUID(msg.getEntityIdMSB(), msg.getEntityIdLSB())); |
|
|
|
ListenableFuture<?> future = calculatedFieldsExecutor.submit(() -> calculatedFieldExecutionService.onLinkedTelemetryMsg(linkedMsg, callback)); |
|
|
|
DonAsynchron.withCallback(future, |
|
|
|
__ -> callback.onSuccess(), |
|
|
|
t -> { |
|
|
|
log.warn("[{}] Failed to process calculated field message for calculated field [{}]", tenantId.getId(), calculatedFieldId.getId(), t); |
|
|
|
callback.onFailure(t); |
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
private void forwardToCalculatedFieldService(CalculatedFieldTelemetryMsgProto msg, TbCallback callback) { |
|
|
|
var tenantId = toTenantId(msg.getTenantIdMSB(), msg.getTenantIdLSB()); |
|
|
|
var calculatedFieldId = new CalculatedFieldId(new UUID(msg.getEntityIdMSB(), msg.getEntityIdLSB())); |
|
|
|
ListenableFuture<?> future = calculatedFieldsExecutor.submit(() -> calculatedFieldExecutionService.onTelemetryMsg(msg, callback)); |
|
|
|
DonAsynchron.withCallback(future, |
|
|
|
__ -> callback.onSuccess(), |
|
|
|
t -> { |
|
|
|
log.warn("[{}] Failed to process calculated field message for calculated field [{}]", tenantId.getId(), calculatedFieldId.getId(), t); |
|
|
|
callback.onFailure(t); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
private void forwardToCalculatedFieldService(TransportProtos.ComponentLifecycleMsgProto msg, TbCallback callback) { |
|
|
|
var tenantId = toTenantId(msg.getTenantIdMSB(), msg.getTenantIdLSB()); |
|
|
|
var calculatedFieldId = new CalculatedFieldId(new UUID(msg.getEntityIdMSB(), msg.getEntityIdLSB())); |
|
|
|
|