Commit ef0182414fd39fc534a1b1a277dcea4bcc5e1671
Committed by
GitHub
Merge pull request #3991 from AndrewVolosytnykhThingsboard/andrewdev
#3966 highestAlarmSeverity fixed
Showing
5 changed files
with
85 additions
and
32 deletions
@@ -19,16 +19,18 @@ import com.google.common.util.concurrent.ListenableFuture; | @@ -19,16 +19,18 @@ import com.google.common.util.concurrent.ListenableFuture; | ||
19 | import org.thingsboard.server.common.data.alarm.Alarm; | 19 | import org.thingsboard.server.common.data.alarm.Alarm; |
20 | import org.thingsboard.server.common.data.alarm.AlarmInfo; | 20 | import org.thingsboard.server.common.data.alarm.AlarmInfo; |
21 | import org.thingsboard.server.common.data.alarm.AlarmQuery; | 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 | import org.thingsboard.server.common.data.id.CustomerId; | 24 | import org.thingsboard.server.common.data.id.CustomerId; |
23 | import org.thingsboard.server.common.data.id.EntityId; | 25 | import org.thingsboard.server.common.data.id.EntityId; |
24 | import org.thingsboard.server.common.data.id.TenantId; | 26 | import org.thingsboard.server.common.data.id.TenantId; |
25 | import org.thingsboard.server.common.data.page.PageData; | 27 | import org.thingsboard.server.common.data.page.PageData; |
26 | import org.thingsboard.server.common.data.query.AlarmData; | 28 | import org.thingsboard.server.common.data.query.AlarmData; |
27 | -import org.thingsboard.server.common.data.query.AlarmDataPageLink; | ||
28 | import org.thingsboard.server.common.data.query.AlarmDataQuery; | 29 | import org.thingsboard.server.common.data.query.AlarmDataQuery; |
29 | import org.thingsboard.server.dao.Dao; | 30 | import org.thingsboard.server.dao.Dao; |
30 | 31 | ||
31 | import java.util.Collection; | 32 | import java.util.Collection; |
33 | +import java.util.Set; | ||
32 | import java.util.UUID; | 34 | import java.util.UUID; |
33 | 35 | ||
34 | /** | 36 | /** |
@@ -48,4 +50,6 @@ public interface AlarmDao extends Dao<Alarm> { | @@ -48,4 +50,6 @@ public interface AlarmDao extends Dao<Alarm> { | ||
48 | 50 | ||
49 | PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, | 51 | PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, |
50 | AlarmDataQuery query, Collection<EntityId> orderedEntityIds); | 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,10 +39,10 @@ import org.thingsboard.server.common.data.id.CustomerId; | ||
39 | import org.thingsboard.server.common.data.id.EntityId; | 39 | import org.thingsboard.server.common.data.id.EntityId; |
40 | import org.thingsboard.server.common.data.id.TenantId; | 40 | import org.thingsboard.server.common.data.id.TenantId; |
41 | import org.thingsboard.server.common.data.page.PageData; | 41 | import org.thingsboard.server.common.data.page.PageData; |
42 | -import org.thingsboard.server.common.data.page.TimePageLink; | ||
43 | import org.thingsboard.server.common.data.query.AlarmData; | 42 | import org.thingsboard.server.common.data.query.AlarmData; |
44 | import org.thingsboard.server.common.data.query.AlarmDataPageLink; | 43 | import org.thingsboard.server.common.data.query.AlarmDataPageLink; |
45 | import org.thingsboard.server.common.data.query.AlarmDataQuery; | 44 | import org.thingsboard.server.common.data.query.AlarmDataQuery; |
45 | +import org.thingsboard.server.common.data.query.DeviceTypeFilter; | ||
46 | import org.thingsboard.server.common.data.relation.EntityRelation; | 46 | import org.thingsboard.server.common.data.relation.EntityRelation; |
47 | import org.thingsboard.server.common.data.relation.EntityRelationsQuery; | 47 | import org.thingsboard.server.common.data.relation.EntityRelationsQuery; |
48 | import org.thingsboard.server.common.data.relation.EntitySearchDirection; | 48 | import org.thingsboard.server.common.data.relation.EntitySearchDirection; |
@@ -60,7 +60,6 @@ import javax.annotation.PreDestroy; | @@ -60,7 +60,6 @@ import javax.annotation.PreDestroy; | ||
60 | import java.util.ArrayList; | 60 | import java.util.ArrayList; |
61 | import java.util.Collection; | 61 | import java.util.Collection; |
62 | import java.util.Collections; | 62 | import java.util.Collections; |
63 | -import java.util.Comparator; | ||
64 | import java.util.LinkedHashSet; | 63 | import java.util.LinkedHashSet; |
65 | import java.util.List; | 64 | import java.util.List; |
66 | import java.util.Set; | 65 | import java.util.Set; |
@@ -316,37 +315,16 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ | @@ -316,37 +315,16 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ | ||
316 | @Override | 315 | @Override |
317 | public AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus, | 316 | public AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus, |
318 | AlarmStatus alarmStatus) { | 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 | private void deleteRelation(TenantId tenantId, EntityRelation alarmRelation) { | 330 | private void deleteRelation(TenantId tenantId, EntityRelation alarmRelation) { |
@@ -20,6 +20,7 @@ import org.springframework.data.domain.Pageable; | @@ -20,6 +20,7 @@ import org.springframework.data.domain.Pageable; | ||
20 | import org.springframework.data.jpa.repository.Query; | 20 | import org.springframework.data.jpa.repository.Query; |
21 | import org.springframework.data.repository.CrudRepository; | 21 | import org.springframework.data.repository.CrudRepository; |
22 | import org.springframework.data.repository.query.Param; | 22 | import org.springframework.data.repository.query.Param; |
23 | +import org.thingsboard.server.common.data.alarm.AlarmSeverity; | ||
23 | import org.thingsboard.server.common.data.alarm.AlarmStatus; | 24 | import org.thingsboard.server.common.data.alarm.AlarmStatus; |
24 | import org.thingsboard.server.dao.model.sql.AlarmEntity; | 25 | import org.thingsboard.server.dao.model.sql.AlarmEntity; |
25 | import org.thingsboard.server.dao.model.sql.AlarmInfoEntity; | 26 | import org.thingsboard.server.dao.model.sql.AlarmInfoEntity; |
@@ -75,4 +76,12 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> { | @@ -75,4 +76,12 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> { | ||
75 | @Param("searchText") String searchText, | 76 | @Param("searchText") String searchText, |
76 | Pageable pageable); | 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,6 +24,7 @@ import org.springframework.stereotype.Component; | ||
24 | import org.thingsboard.server.common.data.alarm.Alarm; | 24 | import org.thingsboard.server.common.data.alarm.Alarm; |
25 | import org.thingsboard.server.common.data.alarm.AlarmInfo; | 25 | import org.thingsboard.server.common.data.alarm.AlarmInfo; |
26 | import org.thingsboard.server.common.data.alarm.AlarmQuery; | 26 | import org.thingsboard.server.common.data.alarm.AlarmQuery; |
27 | +import org.thingsboard.server.common.data.alarm.AlarmSeverity; | ||
27 | import org.thingsboard.server.common.data.alarm.AlarmStatus; | 28 | import org.thingsboard.server.common.data.alarm.AlarmStatus; |
28 | import org.thingsboard.server.common.data.id.CustomerId; | 29 | import org.thingsboard.server.common.data.id.CustomerId; |
29 | import org.thingsboard.server.common.data.id.EntityId; | 30 | import org.thingsboard.server.common.data.id.EntityId; |
@@ -120,4 +121,9 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A | @@ -120,4 +121,9 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A | ||
120 | public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) { | 121 | public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) { |
121 | return alarmQueryRepository.findAlarmDataByQueryForEntities(tenantId, customerId, query, orderedEntityIds); | 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,6 +355,62 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { | ||
355 | } | 355 | } |
356 | 356 | ||
357 | @Test | 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 | public void testFindAlarmUsingAlarmDataQuery() throws ExecutionException, InterruptedException { | 414 | public void testFindAlarmUsingAlarmDataQuery() throws ExecutionException, InterruptedException { |
359 | AssetId parentId = new AssetId(Uuids.timeBased()); | 415 | AssetId parentId = new AssetId(Uuids.timeBased()); |
360 | AssetId parentId2 = new AssetId(Uuids.timeBased()); | 416 | AssetId parentId2 = new AssetId(Uuids.timeBased()); |