Commit 581bb536f5e2281981815e338d48f05e41bb2592

Authored by AndrewVolostnykhThingsboard
1 parent 3c558a7d

findHighestAlarmStatus: fixed using Repository Query

... ... @@ -28,26 +28,43 @@ import org.springframework.util.CollectionUtils;
28 28 import org.springframework.util.StringUtils;
29 29 import org.thingsboard.common.util.ThingsBoardThreadFactory;
30 30 import org.thingsboard.server.common.data.Tenant;
31   -import org.thingsboard.server.common.data.alarm.*;
  31 +import org.thingsboard.server.common.data.alarm.Alarm;
  32 +import org.thingsboard.server.common.data.alarm.AlarmInfo;
  33 +import org.thingsboard.server.common.data.alarm.AlarmQuery;
  34 +import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
  35 +import org.thingsboard.server.common.data.alarm.AlarmSeverity;
  36 +import org.thingsboard.server.common.data.alarm.AlarmStatus;
32 37 import org.thingsboard.server.common.data.id.AlarmId;
33 38 import org.thingsboard.server.common.data.id.CustomerId;
34 39 import org.thingsboard.server.common.data.id.EntityId;
35 40 import org.thingsboard.server.common.data.id.TenantId;
36 41 import org.thingsboard.server.common.data.page.PageData;
37   -import org.thingsboard.server.common.data.page.TimePageLink;
38 42 import org.thingsboard.server.common.data.query.AlarmData;
  43 +import org.thingsboard.server.common.data.query.AlarmDataPageLink;
39 44 import org.thingsboard.server.common.data.query.AlarmDataQuery;
40   -import org.thingsboard.server.common.data.relation.*;
  45 +import org.thingsboard.server.common.data.query.DeviceTypeFilter;
  46 +import org.thingsboard.server.common.data.relation.EntityRelation;
  47 +import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
  48 +import org.thingsboard.server.common.data.relation.EntitySearchDirection;
  49 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
  50 +import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
41 51 import org.thingsboard.server.dao.entity.AbstractEntityService;
42 52 import org.thingsboard.server.dao.entity.EntityService;
43 53 import org.thingsboard.server.dao.exception.DataValidationException;
44 54 import org.thingsboard.server.dao.service.DataValidator;
  55 +import org.thingsboard.server.dao.sql.alarm.AlarmRepository;
45 56 import org.thingsboard.server.dao.tenant.TenantDao;
46 57
47 58 import javax.annotation.Nullable;
48 59 import javax.annotation.PostConstruct;
49 60 import javax.annotation.PreDestroy;
50   -import java.util.*;
  61 +import java.util.ArrayList;
  62 +import java.util.Collection;
  63 +import java.util.Collections;
  64 +import java.util.Comparator;
  65 +import java.util.LinkedHashSet;
  66 +import java.util.List;
  67 +import java.util.Set;
51 68 import java.util.concurrent.ExecutionException;
52 69 import java.util.concurrent.ExecutorService;
53 70 import java.util.concurrent.Executors;
... ... @@ -72,6 +89,9 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
72 89 @Autowired
73 90 private EntityService entityService;
74 91
  92 + @Autowired
  93 + private AlarmRepository alarmRepository;
  94 +
75 95 protected ExecutorService readResultsProcessingExecutor;
76 96
77 97 @PostConstruct
... ... @@ -300,35 +320,23 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
300 320 @Override
301 321 public AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus,
302 322 AlarmStatus alarmStatus) {
303   - TimePageLink nextPageLink = new TimePageLink(100);
304   - boolean hasNext = true;
305   - AlarmSeverity highestSeverity = null;
306   - AlarmQuery query;
307   - while (hasNext && AlarmSeverity.CRITICAL != highestSeverity) {
308   - query = new AlarmQuery(entityId, nextPageLink, alarmSearchStatus, alarmStatus, false, null);
309   - PageData<AlarmInfo> alarms = alarmDao.findAlarms(tenantId, query);
310   -
311   - if (alarms.hasNext()) {
312   - nextPageLink = nextPageLink.nextPageLink();
313   - } else {
314   - hasNext = false;
315   - }
  323 + Set<AlarmStatus> statusList = null;
  324 + if (alarmSearchStatus != null) {
  325 + statusList = alarmSearchStatus.getStatuses();
  326 + } else if (alarmStatus != null) {
  327 + statusList = Collections.singleton(alarmStatus);
  328 + }
316 329
317   - AlarmSeverity severity = detectHighestSeverity(alarms.getData());
318   - if (severity == null) {
319   - continue;
320   - }
  330 + List<AlarmSeverity> alarmSeverities = alarmRepository.findHighestAlarmSeverity(tenantId.getId(), entityId.getId(), statusList);
321 331
322   - if (severity == AlarmSeverity.CRITICAL || highestSeverity == null) {
323   - highestSeverity = severity;
324   - } else {
325   - highestSeverity = highestSeverity.compareTo(severity) < 0 ? highestSeverity : severity;
326   - }
327   - }
328   - return highestSeverity;
  332 + return alarmSeverities.stream().min(AlarmSeverity::compareTo).orElse(null);
  333 + }
  334 +
  335 + private AlarmDataQuery toQuery(AlarmDataPageLink pageLink) {
  336 + return new AlarmDataQuery(new DeviceTypeFilter(), pageLink, null, null, null, Collections.EMPTY_LIST);
329 337 }
330 338
331   - private AlarmSeverity detectHighestSeverity(List<AlarmInfo> alarms) {
  339 + private AlarmSeverity detectHighestSeverity(List<AlarmData> alarms) {
332 340 if (!alarms.isEmpty()) {
333 341 List<AlarmInfo> sorted = new ArrayList(alarms);
334 342 sorted.sort(Comparator.comparing(Alarm::getSeverity));
... ...
... ... @@ -20,6 +20,7 @@ import org.springframework.data.domain.Pageable;
20 20 import org.springframework.data.jpa.repository.Query;
21 21 import org.springframework.data.repository.CrudRepository;
22 22 import org.springframework.data.repository.query.Param;
  23 +import org.thingsboard.server.common.data.alarm.AlarmSeverity;
23 24 import org.thingsboard.server.common.data.alarm.AlarmStatus;
24 25 import org.thingsboard.server.dao.model.sql.AlarmEntity;
25 26 import org.thingsboard.server.dao.model.sql.AlarmInfoEntity;
... ... @@ -75,4 +76,12 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
75 76 @Param("searchText") String searchText,
76 77 Pageable pageable);
77 78
  79 + @Query("SELECT alarm.severity FROM AlarmEntity alarm" +
  80 + " WHERE alarm.tenantId = :tenantId" +
  81 + " AND alarm.originatorId = :entityId" +
  82 + " AND ((:status) IS NULL OR alarm.status in (:status))")
  83 + List<AlarmSeverity> findHighestAlarmSeverity(@Param("tenantId") UUID tenantId,
  84 + @Param("entityId") UUID entityId,
  85 + @Param("status") Set<AlarmStatus> status);
  86 +
78 87 }
... ...
... ... @@ -355,6 +355,62 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
355 355 }
356 356
357 357 @Test
  358 + public void testFindHighestAlarmSeverity() throws ExecutionException, InterruptedException {
  359 + Customer customer = new Customer();
  360 + customer.setTitle("TestCustomer");
  361 + customer.setTenantId(tenantId);
  362 + customer = customerService.saveCustomer(customer);
  363 +
  364 + Device customerDevice = new Device();
  365 + customerDevice.setName("TestCustomerDevice");
  366 + customerDevice.setType("default");
  367 + customerDevice.setTenantId(tenantId);
  368 + customerDevice.setCustomerId(customer.getId());
  369 + customerDevice = deviceService.saveDevice(customerDevice);
  370 +
  371 + long ts = System.currentTimeMillis();
  372 + Alarm alarm1 = Alarm.builder()
  373 + .tenantId(tenantId)
  374 + .originator(customerDevice.getId())
  375 + .type(TEST_ALARM)
  376 + .severity(AlarmSeverity.MAJOR)
  377 + .status(AlarmStatus.ACTIVE_UNACK)
  378 + .startTs(ts)
  379 + .build();
  380 + alarm1 = alarmService.createOrUpdateAlarm(alarm1).getAlarm();
  381 + alarmService.clearAlarm(tenantId, alarm1.getId(), null, System.currentTimeMillis()).get();
  382 +
  383 + ts = System.currentTimeMillis();
  384 + Alarm alarm2 = Alarm.builder()
  385 + .tenantId(tenantId)
  386 + .originator(customerDevice.getId())
  387 + .type(TEST_ALARM)
  388 + .severity(AlarmSeverity.MINOR)
  389 + .status(AlarmStatus.ACTIVE_ACK)
  390 + .startTs(ts)
  391 + .build();
  392 + alarm2 = alarmService.createOrUpdateAlarm(alarm2).getAlarm();
  393 + alarmService.clearAlarm(tenantId, alarm2.getId(), null, System.currentTimeMillis()).get();
  394 +
  395 + ts = System.currentTimeMillis();
  396 + Alarm alarm3 = Alarm.builder()
  397 + .tenantId(tenantId)
  398 + .originator(customerDevice.getId())
  399 + .type(TEST_ALARM)
  400 + .severity(AlarmSeverity.CRITICAL)
  401 + .status(AlarmStatus.ACTIVE_ACK)
  402 + .startTs(ts)
  403 + .build();
  404 + alarm3 = alarmService.createOrUpdateAlarm(alarm3).getAlarm();
  405 +
  406 + Assert.assertEquals(AlarmSeverity.MAJOR, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), AlarmSearchStatus.UNACK, null));
  407 + Assert.assertEquals(AlarmSeverity.CRITICAL, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, null));
  408 + Assert.assertEquals(AlarmSeverity.MAJOR, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, AlarmStatus.CLEARED_UNACK));
  409 + Assert.assertEquals(AlarmSeverity.CRITICAL, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), AlarmSearchStatus.ACTIVE, null));
  410 + Assert.assertEquals(AlarmSeverity.MINOR, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, AlarmStatus.CLEARED_ACK));
  411 + }
  412 +
  413 + @Test
358 414 public void testFindAlarmUsingAlarmDataQuery() throws ExecutionException, InterruptedException {
359 415 AssetId parentId = new AssetId(Uuids.timeBased());
360 416 AssetId parentId2 = new AssetId(Uuids.timeBased());
... ...