Merge pull request #13556 from dashevchenko/alarmCountFilterFix
Added entity and key filters support for alarm count query
This commit is contained in:
commit
591d01e3e2
@ -208,9 +208,26 @@ public class DefaultEntityQueryService implements EntityQueryService {
|
||||
|
||||
@Override
|
||||
public long countAlarmsByQuery(SecurityUser securityUser, AlarmCountQuery query) {
|
||||
if (query.getEntityFilter() != null) {
|
||||
EntityDataQuery entityDataQuery = this.buildEntityDataQuery(query);
|
||||
PageData<EntityData> entities = entityService.findEntityDataByQuery(securityUser.getTenantId(),
|
||||
securityUser.getCustomerId(), entityDataQuery);
|
||||
if (entities.getTotalElements() > 0) {
|
||||
List<EntityId> entityIds = entities.getData().stream().map(EntityData::getEntityId).toList();
|
||||
return alarmService.countAlarmsByQuery(securityUser.getTenantId(), securityUser.getCustomerId(), query, entityIds);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return alarmService.countAlarmsByQuery(securityUser.getTenantId(), securityUser.getCustomerId(), query);
|
||||
}
|
||||
|
||||
private EntityDataQuery buildEntityDataQuery(AlarmCountQuery query) {
|
||||
EntityDataPageLink edpl = new EntityDataPageLink(maxEntitiesPerAlarmSubscription, 0, null,
|
||||
new EntityDataSortOrder(new EntityKey(EntityKeyType.ENTITY_FIELD, ModelConstants.CREATED_TIME_PROPERTY)));
|
||||
return new EntityDataQuery(query.getEntityFilter(), edpl, null, null, query.getKeyFilters());
|
||||
}
|
||||
|
||||
private EntityDataQuery buildEntityDataQuery(AlarmDataQuery query) {
|
||||
EntityDataSortOrder sortOrder = query.getPageLink().getSortOrder();
|
||||
EntityDataSortOrder entitiesSortOrder;
|
||||
@ -220,7 +237,7 @@ public class DefaultEntityQueryService implements EntityQueryService {
|
||||
entitiesSortOrder = sortOrder;
|
||||
}
|
||||
EntityDataPageLink edpl = new EntityDataPageLink(maxEntitiesPerAlarmSubscription, 0, null, entitiesSortOrder);
|
||||
return new EntityDataQuery(query.getEntityFilter(), edpl, query.getEntityFields(), query.getLatestValues(), query.getKeyFilters());
|
||||
return new EntityDataQuery(query.getEntityFilter(), edpl, null, null, query.getKeyFilters());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -36,10 +36,14 @@ import org.thingsboard.server.common.data.Tenant;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.alarm.Alarm;
|
||||
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.query.AlarmCountQuery;
|
||||
import org.thingsboard.server.common.data.query.AlarmData;
|
||||
import org.thingsboard.server.common.data.query.AlarmDataPageLink;
|
||||
import org.thingsboard.server.common.data.query.AlarmDataQuery;
|
||||
import org.thingsboard.server.common.data.query.DeviceTypeFilter;
|
||||
import org.thingsboard.server.common.data.query.DynamicValue;
|
||||
import org.thingsboard.server.common.data.query.DynamicValueSourceType;
|
||||
@ -230,6 +234,60 @@ public class EntityQueryControllerTest extends AbstractControllerTest {
|
||||
testCountAlarmsByQuery(alarms);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTenantCountAlarmsWithEntityFilter() throws Exception {
|
||||
loginTenantAdmin();
|
||||
List<Device> devices = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Device device = new Device();
|
||||
device.setName("Device" + i);
|
||||
device.setType("default");
|
||||
device.setLabel("testLabel" + (int) (Math.random() * 1000));
|
||||
Device savedDevice = doPost("/api/device", device, Device.class);
|
||||
devices.add(savedDevice);
|
||||
Thread.sleep(1);
|
||||
|
||||
Alarm alarm = new Alarm();
|
||||
alarm.setOriginator(savedDevice.getId());
|
||||
alarm.setType("alarm" + i);
|
||||
alarm.setSeverity(AlarmSeverity.WARNING);
|
||||
doPost("/api/alarm", alarm, Alarm.class);
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
List<Asset> assets = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Asset asset = new Asset();
|
||||
asset.setName("Asset" + i);
|
||||
asset.setType("default");
|
||||
asset.setLabel("testLabel" + (int) (Math.random() * 1000));
|
||||
Asset savedAsset = doPost("/api/asset", asset, Asset.class);
|
||||
assets.add(savedAsset);
|
||||
Thread.sleep(1);
|
||||
|
||||
Alarm alarm = new Alarm();
|
||||
alarm.setOriginator(savedAsset.getId());
|
||||
alarm.setType("alarm" + i);
|
||||
alarm.setSeverity(AlarmSeverity.WARNING);
|
||||
doPost("/api/alarm", alarm, Alarm.class);
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
EntityTypeFilter assetTypeFilter = new EntityTypeFilter();
|
||||
assetTypeFilter.setEntityType(EntityType.ASSET);
|
||||
AlarmCountQuery assetAlarmQuery = new AlarmCountQuery(assetTypeFilter);
|
||||
|
||||
Long assetAlamCount = doPostWithResponse("/api/alarmsQuery/count", assetAlarmQuery, Long.class);
|
||||
Assert.assertEquals(assets.size(), assetAlamCount.longValue());
|
||||
|
||||
KeyFilter nameFilter = buildStringKeyFilter(EntityKeyType.ENTITY_FIELD, "name", StringFilterPredicate.StringOperation.STARTS_WITH, "Asset1");
|
||||
List<KeyFilter> keyFilters = Collections.singletonList(nameFilter);
|
||||
AlarmCountQuery filteredAssetAlarmQuery = new AlarmCountQuery(assetTypeFilter, keyFilters);
|
||||
|
||||
Long filteredAssetAlamCount = doPostWithResponse("/api/alarmsQuery/count", filteredAssetAlarmQuery, Long.class);
|
||||
Assert.assertEquals(1, filteredAssetAlamCount.longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomerCountAlarmsByQuery() throws Exception {
|
||||
loginTenantAdmin();
|
||||
@ -259,6 +317,213 @@ public class EntityQueryControllerTest extends AbstractControllerTest {
|
||||
testCountAlarmsByQuery(alarms);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomerCountAlarmsWithEntityFilter() throws Exception {
|
||||
loginTenantAdmin();
|
||||
List<Device> devices = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Device device = new Device();
|
||||
device.setCustomerId(customerId);
|
||||
device.setName("Device" + i);
|
||||
device.setType("default");
|
||||
device.setLabel("testLabel" + (int) (Math.random() * 1000));
|
||||
devices.add(doPost("/api/device", device, Device.class));
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
List<Asset> assets = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Asset asset = new Asset();
|
||||
asset.setCustomerId(customerId);
|
||||
asset.setName("Asset" + i);
|
||||
asset.setType("default");
|
||||
asset.setLabel("testLabel" + (int) (Math.random() * 1000));
|
||||
assets.add(doPost("/api/asset", asset, Asset.class));
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
loginCustomerUser();
|
||||
|
||||
for (int i = 0; i < devices.size(); i++) {
|
||||
Alarm alarm = new Alarm();
|
||||
alarm.setCustomerId(customerId);
|
||||
alarm.setOriginator(devices.get(i).getId());
|
||||
alarm.setType("alarm" + i);
|
||||
alarm.setSeverity(AlarmSeverity.WARNING);
|
||||
doPost("/api/alarm", alarm, Alarm.class);
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < assets.size(); i++) {
|
||||
Alarm alarm = new Alarm();
|
||||
alarm.setCustomerId(customerId);
|
||||
alarm.setOriginator(assets.get(i).getId());
|
||||
alarm.setType("alarm" + i);
|
||||
alarm.setSeverity(AlarmSeverity.WARNING);
|
||||
doPost("/api/alarm", alarm, Alarm.class);
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
EntityTypeFilter assetTypeFilter = new EntityTypeFilter();
|
||||
assetTypeFilter.setEntityType(EntityType.ASSET);
|
||||
AlarmCountQuery assetAlarmQuery = new AlarmCountQuery(assetTypeFilter);
|
||||
|
||||
Long assetAlamCount = doPostWithResponse("/api/alarmsQuery/count", assetAlarmQuery, Long.class);
|
||||
Assert.assertEquals(10, assetAlamCount.longValue());
|
||||
|
||||
KeyFilter nameFilter = buildStringKeyFilter(EntityKeyType.ENTITY_FIELD, "name", StringFilterPredicate.StringOperation.STARTS_WITH, "Asset1");
|
||||
List<KeyFilter> keyFilters = Collections.singletonList(nameFilter);
|
||||
AlarmCountQuery filteredAssetAlarmQuery = new AlarmCountQuery(assetTypeFilter, keyFilters);
|
||||
|
||||
Long filteredAssetAlamCount = doPostWithResponse("/api/alarmsQuery/count", filteredAssetAlarmQuery, Long.class);
|
||||
Assert.assertEquals(1, filteredAssetAlamCount.longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindTenantAlarmsWithEntityFilter() throws Exception {
|
||||
loginTenantAdmin();
|
||||
List<Device> devices = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Device device = new Device();
|
||||
device.setCustomerId(customerId);
|
||||
device.setName("Device" + i);
|
||||
device.setType("default");
|
||||
device.setLabel("testLabel" + (int) (Math.random() * 1000));
|
||||
devices.add(doPost("/api/device", device, Device.class));
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
List<Asset> assets = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Asset asset = new Asset();
|
||||
asset.setCustomerId(customerId);
|
||||
asset.setName("Asset" + i);
|
||||
asset.setType("default");
|
||||
asset.setLabel("testLabel" + (int) (Math.random() * 1000));
|
||||
assets.add(doPost("/api/asset", asset, Asset.class));
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < devices.size(); i++) {
|
||||
Alarm alarm = new Alarm();
|
||||
alarm.setOriginator(devices.get(i).getId());
|
||||
alarm.setType("alarm" + i);
|
||||
alarm.setSeverity(AlarmSeverity.WARNING);
|
||||
doPost("/api/alarm", alarm, Alarm.class);
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
List<String> assetAlarmTypes = new ArrayList<>();
|
||||
for (int i = 0; i < assets.size(); i++) {
|
||||
Alarm alarm = new Alarm();
|
||||
alarm.setOriginator(assets.get(i).getId());
|
||||
String type = "asset alarm" + i;
|
||||
alarm.setType(type);
|
||||
assetAlarmTypes.add(type);
|
||||
alarm.setSeverity(AlarmSeverity.WARNING);
|
||||
doPost("/api/alarm", alarm, Alarm.class);
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
AlarmDataPageLink pageLink = new AlarmDataPageLink();
|
||||
pageLink.setPage(0);
|
||||
pageLink.setPageSize(100);
|
||||
pageLink.setSortOrder(new EntityDataSortOrder(new EntityKey(EntityKeyType.ALARM_FIELD, "assignee")));
|
||||
|
||||
List<EntityKey> alarmFields = new ArrayList<>();
|
||||
alarmFields.add(new EntityKey(EntityKeyType.ALARM_FIELD, "type"));
|
||||
|
||||
EntityTypeFilter assetTypeFilter = new EntityTypeFilter();
|
||||
assetTypeFilter.setEntityType(EntityType.ASSET);
|
||||
AlarmDataQuery assetAlarmQuery = new AlarmDataQuery(assetTypeFilter, pageLink, null, null, null, alarmFields);
|
||||
|
||||
PageData<AlarmData> alarmPageData = doPostWithTypedResponse("/api/alarmsQuery/find", assetAlarmQuery, new TypeReference<>() {
|
||||
});
|
||||
Assert.assertEquals(10, alarmPageData.getTotalElements());
|
||||
List<String> retrievedAlarmTypes = alarmPageData.getData().stream().map(Alarm::getType).toList();
|
||||
assertThat(retrievedAlarmTypes).containsExactlyInAnyOrderElementsOf(assetAlarmTypes);
|
||||
|
||||
KeyFilter nameFilter = buildStringKeyFilter(EntityKeyType.ENTITY_FIELD, "name", StringFilterPredicate.StringOperation.STARTS_WITH, "Asset1");
|
||||
List<KeyFilter> keyFilters = Collections.singletonList(nameFilter);
|
||||
AlarmDataQuery filteredAssetAlarmQuery = new AlarmDataQuery(assetTypeFilter, pageLink, null, null, keyFilters, alarmFields);
|
||||
PageData<AlarmData> filteredAssetAlamData = doPostWithTypedResponse("/api/alarmsQuery/find", filteredAssetAlarmQuery, new TypeReference<>() {
|
||||
});
|
||||
Assert.assertEquals(1, filteredAssetAlamData.getTotalElements());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCustomerAlarmsWithEntityFilter() throws Exception {
|
||||
loginTenantAdmin();
|
||||
List<Device> devices = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Device device = new Device();
|
||||
device.setCustomerId(customerId);
|
||||
device.setName("Device" + i);
|
||||
device.setType("default");
|
||||
device.setLabel("testLabel" + (int) (Math.random() * 1000));
|
||||
devices.add(doPost("/api/device", device, Device.class));
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
List<Asset> assets = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Asset asset = new Asset();
|
||||
asset.setCustomerId(customerId);
|
||||
asset.setName("Asset" + i);
|
||||
asset.setType("default");
|
||||
asset.setLabel("testLabel" + (int) (Math.random() * 1000));
|
||||
assets.add(doPost("/api/asset", asset, Asset.class));
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
loginCustomerUser();
|
||||
|
||||
for (int i = 0; i < devices.size(); i++) {
|
||||
Alarm alarm = new Alarm();
|
||||
alarm.setCustomerId(customerId);
|
||||
alarm.setOriginator(devices.get(i).getId());
|
||||
alarm.setType("alarm" + i);
|
||||
alarm.setSeverity(AlarmSeverity.WARNING);
|
||||
doPost("/api/alarm", alarm, Alarm.class);
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
List<String> assetAlarmTypes = new ArrayList<>();
|
||||
for (int i = 0; i < assets.size(); i++) {
|
||||
Alarm alarm = new Alarm();
|
||||
alarm.setCustomerId(customerId);
|
||||
alarm.setOriginator(assets.get(i).getId());
|
||||
String type = "asset alarm" + i;
|
||||
alarm.setType(type);
|
||||
assetAlarmTypes.add(type);
|
||||
alarm.setSeverity(AlarmSeverity.WARNING);
|
||||
doPost("/api/alarm", alarm, Alarm.class);
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
AlarmDataPageLink pageLink = new AlarmDataPageLink();
|
||||
pageLink.setPage(0);
|
||||
pageLink.setPageSize(100);
|
||||
pageLink.setSortOrder(new EntityDataSortOrder(new EntityKey(EntityKeyType.ALARM_FIELD, "assignee")));
|
||||
|
||||
EntityTypeFilter assetTypeFilter = new EntityTypeFilter();
|
||||
assetTypeFilter.setEntityType(EntityType.ASSET);
|
||||
AlarmDataQuery assetAlarmQuery = new AlarmDataQuery(assetTypeFilter, pageLink, null, null, null, Collections.emptyList());
|
||||
|
||||
PageData<AlarmData> alarmPageData = doPostWithTypedResponse("/api/alarmsQuery/find", assetAlarmQuery, new TypeReference<>() {
|
||||
});
|
||||
Assert.assertEquals(10, alarmPageData.getTotalElements());
|
||||
List<String> retrievedAlarmTypes = alarmPageData.getData().stream().map(Alarm::getType).toList();
|
||||
assertThat(retrievedAlarmTypes).containsExactlyInAnyOrderElementsOf(assetAlarmTypes);
|
||||
|
||||
KeyFilter nameFilter = buildStringKeyFilter(EntityKeyType.ENTITY_FIELD, "name", StringFilterPredicate.StringOperation.STARTS_WITH, "Asset1");
|
||||
List<KeyFilter> keyFilters = Collections.singletonList(nameFilter);
|
||||
AlarmDataQuery filteredAssetAlarmQuery = new AlarmDataQuery(assetTypeFilter, pageLink, null, null, keyFilters, Collections.emptyList());
|
||||
PageData<AlarmData> filteredAssetAlamData = doPostWithTypedResponse("/api/alarmsQuery/find", filteredAssetAlarmQuery, new TypeReference<>() {
|
||||
});
|
||||
Assert.assertEquals(1, filteredAssetAlamData.getTotalElements());
|
||||
}
|
||||
|
||||
private void testCountAlarmsByQuery(List<Alarm> alarms) throws Exception {
|
||||
AlarmCountQuery countQuery = new AlarmCountQuery();
|
||||
|
||||
@ -913,4 +1178,14 @@ public class EntityQueryControllerTest extends AbstractControllerTest {
|
||||
return numericFilter;
|
||||
}
|
||||
|
||||
private KeyFilter buildStringKeyFilter(EntityKeyType entityKeyType, String name, StringFilterPredicate.StringOperation operation, String value) {
|
||||
KeyFilter nameFilter = new KeyFilter();
|
||||
nameFilter.setKey(new EntityKey(entityKeyType, name));
|
||||
StringFilterPredicate predicate = new StringFilterPredicate();
|
||||
predicate.setOperation(operation);
|
||||
predicate.setValue(FilterPredicateValue.fromString(value));
|
||||
nameFilter.setPredicate(predicate);
|
||||
return nameFilter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -45,4 +45,8 @@ public class AlarmCountQuery extends EntityCountQuery {
|
||||
super(entityFilter);
|
||||
}
|
||||
|
||||
public AlarmCountQuery(EntityFilter entityFilter, List<KeyFilter> keyFilters) {
|
||||
super(entityFilter, keyFilters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data.query;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.thingsboard.server.common.data.alarm.Alarm;
|
||||
@ -34,6 +36,12 @@ public class AlarmData extends AlarmInfo {
|
||||
@Getter
|
||||
private final Map<EntityKeyType, Map<String, TsValue>> latest;
|
||||
|
||||
@JsonCreator
|
||||
public AlarmData(@JsonProperty("entityId") EntityId entityId, @JsonProperty("latest") Map<EntityKeyType, Map<String, TsValue>> latest) {
|
||||
this.entityId = entityId;
|
||||
this.latest = latest;
|
||||
}
|
||||
|
||||
public AlarmData(AlarmInfo main, AlarmData prototype) {
|
||||
super(main);
|
||||
this.entityId = prototype.entityId;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user