diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetController.java b/application/src/main/java/org/thingsboard/server/controller/AssetController.java index b05e32efe7..5e44e1433a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java @@ -155,9 +155,7 @@ public class AssetController extends BaseController { checkEntity(asset.getId(), asset, Resource.ASSET); Asset savedAsset = checkNotNull(assetService.saveAsset(asset)); - - onEntityUpdatedOrCreated(getCurrentUser(), savedAsset, null, asset.getId() == null); - + entityActionService.onAssetCreatedOrUpdated(getCurrentUser(), savedAsset, asset.getId() == null); return savedAsset; } catch (Exception e) { logEntityAction(emptyId(EntityType.ASSET), asset, @@ -667,7 +665,7 @@ public class AssetController extends BaseController { public BulkImportResult processAssetsBulkImport(@RequestBody BulkImportRequest request) throws Exception { SecurityUser user = getCurrentUser(); return assetBulkImportService.processBulkImport(request, user, importedAssetInfo -> { - onEntityUpdatedOrCreated(user, importedAssetInfo.getEntity(), importedAssetInfo.getOldEntity(), !importedAssetInfo.isUpdated()); + entityActionService.onAssetCreatedOrUpdated(user, importedAssetInfo.getEntity(), !importedAssetInfo.isUpdated()); }); } diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 1f683c7874..f945cc30b7 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -37,7 +37,6 @@ import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityViewInfo; -import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.OtaPackage; @@ -69,7 +68,6 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.RpcId; import org.thingsboard.server.common.data.id.RuleChainId; @@ -85,7 +83,6 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.SortOrder; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; -import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.rpc.Rpc; @@ -144,7 +141,6 @@ import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -923,66 +919,4 @@ public abstract class BaseController { return MediaType.APPLICATION_OCTET_STREAM; } } - - protected , I extends EntityId> void onEntityUpdatedOrCreated(User user, E savedEntity, E oldEntity, boolean isNewEntity) { - boolean notifyEdgeService = false; - - EntityType entityType = savedEntity.getId().getEntityType(); - switch (entityType) { - case DEVICE: - tbClusterService.onDeviceUpdated((Device) savedEntity, (Device) oldEntity); - break; - case DEVICE_PROFILE: - DeviceProfile deviceProfile = (DeviceProfile) savedEntity; - DeviceProfile oldDeviceProfile = (DeviceProfile) oldEntity; - boolean isFirmwareChanged = false; - boolean isSoftwareChanged = false; - if (!isNewEntity) { - if (!Objects.equals(deviceProfile.getFirmwareId(), oldDeviceProfile.getFirmwareId())) { - isFirmwareChanged = true; - } - if (!Objects.equals(deviceProfile.getSoftwareId(), oldDeviceProfile.getSoftwareId())) { - isSoftwareChanged = true; - } - } - tbClusterService.onDeviceProfileChange(deviceProfile, null); - tbClusterService.broadcastEntityStateChangeEvent(deviceProfile.getTenantId(), deviceProfile.getId(), - isNewEntity ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); - otaPackageStateService.update(deviceProfile, isFirmwareChanged, isSoftwareChanged); - notifyEdgeService = true; - break; - case RULE_CHAIN: - RuleChainType ruleChainType = ((RuleChain) savedEntity).getType(); - if (RuleChainType.CORE.equals(ruleChainType)) { - tbClusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedEntity.getId(), - isNewEntity ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); - } - if (RuleChainType.EDGE.equals(ruleChainType)) { - if (!isNewEntity) { - notifyEdgeService = true; - } - } - break; - case ASSET: - case CUSTOMER: - case DASHBOARD: - if (!isNewEntity) { - notifyEdgeService = true; - } - break; - default: - throw new UnsupportedOperationException(); - } - - try { - logEntityAction(user, savedEntity.getId(), savedEntity, savedEntity instanceof HasCustomerId ? ((HasCustomerId) savedEntity).getCustomerId() : null, - isNewEntity ? ActionType.ADDED : ActionType.UPDATED, null); - } catch (ThingsboardException e) { - log.error("Failed to log entity action", e); - } - if (notifyEdgeService) { - sendEntityNotificationMsg(user.getTenantId(), savedEntity.getId(), isNewEntity ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); - } - } - } diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java index 27037f36e7..b419121459 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -33,6 +33,7 @@ import org.springframework.web.bind.annotation.RestController; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; @@ -150,7 +151,14 @@ public class CustomerController extends BaseController { checkEntity(customer.getId(), customer, Resource.CUSTOMER); Customer savedCustomer = checkNotNull(customerService.saveCustomer(customer)); - onEntityUpdatedOrCreated(getCurrentUser(), savedCustomer, null, customer.getId() == null); + + logEntityAction(savedCustomer.getId(), savedCustomer, + savedCustomer.getId(), + customer.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); + + if (customer.getId() != null) { + sendEntityNotificationMsg(savedCustomer.getTenantId(), savedCustomer.getId(), EdgeEventActionType.UPDATED); + } return savedCustomer; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index 4ea1ca83c7..b4b6d6be89 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -186,9 +186,7 @@ public class DashboardController extends BaseController { checkEntity(dashboard.getId(), dashboard, Resource.DASHBOARD); Dashboard savedDashboard = checkNotNull(dashboardService.saveDashboard(dashboard)); - - onEntityUpdatedOrCreated(getCurrentUser(), savedDashboard, null, dashboard.getId() == null); - + entityActionService.onDashboardCreatedOrUpdated(getCurrentUser(), savedDashboard, dashboard.getId() == null); return savedDashboard; } catch (Exception e) { logEntityAction(emptyId(EntityType.DASHBOARD), dashboard, diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index feb58edb7a..2dff62aec6 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -74,11 +74,11 @@ import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.device.DeviceBulkImportService; import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; -import org.thingsboard.server.service.sync.importing.csv.BulkImportRequest; -import org.thingsboard.server.service.sync.importing.csv.BulkImportResult; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; +import org.thingsboard.server.service.sync.importing.csv.BulkImportRequest; +import org.thingsboard.server.service.sync.importing.csv.BulkImportResult; import javax.annotation.Nullable; import java.io.IOException; @@ -194,9 +194,7 @@ public class DeviceController extends BaseController { } Device savedDevice = checkNotNull(deviceService.saveDeviceWithAccessToken(device, accessToken)); - - onEntityUpdatedOrCreated(getCurrentUser(), savedDevice, oldDevice, created); - + entityActionService.onDeviceCreatedOrUpdated(getCurrentUser(), savedDevice, oldDevice, created); return savedDevice; } catch (Exception e) { logEntityAction(emptyId(EntityType.DEVICE), device, @@ -224,9 +222,7 @@ public class DeviceController extends BaseController { checkEntity(device.getId(), device, Resource.DEVICE); Device savedDevice = deviceService.saveDeviceWithCredentials(device, credentials); checkNotNull(savedDevice); - - onEntityUpdatedOrCreated(getCurrentUser(), savedDevice, device, device.getId() == null); - + entityActionService.onDeviceCreatedOrUpdated(getCurrentUser(), savedDevice, device, created); return savedDevice; } catch (Exception e) { logEntityAction(emptyId(EntityType.DEVICE), device, @@ -1001,7 +997,7 @@ public class DeviceController extends BaseController { public BulkImportResult processDevicesBulkImport(@RequestBody BulkImportRequest request) throws Exception { SecurityUser user = getCurrentUser(); return deviceBulkImportService.processBulkImport(request, user, importedDeviceInfo -> { - onEntityUpdatedOrCreated(user, importedDeviceInfo.getEntity(), importedDeviceInfo.getOldEntity(), !importedDeviceInfo.isUpdated()); + entityActionService.onDeviceCreatedOrUpdated(user, importedDeviceInfo.getEntity(), importedDeviceInfo.getOldEntity(), !importedDeviceInfo.isUpdated()); }); } diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java index 240e60be2c..25a35e77fa 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java @@ -46,6 +46,7 @@ import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; import java.util.List; +import java.util.Objects; import java.util.UUID; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_DATA; @@ -206,14 +207,32 @@ public class DeviceProfileController extends BaseController { checkEntity(deviceProfile.getId(), deviceProfile, Resource.DEVICE_PROFILE); - DeviceProfile oldDeviceProfile = null; + boolean isFirmwareChanged = false; + boolean isSoftwareChanged = false; + if (!created) { - oldDeviceProfile = deviceProfileService.findDeviceProfileById(getTenantId(), deviceProfile.getId()); + DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(getTenantId(), deviceProfile.getId()); + if (!Objects.equals(deviceProfile.getFirmwareId(), oldDeviceProfile.getFirmwareId())) { + isFirmwareChanged = true; + } + if (!Objects.equals(deviceProfile.getSoftwareId(), oldDeviceProfile.getSoftwareId())) { + isSoftwareChanged = true; + } } DeviceProfile savedDeviceProfile = checkNotNull(deviceProfileService.saveDeviceProfile(deviceProfile)); - onEntityUpdatedOrCreated(getCurrentUser(), deviceProfile, oldDeviceProfile, created); + tbClusterService.onDeviceProfileChange(savedDeviceProfile, null); + tbClusterService.broadcastEntityStateChangeEvent(deviceProfile.getTenantId(), savedDeviceProfile.getId(), + created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); + logEntityAction(savedDeviceProfile.getId(), savedDeviceProfile, + null, + created ? ActionType.ADDED : ActionType.UPDATED, null); + + otaPackageStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged); + + sendEntityNotificationMsg(getTenantId(), savedDeviceProfile.getId(), + deviceProfile.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); return savedDeviceProfile; } catch (Exception e) { logEntityAction(emptyId(EntityType.DEVICE_PROFILE), deviceProfile, diff --git a/application/src/main/java/org/thingsboard/server/controller/EntitiesExportImportController.java b/application/src/main/java/org/thingsboard/server/controller/EntitiesExportImportController.java index 25d48c54a7..6d6a2e4619 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntitiesExportImportController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntitiesExportImportController.java @@ -200,11 +200,13 @@ public class EntitiesExportImportController extends BaseController { EntityImportSettings importSettings = toImportSettings(importSettingsParams); try { - return importEntities(user, exportDataList, importSettings) - .stream().peek(entityImportResult -> { - onEntityUpdatedOrCreated(user, entityImportResult.getSavedEntity(), entityImportResult.getOldEntity(), entityImportResult.getOldEntity() == null); - }) - .collect(Collectors.toList()); + List>> importResults = importEntities(user, exportDataList, importSettings); + for (EntityImportResult> entityImportResult : importResults) { + if (entityImportResult.getCallback() != null) { + entityImportResult.getCallback().run(); + } + } + return importResults; } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index cb59951ac5..e27090c700 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -78,9 +78,11 @@ import org.thingsboard.server.service.security.permission.Resource; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -247,12 +249,10 @@ public class RuleChainController extends BaseController { try { boolean created = ruleChain.getId() == null; ruleChain.setTenantId(getCurrentUser().getTenantId()); - checkEntity(ruleChain.getId(), ruleChain, Resource.RULE_CHAIN); RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain)); - - onEntityUpdatedOrCreated(getCurrentUser(), savedRuleChain, null, created); + entityActionService.onRuleChainCreatedOrUpdated(getCurrentUser(), savedRuleChain, created); return savedRuleChain; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java index b8c0656bd2..d692e24bbe 100644 --- a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java +++ b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java @@ -22,12 +22,17 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; @@ -36,13 +41,20 @@ import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.DataType; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainMetaData; +import org.thingsboard.server.common.data.rule.RuleChainType; +import org.thingsboard.server.common.data.rule.RuleChainUpdateResult; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.service.security.model.SecurityUser; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -212,7 +224,7 @@ public class EntityActionService { } } - public void logEntityAction(User user, I entityId, E entity, CustomerId customerId, + public void logEntityAction(User user, I entityId, E entity, CustomerId customerId, ActionType actionType, Exception e, Object... additionalInfo) { if (customerId == null || customerId.isNullUid()) { customerId = user.getCustomerId(); @@ -267,4 +279,49 @@ public class EntityActionService { entityNode.put(kvEntry.getKey(), kvEntry.getValueAsString()); } } + + + public void onDeviceCreatedOrUpdated(SecurityUser user, Device savedDevice, Device oldDevice, boolean newEntity) { + tbClusterService.onDeviceUpdated(savedDevice, oldDevice); + logEntityAction(user, savedDevice.getId(), savedDevice, savedDevice.getCustomerId(), + newEntity ? ActionType.ADDED : ActionType.UPDATED, null); + } + + public void onAssetCreatedOrUpdated(SecurityUser user, Asset savedAsset, boolean newEntity) { + logEntityAction(user, savedAsset.getId(), savedAsset, savedAsset.getCustomerId(), + newEntity ? ActionType.ADDED : ActionType.UPDATED, null); + if (!newEntity) { + tbClusterService.sendNotificationMsgToEdgeService(user.getTenantId(), null, savedAsset.getId(), + null, null, EdgeEventActionType.UPDATED); + } + } + + public void onDashboardCreatedOrUpdated(SecurityUser user, Dashboard savedDashboard, boolean newEntity) { + logEntityAction(user, savedDashboard.getId(), savedDashboard, null, + newEntity ? ActionType.ADDED : ActionType.UPDATED, null); + if (!newEntity) { + tbClusterService.sendNotificationMsgToEdgeService(user.getTenantId(), null, savedDashboard.getId(), + null, null, EdgeEventActionType.UPDATED); + } + } + + public void onRuleChainCreatedOrUpdated(SecurityUser user, RuleChain savedRuleChain, boolean newEntity) { + if (RuleChainType.CORE.equals(savedRuleChain.getType())) { + tbClusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedRuleChain.getId(), + newEntity ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); + } + logEntityAction(user, savedRuleChain.getId(), savedRuleChain, null, + newEntity ? ActionType.ADDED : ActionType.UPDATED, null); + if (RuleChainType.EDGE.equals(savedRuleChain.getType())) { + if (!newEntity) { + tbClusterService.sendNotificationMsgToEdgeService(user.getTenantId(), null, savedRuleChain.getId(), + null, null, EdgeEventActionType.UPDATED); + } + } + } + + public void onCustomerCreatedOrUpdated(SecurityUser user, Customer savedCustomer) { + + } + } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/exporting/impl/BaseEntityExportService.java b/application/src/main/java/org/thingsboard/server/service/sync/exporting/impl/BaseEntityExportService.java index f098485fd6..772e010b2b 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/exporting/impl/BaseEntityExportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/exporting/impl/BaseEntityExportService.java @@ -52,9 +52,16 @@ public abstract class BaseEntityExportService inboundRelations = relationService.findByTo(user.getTenantId(), entityId, RelationTypeGroup.COMMON); + List inboundRelations = relationService.findByTo(user.getTenantId(), entity.getId(), RelationTypeGroup.COMMON); if (inboundRelations != null) { for (EntityRelation relation : inboundRelations) { exportableEntitiesService.checkPermission(user, relation.getFrom(), Operation.READ); @@ -63,7 +70,7 @@ public abstract class BaseEntityExportService outboundRelations = relationService.findByFrom(user.getTenantId(), entityId, RelationTypeGroup.COMMON); + List outboundRelations = relationService.findByFrom(user.getTenantId(), entity.getId(), RelationTypeGroup.COMMON); if (outboundRelations != null) { for (EntityRelation relation : outboundRelations) { exportableEntitiesService.checkPermission(user, relation.getTo(), Operation.READ); @@ -71,12 +78,8 @@ public abstract class BaseEntityExportService> { private E savedEntity; private E oldEntity; + @JsonIgnore + private transient ThrowingRunnable callback; // to call when entity is successfully saved and transaction is committed } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/AssetImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/AssetImportService.java index 326e15a91b..1c031f50e4 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/AssetImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/AssetImportService.java @@ -23,7 +23,9 @@ import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.sync.exporting.data.AssetExportData; +import org.thingsboard.server.utils.ThrowingRunnable; @Service @TbCoreComponent @@ -43,6 +45,13 @@ public class AssetImportService extends BaseEntityImportService { + entityActionService.onAssetCreatedOrUpdated(user, savedAsset, oldAsset == null); + }; + } + @Override public EntityType getEntityType() { return EntityType.ASSET; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/BaseEntityImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/BaseEntityImportService.java index 42e9263e77..bf3c126c92 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/BaseEntityImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/BaseEntityImportService.java @@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.dao.relation.RelationService; +import org.thingsboard.server.service.action.EntityActionService; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.sync.exporting.ExportableEntitiesService; @@ -36,6 +37,7 @@ import org.thingsboard.server.service.sync.exporting.data.EntityExportData; import org.thingsboard.server.service.sync.importing.EntityImportResult; import org.thingsboard.server.service.sync.importing.EntityImportService; import org.thingsboard.server.service.sync.importing.EntityImportSettings; +import org.thingsboard.server.utils.ThrowingRunnable; import java.util.Collections; import java.util.LinkedList; @@ -52,6 +54,8 @@ public abstract class BaseEntityImportService importResult = new EntityImportResult<>(); importResult.setSavedEntity(savedEntity); importResult.setOldEntity(existingEntity); + importResult.setCallback(callback); return importResult; } @@ -84,30 +89,8 @@ public abstract class BaseEntityImportService Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndId(tenantId, entity.getId()))) - .or(() -> { - if (importSettings.isFindExistingByName()) { - return Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndName(tenantId, getEntityType(), entity.getName())); - } else { - return Optional.empty(); - } - }) - .orElse(null); - } - - private HasId findInternalEntity(TenantId tenantId, ID externalId) { - if (externalId == null || externalId.isNullUid()) return null; - - return (HasId) Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndExternalId(tenantId, externalId)) - .or(() -> Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndId(tenantId, externalId))) - .orElseThrow(() -> new IllegalArgumentException("Cannot find " + externalId.getEntityType() + " by external id " + externalId)); - } - - - private void importRelations(SecurityUser user, E savedEntity, E existingEntity, D exportData, EntityImportSettings importSettings) throws ThingsboardException { + protected ThrowingRunnable processAfterSavedAndGetCallback(SecurityUser user, E savedEntity, E oldEntity, D exportData, + EntityImportSettings importSettings, NewIdProvider idProvider) throws ThingsboardException { List newRelations = new LinkedList<>(); if (importSettings.isImportInboundRelations() && CollectionUtils.isNotEmpty(exportData.getInboundRelations())) { @@ -115,7 +98,7 @@ public abstract class BaseEntityImportService relation.setTo(savedEntity.getId())) .collect(Collectors.toList())); - if (importSettings.isRemoveExistingRelations() && existingEntity != null) { + if (importSettings.isRemoveExistingRelations() && oldEntity != null) { for (EntityRelation existingRelation : relationService.findByTo(user.getTenantId(), savedEntity.getId(), RelationTypeGroup.COMMON)) { exportableEntitiesService.checkPermission(user, existingRelation.getFrom(), Operation.WRITE); relationService.deleteRelation(user.getTenantId(), existingRelation); @@ -127,7 +110,7 @@ public abstract class BaseEntityImportService relation.setFrom(savedEntity.getId())) .collect(Collectors.toList())); - if (importSettings.isRemoveExistingRelations() && existingEntity != null) { + if (importSettings.isRemoveExistingRelations() && oldEntity != null) { for (EntityRelation existingRelation : relationService.findByFrom(user.getTenantId(), savedEntity.getId(), RelationTypeGroup.COMMON)) { exportableEntitiesService.checkPermission(user, existingRelation.getTo(), Operation.WRITE); relationService.deleteRelation(user.getTenantId(), existingRelation); @@ -151,6 +134,34 @@ public abstract class BaseEntityImportService {}; + } + + + private E findExistingEntity(TenantId tenantId, E entity, EntityImportSettings importSettings) { + return (E) Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndExternalId(tenantId, entity.getId())) + .or(() -> Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndId(tenantId, entity.getId()))) + .or(() -> { + if (importSettings.isFindExistingByName()) { + return Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndName(tenantId, getEntityType(), entity.getName())); + } else { + return Optional.empty(); + } + }) + .orElse(null); + } + + private HasId findInternalEntity(TenantId tenantId, ID externalId) { + if (externalId == null || externalId.isNullUid()) return null; + + return (HasId) Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndExternalId(tenantId, externalId)) + .or(() -> Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndId(tenantId, externalId))) + .orElseThrow(() -> new IllegalArgumentException("Cannot find " + externalId.getEntityType() + " by external id " + externalId)); } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/CustomerImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/CustomerImportService.java index d17e6c8b41..336d9f68f2 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/CustomerImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/CustomerImportService.java @@ -19,11 +19,15 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.sync.exporting.data.CustomerExportData; +import org.thingsboard.server.service.sync.importing.EntityImportSettings; +import org.thingsboard.server.utils.ThrowingRunnable; @Service @TbCoreComponent @@ -42,6 +46,13 @@ public class CustomerImportService extends BaseEntityImportService { + entityActionService.onCustomerCreatedOrUpdated(user, savedCustomer); + }; + } + @Override public EntityType getEntityType() { return EntityType.CUSTOMER; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DashboardImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DashboardImportService.java index 67f4ffc4a7..af24576d34 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DashboardImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DashboardImportService.java @@ -23,6 +23,7 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.ShortCustomerInfo; +import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EntityId; @@ -32,7 +33,10 @@ import org.thingsboard.server.common.data.query.EntityFilter; import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.sql.query.DefaultEntityQueryRepository; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.sync.exporting.data.DashboardExportData; +import org.thingsboard.server.service.sync.importing.EntityImportSettings; +import org.thingsboard.server.utils.ThrowingRunnable; import java.util.Collections; import java.util.HashSet; @@ -108,6 +112,13 @@ public class DashboardImportService extends BaseEntityImportService { + entityActionService.onDashboardCreatedOrUpdated(user, savedDashboard, oldDashboard == null); + }; + } + @Override public EntityType getEntityType() { return EntityType.DASHBOARD; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DeviceImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DeviceImportService.java index ccff72dcdb..4212083dea 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DeviceImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DeviceImportService.java @@ -17,13 +17,18 @@ package org.thingsboard.server.service.sync.importing.impl; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.sync.exporting.data.DeviceExportData; +import org.thingsboard.server.service.sync.importing.EntityImportSettings; +import org.thingsboard.server.utils.ThrowingRunnable; @Service @TbCoreComponent @@ -31,6 +36,7 @@ import org.thingsboard.server.service.sync.exporting.data.DeviceExportData; public class DeviceImportService extends BaseEntityImportService { private final DeviceService deviceService; + private final TbClusterService clusterService; @Override protected void setOwner(TenantId tenantId, Device device, NewIdProvider idProvider) { @@ -52,6 +58,13 @@ public class DeviceImportService extends BaseEntityImportService { + clusterService.onDeviceUpdated(savedDevice, oldDevice); + }; + } + @Override public EntityType getEntityType() { return EntityType.DEVICE; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DeviceProfileImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DeviceProfileImportService.java index b59d4fa23e..f9d8d2ddd1 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DeviceProfileImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/DeviceProfileImportService.java @@ -23,7 +23,9 @@ import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.sync.exporting.data.DeviceProfileExportData; +import org.thingsboard.server.utils.ThrowingRunnable; @Service @TbCoreComponent @@ -46,6 +48,13 @@ public class DeviceProfileImportService extends BaseEntityImportService { + + }; + } + @Override public EntityType getEntityType() { return EntityType.DEVICE_PROFILE; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/RuleChainImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/RuleChainImportService.java index 8f0ff5dc7e..f6a96f24bf 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/RuleChainImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/importing/impl/RuleChainImportService.java @@ -27,7 +27,9 @@ import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.sync.exporting.data.RuleChainExportData; +import org.thingsboard.server.utils.ThrowingRunnable; import java.util.Collections; import java.util.Optional; @@ -79,6 +81,13 @@ public class RuleChainImportService extends BaseEntityImportService { + + }; + } + @Override public EntityType getEntityType() { return EntityType.RULE_CHAIN; diff --git a/application/src/main/java/org/thingsboard/server/utils/ThrowingRunnable.java b/application/src/main/java/org/thingsboard/server/utils/ThrowingRunnable.java new file mode 100644 index 0000000000..6965a79d19 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/utils/ThrowingRunnable.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.utils; + +import org.thingsboard.server.common.data.exception.ThingsboardException; + +public interface ThrowingRunnable { + + void run() throws ThingsboardException; + +}