Merge pull request #3991 from AndrewVolosytnykhThingsboard/andrewdev

#3966 highestAlarmSeverity fixed
This commit is contained in:
Igor Kulikov 2021-01-29 13:12:32 +02:00 committed by GitHub
commit ef0182414f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 32 deletions

View File

@ -19,16 +19,18 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmQuery;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.query.AlarmData;
import org.thingsboard.server.common.data.query.AlarmDataPageLink;
import org.thingsboard.server.common.data.query.AlarmDataQuery;
import org.thingsboard.server.dao.Dao;
import java.util.Collection;
import java.util.Set;
import java.util.UUID;
/**
@ -48,4 +50,6 @@ public interface AlarmDao extends Dao<Alarm> {
PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId,
AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
Set<AlarmSeverity> findAlarmSeverities(TenantId tenantId, EntityId entityId, Set<AlarmStatus> status);
}

View File

@ -39,10 +39,10 @@ import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.query.AlarmData;
import org.thingsboard.server.common.data.query.AlarmDataPageLink;
import org.thingsboard.server.common.data.query.AlarmDataQuery;
import org.thingsboard.server.common.data.query.DeviceTypeFilter;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
@ -60,7 +60,6 @@ import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@ -316,37 +315,16 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
@Override
public AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus,
AlarmStatus alarmStatus) {
TimePageLink nextPageLink = new TimePageLink(100);
boolean hasNext = true;
AlarmSeverity highestSeverity = null;
AlarmQuery query;
while (hasNext && AlarmSeverity.CRITICAL != highestSeverity) {
query = new AlarmQuery(entityId, nextPageLink, alarmSearchStatus, alarmStatus, false, null);
PageData<AlarmInfo> alarms = alarmDao.findAlarms(tenantId, query);
if (alarms.hasNext()) {
nextPageLink = nextPageLink.nextPageLink();
}
AlarmSeverity severity = detectHighestSeverity(alarms.getData());
if (severity == null) {
continue;
}
if (severity == AlarmSeverity.CRITICAL || highestSeverity == null) {
highestSeverity = severity;
} else {
highestSeverity = highestSeverity.compareTo(severity) < 0 ? highestSeverity : severity;
}
Set<AlarmStatus> statusList = null;
if (alarmSearchStatus != null) {
statusList = alarmSearchStatus.getStatuses();
} else if (alarmStatus != null) {
statusList = Collections.singleton(alarmStatus);
}
return highestSeverity;
}
private AlarmSeverity detectHighestSeverity(List<AlarmInfo> alarms) {
if (!alarms.isEmpty()) {
List<AlarmInfo> sorted = new ArrayList(alarms);
sorted.sort(Comparator.comparing(Alarm::getSeverity));
return sorted.get(0).getSeverity();
} else {
return null;
}
Set<AlarmSeverity> alarmSeverities = alarmDao.findAlarmSeverities(tenantId, entityId, statusList);
return alarmSeverities.stream().min(AlarmSeverity::compareTo).orElse(null);
}
private void deleteRelation(TenantId tenantId, EntityRelation alarmRelation) {

View File

@ -20,6 +20,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.dao.model.sql.AlarmEntity;
import org.thingsboard.server.dao.model.sql.AlarmInfoEntity;
@ -75,4 +76,12 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
@Param("searchText") String searchText,
Pageable pageable);
@Query("SELECT alarm.severity FROM AlarmEntity alarm" +
" WHERE alarm.tenantId = :tenantId" +
" AND alarm.originatorId = :entityId" +
" AND ((:status) IS NULL OR alarm.status in (:status))")
Set<AlarmSeverity> findAlarmSeverities(@Param("tenantId") UUID tenantId,
@Param("entityId") UUID entityId,
@Param("status") Set<AlarmStatus> status);
}

View File

@ -24,6 +24,7 @@ import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmQuery;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
@ -120,4 +121,9 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
return alarmQueryRepository.findAlarmDataByQueryForEntities(tenantId, customerId, query, orderedEntityIds);
}
@Override
public Set<AlarmSeverity> findAlarmSeverities(TenantId tenantId, EntityId entityId, Set<AlarmStatus> status) {
return alarmRepository.findAlarmSeverities(tenantId.getId(), entityId.getId(), status);
}
}

View File

@ -354,6 +354,62 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
return new AlarmDataQuery(new DeviceTypeFilter(), pageLink, null, null, null, alarmFields);
}
@Test
public void testFindHighestAlarmSeverity() throws ExecutionException, InterruptedException {
Customer customer = new Customer();
customer.setTitle("TestCustomer");
customer.setTenantId(tenantId);
customer = customerService.saveCustomer(customer);
Device customerDevice = new Device();
customerDevice.setName("TestCustomerDevice");
customerDevice.setType("default");
customerDevice.setTenantId(tenantId);
customerDevice.setCustomerId(customer.getId());
customerDevice = deviceService.saveDevice(customerDevice);
// no one alarms was created
Assert.assertNull(alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, null));
Alarm alarm1 = Alarm.builder()
.tenantId(tenantId)
.originator(customerDevice.getId())
.type(TEST_ALARM)
.severity(AlarmSeverity.MAJOR)
.status(AlarmStatus.ACTIVE_UNACK)
.startTs(System.currentTimeMillis())
.build();
alarm1 = alarmService.createOrUpdateAlarm(alarm1).getAlarm();
alarmService.clearAlarm(tenantId, alarm1.getId(), null, System.currentTimeMillis()).get();
Alarm alarm2 = Alarm.builder()
.tenantId(tenantId)
.originator(customerDevice.getId())
.type(TEST_ALARM)
.severity(AlarmSeverity.MINOR)
.status(AlarmStatus.ACTIVE_ACK)
.startTs(System.currentTimeMillis())
.build();
alarm2 = alarmService.createOrUpdateAlarm(alarm2).getAlarm();
alarmService.clearAlarm(tenantId, alarm2.getId(), null, System.currentTimeMillis()).get();
Alarm alarm3 = Alarm.builder()
.tenantId(tenantId)
.originator(customerDevice.getId())
.type(TEST_ALARM)
.severity(AlarmSeverity.CRITICAL)
.status(AlarmStatus.ACTIVE_ACK)
.startTs(System.currentTimeMillis())
.build();
alarm3 = alarmService.createOrUpdateAlarm(alarm3).getAlarm();
Assert.assertEquals(AlarmSeverity.MAJOR, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), AlarmSearchStatus.UNACK, null));
Assert.assertEquals(AlarmSeverity.CRITICAL, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, null));
Assert.assertEquals(AlarmSeverity.MAJOR, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, AlarmStatus.CLEARED_UNACK));
Assert.assertEquals(AlarmSeverity.CRITICAL, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), AlarmSearchStatus.ACTIVE, null));
Assert.assertEquals(AlarmSeverity.MINOR, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, AlarmStatus.CLEARED_ACK));
}
@Test
public void testFindAlarmUsingAlarmDataQuery() throws ExecutionException, InterruptedException {
AssetId parentId = new AssetId(Uuids.timeBased());