Support for job manager on Rule Engine
This commit is contained in:
parent
325c71f2ab
commit
5e46608abc
@ -31,6 +31,7 @@ import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.rule.engine.api.DeviceStateManager;
|
||||
import org.thingsboard.rule.engine.api.JobManager;
|
||||
import org.thingsboard.rule.engine.api.MailService;
|
||||
import org.thingsboard.rule.engine.api.MqttClientSettings;
|
||||
import org.thingsboard.rule.engine.api.NotificationCenter;
|
||||
@ -553,11 +554,14 @@ public class ActorSystemContext {
|
||||
@Getter
|
||||
private CalculatedFieldQueueService calculatedFieldQueueService;
|
||||
|
||||
@Lazy
|
||||
@Autowired(required = false)
|
||||
@Autowired
|
||||
@Getter
|
||||
private JobService jobService;
|
||||
|
||||
@Autowired
|
||||
@Getter
|
||||
private JobManager jobManager;
|
||||
|
||||
@Value("${actors.session.max_concurrent_sessions_per_device:1}")
|
||||
@Getter
|
||||
private int maxConcurrentSessionsPerDevice;
|
||||
|
||||
@ -24,6 +24,7 @@ import org.thingsboard.common.util.DebugModeUtil;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.common.util.ListeningExecutor;
|
||||
import org.thingsboard.rule.engine.api.DeviceStateManager;
|
||||
import org.thingsboard.rule.engine.api.JobManager;
|
||||
import org.thingsboard.rule.engine.api.MailService;
|
||||
import org.thingsboard.rule.engine.api.MqttClientSettings;
|
||||
import org.thingsboard.rule.engine.api.NotificationCenter;
|
||||
@ -93,6 +94,7 @@ import org.thingsboard.server.dao.edge.EdgeService;
|
||||
import org.thingsboard.server.dao.entity.EntityService;
|
||||
import org.thingsboard.server.dao.entityview.EntityViewService;
|
||||
import org.thingsboard.server.dao.event.EventService;
|
||||
import org.thingsboard.server.dao.job.JobService;
|
||||
import org.thingsboard.server.dao.mobile.MobileAppBundleService;
|
||||
import org.thingsboard.server.dao.mobile.MobileAppService;
|
||||
import org.thingsboard.server.dao.nosql.CassandraStatementTask;
|
||||
@ -108,7 +110,6 @@ import org.thingsboard.server.dao.queue.QueueStatsService;
|
||||
import org.thingsboard.server.dao.relation.RelationService;
|
||||
import org.thingsboard.server.dao.resource.ResourceService;
|
||||
import org.thingsboard.server.dao.rule.RuleChainService;
|
||||
import org.thingsboard.server.dao.job.JobService;
|
||||
import org.thingsboard.server.dao.tenant.TenantService;
|
||||
import org.thingsboard.server.dao.timeseries.TimeseriesService;
|
||||
import org.thingsboard.server.dao.user.UserService;
|
||||
@ -895,6 +896,11 @@ public class DefaultTbContext implements TbContext {
|
||||
return mainCtx.getJobService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JobManager getJobManager() {
|
||||
return mainCtx.getJobManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExternalNodeForceAck() {
|
||||
return mainCtx.isExternalNodeForceAck();
|
||||
|
||||
@ -36,7 +36,7 @@ import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.dao.job.JobService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.job.JobManager;
|
||||
import org.thingsboard.rule.engine.api.JobManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -59,9 +59,8 @@ import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
|
||||
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
|
||||
import org.thingsboard.server.dao.tenant.TenantService;
|
||||
import org.thingsboard.server.queue.TbQueueCallback;
|
||||
import org.thingsboard.server.service.job.JobManager;
|
||||
import org.thingsboard.rule.engine.api.JobManager;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@Slf4j
|
||||
@ -72,7 +71,7 @@ public class EntityStateSourcingListener {
|
||||
private final TenantService tenantService;
|
||||
private final TbClusterService tbClusterService;
|
||||
private final EdgeSynchronizationManager edgeSynchronizationManager;
|
||||
private final Optional<JobManager> jobManager;
|
||||
private final JobManager jobManager;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
@ -303,7 +302,7 @@ public class EntityStateSourcingListener {
|
||||
}
|
||||
|
||||
private void onJobUpdate(Job job) {
|
||||
jobManager.ifPresent(jobManager -> jobManager.onJobUpdate(job));
|
||||
jobManager.onJobUpdate(job);
|
||||
|
||||
ComponentLifecycleEvent event;
|
||||
if (job.getResult().getCancellationTs() > 0) {
|
||||
|
||||
@ -16,20 +16,18 @@
|
||||
package org.thingsboard.server.service.job;
|
||||
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.common.util.ThingsBoardExecutors;
|
||||
import org.thingsboard.common.util.ThingsBoardThreadFactory;
|
||||
import org.thingsboard.rule.engine.api.JobManager;
|
||||
import org.thingsboard.rule.engine.api.NotificationCenter;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.JobId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.job.Job;
|
||||
import org.thingsboard.server.common.data.job.JobResult;
|
||||
import org.thingsboard.server.common.data.job.JobStats;
|
||||
import org.thingsboard.server.common.data.job.JobStatus;
|
||||
import org.thingsboard.server.common.data.job.JobType;
|
||||
import org.thingsboard.server.common.data.job.task.Task;
|
||||
@ -41,28 +39,22 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
|
||||
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
|
||||
import org.thingsboard.server.dao.job.JobService;
|
||||
import org.thingsboard.server.dao.notification.DefaultNotifications;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.JobStatsMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.TaskProto;
|
||||
import org.thingsboard.server.queue.TbQueueCallback;
|
||||
import org.thingsboard.server.queue.TbQueueConsumer;
|
||||
import org.thingsboard.server.queue.TbQueueMsgMetadata;
|
||||
import org.thingsboard.server.queue.TbQueueProducer;
|
||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||
import org.thingsboard.server.queue.common.consumer.QueueConsumerManager;
|
||||
import org.thingsboard.server.queue.discovery.PartitionService;
|
||||
import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
|
||||
import org.thingsboard.server.queue.settings.TasksQueueConfig;
|
||||
import org.thingsboard.server.queue.task.JobStatsService;
|
||||
import org.thingsboard.server.queue.util.AfterStartUp;
|
||||
import org.thingsboard.server.queue.task.TaskProducerQueueFactory;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -78,12 +70,10 @@ public class DefaultJobManager implements JobManager {
|
||||
private final TasksQueueConfig queueConfig;
|
||||
private final Map<JobType, JobProcessor> jobProcessors;
|
||||
private final Map<JobType, TbQueueProducer<TbProtoQueueMsg<TaskProto>>> taskProducers;
|
||||
private final QueueConsumerManager<TbProtoQueueMsg<JobStatsMsg>> jobStatsConsumer;
|
||||
private final ExecutorService executor;
|
||||
private final ExecutorService consumerExecutor;
|
||||
|
||||
public DefaultJobManager(JobService jobService, JobStatsService jobStatsService, NotificationCenter notificationCenter,
|
||||
PartitionService partitionService, TbCoreQueueFactory queueFactory, TasksQueueConfig queueConfig,
|
||||
PartitionService partitionService, TaskProducerQueueFactory queueFactory, TasksQueueConfig queueConfig,
|
||||
List<JobProcessor> jobProcessors) {
|
||||
this.jobService = jobService;
|
||||
this.jobStatsService = jobStatsService;
|
||||
@ -93,20 +83,6 @@ public class DefaultJobManager implements JobManager {
|
||||
this.jobProcessors = jobProcessors.stream().collect(Collectors.toMap(JobProcessor::getType, Function.identity()));
|
||||
this.taskProducers = Arrays.stream(JobType.values()).collect(Collectors.toMap(Function.identity(), queueFactory::createTaskProducer));
|
||||
this.executor = ThingsBoardExecutors.newWorkStealingPool(Math.max(4, Runtime.getRuntime().availableProcessors()), getClass());
|
||||
this.consumerExecutor = Executors.newCachedThreadPool(ThingsBoardThreadFactory.forName("job-stats-consumer"));
|
||||
this.jobStatsConsumer = QueueConsumerManager.<TbProtoQueueMsg<JobStatsMsg>>builder()
|
||||
.name("job-stats")
|
||||
.msgPackProcessor(this::processStats)
|
||||
.pollInterval(queueConfig.getStatsPollInterval())
|
||||
.consumerCreator(queueFactory::createJobStatsConsumer)
|
||||
.consumerExecutor(consumerExecutor)
|
||||
.build();
|
||||
}
|
||||
|
||||
@AfterStartUp(order = AfterStartUp.REGULAR_SERVICE)
|
||||
public void afterStartUp() {
|
||||
jobStatsConsumer.subscribe();
|
||||
jobStatsConsumer.launch();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -229,39 +205,6 @@ public class DefaultJobManager implements JobManager {
|
||||
});
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void processStats(List<TbProtoQueueMsg<JobStatsMsg>> msgs, TbQueueConsumer<TbProtoQueueMsg<JobStatsMsg>> consumer) {
|
||||
Map<JobId, JobStats> stats = new HashMap<>();
|
||||
|
||||
for (TbProtoQueueMsg<JobStatsMsg> msg : msgs) {
|
||||
JobStatsMsg statsMsg = msg.getValue();
|
||||
TenantId tenantId = TenantId.fromUUID(new UUID(statsMsg.getTenantIdMSB(), statsMsg.getTenantIdLSB()));
|
||||
JobId jobId = new JobId(new UUID(statsMsg.getJobIdMSB(), statsMsg.getJobIdLSB()));
|
||||
JobStats jobStats = stats.computeIfAbsent(jobId, __ -> new JobStats(tenantId, jobId));
|
||||
|
||||
if (statsMsg.hasTaskResult()) {
|
||||
TaskResult taskResult = JacksonUtil.fromString(statsMsg.getTaskResult().getValue(), TaskResult.class);
|
||||
jobStats.getTaskResults().add(taskResult);
|
||||
}
|
||||
if (statsMsg.hasTotalTasksCount()) {
|
||||
jobStats.setTotalTasksCount(statsMsg.getTotalTasksCount());
|
||||
}
|
||||
}
|
||||
|
||||
stats.forEach((jobId, jobStats) -> {
|
||||
TenantId tenantId = jobStats.getTenantId();
|
||||
try {
|
||||
log.debug("[{}][{}] Processing job stats: {}", tenantId, jobId, stats);
|
||||
jobService.processStats(tenantId, jobId, jobStats);
|
||||
} catch (Exception e) {
|
||||
log.error("[{}][{}] Failed to process job stats: {}", tenantId, jobId, jobStats, e);
|
||||
}
|
||||
});
|
||||
consumer.commit();
|
||||
|
||||
Thread.sleep(queueConfig.getStatsProcessingInterval());
|
||||
}
|
||||
|
||||
private void sendJobFinishedNotification(Job job) {
|
||||
NotificationTemplate template = DefaultNotifications.DefaultNotification.builder()
|
||||
.name("Job finished")
|
||||
@ -284,9 +227,7 @@ public class DefaultJobManager implements JobManager {
|
||||
|
||||
@PreDestroy
|
||||
private void destroy() {
|
||||
jobStatsConsumer.stop();
|
||||
executor.shutdownNow();
|
||||
consumerExecutor.shutdownNow();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,115 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.job;
|
||||
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.common.util.ThingsBoardThreadFactory;
|
||||
import org.thingsboard.server.common.data.id.JobId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.job.JobStats;
|
||||
import org.thingsboard.server.common.data.job.task.TaskResult;
|
||||
import org.thingsboard.server.dao.job.JobService;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.JobStatsMsg;
|
||||
import org.thingsboard.server.queue.TbQueueConsumer;
|
||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||
import org.thingsboard.server.queue.common.consumer.QueueConsumerManager;
|
||||
import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
|
||||
import org.thingsboard.server.queue.settings.TasksQueueConfig;
|
||||
import org.thingsboard.server.queue.util.AfterStartUp;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@TbCoreComponent
|
||||
@Component
|
||||
@Slf4j
|
||||
public class JobStatsProcessor {
|
||||
|
||||
private final JobService jobService;
|
||||
private final TasksQueueConfig queueConfig;
|
||||
private final QueueConsumerManager<TbProtoQueueMsg<JobStatsMsg>> jobStatsConsumer;
|
||||
private final ExecutorService consumerExecutor;
|
||||
|
||||
public JobStatsProcessor(JobService jobService,
|
||||
TasksQueueConfig queueConfig,
|
||||
TbCoreQueueFactory queueFactory) {
|
||||
this.jobService = jobService;
|
||||
this.queueConfig = queueConfig;
|
||||
this.consumerExecutor = Executors.newCachedThreadPool(ThingsBoardThreadFactory.forName("job-stats-consumer"));
|
||||
this.jobStatsConsumer = QueueConsumerManager.<TbProtoQueueMsg<JobStatsMsg>>builder()
|
||||
.name("job-stats")
|
||||
.msgPackProcessor(this::processStats)
|
||||
.pollInterval(queueConfig.getStatsPollInterval())
|
||||
.consumerCreator(queueFactory::createJobStatsConsumer)
|
||||
.consumerExecutor(consumerExecutor)
|
||||
.build();
|
||||
}
|
||||
|
||||
@AfterStartUp(order = AfterStartUp.REGULAR_SERVICE)
|
||||
public void afterStartUp() {
|
||||
jobStatsConsumer.subscribe();
|
||||
jobStatsConsumer.launch();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void processStats(List<TbProtoQueueMsg<JobStatsMsg>> msgs, TbQueueConsumer<TbProtoQueueMsg<JobStatsMsg>> consumer) {
|
||||
Map<JobId, JobStats> stats = new HashMap<>();
|
||||
|
||||
for (TbProtoQueueMsg<JobStatsMsg> msg : msgs) {
|
||||
JobStatsMsg statsMsg = msg.getValue();
|
||||
TenantId tenantId = TenantId.fromUUID(new UUID(statsMsg.getTenantIdMSB(), statsMsg.getTenantIdLSB()));
|
||||
JobId jobId = new JobId(new UUID(statsMsg.getJobIdMSB(), statsMsg.getJobIdLSB()));
|
||||
JobStats jobStats = stats.computeIfAbsent(jobId, __ -> new JobStats(tenantId, jobId));
|
||||
|
||||
if (statsMsg.hasTaskResult()) {
|
||||
TaskResult taskResult = JacksonUtil.fromString(statsMsg.getTaskResult().getValue(), TaskResult.class);
|
||||
jobStats.getTaskResults().add(taskResult);
|
||||
}
|
||||
if (statsMsg.hasTotalTasksCount()) {
|
||||
jobStats.setTotalTasksCount(statsMsg.getTotalTasksCount());
|
||||
}
|
||||
}
|
||||
|
||||
stats.forEach((jobId, jobStats) -> {
|
||||
TenantId tenantId = jobStats.getTenantId();
|
||||
try {
|
||||
log.debug("[{}][{}] Processing job stats: {}", tenantId, jobId, stats);
|
||||
jobService.processStats(tenantId, jobId, jobStats);
|
||||
} catch (Exception e) {
|
||||
log.error("[{}][{}] Failed to process job stats: {}", tenantId, jobId, jobStats, e);
|
||||
}
|
||||
});
|
||||
consumer.commit();
|
||||
|
||||
Thread.sleep(queueConfig.getStatsProcessingInterval());
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
private void destroy() {
|
||||
jobStatsConsumer.stop();
|
||||
consumerExecutor.shutdownNow();
|
||||
}
|
||||
|
||||
}
|
||||
@ -23,6 +23,7 @@ import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.thingsboard.rule.engine.api.JobManager;
|
||||
import org.thingsboard.server.common.data.id.JobId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.job.DummyJobConfiguration;
|
||||
|
||||
@ -20,7 +20,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.job.JobType;
|
||||
import org.thingsboard.server.common.data.queue.Queue;
|
||||
import org.thingsboard.server.common.msg.queue.ServiceType;
|
||||
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
|
||||
@ -262,11 +261,6 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TbQueueProducer<TbProtoQueueMsg<TransportProtos.TaskProto>> createTaskProducer(JobType jobType) {
|
||||
return new InMemoryTbQueueProducer<>(storage, jobType.getTasksTopic());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TbQueueConsumer<TbProtoQueueMsg<JobStatsMsg>> createJobStatsConsumer() {
|
||||
return new InMemoryTbQueueConsumer<>(storage, tasksQueueConfig.getStatsTopic());
|
||||
|
||||
@ -23,7 +23,6 @@ import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.DataConstants;
|
||||
import org.thingsboard.server.common.data.id.EdgeId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.job.JobType;
|
||||
import org.thingsboard.server.common.data.queue.Queue;
|
||||
import org.thingsboard.server.common.msg.queue.ServiceType;
|
||||
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
|
||||
@ -31,7 +30,6 @@ import org.thingsboard.server.gen.js.JsInvokeProtos;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldStateProto;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.FromEdqsMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.JobStatsMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.TaskProto;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldNotificationMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
|
||||
@ -650,16 +648,6 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TbQueueProducer<TbProtoQueueMsg<TaskProto>> createTaskProducer(JobType jobType) {
|
||||
return TbKafkaProducerTemplate.<TbProtoQueueMsg<TaskProto>>builder()
|
||||
.clientId(jobType.name().toLowerCase() + "-task-producer-" + serviceInfoProvider.getServiceId())
|
||||
.defaultTopic(topicService.buildTopicName(jobType.getTasksTopic()))
|
||||
.settings(kafkaSettings)
|
||||
.admin(tasksAdmin)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TbQueueConsumer<TbProtoQueueMsg<JobStatsMsg>> createJobStatsConsumer() {
|
||||
return TbKafkaConsumerTemplate.<TbProtoQueueMsg<JobStatsMsg>>builder()
|
||||
|
||||
@ -22,12 +22,10 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.id.EdgeId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.job.JobType;
|
||||
import org.thingsboard.server.common.msg.queue.ServiceType;
|
||||
import org.thingsboard.server.gen.js.JsInvokeProtos;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.FromEdqsMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.JobStatsMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.TaskProto;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldNotificationMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
|
||||
@ -529,16 +527,6 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory {
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TbQueueProducer<TbProtoQueueMsg<TaskProto>> createTaskProducer(JobType jobType) {
|
||||
return TbKafkaProducerTemplate.<TbProtoQueueMsg<TaskProto>>builder()
|
||||
.clientId(jobType.name().toLowerCase() + "-task-producer-" + serviceInfoProvider.getServiceId())
|
||||
.defaultTopic(topicService.buildTopicName(jobType.getTasksTopic()))
|
||||
.settings(kafkaSettings)
|
||||
.admin(tasksAdmin)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TbQueueConsumer<TbProtoQueueMsg<JobStatsMsg>> createJobStatsConsumer() {
|
||||
return TbKafkaConsumerTemplate.<TbProtoQueueMsg<JobStatsMsg>>builder()
|
||||
|
||||
@ -17,10 +17,8 @@ package org.thingsboard.server.queue.provider;
|
||||
|
||||
import org.thingsboard.server.common.data.id.EdgeId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.job.JobType;
|
||||
import org.thingsboard.server.gen.js.JsInvokeProtos;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.JobStatsMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.TaskProto;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldNotificationMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
|
||||
@ -168,8 +166,6 @@ public interface TbCoreQueueFactory extends TbUsageStatsClientQueueFactory, Hous
|
||||
|
||||
TbQueueProducer<TbProtoQueueMsg<ToCalculatedFieldNotificationMsg>> createToCalculatedFieldNotificationMsgProducer();
|
||||
|
||||
TbQueueProducer<TbProtoQueueMsg<TaskProto>> createTaskProducer(JobType jobType);
|
||||
|
||||
TbQueueConsumer<TbProtoQueueMsg<JobStatsMsg>> createJobStatsConsumer();
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.queue.task;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.job.JobType;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.TaskProto;
|
||||
import org.thingsboard.server.queue.TbQueueProducer;
|
||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||
import org.thingsboard.server.queue.memory.InMemoryStorage;
|
||||
import org.thingsboard.server.queue.memory.InMemoryTbQueueProducer;
|
||||
|
||||
@Component
|
||||
@ConditionalOnExpression("'${queue.type:null}' == 'in-memory'")
|
||||
@RequiredArgsConstructor
|
||||
public class InMemoryTaskProducerQueueFactory implements TaskProducerQueueFactory {
|
||||
|
||||
private final InMemoryStorage storage;
|
||||
|
||||
@Override
|
||||
public TbQueueProducer<TbProtoQueueMsg<TaskProto>> createTaskProducer(JobType jobType) {
|
||||
return new InMemoryTbQueueProducer<>(storage, jobType.getTasksTopic());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.queue.task;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.job.JobType;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.TaskProto;
|
||||
import org.thingsboard.server.queue.TbQueueAdmin;
|
||||
import org.thingsboard.server.queue.TbQueueProducer;
|
||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
|
||||
import org.thingsboard.server.queue.discovery.TopicService;
|
||||
import org.thingsboard.server.queue.kafka.TbKafkaAdmin;
|
||||
import org.thingsboard.server.queue.kafka.TbKafkaProducerTemplate;
|
||||
import org.thingsboard.server.queue.kafka.TbKafkaSettings;
|
||||
import org.thingsboard.server.queue.kafka.TbKafkaTopicConfigs;
|
||||
|
||||
@Component
|
||||
@ConditionalOnExpression("'${queue.type:null}' == 'kafka' && ('${service.type:null}' == 'monolith' || " +
|
||||
"'${service.type:null}' == 'tb-core' || '${service.type:null}' == 'tb-rule-engine')")
|
||||
public class KafkaTaskProducerQueueFactory implements TaskProducerQueueFactory {
|
||||
|
||||
private final TopicService topicService;
|
||||
private final TbServiceInfoProvider serviceInfoProvider;
|
||||
private final TbKafkaSettings kafkaSettings;
|
||||
private final TbQueueAdmin tasksAdmin;
|
||||
|
||||
KafkaTaskProducerQueueFactory(TopicService topicService,
|
||||
TbServiceInfoProvider serviceInfoProvider,
|
||||
TbKafkaSettings kafkaSettings,
|
||||
TbKafkaTopicConfigs kafkaTopicConfigs) {
|
||||
this.topicService = topicService;
|
||||
this.kafkaSettings = kafkaSettings;
|
||||
this.serviceInfoProvider = serviceInfoProvider;
|
||||
this.tasksAdmin = new TbKafkaAdmin(kafkaSettings, kafkaTopicConfigs.getTasksConfigs());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TbQueueProducer<TbProtoQueueMsg<TaskProto>> createTaskProducer(JobType jobType) {
|
||||
return TbKafkaProducerTemplate.<TbProtoQueueMsg<TaskProto>>builder()
|
||||
.clientId(jobType.name().toLowerCase() + "-task-producer-" + serviceInfoProvider.getServiceId())
|
||||
.defaultTopic(topicService.buildTopicName(jobType.getTasksTopic()))
|
||||
.settings(kafkaSettings)
|
||||
.admin(tasksAdmin)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.queue.task;
|
||||
|
||||
import org.thingsboard.server.common.data.job.JobType;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.TaskProto;
|
||||
import org.thingsboard.server.queue.TbQueueProducer;
|
||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||
|
||||
public interface TaskProducerQueueFactory {
|
||||
|
||||
TbQueueProducer<TbProtoQueueMsg<TaskProto>> createTaskProducer(JobType jobType);
|
||||
|
||||
}
|
||||
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.service.job;
|
||||
package org.thingsboard.rule.engine.api;
|
||||
|
||||
import org.thingsboard.server.common.data.id.JobId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
@ -62,6 +62,7 @@ import org.thingsboard.server.dao.edge.EdgeService;
|
||||
import org.thingsboard.server.dao.entity.EntityService;
|
||||
import org.thingsboard.server.dao.entityview.EntityViewService;
|
||||
import org.thingsboard.server.dao.event.EventService;
|
||||
import org.thingsboard.server.dao.job.JobService;
|
||||
import org.thingsboard.server.dao.mobile.MobileAppBundleService;
|
||||
import org.thingsboard.server.dao.mobile.MobileAppService;
|
||||
import org.thingsboard.server.dao.nosql.CassandraStatementTask;
|
||||
@ -77,7 +78,6 @@ import org.thingsboard.server.dao.queue.QueueStatsService;
|
||||
import org.thingsboard.server.dao.relation.RelationService;
|
||||
import org.thingsboard.server.dao.resource.ResourceService;
|
||||
import org.thingsboard.server.dao.rule.RuleChainService;
|
||||
import org.thingsboard.server.dao.job.JobService;
|
||||
import org.thingsboard.server.dao.tenant.TenantService;
|
||||
import org.thingsboard.server.dao.timeseries.TimeseriesService;
|
||||
import org.thingsboard.server.dao.user.UserService;
|
||||
@ -365,6 +365,8 @@ public interface TbContext {
|
||||
|
||||
JobService getJobService();
|
||||
|
||||
JobManager getJobManager();
|
||||
|
||||
boolean isExternalNodeForceAck();
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user