Browse Source

new entity for queue statistics: added cleanup for tenant, added tests, updated UI

pull/10145/head
dashevchenko 3 years ago
parent
commit
c0f9ef8a6d
  1. 17
      application/src/main/data/json/demo/dashboards/rule_engine_statistics.json
  2. 5
      application/src/main/data/upgrade/3.6.2/schema_update.sql
  3. 13
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  4. 3
      application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java
  5. 1
      application/src/test/java/org/thingsboard/server/controller/BaseQueueControllerTest.java
  6. 47
      application/src/test/java/org/thingsboard/server/controller/EntityQueryControllerTest.java
  7. 4
      common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueStatsService.java
  8. 2
      common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java
  9. 6
      common/data/src/main/java/org/thingsboard/server/common/data/queue/QueueStats.java
  10. 1
      common/proto/src/main/proto/queue.proto
  11. 1
      dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java
  12. 21
      dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueStatsService.java
  13. 4
      dao/src/main/java/org/thingsboard/server/dao/queue/QueueStatsDao.java
  14. 40
      dao/src/main/java/org/thingsboard/server/dao/service/validator/QueueStatsDataValidator.java
  15. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java
  16. 9
      dao/src/main/java/org/thingsboard/server/dao/sql/queue/JpaQueueStatsDao.java
  17. 11
      dao/src/main/java/org/thingsboard/server/dao/sql/queue/QueueStatsRepository.java
  18. 6
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java
  19. 134
      dao/src/test/java/org/thingsboard/server/dao/service/QueueStatsServiceTest.java
  20. 17
      ui-ngx/src/assets/dashboard/api_usage.json

17
application/src/main/data/json/demo/dashboards/rule_engine_statistics.json

@ -105,7 +105,7 @@
"_hash": 0.49891007198715376
}
],
"entityAliasId": "140f23dd-e3a0-ed98-6189-03c49d2d8018"
"entityAliasId": "26f9d890-9611-acd4-1cdb-e0a77fd0e7ba"
}
],
"timewindow": {
@ -228,7 +228,7 @@
"_hash": 0.7255162989552142
}
],
"entityAliasId": "140f23dd-e3a0-ed98-6189-03c49d2d8018"
"entityAliasId": "26f9d890-9611-acd4-1cdb-e0a77fd0e7ba"
}
],
"timewindow": {
@ -341,7 +341,7 @@
"_hash": 0.2679547062508352
}
],
"entityAliasId": "140f23dd-e3a0-ed98-6189-03c49d2d8018"
"entityAliasId": "26f9d890-9611-acd4-1cdb-e0a77fd0e7ba"
}
],
"timewindow": {
@ -463,16 +463,13 @@
}
},
"entityAliases": {
"140f23dd-e3a0-ed98-6189-03c49d2d8018": {
"id": "140f23dd-e3a0-ed98-6189-03c49d2d8018",
"26f9d890-9611-acd4-1cdb-e0a77fd0e7ba": {
"id": "26f9d890-9611-acd4-1cdb-e0a77fd0e7ba",
"alias": "TbServiceQueues",
"filter": {
"type": "assetType",
"type": "entityType",
"resolveMultiple": true,
"assetNameFilter": "",
"assetTypes": [
"TbServiceQueue"
]
"entityType": "QUEUE_STATS"
}
}
},

5
application/src/main/data/upgrade/3.6.2/schema_update.sql

@ -40,9 +40,10 @@ CREATE TABLE IF NOT EXISTS queue_stats (
CONSTRAINT queue_stats_name_unq_key UNIQUE (tenant_id, queue_name, service_id));
INSERT INTO queue_stats
SELECT id, created_time, tenant_id, split_part(name, '_', 1) AS queue_name, split_part(name, '_', 2) AS service_id
SELECT id, created_time, tenant_id, substring(name FROM 1 FOR position('_' IN name) - 1) AS queue_name,
substring(name FROM position('_' IN name) + 1) AS service_id
FROM asset
WHERE type = 'TbServiceQueue';
WHERE type = 'TbServiceQueue' and name LIKE '%\_%';
DELETE FROM asset WHERE type='TbServiceQueue';
DELETE FROM asset_profile WHERE name ='TbServiceQueue';

13
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -78,7 +78,6 @@ import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.HasId;
import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.QueueId;
import org.thingsboard.server.common.data.id.QueueStatsId;
import org.thingsboard.server.common.data.id.RpcId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
@ -97,7 +96,6 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.query.EntityDataSortOrder;
import org.thingsboard.server.common.data.query.EntityKey;
import org.thingsboard.server.common.data.queue.Queue;
import org.thingsboard.server.common.data.queue.QueueStats;
import org.thingsboard.server.common.data.rpc.Rpc;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType;
@ -125,7 +123,6 @@ import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
import org.thingsboard.server.dao.oauth2.OAuth2Service;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
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.rpc.RpcService;
@ -310,9 +307,6 @@ public abstract class BaseController {
@Autowired
protected QueueService queueService;
@Autowired
protected QueueStatsService queueStatsService;
@Autowired
protected EntitiesVersionControlService vcService;
@ -606,9 +600,6 @@ public abstract class BaseController {
case QUEUE:
checkQueueId(new QueueId(entityId.getId()), operation);
return;
case QUEUE_STATS:
checkQueueStatsId(new QueueStatsId(entityId.getId()), operation);
return;
default:
checkEntityId(entityId, entitiesService::findEntityByTenantIdAndId, operation);
}
@ -785,10 +776,6 @@ public abstract class BaseController {
return queue;
}
protected QueueStats checkQueueStatsId(QueueStatsId queueStatsId, Operation operation) throws ThingsboardException {
return checkEntityId(queueStatsId, queueStatsService::findQueueStatsById, operation);
}
protected <I extends EntityId> I emptyId(EntityType entityType) {
return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
}

3
application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java

@ -46,8 +46,7 @@ public enum Resource {
QUEUE(EntityType.QUEUE),
VERSION_CONTROL,
NOTIFICATION(EntityType.NOTIFICATION_TARGET, EntityType.NOTIFICATION_TEMPLATE,
EntityType.NOTIFICATION_REQUEST, EntityType.NOTIFICATION_RULE),
QUEUE_STATS(EntityType.QUEUE_STATS);
EntityType.NOTIFICATION_REQUEST, EntityType.NOTIFICATION_RULE);
private final Set<EntityType> entityTypes;

1
application/src/test/java/org/thingsboard/server/controller/BaseQueueControllerTest.java

@ -179,6 +179,7 @@ public class BaseQueueControllerTest extends AbstractControllerTest {
List<QueueStats> queueStatsList = queueStatsService.findByTenantId(tenantId);
assertThat(queueStatsList).hasSize(1);
QueueStats queueStats = queueStatsList.get(0);
assertThat(queueStats.getQueueName()).isEqualTo(queue.getName());
ArgumentCaptor<Long> ttlCaptor = ArgumentCaptor.forClass(Long.class);
verify(timeseriesDao).save(eq(tenantId), eq(queueStats.getId()), argThat(tsKvEntry -> {

47
application/src/test/java/org/thingsboard/server/controller/EntityQueryControllerTest.java

@ -22,11 +22,13 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.web.servlet.ResultActions;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm;
@ -51,10 +53,13 @@ import org.thingsboard.server.common.data.query.FilterPredicateValue;
import org.thingsboard.server.common.data.query.KeyFilter;
import org.thingsboard.server.common.data.query.NumericFilterPredicate;
import org.thingsboard.server.common.data.query.TsValue;
import org.thingsboard.server.common.data.queue.QueueStats;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.queue.QueueStatsService;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -69,6 +74,9 @@ public class EntityQueryControllerTest extends AbstractControllerTest {
private Tenant savedTenant;
private User tenantAdmin;
@Autowired
private QueueStatsService queueStatsService;
@Before
public void beforeTest() throws Exception {
loginSysAdmin();
@ -593,4 +601,43 @@ public class EntityQueryControllerTest extends AbstractControllerTest {
assertThat(getErrorMessage(result)).contains("Invalid").contains("sort property");
}
@Test
public void testFindQueueStatsEntitiesByQuery() throws Exception {
List<QueueStats> queueStatsList = new ArrayList<>();
for (int i = 0; i < 97; i++) {
QueueStats queueStats = new QueueStats();
queueStats.setQueueName(StringUtils.randomAlphabetic(5));
queueStats.setServiceId(StringUtils.randomAlphabetic(5));
queueStats.setTenantId(savedTenant.getTenantId());
queueStatsList.add(queueStatsService.save(savedTenant.getId(), queueStats));
Thread.sleep(1);
}
EntityTypeFilter entityTypeFilter = new EntityTypeFilter();
entityTypeFilter.setEntityType(EntityType.QUEUE_STATS);
EntityDataSortOrder sortOrder = new EntityDataSortOrder(
new EntityKey(EntityKeyType.ENTITY_FIELD, "queueName"), EntityDataSortOrder.Direction.ASC
);
EntityDataPageLink pageLink = new EntityDataPageLink(10, 0, null, sortOrder);
List<EntityKey> entityFields = Arrays.asList(new EntityKey(EntityKeyType.ENTITY_FIELD, "queueName"),
new EntityKey(EntityKeyType.ENTITY_FIELD, "serviceId"));
EntityDataQuery query = new EntityDataQuery(entityTypeFilter, pageLink, entityFields, null, null);
PageData<EntityData> data =
doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {
});
Assert.assertEquals(97, data.getTotalElements());
Assert.assertEquals(10, data.getTotalPages());
Assert.assertTrue(data.hasNext());
Assert.assertEquals(10, data.getData().size());
EntityCountQuery countQuery = new EntityCountQuery(entityTypeFilter);
Long count = doPostWithResponse("/api/entitiesQuery/count", countQuery, Long.class);
Assert.assertEquals(97, count.longValue());
}
}

4
common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueStatsService.java

@ -28,8 +28,10 @@ public interface QueueStatsService extends EntityDaoService {
QueueStats findQueueStatsById(TenantId tenantId, QueueStatsId queueStatsId);
QueueStats findByTenantIdAndNameAndServiceId(TenantId tenantId, String queueStatsName, String serviceId);
QueueStats findByTenantIdAndNameAndServiceId(TenantId tenantId, String queueName, String serviceId);
List<QueueStats> findByTenantId(TenantId tenantId);
void deleteByTenantId(TenantId tenantId);
}

2
common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java

@ -103,6 +103,8 @@ public class EntityIdFactory {
return new NotificationTemplateId(uuid);
case NOTIFICATION:
return new NotificationId(uuid);
case QUEUE_STATS:
return new QueueStatsId(uuid);
}
throw new IllegalArgumentException("EntityType " + type + " is not supported!");
}

6
common/data/src/main/java/org/thingsboard/server/common/data/queue/QueueStats.java

@ -16,13 +16,15 @@
package org.thingsboard.server.common.data.queue;
import lombok.Data;
import org.thingsboard.server.common.data.BaseDataWithAdditionalInfo;
import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.QueueStatsId;
@EqualsAndHashCode(callSuper = true)
@Data
public class QueueStats extends BaseDataWithAdditionalInfo<QueueStatsId> implements HasTenantId {
public class QueueStats extends BaseData<QueueStatsId> implements HasTenantId {
private TenantId tenantId;
private String queueName;
private String serviceId;

1
common/proto/src/main/proto/queue.proto

@ -54,6 +54,7 @@ enum EntityTypeProto {
NOTIFICATION_REQUEST = 31;
NOTIFICATION = 32;
NOTIFICATION_RULE = 33;
QUEUE_STATS = 34;
}
/**

1
dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java

@ -75,7 +75,6 @@ public class BaseAssetService extends AbstractCachedEntityService<AssetCacheKey,
public static final String INCORRECT_ASSET_PROFILE_ID = "Incorrect assetProfileId ";
public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId ";
public static final String INCORRECT_ASSET_ID = "Incorrect assetId ";
public static final String TB_SERVICE_QUEUE = "TbServiceQueue";
@Autowired
private AssetDao assetDao;

21
dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueStatsService.java

@ -17,7 +17,6 @@ package org.thingsboard.server.dao.queue;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.EntityId;
@ -26,6 +25,7 @@ import org.thingsboard.server.common.data.id.QueueStatsId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.queue.QueueStats;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.service.DataValidator;
import java.util.List;
import java.util.Optional;
@ -37,11 +37,16 @@ import static org.thingsboard.server.dao.service.Validator.validateId;
@RequiredArgsConstructor
public class BaseQueueStatsService extends AbstractEntityService implements QueueStatsService {
@Autowired
private QueueStatsDao queueStatsDao;
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
private final QueueStatsDao queueStatsDao;
private final DataValidator<QueueStats> queueStatsValidator;
@Override
public QueueStats save(TenantId tenantId, QueueStats queueStats) {
log.trace("Executing save [{}]", queueStats);
queueStatsValidator.validate(queueStats, QueueStats::getTenantId);
return queueStatsDao.save(tenantId, queueStats);
}
@ -55,15 +60,23 @@ public class BaseQueueStatsService extends AbstractEntityService implements Queu
@Override
public QueueStats findByTenantIdAndNameAndServiceId(TenantId tenantId, String queueName, String serviceId) {
log.trace("Executing findByTenantIdAndNameAndServiceId, tenantId: [{}], queueName: [{}], serviceId: [{}]", tenantId, queueName, serviceId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return queueStatsDao.findByTenantIdQueueNameAndServiceId(tenantId, queueName, serviceId);
}
@Override
public List<QueueStats> findByTenantId(TenantId tenantId) {
log.trace("Executing findByTenantId, tenantId: [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return queueStatsDao.findByTenantId(tenantId);
}
@Override
public void deleteByTenantId(TenantId tenantId) {
log.trace("Executing deleteDevicesByTenantId, tenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
queueStatsDao.deleteByTenantId(tenantId);
}
@Override
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
@ -72,6 +85,6 @@ public class BaseQueueStatsService extends AbstractEntityService implements Queu
@Override
public EntityType getEntityType() {
return null;
return EntityType.QUEUE_STATS;
}
}

4
dao/src/main/java/org/thingsboard/server/dao/queue/QueueStatsDao.java

@ -23,8 +23,10 @@ import java.util.List;
public interface QueueStatsDao extends Dao<QueueStats> {
QueueStats findByTenantIdQueueNameAndServiceId(TenantId tenantId, String name, String serviceId);
QueueStats findByTenantIdQueueNameAndServiceId(TenantId tenantId, String queueName, String serviceId);
List<QueueStats> findByTenantId(TenantId tenantId);
void deleteByTenantId(TenantId tenantId);
}

40
dao/src/main/java/org/thingsboard/server/dao/service/validator/QueueStatsDataValidator.java

@ -0,0 +1,40 @@
/**
* Copyright © 2016-2024 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.dao.service.validator;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.queue.QueueStats;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DataValidator;
@Component
public class QueueStatsDataValidator extends DataValidator<QueueStats> {
@Override
protected void validateDataImpl(TenantId tenantId, QueueStats queueStats) {
if (queueStats.getTenantId() == null) {
throw new DataValidationException("Tenant id should be specified!.");
}
if (queueStats.getQueueName() == null) {
throw new DataValidationException("Queue name should be specified!.");
}
if (StringUtils.isEmpty(queueStats.getServiceId())) {
throw new DataValidationException("Service id should be specified!.");
}
}
}

5
dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java

@ -73,6 +73,8 @@ public class EntityKeyMapping {
public static final String PHONE = "phone";
public static final String ADDITIONAL_INFO = "additionalInfo";
public static final String RELATED_PARENT_ID = "parentId";
public static final String QUEUE_NAME = "queueName";
public static final String SERVICE_ID = "serviceId";
public static final List<String> typedEntityFields = Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME, TYPE, ADDITIONAL_INFO);
public static final List<String> widgetEntityFields = Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME);
@ -104,6 +106,7 @@ public class EntityKeyMapping {
allowedEntityFieldMap.put(EntityType.API_USAGE_STATE, apiUsageStateEntityFields);
allowedEntityFieldMap.put(EntityType.DEVICE_PROFILE, Set.of(CREATED_TIME, NAME, TYPE));
allowedEntityFieldMap.put(EntityType.ASSET_PROFILE, Set.of(CREATED_TIME, NAME));
allowedEntityFieldMap.put(EntityType.QUEUE_STATS, new HashSet<>(Arrays.asList(CREATED_TIME, QUEUE_NAME, SERVICE_ID)));
entityFieldColumnMap.put(CREATED_TIME, ModelConstants.CREATED_TIME_PROPERTY);
entityFieldColumnMap.put(ENTITY_TYPE, ModelConstants.ENTITY_TYPE_PROPERTY);
@ -124,6 +127,8 @@ public class EntityKeyMapping {
entityFieldColumnMap.put(PHONE, ModelConstants.PHONE_PROPERTY);
entityFieldColumnMap.put(ADDITIONAL_INFO, ModelConstants.ADDITIONAL_INFO_PROPERTY);
entityFieldColumnMap.put(RELATED_PARENT_ID, "parent_id");
entityFieldColumnMap.put(QUEUE_NAME, ModelConstants.QUEUE_STATS_QUEUE_NAME_PROPERTY);
entityFieldColumnMap.put(SERVICE_ID, ModelConstants.QUEUE_STATS_SERVICE_ID_PROPERTY);
Map<String, String> contactBasedAliases = new HashMap<>();
contactBasedAliases.put(NAME, TITLE);

9
dao/src/main/java/org/thingsboard/server/dao/sql/queue/JpaQueueStatsDao.java

@ -49,8 +49,8 @@ public class JpaQueueStatsDao extends JpaAbstractDao<QueueStatsEntity, QueueStat
}
@Override
public QueueStats findByTenantIdQueueNameAndServiceId(TenantId tenantId, String name, String serviceId) {
return DaoUtil.getData(queueStatsRepository.findByTenantIdAndQueueNameAndServiceId(tenantId.getId(), name, serviceId));
public QueueStats findByTenantIdQueueNameAndServiceId(TenantId tenantId, String queueName, String serviceId) {
return DaoUtil.getData(queueStatsRepository.findByTenantIdAndQueueNameAndServiceId(tenantId.getId(), queueName, serviceId));
}
@Override
@ -58,4 +58,9 @@ public class JpaQueueStatsDao extends JpaAbstractDao<QueueStatsEntity, QueueStat
return DaoUtil.convertDataList(queueStatsRepository.findByTenantId(tenantId.getId()));
}
@Override
public void deleteByTenantId(TenantId tenantId) {
queueStatsRepository.deleteByTenantId(tenantId.getId());
}
}

11
dao/src/main/java/org/thingsboard/server/dao/sql/queue/QueueStatsRepository.java

@ -16,6 +16,10 @@
package org.thingsboard.server.dao.sql.queue;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.dao.model.sql.QueueStatsEntity;
import java.util.List;
@ -23,8 +27,13 @@ import java.util.UUID;
public interface QueueStatsRepository extends JpaRepository<QueueStatsEntity, UUID> {
QueueStatsEntity findByTenantIdAndQueueNameAndServiceId(UUID tenantId, String name, String serviceId);
QueueStatsEntity findByTenantIdAndQueueNameAndServiceId(UUID tenantId, String queueName, String serviceId);
List<QueueStatsEntity> findByTenantId(UUID tenantId);
@Transactional
@Modifying
@Query("DELETE FROM QueueStatsEntity t WHERE t.tenantId = :tenantId")
void deleteByTenantId(@Param("tenantId") UUID tenantId);
}

6
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java

@ -49,6 +49,7 @@ import org.thingsboard.server.dao.notification.NotificationTargetService;
import org.thingsboard.server.dao.notification.NotificationTemplateService;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
import org.thingsboard.server.dao.queue.QueueStatsService;
import org.thingsboard.server.dao.resource.ResourceService;
import org.thingsboard.server.dao.rpc.RpcService;
import org.thingsboard.server.dao.rule.RuleChainService;
@ -131,6 +132,10 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
@Autowired
private QueueService queueService;
@Lazy
@Autowired
private QueueStatsService queueStatsService;
@Autowired
private AdminSettingsService adminSettingsService;
@ -247,6 +252,7 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(tenantId).build());
relationService.deleteEntityRelations(tenantId, tenantId);
alarmService.deleteEntityAlarmRecordsByTenantId(tenantId);
queueStatsService.deleteByTenantId(tenantId);
}
@Override

134
dao/src/test/java/org/thingsboard/server/dao/service/QueueStatsServiceTest.java

@ -0,0 +1,134 @@
/**
* Copyright © 2016-2024 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.dao.service;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.queue.QueueStats;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.queue.QueueStatsService;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@DaoSqlTest
public class QueueStatsServiceTest extends AbstractServiceTest {
@Autowired
QueueStatsService queueStatsService;
private TenantId tenantId;
@Before
public void before() throws NoSuchFieldException, IllegalAccessException {
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
Tenant savedTenant = tenantService.saveTenant(tenant);
Assert.assertNotNull(savedTenant);
tenantId = savedTenant.getId();
}
@After
public void after() {
tenantService.deleteTenant(tenantId);
}
@Test
public void testSaveQueueStats() {
QueueStats queueStats = new QueueStats();
queueStats.setTenantId(tenantId);
String queueName = StringUtils.randomAlphabetic(8);
queueStats.setQueueName(queueName);
queueStats.setServiceId(StringUtils.randomAlphabetic(8));
QueueStats savedQueueStats = queueStatsService.save(tenantId, queueStats);
Assert.assertNotNull(savedQueueStats);
Assert.assertNotNull(savedQueueStats.getId());
Assert.assertTrue(savedQueueStats.getCreatedTime() > 0);
Assert.assertEquals(queueStats.getTenantId(), savedQueueStats.getTenantId());
Assert.assertEquals(savedQueueStats.getQueueName(), queueStats.getQueueName());
QueueStats retrievedQueueStatsById = queueStatsService.findQueueStatsById(tenantId, savedQueueStats.getId());
Assert.assertEquals(retrievedQueueStatsById.getQueueName(), queueName);
String secondQueueName = StringUtils.randomAlphabetic(8);
queueStats.setQueueName(secondQueueName);
QueueStats savedQueueStats2 = queueStatsService.save(tenantId, queueStats);
QueueStats retrievedQueueStatsById2 = queueStatsService.findQueueStatsById(tenantId, savedQueueStats2.getId());
Assert.assertEquals(retrievedQueueStatsById2.getQueueName(), secondQueueName);
List<QueueStats> queueStatsList = queueStatsService.findByTenantId(tenantId);
Assert.assertEquals(2, queueStatsList.size());
assertThat(queueStatsList).containsOnly(retrievedQueueStatsById, retrievedQueueStatsById2);
queueStatsService.deleteByTenantId(tenantId);
QueueStats retrievedQueueStatsAfterDelete = queueStatsService.findQueueStatsById(tenantId, savedQueueStats.getId());
Assert.assertNull(retrievedQueueStatsAfterDelete);
}
@Test
public void testSaveWithNullQueueName() {
QueueStats queueStats = new QueueStats();
queueStats.setTenantId(tenantId);
queueStats.setQueueName(null);
queueStats.setServiceId(StringUtils.randomAlphabetic(8));
Assertions.assertThrows(DataValidationException.class, () -> {
queueStatsService.save(tenantId, queueStats);
});
}
@Test
public void testSaveWithNullServiceId() {
QueueStats queueStats = new QueueStats();
queueStats.setTenantId(tenantId);
queueStats.setQueueName(StringUtils.randomAlphabetic(8));
queueStats.setServiceId(null);
Assertions.assertThrows(DataValidationException.class, () -> {
queueStatsService.save(tenantId, queueStats);
});
}
@Test
public void testFindByTenantIdAndNameAndServiceId() {
QueueStats queueStats = new QueueStats();
queueStats.setTenantId(tenantId);
queueStats.setQueueName(StringUtils.randomAlphabetic(8));
queueStats.setServiceId(StringUtils.randomAlphabetic(8));
QueueStats savedQueueStats = queueStatsService.save(tenantId, queueStats);
QueueStats queueStats2 = new QueueStats();
queueStats2.setTenantId(tenantId);
queueStats2.setQueueName(StringUtils.randomAlphabetic(8));
queueStats2.setServiceId(StringUtils.randomAlphabetic(8));
queueStatsService.save(tenantId, queueStats2);
QueueStats retrievedQueueStatsById = queueStatsService.findByTenantIdAndNameAndServiceId(tenantId, queueStats.getQueueName(), queueStats.getServiceId());
assertThat(retrievedQueueStatsById).isEqualTo(savedQueueStats);
}
}

17
ui-ngx/src/assets/dashboard/api_usage.json

@ -3729,7 +3729,7 @@
"_hash": 0.49891007198715376
}
],
"entityAliasId": "2e4c97b0-257a-a1b9-690c-141d9bf2ec6f"
"entityAliasId": "1fcc06b0-ba0d-11ee-8765-750128ef3ba9"
}
],
"timewindow": {
@ -3880,7 +3880,7 @@
"_hash": 0.2679547062508352
}
],
"entityAliasId": "2e4c97b0-257a-a1b9-690c-141d9bf2ec6f"
"entityAliasId": "1fcc06b0-ba0d-11ee-8765-750128ef3ba9"
}
],
"timewindow": {
@ -4007,7 +4007,7 @@
"_hash": 0.7255162989552142
}
],
"entityAliasId": "2e4c97b0-257a-a1b9-690c-141d9bf2ec6f"
"entityAliasId": "1fcc06b0-ba0d-11ee-8765-750128ef3ba9"
}
],
"timewindow": {
@ -4880,16 +4880,13 @@
"resolveMultiple": false
}
},
"2e4c97b0-257a-a1b9-690c-141d9bf2ec6f": {
"id": "2e4c97b0-257a-a1b9-690c-141d9bf2ec6f",
"1fcc06b0-ba0d-11ee-8765-750128ef3ba9": {
"id": "1fcc06b0-ba0d-11ee-8765-750128ef3ba9",
"alias": "TbServiceQueues",
"filter": {
"type": "assetType",
"type": "entityType",
"resolveMultiple": true,
"assetNameFilter": "",
"assetTypes": [
"TbServiceQueue"
]
"entityType": "QUEUE_STATS"
}
}
},

Loading…
Cancel
Save