Commit ef0182414fd39fc534a1b1a277dcea4bcc5e1671

Authored by Igor Kulikov
Committed by GitHub
2 parents 06420d2b 82ae2eb3

Merge pull request #3991 from AndrewVolosytnykhThingsboard/andrewdev

#3966 highestAlarmSeverity fixed
... ... @@ -19,16 +19,18 @@ import com.google.common.util.concurrent.ListenableFuture;
19 19 import org.thingsboard.server.common.data.alarm.Alarm;
20 20 import org.thingsboard.server.common.data.alarm.AlarmInfo;
21 21 import org.thingsboard.server.common.data.alarm.AlarmQuery;
  22 +import org.thingsboard.server.common.data.alarm.AlarmSeverity;
  23 +import org.thingsboard.server.common.data.alarm.AlarmStatus;
22 24 import org.thingsboard.server.common.data.id.CustomerId;
23 25 import org.thingsboard.server.common.data.id.EntityId;
24 26 import org.thingsboard.server.common.data.id.TenantId;
25 27 import org.thingsboard.server.common.data.page.PageData;
26 28 import org.thingsboard.server.common.data.query.AlarmData;
27   -import org.thingsboard.server.common.data.query.AlarmDataPageLink;
28 29 import org.thingsboard.server.common.data.query.AlarmDataQuery;
29 30 import org.thingsboard.server.dao.Dao;
30 31
31 32 import java.util.Collection;
  33 +import java.util.Set;
32 34 import java.util.UUID;
33 35
34 36 /**
... ... @@ -48,4 +50,6 @@ public interface AlarmDao extends Dao<Alarm> {
48 50
49 51 PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId,
50 52 AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
  53 +
  54 + Set<AlarmSeverity> findAlarmSeverities(TenantId tenantId, EntityId entityId, Set<AlarmStatus> status);
51 55 }
... ...
... ... @@ -39,10 +39,10 @@ import org.thingsboard.server.common.data.id.CustomerId;
39 39 import org.thingsboard.server.common.data.id.EntityId;
40 40 import org.thingsboard.server.common.data.id.TenantId;
41 41 import org.thingsboard.server.common.data.page.PageData;
42   -import org.thingsboard.server.common.data.page.TimePageLink;
43 42 import org.thingsboard.server.common.data.query.AlarmData;
44 43 import org.thingsboard.server.common.data.query.AlarmDataPageLink;
45 44 import org.thingsboard.server.common.data.query.AlarmDataQuery;
  45 +import org.thingsboard.server.common.data.query.DeviceTypeFilter;
46 46 import org.thingsboard.server.common.data.relation.EntityRelation;
47 47 import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
48 48 import org.thingsboard.server.common.data.relation.EntitySearchDirection;
... ... @@ -60,7 +60,6 @@ import javax.annotation.PreDestroy;
60 60 import java.util.ArrayList;
61 61 import java.util.Collection;
62 62 import java.util.Collections;
63   -import java.util.Comparator;
64 63 import java.util.LinkedHashSet;
65 64 import java.util.List;
66 65 import java.util.Set;
... ... @@ -316,37 +315,16 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
316 315 @Override
317 316 public AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus,
318 317 AlarmStatus alarmStatus) {
319   - TimePageLink nextPageLink = new TimePageLink(100);
320   - boolean hasNext = true;
321   - AlarmSeverity highestSeverity = null;
322   - AlarmQuery query;
323   - while (hasNext && AlarmSeverity.CRITICAL != highestSeverity) {
324   - query = new AlarmQuery(entityId, nextPageLink, alarmSearchStatus, alarmStatus, false, null);
325   - PageData<AlarmInfo> alarms = alarmDao.findAlarms(tenantId, query);
326   - if (alarms.hasNext()) {
327   - nextPageLink = nextPageLink.nextPageLink();
328   - }
329   - AlarmSeverity severity = detectHighestSeverity(alarms.getData());
330   - if (severity == null) {
331   - continue;
332   - }
333   - if (severity == AlarmSeverity.CRITICAL || highestSeverity == null) {
334   - highestSeverity = severity;
335   - } else {
336   - highestSeverity = highestSeverity.compareTo(severity) < 0 ? highestSeverity : severity;
337   - }
  318 + Set<AlarmStatus> statusList = null;
  319 + if (alarmSearchStatus != null) {
  320 + statusList = alarmSearchStatus.getStatuses();
  321 + } else if (alarmStatus != null) {
  322 + statusList = Collections.singleton(alarmStatus);
338 323 }
339   - return highestSeverity;
340   - }
341 324
342   - private AlarmSeverity detectHighestSeverity(List<AlarmInfo> alarms) {
343   - if (!alarms.isEmpty()) {
344   - List<AlarmInfo> sorted = new ArrayList(alarms);
345   - sorted.sort(Comparator.comparing(Alarm::getSeverity));
346   - return sorted.get(0).getSeverity();
347   - } else {
348   - return null;
349   - }
  325 + Set<AlarmSeverity> alarmSeverities = alarmDao.findAlarmSeverities(tenantId, entityId, statusList);
  326 +
  327 + return alarmSeverities.stream().min(AlarmSeverity::compareTo).orElse(null);
350 328 }
351 329
352 330 private void deleteRelation(TenantId tenantId, EntityRelation alarmRelation) {
... ...
... ... @@ -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 + Set<AlarmSeverity> findAlarmSeverities(@Param("tenantId") UUID tenantId,
  84 + @Param("entityId") UUID entityId,
  85 + @Param("status") Set<AlarmStatus> status);
  86 +
78 87 }
... ...
... ... @@ -24,6 +24,7 @@ import org.springframework.stereotype.Component;
24 24 import org.thingsboard.server.common.data.alarm.Alarm;
25 25 import org.thingsboard.server.common.data.alarm.AlarmInfo;
26 26 import org.thingsboard.server.common.data.alarm.AlarmQuery;
  27 +import org.thingsboard.server.common.data.alarm.AlarmSeverity;
27 28 import org.thingsboard.server.common.data.alarm.AlarmStatus;
28 29 import org.thingsboard.server.common.data.id.CustomerId;
29 30 import org.thingsboard.server.common.data.id.EntityId;
... ... @@ -120,4 +121,9 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
120 121 public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
121 122 return alarmQueryRepository.findAlarmDataByQueryForEntities(tenantId, customerId, query, orderedEntityIds);
122 123 }
  124 +
  125 + @Override
  126 + public Set<AlarmSeverity> findAlarmSeverities(TenantId tenantId, EntityId entityId, Set<AlarmStatus> status) {
  127 + return alarmRepository.findAlarmSeverities(tenantId.getId(), entityId.getId(), status);
  128 + }
123 129 }
... ...
... ... @@ -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 + // no one alarms was created
  372 + Assert.assertNull(alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, null));
  373 +
  374 + Alarm alarm1 = Alarm.builder()
  375 + .tenantId(tenantId)
  376 + .originator(customerDevice.getId())
  377 + .type(TEST_ALARM)
  378 + .severity(AlarmSeverity.MAJOR)
  379 + .status(AlarmStatus.ACTIVE_UNACK)
  380 + .startTs(System.currentTimeMillis())
  381 + .build();
  382 + alarm1 = alarmService.createOrUpdateAlarm(alarm1).getAlarm();
  383 + alarmService.clearAlarm(tenantId, alarm1.getId(), null, System.currentTimeMillis()).get();
  384 +
  385 + Alarm alarm2 = Alarm.builder()
  386 + .tenantId(tenantId)
  387 + .originator(customerDevice.getId())
  388 + .type(TEST_ALARM)
  389 + .severity(AlarmSeverity.MINOR)
  390 + .status(AlarmStatus.ACTIVE_ACK)
  391 + .startTs(System.currentTimeMillis())
  392 + .build();
  393 + alarm2 = alarmService.createOrUpdateAlarm(alarm2).getAlarm();
  394 + alarmService.clearAlarm(tenantId, alarm2.getId(), null, System.currentTimeMillis()).get();
  395 +
  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(System.currentTimeMillis())
  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());
... ...