Browse Source

Merge branch 'master' of github.com:thingsboard/thingsboard

pull/9390/head
Igor Kulikov 3 years ago
parent
commit
7699e49655
  1. 12
      application/src/main/java/org/thingsboard/server/controller/AlarmController.java
  2. 2
      application/src/main/java/org/thingsboard/server/controller/AssetController.java
  3. 2
      application/src/main/java/org/thingsboard/server/controller/DeviceController.java
  4. 20
      application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java
  5. 7
      application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java
  6. 3
      application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java
  7. 7
      application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java
  8. 2
      application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java
  9. 80
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java
  10. 65
      application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java
  11. 36
      application/src/test/java/org/thingsboard/server/controller/AssetControllerTest.java
  12. 37
      application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java
  13. 8
      application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java
  14. 64
      common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmOperationResult.java
  15. 31
      common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java
  16. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsService.java
  17. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java
  18. 2
      dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java
  19. 140
      dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
  20. 46
      dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java
  21. 4
      dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardDao.java
  22. 25
      dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java
  23. 3
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsDao.java
  24. 9
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsServiceImpl.java
  25. 50
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
  26. 2
      dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java
  27. 2
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java
  28. 5
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
  29. 3
      dao/src/main/java/org/thingsboard/server/dao/service/PaginatedRemover.java
  30. 4
      dao/src/main/java/org/thingsboard/server/dao/sql/alarm/EntityAlarmRepository.java
  31. 6
      dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java
  32. 3
      dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/DashboardRepository.java
  33. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardDao.java
  34. 8
      dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceCredentialsRepository.java
  35. 7
      dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceCredentialsDao.java
  36. 2
      dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java
  37. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java
  38. 7
      dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java
  39. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/user/UserCredentialsRepository.java
  40. 3
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java
  41. 3
      dao/src/main/java/org/thingsboard/server/dao/user/UserCredentialsDao.java
  42. 8
      dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java
  43. 11
      dao/src/test/java/org/thingsboard/server/dao/service/AlarmCommentServiceTest.java
  44. 52
      dao/src/test/java/org/thingsboard/server/dao/service/AlarmServiceTest.java
  45. 26
      rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java

12
application/src/main/java/org/thingsboard/server/controller/AlarmController.java

@ -286,7 +286,7 @@ public class AlarmController extends BaseController {
}
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, assigneeUserId, fetchOriginator)).get());
return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, assigneeUserId, fetchOriginator)));
}
@ApiOperation(value = "Get All Alarms (getAllAlarms)",
@ -335,9 +335,9 @@ public class AlarmController extends BaseController {
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
if (getCurrentUser().isCustomerUser()) {
return checkNotNull(alarmService.findCustomerAlarms(getCurrentUser().getTenantId(), getCurrentUser().getCustomerId(), new AlarmQuery(null, pageLink, alarmSearchStatus, alarmStatus, assigneeUserId, fetchOriginator)).get());
return checkNotNull(alarmService.findCustomerAlarms(getCurrentUser().getTenantId(), getCurrentUser().getCustomerId(), new AlarmQuery(null, pageLink, alarmSearchStatus, alarmStatus, assigneeUserId, fetchOriginator)));
} else {
return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(null, pageLink, alarmSearchStatus, alarmStatus, assigneeUserId, fetchOriginator)).get());
return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(null, pageLink, alarmSearchStatus, alarmStatus, assigneeUserId, fetchOriginator)));
}
}
@ -402,7 +402,7 @@ public class AlarmController extends BaseController {
}
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
return checkNotNull(alarmService.findAlarmsV2(getCurrentUser().getTenantId(), new AlarmQueryV2(entityId, pageLink, alarmTypeList, alarmStatusList, alarmSeverityList, assigneeUserId)).get());
return checkNotNull(alarmService.findAlarmsV2(getCurrentUser().getTenantId(), new AlarmQueryV2(entityId, pageLink, alarmTypeList, alarmStatusList, alarmSeverityList, assigneeUserId)));
}
@ApiOperation(value = "Get All Alarms (getAllAlarmsV2)",
@ -461,9 +461,9 @@ public class AlarmController extends BaseController {
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
if (getCurrentUser().isCustomerUser()) {
return checkNotNull(alarmService.findCustomerAlarmsV2(getCurrentUser().getTenantId(), getCurrentUser().getCustomerId(), new AlarmQueryV2(null, pageLink, alarmTypeList, alarmStatusList, alarmSeverityList, assigneeUserId)).get());
return checkNotNull(alarmService.findCustomerAlarmsV2(getCurrentUser().getTenantId(), getCurrentUser().getCustomerId(), new AlarmQueryV2(null, pageLink, alarmTypeList, alarmStatusList, alarmSeverityList, assigneeUserId)));
} else {
return checkNotNull(alarmService.findAlarmsV2(getCurrentUser().getTenantId(), new AlarmQueryV2(null, pageLink, alarmTypeList, alarmStatusList, alarmSeverityList, assigneeUserId)).get());
return checkNotNull(alarmService.findAlarmsV2(getCurrentUser().getTenantId(), new AlarmQueryV2(null, pageLink, alarmTypeList, alarmStatusList, alarmSeverityList, assigneeUserId)));
}
}

2
application/src/main/java/org/thingsboard/server/controller/AssetController.java

@ -153,7 +153,7 @@ public class AssetController extends BaseController {
checkParameter(ASSET_ID, strAssetId);
AssetId assetId = new AssetId(toUUID(strAssetId));
Asset asset = checkAssetId(assetId, Operation.DELETE);
tbAssetService.delete(asset, getCurrentUser()).get();
tbAssetService.delete(asset, getCurrentUser());
}
@ApiOperation(value = "Assign asset to customer (assignAssetToCustomer)",

2
application/src/main/java/org/thingsboard/server/controller/DeviceController.java

@ -229,7 +229,7 @@ public class DeviceController extends BaseController {
checkParameter(DEVICE_ID, strDeviceId);
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
Device device = checkDeviceId(deviceId, Operation.DELETE);
tbDeviceService.delete(device, getCurrentUser()).get();
tbDeviceService.delete(device, getCurrentUser());
}
@ApiOperation(value = "Assign device to customer (assignDeviceToCustomer)",

20
application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java

@ -29,7 +29,6 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmQuery;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
@ -46,7 +45,6 @@ import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
@Slf4j
public abstract class AbstractTbEntityService {
@ -63,26 +61,22 @@ public abstract class AbstractTbEntityService {
protected EdgeService edgeService;
@Autowired
protected AlarmService alarmService;
@Autowired @Lazy
@Autowired
@Lazy
protected AlarmSubscriptionService alarmSubscriptionService;
@Autowired
protected CustomerService customerService;
@Autowired
protected TbClusterService tbClusterService;
@Autowired(required = false) @Lazy
@Autowired(required = false)
@Lazy
private EntitiesVersionControlService vcService;
protected ListenableFuture<Void> removeAlarmsByEntityId(TenantId tenantId, EntityId entityId) {
ListenableFuture<PageData<AlarmInfo>> alarmsFuture =
protected void removeAlarmsByEntityId(TenantId tenantId, EntityId entityId) {
PageData<AlarmInfo> alarms =
alarmService.findAlarms(tenantId, new AlarmQuery(entityId, new TimePageLink(Integer.MAX_VALUE), null, null, null, false));
ListenableFuture<List<AlarmId>> alarmIdsFuture = Futures.transform(alarmsFuture, page ->
page.getData().stream().map(AlarmInfo::getId).collect(Collectors.toList()), dbExecutor);
return Futures.transform(alarmIdsFuture, ids -> {
ids.stream().map(alarmId -> alarmService.deleteAlarm(tenantId, alarmId)).collect(Collectors.toList());
return null;
}, dbExecutor);
alarms.getData().stream().map(AlarmInfo::getId).forEach(alarmId -> alarmService.delAlarm(tenantId, alarmId));
}
protected <T> T checkNotNull(T reference) throws ThingsboardException {

7
application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java

@ -15,9 +15,9 @@
*/
package org.thingsboard.server.service.entitiy.asset;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.User;
@ -72,15 +72,16 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb
}
@Override
public ListenableFuture<Void> delete(Asset asset, User user) {
@Transactional
public void delete(Asset asset, User user) {
ActionType actionType = ActionType.DELETED;
TenantId tenantId = asset.getTenantId();
AssetId assetId = asset.getId();
try {
removeAlarmsByEntityId(tenantId, assetId);
assetService.deleteAsset(tenantId, assetId);
notificationEntityService.logEntityAction(tenantId, assetId, asset, asset.getCustomerId(), actionType, user, assetId.toString());
tbClusterService.broadcastEntityStateChangeEvent(tenantId, assetId, ComponentLifecycleEvent.DELETED);
return removeAlarmsByEntityId(tenantId, assetId);
} catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, user, e,
assetId.toString());

3
application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.service.entitiy.asset;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.asset.Asset;
@ -28,7 +27,7 @@ public interface TbAssetService {
Asset save(Asset asset, User user) throws Exception;
ListenableFuture<Void> delete(Asset asset, User user);
void delete(Asset asset, User user);
Asset assignAssetToCustomer(TenantId tenantId, AssetId assetId, Customer customer, User user) throws ThingsboardException;

7
application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java

@ -21,6 +21,7 @@ import com.google.common.util.concurrent.MoreExecutors;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityType;
@ -91,15 +92,15 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
}
@Override
public ListenableFuture<Void> delete(Device device, User user) {
@Transactional
public void delete(Device device, User user) {
TenantId tenantId = device.getTenantId();
DeviceId deviceId = device.getId();
try {
removeAlarmsByEntityId(tenantId, deviceId);
deviceService.deleteDevice(tenantId, deviceId);
notificationEntityService.notifyDeleteDevice(tenantId, deviceId, device.getCustomerId(), device,
user, deviceId.toString());
return removeAlarmsByEntityId(tenantId, deviceId);
} catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), ActionType.DELETED,
user, e, deviceId.toString());

2
application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java

@ -35,7 +35,7 @@ public interface TbDeviceService {
Device saveDeviceWithCredentials(Device device, DeviceCredentials deviceCredentials, User user) throws ThingsboardException;
ListenableFuture<Void> delete(Device device, User user);
void delete(Device device, User user);
Device assignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, Customer customer, User user) throws ThingsboardException;

80
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java

@ -53,7 +53,6 @@ import org.thingsboard.server.common.data.query.AlarmDataQuery;
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.stats.TbApiUsageReportClient;
import org.thingsboard.server.dao.alarm.AlarmOperationResult;
import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.entitiy.alarm.TbAlarmCommentService;
@ -115,31 +114,6 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
return withWsCallback(alarmService.unassignAlarm(tenantId, alarmId, assignTs));
}
@Override
public Alarm createOrUpdateAlarm(Alarm alarm) {
AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm, apiUsageStateService.getApiUsageState(alarm.getTenantId()).isAlarmCreationEnabled());
if (result.isSuccessful()) {
onAlarmUpdated(result);
AlarmSeverity oldSeverity = result.getOldSeverity();
if (oldSeverity != null && !oldSeverity.equals(result.getAlarm().getSeverity())) {
AlarmComment alarmComment = AlarmComment.builder()
.alarmId(alarm.getId())
.type(AlarmCommentType.SYSTEM)
.comment(JacksonUtil.newObjectNode().put("text", String.format("Alarm severity was updated from %s to %s", oldSeverity, result.getAlarm().getSeverity())))
.build();
try {
alarmCommentService.saveAlarmComment(alarm, alarmComment, null);
} catch (ThingsboardException e) {
log.error("Failed to save alarm comment", e);
}
}
}
if (result.isCreated()) {
apiUsageClient.report(alarm.getTenantId(), null, ApiUsageRecordKey.CREATED_ALARMS_COUNT);
}
return result.getAlarm();
}
@Override
public Boolean deleteAlarm(TenantId tenantId, AlarmId alarmId) {
AlarmApiCallResult result = alarmService.delAlarm(tenantId, alarmId);
@ -147,26 +121,6 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
return result.isSuccessful();
}
@Override
public ListenableFuture<Boolean> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTs) {
ListenableFuture<AlarmApiCallResult> result = Futures.immediateFuture(alarmService.acknowledgeAlarm(tenantId, alarmId, ackTs));
Futures.addCallback(result, new AlarmUpdateCallback(), wsCallBackExecutor);
return Futures.transform(result, AlarmApiCallResult::isSuccessful, wsCallBackExecutor);
}
@Override
public ListenableFuture<Boolean> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs) {
AlarmApiCallResult result = alarmService.clearAlarm(tenantId, alarmId, clearTs, details);
return Futures.transform(Futures.immediateFuture(result), AlarmApiCallResult::isSuccessful, wsCallBackExecutor);
}
@Override
public ListenableFuture<AlarmOperationResult> clearAlarmForResult(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs) {
AlarmApiCallResult result = alarmService.clearAlarm(tenantId, alarmId, clearTs, details);
Futures.addCallback(Futures.immediateFuture(result), new AlarmUpdateCallback(), wsCallBackExecutor);
return Futures.immediateFuture(new AlarmOperationResult(result));
}
@Override
public ListenableFuture<Alarm> findAlarmByIdAsync(TenantId tenantId, AlarmId alarmId) {
return alarmService.findAlarmByIdAsync(tenantId, alarmId);
@ -183,22 +137,22 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
}
@Override
public ListenableFuture<PageData<AlarmInfo>> findAlarms(TenantId tenantId, AlarmQuery query) {
public PageData<AlarmInfo> findAlarms(TenantId tenantId, AlarmQuery query) {
return alarmService.findAlarms(tenantId, query);
}
@Override
public ListenableFuture<PageData<AlarmInfo>> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query) {
public PageData<AlarmInfo> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query) {
return alarmService.findCustomerAlarms(tenantId, customerId, query);
}
@Override
public ListenableFuture<PageData<AlarmInfo>> findAlarmsV2(TenantId tenantId, AlarmQueryV2 query) {
public PageData<AlarmInfo> findAlarmsV2(TenantId tenantId, AlarmQueryV2 query) {
return alarmService.findAlarmsV2(tenantId, query);
}
@Override
public ListenableFuture<PageData<AlarmInfo>> findCustomerAlarmsV2(TenantId tenantId, CustomerId customerId, AlarmQueryV2 query) {
public PageData<AlarmInfo> findCustomerAlarmsV2(TenantId tenantId, CustomerId customerId, AlarmQueryV2 query) {
return alarmService.findCustomerAlarmsV2(tenantId, customerId, query);
}
@ -218,23 +172,8 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
}
@Override
public ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) {
return alarmService.findLatestByOriginatorAndType(tenantId, originator, type);
}
@Deprecated
private void onAlarmUpdated(AlarmOperationResult result) {
wsCallBackExecutor.submit(() -> {
AlarmInfo alarm = new AlarmInfo(result.getAlarm());
TenantId tenantId = alarm.getTenantId();
for (EntityId entityId : result.getPropagatedEntitiesList()) {
forwardToSubscriptionManagerService(tenantId, entityId, subscriptionManagerService -> {
subscriptionManagerService.onAlarmUpdate(tenantId, entityId, alarm, TbCallback.EMPTY);
}, () -> {
return TbSubscriptionUtils.toAlarmUpdateProto(tenantId, entityId, alarm);
});
}
});
public Alarm findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) {
return alarmService.findLatestActiveByOriginatorAndType(tenantId, originator, type);
}
@Override
@ -248,10 +187,9 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
TenantId tenantId = alarm.getTenantId();
for (EntityId entityId : result.getPropagatedEntitiesList()) {
forwardToSubscriptionManagerService(tenantId, entityId, subscriptionManagerService -> {
subscriptionManagerService.onAlarmUpdate(tenantId, entityId, alarm, TbCallback.EMPTY);
}, () -> {
return TbSubscriptionUtils.toAlarmUpdateProto(tenantId, entityId, alarm);
});
subscriptionManagerService.onAlarmUpdate(tenantId, entityId, alarm, TbCallback.EMPTY);
}, () -> TbSubscriptionUtils.toAlarmUpdateProto(tenantId, entityId, alarm)
);
}
notificationRuleProcessor.process(AlarmTrigger.builder()
.tenantId(tenantId)

65
application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java

@ -41,6 +41,8 @@ import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.alarm.AlarmDao;
@ -48,6 +50,7 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
@ -806,10 +809,14 @@ public class AlarmControllerTest extends AbstractControllerTest {
}
private AlarmInfo createAlarm(String type) throws Exception {
return createAlarm(type, customerDevice.getId(), customerId);
}
private AlarmInfo createAlarm(String type, EntityId originatorId, CustomerId customerId) throws Exception {
Alarm alarm = Alarm.builder()
.tenantId(tenantId)
.customerId(customerId)
.originator(customerDevice.getId())
.originator(originatorId)
.severity(AlarmSeverity.CRITICAL)
.type(type)
.build();
@ -963,4 +970,60 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertTrue(foundTypes.isEmpty());
}
@Test
public void testDeleteAlarmTypesAfterDeletingAlarmOriginator() throws Exception {
loginTenantAdmin();
List<Device> devices = new ArrayList<>();
List<String> types = new ArrayList<>();
for (int i = 0; i < 13; i++) {
Device device = new Device();
device.setName("Test_device_" + i);
devices.add(device = doPost("/api/device", device, Device.class));
types.add(createAlarm(TEST_ALARM_TYPE + i, device.getId(), null).getType());
}
devices.sort(Comparator.comparing(Device::getName));
Collections.sort(types);
List<String> foundTypes = doGetTyped("/api/alarm/types?pageSize=1024&page=0", new TypeReference<PageData<EntitySubtype>>() {
})
.getData()
.stream()
.map(EntitySubtype::getType)
.sorted()
.collect(Collectors.toList());
Assert.assertEquals(13, foundTypes.size());
Assert.assertEquals(types, foundTypes);
for (int i = 0; i < 12; i++) {
doDelete("/api/device/" + devices.remove(0).getId()).andExpect(status().isOk());
types.remove(0);
}
foundTypes = doGetTyped("/api/alarm/types?pageSize=1024&page=0", new TypeReference<PageData<EntitySubtype>>() {
})
.getData()
.stream()
.map(EntitySubtype::getType)
.collect(Collectors.toList());
Assert.assertEquals(types.size(), foundTypes.size());
Assert.assertEquals(types, foundTypes);
doDelete("/api/device/" + devices.get(0).getId()).andExpect(status().isOk());
foundTypes = doGetTyped("/api/alarm/types?pageSize=1024&page=0", new TypeReference<PageData<EntitySubtype>>() {
})
.getData()
.stream()
.map(EntitySubtype::getType)
.sorted()
.collect(Collectors.toList());
Assert.assertTrue(foundTypes.isEmpty());
}
}

36
application/src/test/java/org/thingsboard/server/controller/AssetControllerTest.java

@ -34,6 +34,9 @@ import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.audit.ActionType;
@ -291,6 +294,39 @@ public class AssetControllerTest extends AbstractControllerTest {
.andExpect(statusReason(containsString(msgErrorNoFound("Asset", assetIdStr))));
}
@Test
public void testDeleteAssetWithAlarmsAndAlarmTypes() throws Exception {
Asset asset = new Asset();
asset.setName("My asset");
asset.setType("default");
Asset savedAsset = doPost("/api/asset", asset, Asset.class);
Alarm alarm = Alarm.builder()
.tenantId(tenantId)
.originator(savedAsset.getId())
.severity(AlarmSeverity.CRITICAL)
.type("test_type")
.build();
alarm = doPost("/api/alarm", alarm, Alarm.class);
Assert.assertNotNull(alarm);
AlarmInfo foundAlarm = doGet("/api/alarm/info/" + alarm.getId(), AlarmInfo.class);
Assert.assertNotNull(foundAlarm);
doDelete("/api/asset/" + savedAsset.getId().getId().toString())
.andExpect(status().isOk());
String assetIdStr = savedAsset.getId().getId().toString();
doGet("/api/asset/" + assetIdStr)
.andExpect(status().isNotFound())
.andExpect(statusReason(containsString(msgErrorNoFound("Asset", assetIdStr))));
doGet("/api/alarm/info/" + alarm.getId())
.andExpect(status().isNotFound())
.andExpect(statusReason(containsString(msgErrorNoFound("Alarm", alarm.getId().getId().toString()))));
}
@Test
public void testDeleteAssetAssignedToEntityView() throws Exception {
Asset asset1 = new Asset();

37
application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java

@ -48,6 +48,10 @@ import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId;
@ -504,6 +508,39 @@ public class DeviceControllerTest extends AbstractControllerTest {
.andExpect(statusReason(containsString(msgErrorNoFound("Device", savedDeviceId.getId().toString()))));
}
@Test
public void testDeleteDeviceWithAlarmsAndAlarmTypes() throws Exception {
Device device = new Device();
device.setName("My device");
device.setType("default");
Device savedDevice = doPost("/api/device", device, Device.class);
Alarm alarm = Alarm.builder()
.tenantId(tenantId)
.originator(savedDevice.getId())
.severity(AlarmSeverity.CRITICAL)
.type("test_type")
.build();
alarm = doPost("/api/alarm", alarm, Alarm.class);
Assert.assertNotNull(alarm);
AlarmInfo foundAlarm = doGet("/api/alarm/info/" + alarm.getId(), AlarmInfo.class);
Assert.assertNotNull(foundAlarm);
doDelete("/api/device/" + savedDevice.getId().getId().toString())
.andExpect(status().isOk());
String DeviceIdStr = savedDevice.getId().getId().toString();
doGet("/api/device/" + DeviceIdStr)
.andExpect(status().isNotFound())
.andExpect(statusReason(containsString(msgErrorNoFound("Device", DeviceIdStr))));
doGet("/api/device/info/" + alarm.getId())
.andExpect(status().isNotFound())
.andExpect(statusReason(containsString(msgErrorNoFound("Device", alarm.getId().getId().toString()))));
}
@Test
public void testSaveDeviceWithEmptyType() throws Exception {
Device device = new Device();

8
application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java

@ -230,8 +230,8 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
doPost("/api/plugins/telemetry/" + device.getId() + "/" + DataConstants.SHARED_SCOPE, attr);
await().atMost(10, TimeUnit.SECONDS)
.until(() -> alarmSubscriptionService.findLatestByOriginatorAndType(tenantId, device.getId(), alarmType).get() != null);
Alarm alarm = alarmSubscriptionService.findLatestByOriginatorAndType(tenantId, device.getId(), alarmType).get();
.until(() -> alarmSubscriptionService.findLatestByOriginatorAndType(tenantId, device.getId(), alarmType) != null);
Alarm alarm = alarmSubscriptionService.findLatestByOriginatorAndType(tenantId, device.getId(), alarmType);
long ts = System.currentTimeMillis();
await().atMost(15, TimeUnit.SECONDS)
@ -313,8 +313,8 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
doPost("/api/plugins/telemetry/" + device.getId() + "/" + DataConstants.SHARED_SCOPE, attr);
await().atMost(10, TimeUnit.SECONDS)
.until(() -> alarmSubscriptionService.findLatestByOriginatorAndType(tenantId, device.getId(), alarmType).get() != null);
Alarm alarm = alarmSubscriptionService.findLatestByOriginatorAndType(tenantId, device.getId(), alarmType).get();
.until(() -> alarmSubscriptionService.findLatestByOriginatorAndType(tenantId, device.getId(), alarmType) != null);
Alarm alarm = alarmSubscriptionService.findLatestByOriginatorAndType(tenantId, device.getId(), alarmType);
getWsClient().waitForUpdate(true);
Notification notification = getWsClient().getLastDataUpdate().getUpdate();

64
common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmOperationResult.java

@ -1,64 +0,0 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.alarm;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmApiCallResult;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.id.EntityId;
import java.util.Collections;
import java.util.List;
@Builder
@Data
@AllArgsConstructor
@Deprecated
public class AlarmOperationResult {
private final Alarm alarm;
private final boolean successful;
private final boolean created;
private final AlarmSeverity oldSeverity;
private final List<EntityId> propagatedEntitiesList;
public AlarmOperationResult(Alarm alarm, boolean successful) {
this(alarm, successful, Collections.emptyList());
}
public AlarmOperationResult(Alarm alarm, boolean successful, List<EntityId> propagatedEntitiesList) {
this(alarm, successful, false, null, propagatedEntitiesList);
}
public AlarmOperationResult(Alarm alarm, boolean successful, boolean created, List<EntityId> propagatedEntitiesList) {
this.alarm = alarm;
this.successful = successful;
this.created = created;
this.propagatedEntitiesList = propagatedEntitiesList;
this.oldSeverity = null;
}
//Temporary while we have not removed the AlarmOperationResult.
public AlarmOperationResult(AlarmApiCallResult result) {
this.alarm = result.getAlarm() != null ? new Alarm(result.getAlarm()) : null;
this.successful = result.isSuccessful() && (result.isCreated() || result.isModified());
this.created = result.isCreated();
this.oldSeverity = result.getOldSeverity();
this.propagatedEntitiesList = result.getPropagatedEntitiesList();
}
}

31
common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java

@ -81,27 +81,6 @@ public interface AlarmService extends EntityDaoService {
void delAlarmTypes(TenantId tenantId, Set<String> types);
/*
* Legacy API, before 3.5.
*/
@Deprecated(since = "3.5.0", forRemoval = true)
AlarmOperationResult createOrUpdateAlarm(Alarm alarm);
@Deprecated(since = "3.5.0", forRemoval = true)
AlarmOperationResult createOrUpdateAlarm(Alarm alarm, boolean alarmCreationEnabled);
@Deprecated(since = "3.5.0", forRemoval = true)
ListenableFuture<AlarmOperationResult> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTs);
@Deprecated(since = "3.5.0", forRemoval = true)
ListenableFuture<AlarmOperationResult> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs);
@Deprecated(since = "3.5.0", forRemoval = true)
AlarmOperationResult deleteAlarm(TenantId tenantId, AlarmId alarmId);
@Deprecated(since = "3.5.0", forRemoval = true)
ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type);
// Other API
Alarm findAlarmById(TenantId tenantId, AlarmId alarmId);
@ -109,13 +88,13 @@ public interface AlarmService extends EntityDaoService {
AlarmInfo findAlarmInfoById(TenantId tenantId, AlarmId alarmId);
ListenableFuture<PageData<AlarmInfo>> findAlarms(TenantId tenantId, AlarmQuery query);
PageData<AlarmInfo> findAlarms(TenantId tenantId, AlarmQuery query);
ListenableFuture<PageData<AlarmInfo>> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query);
PageData<AlarmInfo> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query);
ListenableFuture<PageData<AlarmInfo>> findAlarmsV2(TenantId tenantId, AlarmQueryV2 query);
PageData<AlarmInfo> findAlarmsV2(TenantId tenantId, AlarmQueryV2 query);
ListenableFuture<PageData<AlarmInfo>> findCustomerAlarmsV2(TenantId tenantId, CustomerId customerId, AlarmQueryV2 query);
PageData<AlarmInfo> findCustomerAlarmsV2(TenantId tenantId, CustomerId customerId, AlarmQueryV2 query);
AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus,
AlarmStatus alarmStatus, String assigneeId);
@ -129,6 +108,8 @@ public interface AlarmService extends EntityDaoService {
void deleteEntityAlarmRelations(TenantId tenantId, EntityId entityId);
void deleteEntityAlarmRecordsByTenantId(TenantId tenantId);
long countAlarmsByQuery(TenantId tenantId, CustomerId customerId, AlarmCountQuery query);
PageData<EntitySubtype> findAlarmTypesByTenantId(TenantId tenantId, PageLink pageLink);

2
common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsService.java

@ -36,4 +36,6 @@ public interface DeviceCredentialsService {
void deleteDeviceCredentials(TenantId tenantId, DeviceCredentials deviceCredentials);
void deleteDeviceCredentialsByDeviceId(TenantId tenantId, DeviceId deviceId);
}

2
common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java

@ -76,6 +76,8 @@ public interface EntityViewService extends EntityDaoService {
List<EntityView> findEntityViewsByTenantIdAndEntityId(TenantId tenantId, EntityId entityId);
boolean existsByTenantIdAndEntityId(TenantId tenantId, EntityId entityId);
void deleteEntityView(TenantId tenantId, EntityViewId entityViewId);
void deleteEntityViewsByTenantId(TenantId tenantId);

2
dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java

@ -86,6 +86,8 @@ public interface AlarmDao extends Dao<Alarm> {
void deleteEntityAlarmRecords(TenantId tenantId, EntityId entityId);
void deleteEntityAlarmRecordsByTenantId(TenantId tenantId);
AlarmApiCallResult createOrUpdateActiveAlarm(AlarmCreateOrUpdateActiveRequest request, boolean alarmCreationEnabled);
AlarmApiCallResult updateAlarm(AlarmUpdateRequest request);

140
dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java

@ -18,7 +18,6 @@ package org.thingsboard.server.dao.alarm;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Function;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -162,51 +161,11 @@ public class BaseAlarmService extends AbstractCachedEntityService<TenantId, Page
return result;
}
@Override
public AlarmOperationResult createOrUpdateAlarm(Alarm alarm) {
return createOrUpdateAlarm(alarm, true);
}
@Override
public AlarmOperationResult createOrUpdateAlarm(Alarm alarm, boolean alarmCreationEnabled) {
alarmDataValidator.validate(alarm, Alarm::getTenantId);
try {
if (alarm.getStartTs() == 0L) {
alarm.setStartTs(System.currentTimeMillis());
}
if (alarm.getEndTs() == 0L) {
alarm.setEndTs(alarm.getStartTs());
}
alarm.setCustomerId(entityService.fetchEntityCustomerId(alarm.getTenantId(), alarm.getOriginator()).orElse(null));
if (alarm.getId() == null) {
// Atomic update and return alarm + assignee.
Alarm existing = alarmDao.findLatestByOriginatorAndType(alarm.getTenantId(), alarm.getOriginator(), alarm.getType());
if (existing == null || existing.getStatus().isCleared()) {
if (!alarmCreationEnabled) {
throw new ApiUsageLimitsExceededException("Alarms creation is disabled");
}
return createAlarm(alarm);
} else {
return updateAlarm(existing, alarm);
}
} else {
return updateAlarm(alarm);
}
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
}
@Override
public Alarm findLatestActiveByOriginatorAndType(TenantId tenantId, EntityId originator, String type) {
return alarmDao.findLatestActiveByOriginatorAndType(tenantId, originator, type);
}
@Override
public ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) {
return alarmDao.findLatestByOriginatorAndTypeAsync(tenantId, originator, type);
}
@Override
public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId,
AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
@ -248,27 +207,6 @@ public class BaseAlarmService extends AbstractCachedEntityService<TenantId, Page
}
}
@Override
@Transactional
public AlarmOperationResult deleteAlarm(TenantId tenantId, AlarmId alarmId) {
log.debug("Deleting Alarm Id: {}", alarmId);
Alarm alarm = alarmDao.findAlarmById(tenantId, alarmId.getId());
if (alarm == null) {
return new AlarmOperationResult(alarm, false);
}
AlarmOperationResult result = new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)));
deleteEntityRelations(tenantId, alarm.getId());
alarmDao.removeById(tenantId, alarm.getUuidId());
return result;
}
private AlarmOperationResult createAlarm(Alarm alarm) throws InterruptedException, ExecutionException {
log.debug("New Alarm : {}", alarm);
Alarm saved = alarmDao.save(alarm.getTenantId(), alarm);
List<EntityId> propagatedEntitiesList = createEntityAlarmRecords(saved);
return new AlarmOperationResult(saved, true, true, propagatedEntitiesList);
}
private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws ExecutionException, InterruptedException {
Set<EntityId> propagatedEntitiesSet = new LinkedHashSet<>();
propagatedEntitiesSet.add(alarm.getOriginator());
@ -299,61 +237,6 @@ public class BaseAlarmService extends AbstractCachedEntityService<TenantId, Page
return relations.map(EntityRelation::getFrom).collect(Collectors.toCollection(LinkedHashSet::new));
}
private AlarmOperationResult updateAlarm(Alarm update) {
alarmDataValidator.validate(update, Alarm::getTenantId);
return getAndUpdate(update.getTenantId(), update.getId(),
(alarm) -> alarm == null ? null : updateAlarm(alarm, update));
}
private AlarmOperationResult updateAlarm(Alarm oldAlarm, Alarm newAlarm) {
boolean propagationEnabled = !oldAlarm.isPropagate() && newAlarm.isPropagate();
boolean propagationToOwnerEnabled = !oldAlarm.isPropagateToOwner() && newAlarm.isPropagateToOwner();
boolean propagationToTenantEnabled = !oldAlarm.isPropagateToTenant() && newAlarm.isPropagateToTenant();
AlarmSeverity oldAlarmSeverity = oldAlarm.getSeverity();
Alarm result = alarmDao.save(newAlarm.getTenantId(), merge(oldAlarm, newAlarm));
List<EntityId> propagatedEntitiesList;
if (propagationEnabled || propagationToOwnerEnabled || propagationToTenantEnabled) {
try {
propagatedEntitiesList = createEntityAlarmRecords(result);
} catch (InterruptedException | ExecutionException e) {
log.warn("Failed to update alarm relations [{}]", result, e);
throw new RuntimeException(e);
}
} else {
propagatedEntitiesList = new ArrayList<>(getPropagationEntityIds(result));
}
return new AlarmOperationResult(result, true, false, oldAlarmSeverity, propagatedEntitiesList);
}
@Override
public ListenableFuture<AlarmOperationResult> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTime) {
Alarm alarm = alarmDao.findAlarmById(tenantId, alarmId.getId());
if (alarm == null || alarm.getStatus().isAck()) {
return Futures.immediateFuture(new AlarmOperationResult(alarm, false));
} else {
alarm.setAcknowledged(true);
alarm.setAckTs(ackTime);
alarm = alarmDao.save(alarm.getTenantId(), alarm);
return Futures.immediateFuture(new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm))));
}
}
@Override
public ListenableFuture<AlarmOperationResult> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTime) {
Alarm alarm = alarmDao.findAlarmById(tenantId, alarmId.getId());
if (alarm == null || alarm.getStatus().isCleared()) {
return Futures.immediateFuture(new AlarmOperationResult(alarm, false));
} else {
alarm.setCleared(true);
alarm.setClearTs(clearTime);
if (details != null) {
alarm.setDetails(details);
}
alarm = alarmDao.save(alarm.getTenantId(), alarm);
return Futures.immediateFuture(new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm))));
}
}
@Override
public AlarmApiCallResult assignAlarm(TenantId tenantId, AlarmId alarmId, UserId assigneeId, long assignTime) {
var result = withPropagated(alarmDao.assignAlarm(tenantId, alarmId, assigneeId, assignTime));
@ -396,23 +279,23 @@ public class BaseAlarmService extends AbstractCachedEntityService<TenantId, Page
}
@Override
public ListenableFuture<PageData<AlarmInfo>> findAlarms(TenantId tenantId, AlarmQuery query) {
return Futures.immediateFuture(alarmDao.findAlarms(tenantId, query));
public PageData<AlarmInfo> findAlarms(TenantId tenantId, AlarmQuery query) {
return alarmDao.findAlarms(tenantId, query);
}
@Override
public ListenableFuture<PageData<AlarmInfo>> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query) {
return Futures.immediateFuture(alarmDao.findCustomerAlarms(tenantId, customerId, query));
public PageData<AlarmInfo> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query) {
return alarmDao.findCustomerAlarms(tenantId, customerId, query);
}
@Override
public ListenableFuture<PageData<AlarmInfo>> findAlarmsV2(TenantId tenantId, AlarmQueryV2 query) {
return Futures.immediateFuture(alarmDao.findAlarmsV2(tenantId, query));
public PageData<AlarmInfo> findAlarmsV2(TenantId tenantId, AlarmQueryV2 query) {
return alarmDao.findAlarmsV2(tenantId, query);
}
@Override
public ListenableFuture<PageData<AlarmInfo>> findCustomerAlarmsV2(TenantId tenantId, CustomerId customerId, AlarmQueryV2 query) {
return Futures.immediateFuture(alarmDao.findCustomerAlarmsV2(tenantId, customerId, query));
public PageData<AlarmInfo> findCustomerAlarmsV2(TenantId tenantId, CustomerId customerId, AlarmQueryV2 query) {
return alarmDao.findCustomerAlarmsV2(tenantId, customerId, query);
}
@Override
@ -440,9 +323,16 @@ public class BaseAlarmService extends AbstractCachedEntityService<TenantId, Page
@Override
public void deleteEntityAlarmRelations(TenantId tenantId, EntityId entityId) {
log.trace("Executing deleteEntityAlarms [{}]", entityId);
alarmDao.deleteEntityAlarmRecords(tenantId, entityId);
}
@Override
public void deleteEntityAlarmRecordsByTenantId(TenantId tenantId) {
log.trace("Executing deleteEntityAlarmRecordsByTenantId [{}]", tenantId);
alarmDao.deleteEntityAlarmRecordsByTenantId(tenantId);
}
@Override
public long countAlarmsByQuery(TenantId tenantId, CustomerId customerId, AlarmCountQuery query) {
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);

46
dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java

@ -26,7 +26,6 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionalEventListener;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetInfo;
@ -205,21 +204,25 @@ public class BaseAssetService extends AbstractCachedEntityService<AssetCacheKey,
@Override
@Transactional
public void deleteAsset(TenantId tenantId, AssetId assetId) {
log.trace("Executing deleteAsset [{}]", assetId);
validateId(assetId, INCORRECT_ASSET_ID + assetId);
deleteEntityRelations(tenantId, assetId);
Asset asset = assetDao.findById(tenantId, assetId.getId());
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityId(asset.getTenantId(), assetId);
if (entityViews != null && !entityViews.isEmpty()) {
if (entityViewService.existsByTenantIdAndEntityId(tenantId, assetId)) {
throw new DataValidationException("Can't delete asset that has entity views!");
}
Asset asset = assetDao.findById(tenantId, assetId.getId());
alarmService.deleteEntityAlarmRelations(tenantId, assetId);
deleteAsset(tenantId, asset);
}
private void deleteAsset(TenantId tenantId, Asset asset) {
log.trace("Executing deleteAsset [{}]", asset.getId());
relationService.deleteEntityRelations(tenantId, asset.getAssetProfileId());
assetDao.removeById(tenantId, asset.getUuidId());
publishEvictEvent(new AssetCacheEvictEvent(asset.getTenantId(), asset.getName(), null));
countService.publishCountEntityEvictEvent(tenantId, EntityType.ASSET);
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(assetId).build());
assetDao.removeById(tenantId, assetId.getId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(asset.getId()).build());
}
@Override
@ -438,21 +441,20 @@ public class BaseAssetService extends AbstractCachedEntityService<AssetCacheKey,
return assetDao.findAssetsByTenantIdAndEdgeIdAndType(tenantId.getId(), edgeId.getId(), type, pageLink);
}
private PaginatedRemover<TenantId, Asset> tenantAssetsRemover =
new PaginatedRemover<TenantId, Asset>() {
private final PaginatedRemover<TenantId, Asset> tenantAssetsRemover = new PaginatedRemover<>() {
@Override
protected PageData<Asset> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
return assetDao.findAssetsByTenantId(id.getId(), pageLink);
}
@Override
protected PageData<Asset> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
return assetDao.findAssetsByTenantId(id.getId(), pageLink);
}
@Override
protected void removeEntity(TenantId tenantId, Asset entity) {
deleteAsset(tenantId, new AssetId(entity.getId().getId()));
}
};
@Override
protected void removeEntity(TenantId tenantId, Asset asset) {
deleteAsset(tenantId, asset);
}
};
private PaginatedRemover<CustomerId, Asset> customerAssetsUnasigner = new PaginatedRemover<CustomerId, Asset>() {
private final PaginatedRemover<CustomerId, Asset> customerAssetsUnasigner = new PaginatedRemover<CustomerId, Asset>() {
@Override
protected PageData<Asset> findEntities(TenantId tenantId, CustomerId id, PageLink pageLink) {

4
dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardDao.java

@ -18,6 +18,8 @@ package org.thingsboard.server.dao.dashboard;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.Dao;
import org.thingsboard.server.dao.ExportableEntityDao;
import org.thingsboard.server.dao.TenantEntityDao;
@ -40,4 +42,6 @@ public interface DashboardDao extends Dao<Dashboard>, TenantEntityDao, Exportabl
List<Dashboard> findByTenantIdAndTitle(UUID tenantId, String title);
PageData<DashboardId> findIdsByTenantId(TenantId tenantId, PageLink pageLink);
}

25
dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java

@ -364,19 +364,18 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
return dashboardDao.findByTenantIdAndTitle(tenantId.getId(), title);
}
private PaginatedRemover<TenantId, DashboardInfo> tenantDashboardsRemover =
new PaginatedRemover<TenantId, DashboardInfo>() {
@Override
protected PageData<DashboardInfo> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
return dashboardInfoDao.findDashboardsByTenantId(id.getId(), pageLink);
}
@Override
protected void removeEntity(TenantId tenantId, DashboardInfo entity) {
deleteDashboard(tenantId, new DashboardId(entity.getUuidId()));
}
};
private final PaginatedRemover<TenantId, DashboardId> tenantDashboardsRemover = new PaginatedRemover<>() {
@Override
protected PageData<DashboardId> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
return dashboardDao.findIdsByTenantId(id, pageLink);
}
@Override
protected void removeEntity(TenantId tenantId, DashboardId dashboardId) {
deleteDashboard(tenantId, dashboardId);
}
};
@Override
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {

3
dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsDao.java

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.dao.device;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.dao.Dao;
@ -53,4 +54,6 @@ public interface DeviceCredentialsDao extends Dao<DeviceCredentials> {
*/
DeviceCredentials findByCredentialsId(TenantId tenantId, String credentialsId);
DeviceCredentials removeByDeviceId(TenantId tenantId, DeviceId deviceId);
}

9
dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsServiceImpl.java

@ -400,4 +400,13 @@ public class DeviceCredentialsServiceImpl extends AbstractCachedEntityService<St
publishEvictEvent(new DeviceCredentialsEvictEvent(deviceCredentials.getCredentialsId(), null));
}
@Override
public void deleteDeviceCredentialsByDeviceId(TenantId tenantId, DeviceId deviceId) {
log.trace("Executing deleteDeviceCredentialsByDeviceId [{}]", deviceId);
DeviceCredentials credentials = deviceCredentialsDao.removeByDeviceId(tenantId, deviceId);
if (credentials != null) {
publishEvictEvent(new DeviceCredentialsEvictEvent(credentials.getCredentialsId(), null));
}
}
}

50
dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java

@ -316,26 +316,27 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
@Transactional
@Override
public void deleteDevice(final TenantId tenantId, final DeviceId deviceId) {
log.trace("Executing deleteDevice [{}]", deviceId);
validateId(deviceId, INCORRECT_DEVICE_ID + deviceId);
Device device = deviceDao.findById(tenantId, deviceId.getId());
DeviceCacheEvictEvent deviceCacheEvictEvent = new DeviceCacheEvictEvent(device.getTenantId(), device.getId(), device.getName(), null);
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityId(device.getTenantId(), deviceId);
if (entityViews != null && !entityViews.isEmpty()) {
if (entityViewService.existsByTenantIdAndEntityId(tenantId, deviceId)) {
throw new DataValidationException("Can't delete device that has entity views!");
}
DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, deviceId);
if (deviceCredentials != null) {
deviceCredentialsService.deleteDeviceCredentials(tenantId, deviceCredentials);
}
deleteEntityRelations(tenantId, deviceId);
deviceDao.removeById(tenantId, deviceId.getId());
Device device = deviceDao.findById(tenantId, deviceId.getId());
alarmService.deleteEntityAlarmRelations(tenantId, deviceId);
deleteDevice(tenantId, device);
}
private void deleteDevice(TenantId tenantId, Device device) {
log.trace("Executing deleteDevice [{}]", device.getId());
deviceCredentialsService.deleteDeviceCredentialsByDeviceId(tenantId, device.getId());
relationService.deleteEntityRelations(tenantId, device.getId());
deviceDao.removeById(tenantId, device.getUuidId());
DeviceCacheEvictEvent deviceCacheEvictEvent = new DeviceCacheEvictEvent(device.getTenantId(), device.getId(), device.getName(), null);
publishEvictEvent(deviceCacheEvictEvent);
countService.publishCountEntityEvictEvent(tenantId, EntityType.DEVICE);
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(deviceId).build());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(device.getId()).build());
}
@Override
@ -650,21 +651,20 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
deleteDevice(tenantId, (DeviceId) id);
}
private PaginatedRemover<TenantId, Device> tenantDevicesRemover =
new PaginatedRemover<>() {
private final PaginatedRemover<TenantId, Device> tenantDevicesRemover = new PaginatedRemover<>() {
@Override
protected PageData<Device> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
return deviceDao.findDevicesByTenantId(id.getId(), pageLink);
}
@Override
protected PageData<Device> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
return deviceDao.findDevicesByTenantId(id.getId(), pageLink);
}
@Override
protected void removeEntity(TenantId tenantId, Device entity) {
deleteDevice(tenantId, new DeviceId(entity.getUuidId()));
}
};
@Override
protected void removeEntity(TenantId tenantId, Device device) {
deleteDevice(tenantId, device);
}
};
private PaginatedRemover<CustomerId, Device> customerDeviceUnasigner = new PaginatedRemover<CustomerId, Device>() {
private final PaginatedRemover<CustomerId, Device> customerDeviceUnasigner = new PaginatedRemover<CustomerId, Device>() {
@Override
protected PageData<Device> findEntities(TenantId tenantId, CustomerId id, PageLink pageLink) {

2
dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java

@ -74,9 +74,7 @@ public abstract class AbstractEntityService {
}
protected void deleteEntityRelations(TenantId tenantId, EntityId entityId) {
log.trace("Executing deleteEntityRelations [{}]", entityId);
relationService.deleteEntityRelations(tenantId, entityId);
log.trace("Executing deleteEntityAlarms [{}]", entityId);
alarmService.deleteEntityAlarmRelations(tenantId, entityId);
}

2
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java

@ -148,6 +148,8 @@ public interface EntityViewDao extends Dao<EntityView>, ExportableEntityDao<Enti
List<EntityView> findEntityViewsByTenantIdAndEntityId(UUID tenantId, UUID entityId);
boolean existsByTenantIdAndEntityId(UUID tenantId, UUID entityId);
/**
* Find tenants entity view types.
*

5
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java

@ -316,6 +316,11 @@ public class EntityViewServiceImpl extends AbstractCachedEntityService<EntityVie
EntityViewCacheValue::getEntityViews, v -> new EntityViewCacheValue(null, v), true);
}
@Override
public boolean existsByTenantIdAndEntityId(TenantId tenantId, EntityId entityId) {
return entityViewDao.existsByTenantIdAndEntityId(tenantId.getId(), entityId.getId());
}
@Override
@Transactional
public void deleteEntityView(TenantId tenantId, EntityViewId entityViewId) {

3
dao/src/main/java/org/thingsboard/server/dao/service/PaginatedRemover.java

@ -15,12 +15,11 @@
*/
package org.thingsboard.server.dao.service;
import org.thingsboard.server.common.data.id.IdBased;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
public abstract class PaginatedRemover<I, D extends IdBased<?>> {
public abstract class PaginatedRemover<I, D> {
private static final int DEFAULT_LIMIT = 100;

4
dao/src/main/java/org/thingsboard/server/dao/sql/alarm/EntityAlarmRepository.java

@ -34,4 +34,8 @@ public interface EntityAlarmRepository extends JpaRepository<EntityAlarmEntity,
@Modifying
@Query("DELETE FROM EntityAlarmEntity e where e.entityId = :entityId")
void deleteByEntityId(@Param("entityId") UUID entityId);
@Transactional
void deleteByTenantId(UUID tenantId);
}

6
dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java

@ -310,10 +310,14 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
@Override
public void deleteEntityAlarmRecords(TenantId tenantId, EntityId entityId) {
log.trace("[{}] Try to delete entity alarm records using [{}]", tenantId, entityId);
entityAlarmRepository.deleteByEntityId(entityId.getId());
}
@Override
public void deleteEntityAlarmRecordsByTenantId(TenantId tenantId) {
entityAlarmRepository.deleteByTenantId(tenantId.getId());
}
@Override
public AlarmApiCallResult createOrUpdateActiveAlarm(AlarmCreateOrUpdateActiveRequest request, boolean alarmCreationEnabled) {
AlarmPropagationInfo ap = getSafePropagationInfo(request.getPropagation());

3
dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/DashboardRepository.java

@ -40,4 +40,7 @@ public interface DashboardRepository extends JpaRepository<DashboardEntity, UUID
@Query("SELECT externalId FROM DashboardEntity WHERE id = :id")
UUID getExternalIdById(@Param("id") UUID id);
@Query("SELECT d.id FROM DashboardEntity d WHERE d.tenantId = :tenantId")
Page<UUID> findIdsByTenantId(@Param("tenantId") UUID tenantId, Pageable pageable);
}

5
dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardDao.java

@ -80,6 +80,11 @@ public class JpaDashboardDao extends JpaAbstractDao<DashboardEntity, Dashboard>
return DaoUtil.convertDataList(dashboardRepository.findByTenantIdAndTitle(tenantId, title));
}
@Override
public PageData<DashboardId> findIdsByTenantId(TenantId tenantId, PageLink pageLink) {
return DaoUtil.pageToPageData(dashboardRepository.findIdsByTenantId(tenantId.getId(), DaoUtil.toPageable(pageLink)).map(DashboardId::new));
}
@Override
public EntityType getEntityType() {
return EntityType.DASHBOARD;

8
dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceCredentialsRepository.java

@ -16,6 +16,9 @@
package org.thingsboard.server.dao.sql.device;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.dao.model.sql.DeviceCredentialsEntity;
import java.util.UUID;
@ -28,4 +31,9 @@ public interface DeviceCredentialsRepository extends JpaRepository<DeviceCredent
DeviceCredentialsEntity findByDeviceId(UUID deviceId);
DeviceCredentialsEntity findByCredentialsId(String credentialsId);
@Transactional
@Query(value = "DELETE FROM device_credentials WHERE device_id = :deviceId RETURNING *", nativeQuery = true)
DeviceCredentialsEntity deleteByDeviceId(@Param("deviceId") UUID deviceId);
}

7
dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceCredentialsDao.java

@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.dao.DaoUtil;
@ -66,4 +67,10 @@ public class JpaDeviceCredentialsDao extends JpaAbstractDao<DeviceCredentialsEnt
public DeviceCredentials findByCredentialsId(TenantId tenantId, String credentialsId) {
return DaoUtil.getData(deviceCredentialsRepository.findByCredentialsId(credentialsId));
}
@Override
public DeviceCredentials removeByDeviceId(TenantId tenantId, DeviceId deviceId) {
return DaoUtil.getData(deviceCredentialsRepository.deleteByDeviceId(deviceId.getId()));
}
}

2
dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java

@ -118,6 +118,8 @@ public interface EntityViewRepository extends JpaRepository<EntityViewEntity, UU
List<EntityViewEntity> findAllByTenantIdAndEntityId(UUID tenantId, UUID entityId);
boolean existsByTenantIdAndEntityId(UUID tenantId, UUID entityId);
@Query("SELECT DISTINCT ev.type FROM EntityViewEntity ev WHERE ev.tenantId = :tenantId")
List<String> findTenantEntityViewTypes(@Param("tenantId") UUID tenantId);

5
dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java

@ -165,6 +165,11 @@ public class JpaEntityViewDao extends JpaAbstractDao<EntityViewEntity, EntityVie
entityViewRepository.findAllByTenantIdAndEntityId(tenantId, entityId));
}
@Override
public boolean existsByTenantIdAndEntityId(UUID tenantId, UUID entityId) {
return entityViewRepository.existsByTenantIdAndEntityId(tenantId, entityId);
}
@Override
public ListenableFuture<List<EntitySubtype>> findTenantEntityViewTypesAsync(UUID tenantId) {
return service.submit(() -> convertTenantEntityTypesToDto(tenantId, EntityType.ENTITY_VIEW, entityViewRepository.findTenantEntityViewTypes(tenantId)));

7
dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java

@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
@ -62,4 +63,10 @@ public class JpaUserCredentialsDao extends JpaAbstractDao<UserCredentialsEntity,
public UserCredentials findByResetToken(TenantId tenantId, String resetToken) {
return DaoUtil.getData(userCredentialsRepository.findByResetToken(resetToken));
}
@Override
public void removeByUserId(TenantId tenantId, UserId userId) {
userCredentialsRepository.removeByUserId(userId.getId());
}
}

5
dao/src/main/java/org/thingsboard/server/dao/sql/user/UserCredentialsRepository.java

@ -16,6 +16,7 @@
package org.thingsboard.server.dao.sql.user;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
import java.util.UUID;
@ -30,4 +31,8 @@ public interface UserCredentialsRepository extends JpaRepository<UserCredentials
UserCredentialsEntity findByActivateToken(String activateToken);
UserCredentialsEntity findByResetToken(String resetToken);
@Transactional
void removeByUserId(UUID userId);
}

3
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java

@ -245,7 +245,8 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
tenantDao.removeById(tenantId, tenantId.getId());
publishEvictEvent(new TenantEvictEvent(tenantId, true));
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(TenantId.SYS_TENANT_ID).entityId(tenantId).build());
deleteEntityRelations(tenantId, tenantId);
relationService.deleteEntityRelations(tenantId, tenantId);
alarmService.deleteEntityAlarmRecordsByTenantId(tenantId);
}
@Override

3
dao/src/main/java/org/thingsboard/server/dao/user/UserCredentialsDao.java

@ -16,6 +16,7 @@
package org.thingsboard.server.dao.user;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.dao.Dao;
@ -58,4 +59,6 @@ public interface UserCredentialsDao extends Dao<UserCredentials> {
*/
UserCredentials findByResetToken(TenantId tenantId, String resetToken);
void removeByUserId(TenantId tenantId, UserId userId);
}

8
dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java

@ -252,10 +252,10 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
UserId userId = user.getId();
log.trace("[{}] Executing deleteUser [{}]", tenantId, userId);
validateId(userId, INCORRECT_USER_ID + userId);
UserCredentials userCredentials = userCredentialsDao.findByUserId(tenantId, userId.getId());
userCredentialsDao.removeById(tenantId, userCredentials.getUuidId());
userCredentialsDao.removeByUserId(tenantId, userId);
userAuthSettingsDao.removeByUserId(userId);
deleteEntityRelations(tenantId, userId);
userDao.removeById(tenantId, userId.getId());
eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(userId));
countService.publishCountEntityEvictEvent(tenantId, EntityType.USER);
@ -446,8 +446,8 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
}
@Override
protected void removeEntity(TenantId tenantId, User entity) {
deleteUser(tenantId, entity);
protected void removeEntity(TenantId tenantId, User user) {
deleteUser(tenantId, user);
}
};

11
dao/src/test/java/org/thingsboard/server/dao/service/AlarmCommentServiceTest.java

@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.AlarmCommentInfo;
import org.thingsboard.server.common.data.alarm.AlarmCommentType;
import org.thingsboard.server.common.data.alarm.AlarmCreateOrUpdateActiveRequest;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.TenantId;
@ -60,11 +61,12 @@ public class AlarmCommentServiceTest extends AbstractServiceTest {
@Before
public void before() {
alarm = Alarm.builder().tenantId(tenantId).originator(new AssetId(Uuids.timeBased()))
alarm = alarmService.createAlarm(AlarmCreateOrUpdateActiveRequest.builder()
.tenantId(tenantId)
.originator(new AssetId(Uuids.timeBased()))
.type(TEST_ALARM)
.severity(AlarmSeverity.CRITICAL)
.startTs(System.currentTimeMillis()).build();
alarm = alarmService.createOrUpdateAlarm(alarm).getAlarm();
.startTs(System.currentTimeMillis()).build()).getAlarm();
user = new User();
user.setAuthority(Authority.TENANT_ADMIN);
@ -77,10 +79,9 @@ public class AlarmCommentServiceTest extends AbstractServiceTest {
@After
public void after() {
alarmService.deleteAlarm(tenantId, alarm.getId());
alarmService.delAlarm(tenantId, alarm.getId());
}
@Test
public void testCreateAndFetchAlarmComment() throws ExecutionException, InterruptedException {
AlarmComment alarmComment = AlarmComment.builder().alarmId(alarm.getId())

52
dao/src/test/java/org/thingsboard/server/dao/service/AlarmServiceTest.java

@ -146,7 +146,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -157,7 +157,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(0, alarms.getData().size());
@ -171,7 +171,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -182,7 +182,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -195,7 +195,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_ACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -206,7 +206,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(0, alarms.getData().size());
@ -218,7 +218,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.CLEARED_ACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -245,11 +245,11 @@ public class AlarmServiceTest extends AbstractServiceTest {
// Check child relation
PageData<AlarmInfo> alarms = alarmService.findAlarmsV2(tenantId, AlarmQueryV2.builder()
.affectedEntityId(childId)
.severityList(Arrays.asList(AlarmSeverity.CRITICAL))
.statusList(Arrays.asList(AlarmSearchStatus.ACTIVE, AlarmSearchStatus.UNACK)).pageLink(
.severityList(Arrays.asList(AlarmSeverity.CRITICAL))
.statusList(Arrays.asList(AlarmSearchStatus.ACTIVE, AlarmSearchStatus.UNACK)).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -261,7 +261,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.statusList(Arrays.asList(AlarmSearchStatus.ACTIVE, AlarmSearchStatus.UNACK)).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(0, alarms.getData().size());
@ -276,7 +276,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.statusList(Arrays.asList(AlarmSearchStatus.ACTIVE, AlarmSearchStatus.UNACK)).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -288,7 +288,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.statusList(Arrays.asList(AlarmSearchStatus.ACTIVE, AlarmSearchStatus.UNACK)).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -302,7 +302,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.statusList(Arrays.asList(AlarmSearchStatus.ACTIVE, AlarmSearchStatus.ACK)).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -314,7 +314,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.statusList(Arrays.asList(AlarmSearchStatus.ACTIVE, AlarmSearchStatus.UNACK)).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(0, alarms.getData().size());
@ -327,7 +327,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.statusList(Arrays.asList(AlarmSearchStatus.CLEARED, AlarmSearchStatus.ACK)).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -371,7 +371,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.fetchOriginator(true)
.pageLink(new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, alarms.getData().get(0));
@ -466,7 +466,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(10, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(tenantAlarm, new AlarmInfo(alarms.getData().get(0)));
@ -752,7 +752,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(10, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarmsInfoData.getData());
Assert.assertEquals(1, alarmsInfoData.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarmsInfoData.getData().get(0)));
@ -763,7 +763,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(10, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarmsInfoData.getData());
Assert.assertEquals(1, alarmsInfoData.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarmsInfoData.getData().get(0)));
@ -774,7 +774,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(10, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarmsInfoData.getData());
Assert.assertEquals(1, alarmsInfoData.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarmsInfoData.getData().get(0)));
@ -899,7 +899,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
@ -910,12 +910,12 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new AlarmInfo(alarms.getData().get(0)));
Assert.assertTrue("Alarm was not deleted when expected", alarmService.deleteAlarm(tenantId, created.getId()).isSuccessful());
Assert.assertTrue("Alarm was not deleted when expected", alarmService.delAlarm(tenantId, created.getId()).isSuccessful());
Alarm fetched = alarmService.findAlarmByIdAsync(tenantId, created.getId()).get();
@ -926,7 +926,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(0, alarms.getData().size());
@ -936,7 +936,7 @@ public class AlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0, "",
new SortOrder("createdTime", SortOrder.Direction.DESC), 0L, System.currentTimeMillis())
).build()).get();
).build());
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(0, alarms.getData().size());

26
rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java

@ -38,7 +38,6 @@ import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.query.AlarmData;
import org.thingsboard.server.common.data.query.AlarmDataQuery;
import org.thingsboard.server.dao.alarm.AlarmOperationResult;
import java.util.Collection;
@ -70,21 +69,6 @@ public interface RuleEngineAlarmService {
AlarmApiCallResult unassignAlarm(TenantId tenantId, AlarmId alarmId, long assignTs);
/*
* Legacy API, before 3.5.
*/
@Deprecated(since = "3.5", forRemoval = true)
Alarm createOrUpdateAlarm(Alarm alarm);
@Deprecated(since = "3.5", forRemoval = true)
ListenableFuture<Boolean> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTs);
@Deprecated(since = "3.5", forRemoval = true)
ListenableFuture<Boolean> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs);
@Deprecated(since = "3.5", forRemoval = true)
ListenableFuture<AlarmOperationResult> clearAlarmForResult(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs);
// Other API
Boolean deleteAlarm(TenantId tenantId, AlarmId alarmId);
@ -94,7 +78,7 @@ public interface RuleEngineAlarmService {
Alarm findLatestActiveByOriginatorAndType(TenantId tenantId, EntityId originator, String type);
ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type);
Alarm findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type);
AlarmInfo findAlarmInfoById(TenantId tenantId, AlarmId alarmId);
@ -102,13 +86,13 @@ public interface RuleEngineAlarmService {
return Futures.immediateFuture(findAlarmInfoById(tenantId, alarmId));
}
ListenableFuture<PageData<AlarmInfo>> findAlarms(TenantId tenantId, AlarmQuery query);
PageData<AlarmInfo> findAlarms(TenantId tenantId, AlarmQuery query);
ListenableFuture<PageData<AlarmInfo>> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query);
PageData<AlarmInfo> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query);
ListenableFuture<PageData<AlarmInfo>> findAlarmsV2(TenantId tenantId, AlarmQueryV2 query);
PageData<AlarmInfo> findAlarmsV2(TenantId tenantId, AlarmQueryV2 query);
ListenableFuture<PageData<AlarmInfo>> findCustomerAlarmsV2(TenantId tenantId, CustomerId customerId, AlarmQueryV2 query);
PageData<AlarmInfo> findCustomerAlarmsV2(TenantId tenantId, CustomerId customerId, AlarmQueryV2 query);
AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus, AlarmStatus alarmStatus, String assigneeId);

Loading…
Cancel
Save