Commit 581bb536f5e2281981815e338d48f05e41bb2592
1 parent
3c558a7d
findHighestAlarmStatus: fixed using Repository Query
Showing
3 changed files
with
102 additions
and
29 deletions
@@ -28,26 +28,43 @@ import org.springframework.util.CollectionUtils; | @@ -28,26 +28,43 @@ import org.springframework.util.CollectionUtils; | ||
28 | import org.springframework.util.StringUtils; | 28 | import org.springframework.util.StringUtils; |
29 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 29 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
30 | import org.thingsboard.server.common.data.Tenant; | 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 | import org.thingsboard.server.common.data.id.AlarmId; | 37 | import org.thingsboard.server.common.data.id.AlarmId; |
33 | import org.thingsboard.server.common.data.id.CustomerId; | 38 | import org.thingsboard.server.common.data.id.CustomerId; |
34 | import org.thingsboard.server.common.data.id.EntityId; | 39 | import org.thingsboard.server.common.data.id.EntityId; |
35 | import org.thingsboard.server.common.data.id.TenantId; | 40 | import org.thingsboard.server.common.data.id.TenantId; |
36 | import org.thingsboard.server.common.data.page.PageData; | 41 | import org.thingsboard.server.common.data.page.PageData; |
37 | -import org.thingsboard.server.common.data.page.TimePageLink; | ||
38 | import org.thingsboard.server.common.data.query.AlarmData; | 42 | import org.thingsboard.server.common.data.query.AlarmData; |
43 | +import org.thingsboard.server.common.data.query.AlarmDataPageLink; | ||
39 | import org.thingsboard.server.common.data.query.AlarmDataQuery; | 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 | import org.thingsboard.server.dao.entity.AbstractEntityService; | 51 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
42 | import org.thingsboard.server.dao.entity.EntityService; | 52 | import org.thingsboard.server.dao.entity.EntityService; |
43 | import org.thingsboard.server.dao.exception.DataValidationException; | 53 | import org.thingsboard.server.dao.exception.DataValidationException; |
44 | import org.thingsboard.server.dao.service.DataValidator; | 54 | import org.thingsboard.server.dao.service.DataValidator; |
55 | +import org.thingsboard.server.dao.sql.alarm.AlarmRepository; | ||
45 | import org.thingsboard.server.dao.tenant.TenantDao; | 56 | import org.thingsboard.server.dao.tenant.TenantDao; |
46 | 57 | ||
47 | import javax.annotation.Nullable; | 58 | import javax.annotation.Nullable; |
48 | import javax.annotation.PostConstruct; | 59 | import javax.annotation.PostConstruct; |
49 | import javax.annotation.PreDestroy; | 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 | import java.util.concurrent.ExecutionException; | 68 | import java.util.concurrent.ExecutionException; |
52 | import java.util.concurrent.ExecutorService; | 69 | import java.util.concurrent.ExecutorService; |
53 | import java.util.concurrent.Executors; | 70 | import java.util.concurrent.Executors; |
@@ -72,6 +89,9 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ | @@ -72,6 +89,9 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ | ||
72 | @Autowired | 89 | @Autowired |
73 | private EntityService entityService; | 90 | private EntityService entityService; |
74 | 91 | ||
92 | + @Autowired | ||
93 | + private AlarmRepository alarmRepository; | ||
94 | + | ||
75 | protected ExecutorService readResultsProcessingExecutor; | 95 | protected ExecutorService readResultsProcessingExecutor; |
76 | 96 | ||
77 | @PostConstruct | 97 | @PostConstruct |
@@ -300,35 +320,23 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ | @@ -300,35 +320,23 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ | ||
300 | @Override | 320 | @Override |
301 | public AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus, | 321 | public AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus, |
302 | AlarmStatus alarmStatus) { | 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 | if (!alarms.isEmpty()) { | 340 | if (!alarms.isEmpty()) { |
333 | List<AlarmInfo> sorted = new ArrayList(alarms); | 341 | List<AlarmInfo> sorted = new ArrayList(alarms); |
334 | sorted.sort(Comparator.comparing(Alarm::getSeverity)); | 342 | sorted.sort(Comparator.comparing(Alarm::getSeverity)); |
@@ -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 | + 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,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 | + 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 | 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()); |