Add entity name for jobs
This commit is contained in:
parent
2bb6eab0ed
commit
43176d37fc
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.service.job;
|
package org.thingsboard.server.service.job;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.Futures;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import jakarta.annotation.PreDestroy;
|
import jakarta.annotation.PreDestroy;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
@ -49,7 +51,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -78,9 +79,9 @@ public class DefaultJobManager implements JobManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<Job> submitJob(Job job) {
|
public ListenableFuture<Job> submitJob(Job job) {
|
||||||
log.debug("Submitting job: {}", job);
|
log.debug("Submitting job: {}", job);
|
||||||
return executor.submit(() -> jobService.saveJob(job.getTenantId(), job));
|
return Futures.submit(() -> jobService.saveJob(job.getTenantId(), job), executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -248,6 +248,8 @@ public class JobManagerTest extends AbstractControllerTest {
|
|||||||
assertThat(job.getStatus()).isEqualTo(JobStatus.COMPLETED);
|
assertThat(job.getStatus()).isEqualTo(JobStatus.COMPLETED);
|
||||||
assertThat(job.getResult().getSuccessfulCount()).isEqualTo(tasksCount);
|
assertThat(job.getResult().getSuccessfulCount()).isEqualTo(tasksCount);
|
||||||
assertThat(job.getResult().getTotalCount()).isEqualTo(tasksCount);
|
assertThat(job.getResult().getTotalCount()).isEqualTo(tasksCount);
|
||||||
|
assertThat(job.getEntityId()).isEqualTo(jobEntity.getId());
|
||||||
|
assertThat(job.getEntityName()).isEqualTo(jobEntity.getName());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.dao.entity;
|
package org.thingsboard.server.dao.entity;
|
||||||
|
|
||||||
|
import org.thingsboard.server.common.data.EntityInfo;
|
||||||
import org.thingsboard.server.common.data.id.CustomerId;
|
import org.thingsboard.server.common.data.id.CustomerId;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.HasId;
|
import org.thingsboard.server.common.data.id.HasId;
|
||||||
@ -25,7 +26,9 @@ import org.thingsboard.server.common.data.query.EntityCountQuery;
|
|||||||
import org.thingsboard.server.common.data.query.EntityData;
|
import org.thingsboard.server.common.data.query.EntityData;
|
||||||
import org.thingsboard.server.common.data.query.EntityDataQuery;
|
import org.thingsboard.server.common.data.query.EntityDataQuery;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public interface EntityService {
|
public interface EntityService {
|
||||||
|
|
||||||
@ -37,6 +40,8 @@ public interface EntityService {
|
|||||||
|
|
||||||
Optional<HasId<?>> fetchEntity(TenantId tenantId, EntityId entityId);
|
Optional<HasId<?>> fetchEntity(TenantId tenantId, EntityId entityId);
|
||||||
|
|
||||||
|
Map<EntityId, EntityInfo> fetchEntityInfos(TenantId tenantId, CustomerId customerId, Set<EntityId> entityIds);
|
||||||
|
|
||||||
Optional<NameLabelAndCustomerDetails> fetchNameLabelAndCustomerDetails(TenantId tenantId, EntityId entityId);
|
Optional<NameLabelAndCustomerDetails> fetchNameLabelAndCustomerDetails(TenantId tenantId, EntityId entityId);
|
||||||
|
|
||||||
long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query);
|
long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query);
|
||||||
|
|||||||
@ -47,6 +47,7 @@ public class Job extends BaseData<JobId> implements HasTenantId {
|
|||||||
private String key;
|
private String key;
|
||||||
@NotNull
|
@NotNull
|
||||||
private EntityId entityId;
|
private EntityId entityId;
|
||||||
|
private String entityName; // read-only
|
||||||
@NotNull
|
@NotNull
|
||||||
private JobStatus status;
|
private JobStatus status;
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.thingsboard.server.common.data.EntityInfo;
|
||||||
import org.thingsboard.server.common.data.EntityType;
|
import org.thingsboard.server.common.data.EntityType;
|
||||||
import org.thingsboard.server.common.data.HasCustomerId;
|
import org.thingsboard.server.common.data.HasCustomerId;
|
||||||
import org.thingsboard.server.common.data.HasEmail;
|
import org.thingsboard.server.common.data.HasEmail;
|
||||||
@ -41,19 +42,24 @@ import org.thingsboard.server.common.data.query.EntityDataPageLink;
|
|||||||
import org.thingsboard.server.common.data.query.EntityDataQuery;
|
import org.thingsboard.server.common.data.query.EntityDataQuery;
|
||||||
import org.thingsboard.server.common.data.query.EntityFilterType;
|
import org.thingsboard.server.common.data.query.EntityFilterType;
|
||||||
import org.thingsboard.server.common.data.query.EntityKey;
|
import org.thingsboard.server.common.data.query.EntityKey;
|
||||||
|
import org.thingsboard.server.common.data.query.EntityKeyType;
|
||||||
import org.thingsboard.server.common.data.query.EntityListFilter;
|
import org.thingsboard.server.common.data.query.EntityListFilter;
|
||||||
import org.thingsboard.server.common.data.query.EntityNameFilter;
|
import org.thingsboard.server.common.data.query.EntityNameFilter;
|
||||||
import org.thingsboard.server.common.data.query.EntityTypeFilter;
|
import org.thingsboard.server.common.data.query.EntityTypeFilter;
|
||||||
import org.thingsboard.server.common.data.query.KeyFilter;
|
import org.thingsboard.server.common.data.query.KeyFilter;
|
||||||
import org.thingsboard.server.common.data.query.RelationsQueryFilter;
|
import org.thingsboard.server.common.data.query.RelationsQueryFilter;
|
||||||
|
import org.thingsboard.server.common.data.query.TsValue;
|
||||||
import org.thingsboard.server.common.msg.edqs.EdqsApiService;
|
import org.thingsboard.server.common.msg.edqs.EdqsApiService;
|
||||||
import org.thingsboard.server.common.stats.EdqsStatsService;
|
import org.thingsboard.server.common.stats.EdqsStatsService;
|
||||||
import org.thingsboard.server.dao.exception.IncorrectParameterException;
|
import org.thingsboard.server.dao.exception.IncorrectParameterException;
|
||||||
|
import org.thingsboard.server.dao.model.ModelConstants;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
@ -199,6 +205,30 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
|
|||||||
return fetchAndConvert(tenantId, entityId, Function.identity());
|
return fetchAndConvert(tenantId, entityId, Function.identity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<EntityId, EntityInfo> fetchEntityInfos(TenantId tenantId, CustomerId customerId, Set<EntityId> entityIds) {
|
||||||
|
Map<EntityId, EntityInfo> infos = new HashMap<>();
|
||||||
|
entityIds.stream()
|
||||||
|
.collect(Collectors.groupingBy(EntityId::getEntityType))
|
||||||
|
.forEach((entityType, ids) -> {
|
||||||
|
EntityListFilter filter = new EntityListFilter();
|
||||||
|
filter.setEntityType(entityType);
|
||||||
|
filter.setEntityList(ids.stream().map(Object::toString).toList());
|
||||||
|
EntityDataQuery query = new EntityDataQuery(filter, new EntityDataPageLink(ids.size(), 0, null, null),
|
||||||
|
List.of(new EntityKey(EntityKeyType.ENTITY_FIELD, ModelConstants.NAME_PROPERTY)), Collections.emptyList(), Collections.emptyList());
|
||||||
|
|
||||||
|
entityQueryDao.findEntityDataByQuery(tenantId, customerId, query).getData().forEach(entityData -> {
|
||||||
|
EntityId entityId = entityData.getEntityId();
|
||||||
|
Optional.ofNullable(entityData.getLatest().get(EntityKeyType.ENTITY_FIELD))
|
||||||
|
.map(fields -> fields.get(ModelConstants.NAME_PROPERTY))
|
||||||
|
.map(TsValue::getValue).ifPresent(name -> {
|
||||||
|
infos.put(entityId, new EntityInfo(entityId, name));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return infos;
|
||||||
|
}
|
||||||
|
|
||||||
private <T> Optional<T> fetchAndConvert(TenantId tenantId, EntityId entityId, Function<HasId<?>, T> converter) {
|
private <T> Optional<T> fetchAndConvert(TenantId tenantId, EntityId entityId, Function<HasId<?>, T> converter) {
|
||||||
EntityDaoService entityDaoService = entityServiceRegistry.getServiceByEntityType(entityId.getEntityType());
|
EntityDaoService entityDaoService = entityServiceRegistry.getServiceByEntityType(entityId.getEntityType());
|
||||||
Optional<HasId<?>> entityOpt = entityDaoService.findEntity(tenantId, entityId);
|
Optional<HasId<?>> entityOpt = entityDaoService.findEntity(tenantId, entityId);
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.springframework.data.domain.Limit;
|
import org.springframework.data.domain.Limit;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.thingsboard.server.common.data.EntityInfo;
|
||||||
import org.thingsboard.server.common.data.EntityType;
|
import org.thingsboard.server.common.data.EntityType;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.JobId;
|
import org.thingsboard.server.common.data.id.JobId;
|
||||||
@ -32,13 +33,17 @@ import org.thingsboard.server.common.data.page.PageData;
|
|||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.util.CollectionsUtil;
|
import org.thingsboard.server.common.data.util.CollectionsUtil;
|
||||||
import org.thingsboard.server.dao.DaoUtil;
|
import org.thingsboard.server.dao.DaoUtil;
|
||||||
|
import org.thingsboard.server.dao.entity.EntityService;
|
||||||
import org.thingsboard.server.dao.job.JobDao;
|
import org.thingsboard.server.dao.job.JobDao;
|
||||||
import org.thingsboard.server.dao.model.sql.JobEntity;
|
import org.thingsboard.server.dao.model.sql.JobEntity;
|
||||||
import org.thingsboard.server.dao.sql.JpaAbstractDao;
|
import org.thingsboard.server.dao.sql.JpaAbstractDao;
|
||||||
import org.thingsboard.server.dao.util.SqlDao;
|
import org.thingsboard.server.dao.util.SqlDao;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@SqlDao
|
@SqlDao
|
||||||
@ -46,16 +51,29 @@ import java.util.UUID;
|
|||||||
public class JpaJobDao extends JpaAbstractDao<JobEntity, Job> implements JobDao {
|
public class JpaJobDao extends JpaAbstractDao<JobEntity, Job> implements JobDao {
|
||||||
|
|
||||||
private final JobRepository jobRepository;
|
private final JobRepository jobRepository;
|
||||||
|
private final EntityService entityService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageData<Job> findByTenantIdAndFilter(TenantId tenantId, JobFilter filter, PageLink pageLink) {
|
public PageData<Job> findByTenantIdAndFilter(TenantId tenantId, JobFilter filter, PageLink pageLink) {
|
||||||
return DaoUtil.toPageData(jobRepository.findByTenantIdAndTypesAndStatusesAndEntitiesAndTimeAndSearchText(tenantId.getId(),
|
PageData<Job> jobs = DaoUtil.toPageData(jobRepository.findByTenantIdAndTypesAndStatusesAndEntitiesAndTimeAndSearchText(tenantId.getId(),
|
||||||
CollectionsUtil.isEmpty(filter.getTypes()) ? null : filter.getTypes(),
|
CollectionsUtil.isEmpty(filter.getTypes()) ? null : filter.getTypes(),
|
||||||
CollectionsUtil.isEmpty(filter.getStatuses()) ? null : filter.getStatuses(),
|
CollectionsUtil.isEmpty(filter.getStatuses()) ? null : filter.getStatuses(),
|
||||||
CollectionsUtil.isEmpty(filter.getEntities()) ? null : filter.getEntities(),
|
CollectionsUtil.isEmpty(filter.getEntities()) ? null : filter.getEntities(),
|
||||||
filter.getStartTime() != null ? filter.getStartTime() : 0,
|
filter.getStartTime() != null ? filter.getStartTime() : 0,
|
||||||
filter.getEndTime() != null ? filter.getEndTime() : 0,
|
filter.getEndTime() != null ? filter.getEndTime() : 0,
|
||||||
Strings.emptyToNull(pageLink.getTextSearch()), DaoUtil.toPageable(pageLink)));
|
Strings.emptyToNull(pageLink.getTextSearch()), DaoUtil.toPageable(pageLink)));
|
||||||
|
|
||||||
|
Set<EntityId> entityIds = jobs.getData().stream()
|
||||||
|
.map(Job::getEntityId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
Map<EntityId, EntityInfo> entityInfos = entityService.fetchEntityInfos(tenantId, null, entityIds);
|
||||||
|
jobs.getData().forEach(job -> {
|
||||||
|
EntityInfo entityInfo = entityInfos.get(job.getEntityId());
|
||||||
|
if (entityInfo != null) {
|
||||||
|
job.setEntityName(entityInfo.getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return jobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -15,15 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.rule.engine.api;
|
package org.thingsboard.rule.engine.api;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import org.thingsboard.server.common.data.id.JobId;
|
import org.thingsboard.server.common.data.id.JobId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.job.Job;
|
import org.thingsboard.server.common.data.job.Job;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
public interface JobManager {
|
public interface JobManager {
|
||||||
|
|
||||||
Future<Job> submitJob(Job job); // TODO: rate limits
|
ListenableFuture<Job> submitJob(Job job); // TODO: rate limits
|
||||||
|
|
||||||
void cancelJob(TenantId tenantId, JobId jobId);
|
void cancelJob(TenantId tenantId, JobId jobId);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user