From 9aed06a37b66bf18d2b10b83825a5a02ec80106a Mon Sep 17 00:00:00 2001 From: Valerii Sosliuk Date: Wed, 30 Jan 2019 14:25:39 +0200 Subject: [PATCH] delete alarm api added (#1431) * delete alarm api added * delete alarm api added --- .../server/controller/AlarmController.java | 13 +++ .../main/scripts/install/install_dev_db.sh | 2 +- .../server/dao/alarm/AlarmDao.java | 2 + .../server/dao/alarm/AlarmService.java | 2 + .../server/dao/alarm/BaseAlarmService.java | 26 +++++- .../server/dao/alarm/CassandraAlarmDao.java | 12 +++ .../server/dao/sql/alarm/JpaAlarmDao.java | 5 ++ .../dao/service/BaseAlarmServiceTest.java | 83 +++++++++++++++++++ pom.xml | 6 -- 9 files changed, 141 insertions(+), 10 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 6261e746aa..68cf2ce4d3 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -92,6 +92,19 @@ public class AlarmController extends BaseController { } } + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.DELETE) + @ResponseBody + public Boolean deleteAlarm(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { + checkParameter(ALARM_ID, strAlarmId); + try { + AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); + return alarmService.deleteAlarm(getTenantId(), alarmId); + } catch (Exception e) { + throw handleException(e); + } + } + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) diff --git a/application/src/main/scripts/install/install_dev_db.sh b/application/src/main/scripts/install/install_dev_db.sh index 212a2accda..70169e0b3d 100644 --- a/application/src/main/scripts/install/install_dev_db.sh +++ b/application/src/main/scripts/install/install_dev_db.sh @@ -28,7 +28,7 @@ export LOADER_PATH=${BASE}/conf,${BASE}/extensions export SQL_DATA_FOLDER=${SQL_DATA_FOLDER:-/tmp} -run_user=thingsboard +run_user="$USER" sudo -u "$run_user" -s /bin/sh -c "java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \ -Dinstall.data_dir=${installDir} \ diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java index 5d5456fb44..68bbbe4e81 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java @@ -31,6 +31,8 @@ import java.util.UUID; */ public interface AlarmDao extends Dao { + Boolean deleteAlarm(TenantId tenantId, Alarm alarm); + ListenableFuture findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type); ListenableFuture findAlarmByIdAsync(TenantId tenantId, UUID key); diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java index aace8327e9..4cac09488a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java @@ -35,6 +35,8 @@ public interface AlarmService { Alarm createOrUpdateAlarm(Alarm alarm); + Boolean deleteAlarm(TenantId tenantId, AlarmId alarmId); + ListenableFuture ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTs); ListenableFuture clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long ackTs); diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index d0698b6986..9405dd5f25 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -24,6 +24,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmId; @@ -118,6 +119,21 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ return alarmDao.findLatestByOriginatorAndType(tenantId, originator, type); } + @Override + public Boolean deleteAlarm(TenantId tenantId, AlarmId alarmId) { + try { + log.debug("Deleting Alarm Id: {}", alarmId); + Alarm alarm = alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()).get(); + if (alarm == null) { + return false; + } + deleteEntityRelations(tenantId, alarm.getId()); + return alarmDao.deleteAlarm(tenantId, alarm); + } catch (ExecutionException | InterruptedException e) { + throw new RuntimeException(e); + } + } + private Alarm createAlarm(Alarm alarm) throws InterruptedException, ExecutionException { log.debug("New Alarm : {}", alarm); Alarm saved = alarmDao.save(alarm.getTenantId(), alarm); @@ -127,9 +143,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ private void createAlarmRelations(Alarm alarm) throws InterruptedException, ExecutionException { if (alarm.isPropagate()) { - EntityRelationsQuery query = new EntityRelationsQuery(); - query.setParameters(new RelationsSearchParameters(alarm.getOriginator(), EntitySearchDirection.TO, Integer.MAX_VALUE)); - List parentEntities = relationService.findByQuery(alarm.getTenantId(), query).get().stream().map(EntityRelation::getFrom).collect(Collectors.toList()); + List parentEntities = getParentEntities(alarm); for (EntityId parentId : parentEntities) { createAlarmRelation(alarm.getTenantId(), parentId, alarm.getId(), alarm.getStatus(), true); } @@ -137,6 +151,12 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ createAlarmRelation(alarm.getTenantId(), alarm.getOriginator(), alarm.getId(), alarm.getStatus(), true); } + private List getParentEntities(Alarm alarm) throws InterruptedException, ExecutionException { + EntityRelationsQuery query = new EntityRelationsQuery(); + query.setParameters(new RelationsSearchParameters(alarm.getOriginator(), EntitySearchDirection.TO, Integer.MAX_VALUE)); + return relationService.findByQuery(alarm.getTenantId(), query).get().stream().map(EntityRelation::getFrom).collect(Collectors.toList()); + } + private ListenableFuture updateAlarm(Alarm update) { alarmDataValidator.validate(update, Alarm::getTenantId); return getAndUpdate(update.getTenantId(), update.getId(), new Function() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/CassandraAlarmDao.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/CassandraAlarmDao.java index ed8666fa81..48adbe31e2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/CassandraAlarmDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/CassandraAlarmDao.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.alarm; +import com.datastax.driver.core.Statement; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.google.common.util.concurrent.Futures; @@ -78,6 +79,17 @@ public class CassandraAlarmDao extends CassandraAbstractModelDao findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) { Select select = select().from(ALARM_COLUMN_FAMILY_NAME); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java index 2e071b1a89..3e2a80fc9d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java @@ -68,6 +68,11 @@ public class JpaAlarmDao extends JpaAbstractDao implements A return alarmRepository; } + @Override + public Boolean deleteAlarm(TenantId tenantId, Alarm alarm) { + return removeById(tenantId, alarm.getUuidId()); + } + @Override public ListenableFuture findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) { return service.submit(() -> { diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java index 8c4437416e..50b2e7ffa6 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java @@ -31,7 +31,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.TimePageData; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.relation.RelationTypeGroup; +import java.util.List; import java.util.concurrent.ExecutionException; public abstract class BaseAlarmServiceTest extends AbstractServiceTest { @@ -184,4 +186,85 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { Assert.assertEquals(1, alarms.getData().size()); Assert.assertEquals(created, alarms.getData().get(0)); } + + @Test + public void testDeleteAlarm() throws ExecutionException, InterruptedException { + AssetId parentId = new AssetId(UUIDs.timeBased()); + AssetId childId = new AssetId(UUIDs.timeBased()); + + EntityRelation relation = new EntityRelation(parentId, childId, EntityRelation.CONTAINS_TYPE); + + Assert.assertTrue(relationService.saveRelationAsync(tenantId, relation).get()); + + long ts = System.currentTimeMillis(); + Alarm alarm = Alarm.builder().tenantId(tenantId).originator(childId) + .type(TEST_ALARM) + .propagate(true) + .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) + .startTs(ts).build(); + + Alarm created = alarmService.createOrUpdateAlarm(alarm); + + TimePageData alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder() + .affectedEntityId(childId) + .status(AlarmStatus.ACTIVE_UNACK).pageLink( + new TimePageLink(1, 0L, System.currentTimeMillis(), false) + ).build()).get(); + Assert.assertNotNull(alarms.getData()); + Assert.assertEquals(1, alarms.getData().size()); + Assert.assertEquals(created, alarms.getData().get(0)); + + // Check parent relation + alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder() + .affectedEntityId(parentId) + .status(AlarmStatus.ACTIVE_UNACK).pageLink( + new TimePageLink(1, 0L, System.currentTimeMillis(), false) + ).build()).get(); + Assert.assertNotNull(alarms.getData()); + Assert.assertEquals(1, alarms.getData().size()); + Assert.assertEquals(created, alarms.getData().get(0)); + + List toAlarmRelations = relationService.findByTo(tenantId, created.getId(), RelationTypeGroup.ALARM); + Assert.assertEquals(8, toAlarmRelations.size()); + + List fromChildRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM); + Assert.assertEquals(4, fromChildRelations.size()); + + List fromParentRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM); + Assert.assertEquals(4, fromParentRelations.size()); + + + Assert.assertTrue("Alarm was not deleted when expected", alarmService.deleteAlarm(tenantId, created.getId())); + + Alarm fetched = alarmService.findAlarmByIdAsync(tenantId, created.getId()).get(); + + Assert.assertNull("Alarm was returned when it was expected to be null", fetched); + + alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder() + .affectedEntityId(childId) + .status(AlarmStatus.ACTIVE_UNACK).pageLink( + new TimePageLink(1, 0L, System.currentTimeMillis(), false) + ).build()).get(); + Assert.assertNotNull(alarms.getData()); + Assert.assertEquals(0, alarms.getData().size()); + + // Check parent relation + alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder() + .affectedEntityId(parentId) + .status(AlarmStatus.ACTIVE_UNACK).pageLink( + new TimePageLink(1, 0L, System.currentTimeMillis(), false) + ).build()).get(); + Assert.assertNotNull(alarms.getData()); + Assert.assertEquals(0, alarms.getData().size()); + + toAlarmRelations = relationService.findByTo(tenantId, created.getId(), RelationTypeGroup.ALARM); + Assert.assertEquals(0, toAlarmRelations.size()); + + fromChildRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM); + Assert.assertEquals(0, fromChildRelations.size()); + + fromParentRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM); + Assert.assertEquals(0, fromParentRelations.size()); + + } } diff --git a/pom.xml b/pom.xml index bfb5caa1ce..2cf62185b1 100755 --- a/pom.xml +++ b/pom.xml @@ -756,12 +756,6 @@ hsqldb ${hsqldb.version} - - ru.yandex.qatools.embed - postgresql-embedded - 2.2 - test - org.springframework.data spring-data-redis