Browse Source

refactor async methods used in tenant deletion transaction

tenant deleting should be transactional, but some services use async methods, what corrupting transaction execution. Withal most of the refactored methods are using instant .get() after getting future, and it is the same if we use non-async methods. Add non-async methods in interfaces of services and dao  and use it for tenant deletion process
pull/5873/head
desoliture 5 years ago
parent
commit
279389bbdf
  1. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java
  2. 11
      dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java
  3. 22
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
  4. 2
      dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java
  5. 1
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java
  6. 21
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
  7. 8
      dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java

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

@ -72,6 +72,8 @@ public interface EntityViewService {
ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEntityIdAsync(TenantId tenantId, EntityId entityId);
List<EntityView> findEntityViewsByTenantIdAndEntityId(TenantId tenantId, EntityId entityId);
void deleteEntityView(TenantId tenantId, EntityViewId entityViewId);
void deleteEntityViewsByTenantId(TenantId tenantId);

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

@ -168,14 +168,9 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
deleteEntityRelations(tenantId, assetId);
Asset asset = assetDao.findById(tenantId, assetId.getId());
try {
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(asset.getTenantId(), assetId).get();
if (entityViews != null && !entityViews.isEmpty()) {
throw new DataValidationException("Can't delete asset that has entity views!");
}
} catch (ExecutionException | InterruptedException e) {
log.error("Exception while finding entity views for assetId [{}]", assetId, e);
throw new RuntimeException("Exception while finding entity views for assetId [" + assetId + "]", e);
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityId(asset.getTenantId(), assetId);
if (entityViews != null && !entityViews.isEmpty()) {
throw new DataValidationException("Can't delete asset that has entity views!");
}
removeAssetFromCacheByName(asset.getTenantId(), asset.getName());

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

@ -344,14 +344,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
Device device = deviceDao.findById(tenantId, deviceId.getId());
final String deviceName = device.getName();
try {
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(device.getTenantId(), deviceId).get();
if (entityViews != null && !entityViews.isEmpty()) {
throw new DataValidationException("Can't delete device that has entity views!");
}
} catch (ExecutionException | InterruptedException e) {
log.error("Exception while finding entity views for deviceId [{}]", deviceId, e);
throw new RuntimeException("Exception while finding entity views for deviceId [" + deviceId + "]", e);
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityId(device.getTenantId(), deviceId);
if (entityViews != null && !entityViews.isEmpty()) {
throw new DataValidationException("Can't delete device that has entity views!");
}
DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, deviceId);
@ -568,14 +563,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
public Device assignDeviceToTenant(TenantId tenantId, Device device) {
log.trace("Executing assignDeviceToTenant [{}][{}]", tenantId, device);
try {
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(device.getTenantId(), device.getId()).get();
if (!CollectionUtils.isEmpty(entityViews)) {
throw new DataValidationException("Can't assign device that has entity views to another tenant!");
}
} catch (ExecutionException | InterruptedException e) {
log.error("Exception while finding entity views for deviceId [{}]", device.getId(), e);
throw new RuntimeException("Exception while finding entity views for deviceId [" + device.getId() + "]", e);
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityId(device.getTenantId(), device.getId());
if (!CollectionUtils.isEmpty(entityViews)) {
throw new DataValidationException("Can't assign device that has entity views to another tenant!");
}
eventService.removeEvents(device.getTenantId(), device.getId());

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

@ -83,7 +83,7 @@ public abstract class AbstractEntityService {
protected void checkAssignedEntityViewsToEdge(TenantId tenantId, EntityId entityId, EdgeId edgeId) {
try {
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(tenantId, entityId).get();
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityId(tenantId, entityId);
if (entityViews != null && !entityViews.isEmpty()) {
EntityView entityView = entityViews.get(0);
// TODO: @voba - refactor this blocking operation

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

@ -179,4 +179,5 @@ public interface EntityViewDao extends Dao<EntityView> {
String type,
PageLink pageLink);
List<EntityView> findEntityViewsByTenantIdAndEntityId(UUID tenantId, UUID entityId);
}

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

@ -302,6 +302,27 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
}
}
@Override
public List<EntityView> findEntityViewsByTenantIdAndEntityId(TenantId tenantId, EntityId entityId) {
log.trace("Executing findEntityViewsByTenantIdAndEntityId, tenantId [{}], entityId [{}]", tenantId, entityId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(entityId.getId(), "Incorrect entityId" + entityId);
List<Object> tenantIdAndEntityId = new ArrayList<>();
tenantIdAndEntityId.add(tenantId);
tenantIdAndEntityId.add(entityId);
Cache cache = cacheManager.getCache(ENTITY_VIEW_CACHE);
List<EntityView> fromCache = cache.get(tenantIdAndEntityId, List.class);
if (fromCache != null) {
return fromCache;
} else {
List<EntityView> result = entityViewDao.findEntityViewsByTenantIdAndEntityId(tenantId.getId(), entityId.getId());
cache.putIfAbsent(tenantIdAndEntityId, result);
return result;
}
}
@CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")
@Override
public void deleteEntityView(TenantId tenantId, EntityViewId entityViewId) {

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

@ -200,4 +200,12 @@ public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
}
@Override
public List<EntityView> findEntityViewsByTenantIdAndEntityId(UUID tenantId, UUID entityId) {
return DaoUtil.convertDataList(
entityViewRepository.findAllByTenantIdAndEntityId(
tenantId, entityId)
);
}
}

Loading…
Cancel
Save