|
|
@ -18,24 +18,31 @@ package org.thingsboard.server.service.queue; |
|
|
import jakarta.annotation.PostConstruct; |
|
|
import jakarta.annotation.PostConstruct; |
|
|
import jakarta.annotation.PreDestroy; |
|
|
import jakarta.annotation.PreDestroy; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
|
import org.apache.commons.collections4.CollectionUtils; |
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
import org.springframework.context.ApplicationEventPublisher; |
|
|
import org.springframework.context.ApplicationEventPublisher; |
|
|
|
|
|
import org.springframework.context.event.EventListener; |
|
|
import org.springframework.stereotype.Service; |
|
|
import org.springframework.stereotype.Service; |
|
|
import org.thingsboard.server.actors.ActorSystemContext; |
|
|
import org.thingsboard.server.actors.ActorSystemContext; |
|
|
import org.thingsboard.server.actors.calculatedField.CalculatedFieldLinkedTelemetryMsg; |
|
|
import org.thingsboard.server.actors.calculatedField.CalculatedFieldLinkedTelemetryMsg; |
|
|
import org.thingsboard.server.actors.calculatedField.CalculatedFieldTelemetryMsg; |
|
|
import org.thingsboard.server.actors.calculatedField.CalculatedFieldTelemetryMsg; |
|
|
import org.thingsboard.server.common.data.DataConstants; |
|
|
import org.thingsboard.server.common.data.DataConstants; |
|
|
|
|
|
import org.thingsboard.server.common.data.EntityType; |
|
|
import org.thingsboard.server.common.data.id.EntityIdFactory; |
|
|
import org.thingsboard.server.common.data.id.EntityIdFactory; |
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
|
|
|
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; |
|
|
import org.thingsboard.server.common.data.queue.QueueConfig; |
|
|
import org.thingsboard.server.common.data.queue.QueueConfig; |
|
|
import org.thingsboard.server.common.msg.cf.CalculatedFieldPartitionChangeMsg; |
|
|
import org.thingsboard.server.common.msg.cf.CalculatedFieldPartitionChangeMsg; |
|
|
|
|
|
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; |
|
|
import org.thingsboard.server.common.msg.queue.ServiceType; |
|
|
import org.thingsboard.server.common.msg.queue.ServiceType; |
|
|
import org.thingsboard.server.common.msg.queue.TbCallback; |
|
|
import org.thingsboard.server.common.msg.queue.TbCallback; |
|
|
|
|
|
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
|
|
import org.thingsboard.server.dao.tenant.TbTenantProfileCache; |
|
|
import org.thingsboard.server.dao.tenant.TbTenantProfileCache; |
|
|
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldLinkedTelemetryMsgProto; |
|
|
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldLinkedTelemetryMsgProto; |
|
|
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldTelemetryMsgProto; |
|
|
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldTelemetryMsgProto; |
|
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldMsg; |
|
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldMsg; |
|
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldNotificationMsg; |
|
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldNotificationMsg; |
|
|
|
|
|
import org.thingsboard.server.queue.TbQueueAdmin; |
|
|
import org.thingsboard.server.queue.TbQueueConsumer; |
|
|
import org.thingsboard.server.queue.TbQueueConsumer; |
|
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
|
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
|
|
import org.thingsboard.server.queue.common.consumer.PartitionedQueueConsumerManager; |
|
|
import org.thingsboard.server.queue.common.consumer.PartitionedQueueConsumerManager; |
|
|
@ -54,6 +61,7 @@ import org.thingsboard.server.service.queue.processing.IdMsgPair; |
|
|
import org.thingsboard.server.service.security.auth.jwt.settings.JwtSettingsService; |
|
|
import org.thingsboard.server.service.security.auth.jwt.settings.JwtSettingsService; |
|
|
|
|
|
|
|
|
import java.util.List; |
|
|
import java.util.List; |
|
|
|
|
|
import java.util.Set; |
|
|
import java.util.UUID; |
|
|
import java.util.UUID; |
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
import java.util.concurrent.ConcurrentMap; |
|
|
import java.util.concurrent.ConcurrentMap; |
|
|
@ -73,10 +81,9 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer |
|
|
private long packProcessingTimeout; |
|
|
private long packProcessingTimeout; |
|
|
|
|
|
|
|
|
private final TbRuleEngineQueueFactory queueFactory; |
|
|
private final TbRuleEngineQueueFactory queueFactory; |
|
|
|
|
|
private final TbQueueAdmin queueAdmin; |
|
|
private final CalculatedFieldStateService stateService; |
|
|
private final CalculatedFieldStateService stateService; |
|
|
|
|
|
|
|
|
private PartitionedQueueConsumerManager<TbProtoQueueMsg<ToCalculatedFieldMsg>> eventConsumer; |
|
|
|
|
|
|
|
|
|
|
|
public DefaultTbCalculatedFieldConsumerService(TbRuleEngineQueueFactory tbQueueFactory, |
|
|
public DefaultTbCalculatedFieldConsumerService(TbRuleEngineQueueFactory tbQueueFactory, |
|
|
ActorSystemContext actorContext, |
|
|
ActorSystemContext actorContext, |
|
|
TbDeviceProfileCache deviceProfileCache, |
|
|
TbDeviceProfileCache deviceProfileCache, |
|
|
@ -87,10 +94,12 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer |
|
|
ApplicationEventPublisher eventPublisher, |
|
|
ApplicationEventPublisher eventPublisher, |
|
|
JwtSettingsService jwtSettingsService, |
|
|
JwtSettingsService jwtSettingsService, |
|
|
CalculatedFieldCache calculatedFieldCache, |
|
|
CalculatedFieldCache calculatedFieldCache, |
|
|
|
|
|
TbQueueAdmin queueAdmin, |
|
|
CalculatedFieldStateService stateService) { |
|
|
CalculatedFieldStateService stateService) { |
|
|
super(actorContext, tenantProfileCache, deviceProfileCache, assetProfileCache, calculatedFieldCache, apiUsageStateService, partitionService, |
|
|
super(actorContext, tenantProfileCache, deviceProfileCache, assetProfileCache, calculatedFieldCache, apiUsageStateService, partitionService, |
|
|
eventPublisher, jwtSettingsService); |
|
|
eventPublisher, jwtSettingsService); |
|
|
this.queueFactory = tbQueueFactory; |
|
|
this.queueFactory = tbQueueFactory; |
|
|
|
|
|
this.queueAdmin = queueAdmin; |
|
|
this.stateService = stateService; |
|
|
this.stateService = stateService; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -99,12 +108,13 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer |
|
|
super.init("tb-cf"); |
|
|
super.init("tb-cf"); |
|
|
|
|
|
|
|
|
var queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME); |
|
|
var queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME); |
|
|
this.eventConsumer = PartitionedQueueConsumerManager.<TbProtoQueueMsg<ToCalculatedFieldMsg>>create() |
|
|
PartitionedQueueConsumerManager<TbProtoQueueMsg<ToCalculatedFieldMsg>> eventConsumer = PartitionedQueueConsumerManager.<TbProtoQueueMsg<ToCalculatedFieldMsg>>create() |
|
|
.queueKey(queueKey) |
|
|
.queueKey(queueKey) |
|
|
.topic(partitionService.getTopic(queueKey)) |
|
|
.topic(partitionService.getTopic(queueKey)) |
|
|
.pollInterval(pollInterval) |
|
|
.pollInterval(pollInterval) |
|
|
.msgPackProcessor(this::processMsgs) |
|
|
.msgPackProcessor(this::processMsgs) |
|
|
.consumerCreator((config, partitionId) -> queueFactory.createToCalculatedFieldMsgConsumer()) |
|
|
.consumerCreator((config, partitionId) -> queueFactory.createToCalculatedFieldMsgConsumer()) |
|
|
|
|
|
.queueAdmin(queueAdmin) |
|
|
.consumerExecutor(consumersExecutor) |
|
|
.consumerExecutor(consumersExecutor) |
|
|
.scheduler(scheduler) |
|
|
.scheduler(scheduler) |
|
|
.taskExecutor(mgmtExecutor) |
|
|
.taskExecutor(mgmtExecutor) |
|
|
@ -124,9 +134,12 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer |
|
|
|
|
|
|
|
|
@Override |
|
|
@Override |
|
|
protected void onTbApplicationEvent(PartitionChangeEvent event) { |
|
|
protected void onTbApplicationEvent(PartitionChangeEvent event) { |
|
|
var partitions = event.getCfPartitions(); |
|
|
|
|
|
try { |
|
|
try { |
|
|
stateService.restore(partitions); |
|
|
event.getNewPartitions().forEach((queueKey, partitions) -> { |
|
|
|
|
|
if (queueKey.getQueueName().equals(DataConstants.CF_QUEUE_NAME)) { |
|
|
|
|
|
stateService.restore(queueKey, partitions); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
// eventConsumer's partitions will be updated by stateService
|
|
|
// eventConsumer's partitions will be updated by stateService
|
|
|
|
|
|
|
|
|
// Cleanup old entities after corresponding consumers are stopped.
|
|
|
// Cleanup old entities after corresponding consumers are stopped.
|
|
|
@ -212,6 +225,21 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@EventListener |
|
|
|
|
|
public void handleComponentLifecycleEvent(ComponentLifecycleMsg event) { |
|
|
|
|
|
if (event.getEntityId().getEntityType() == EntityType.TENANT) { |
|
|
|
|
|
if (event.getEvent() == ComponentLifecycleEvent.DELETED) { |
|
|
|
|
|
Set<TopicPartitionInfo> partitions = stateService.getPartitions(); |
|
|
|
|
|
if (CollectionUtils.isEmpty(partitions)) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
stateService.delete(partitions.stream() |
|
|
|
|
|
.filter(tpi -> tpi.getTenantId().isPresent() && tpi.getTenantId().get().equals(event.getTenantId())) |
|
|
|
|
|
.collect(Collectors.toSet())); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private void forwardToActorSystem(CalculatedFieldTelemetryMsgProto msg, TbCallback callback) { |
|
|
private void forwardToActorSystem(CalculatedFieldTelemetryMsgProto msg, TbCallback callback) { |
|
|
var tenantId = toTenantId(msg.getTenantIdMSB(), msg.getTenantIdLSB()); |
|
|
var tenantId = toTenantId(msg.getTenantIdMSB(), msg.getTenantIdLSB()); |
|
|
var entityId = EntityIdFactory.getByTypeAndUuid(msg.getEntityType(), new UUID(msg.getEntityIdMSB(), msg.getEntityIdLSB())); |
|
|
var entityId = EntityIdFactory.getByTypeAndUuid(msg.getEntityType(), new UUID(msg.getEntityIdMSB(), msg.getEntityIdLSB())); |
|
|
@ -232,9 +260,7 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer |
|
|
@Override |
|
|
@Override |
|
|
protected void stopConsumers() { |
|
|
protected void stopConsumers() { |
|
|
super.stopConsumers(); |
|
|
super.stopConsumers(); |
|
|
eventConsumer.stop(); |
|
|
stateService.stop(); // eventConsumer will be stopped by stateService
|
|
|
eventConsumer.awaitStop(); |
|
|
|
|
|
stateService.stop(); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|