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 | 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()); | ... | ... |