Save relations after all other entities are saved on import; refactoring

This commit is contained in:
Viacheslav Klimov 2022-04-08 13:53:28 +03:00
parent 12840c81e9
commit 1b48a98fa0
18 changed files with 168 additions and 142 deletions

View File

@ -46,16 +46,13 @@ import org.thingsboard.server.service.sync.exporting.data.request.EntityQueryExp
import org.thingsboard.server.service.sync.exporting.data.request.EntityTypeExportRequest; import org.thingsboard.server.service.sync.exporting.data.request.EntityTypeExportRequest;
import org.thingsboard.server.service.sync.exporting.data.request.ExportRequest; import org.thingsboard.server.service.sync.exporting.data.request.ExportRequest;
import org.thingsboard.server.service.sync.exporting.data.request.SingleEntityExportRequest; import org.thingsboard.server.service.sync.exporting.data.request.SingleEntityExportRequest;
import org.thingsboard.server.service.sync.importing.EntityImportResult; import org.thingsboard.server.service.sync.importing.data.EntityImportResult;
import org.thingsboard.server.service.sync.importing.data.request.ImportRequest; import org.thingsboard.server.service.sync.importing.data.request.ImportRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.thingsboard.server.dao.sql.query.EntityKeyMapping.CREATED_TIME; import static org.thingsboard.server.dao.sql.query.EntityKeyMapping.CREATED_TIME;
@ -163,15 +160,7 @@ public class EntitiesExportImportController extends BaseController {
public List<EntityImportResult<ExportableEntity<EntityId>>> importEntities(@RequestBody ImportRequest importRequest) throws ThingsboardException { public List<EntityImportResult<ExportableEntity<EntityId>>> importEntities(@RequestBody ImportRequest importRequest) throws ThingsboardException {
SecurityUser user = getCurrentUser(); SecurityUser user = getCurrentUser();
try { try {
List<EntityImportResult<ExportableEntity<EntityId>>> importResults = exportImportService.importEntities(user, return exportImportService.importEntities(user, importRequest.getExportDataList(), importRequest.getImportSettings());
importRequest.getExportDataList(), importRequest.getImportSettings());
for (EntityImportResult<ExportableEntity<EntityId>> entityImportResult : importResults) {
if (entityImportResult.getCallback() != null) {
entityImportResult.getCallback().run();
}
}
return importResults;
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }

View File

@ -16,6 +16,7 @@
package org.thingsboard.server.service.sync; package org.thingsboard.server.service.sync;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -35,12 +36,13 @@ import org.thingsboard.server.service.security.permission.AccessControlService;
import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource; import org.thingsboard.server.service.security.permission.Resource;
import org.thingsboard.server.service.sync.exporting.EntityExportService; import org.thingsboard.server.service.sync.exporting.EntityExportService;
import org.thingsboard.server.service.sync.exporting.data.request.EntityExportSettings;
import org.thingsboard.server.service.sync.exporting.ExportableEntitiesService; import org.thingsboard.server.service.sync.exporting.ExportableEntitiesService;
import org.thingsboard.server.service.sync.exporting.data.EntityExportData; import org.thingsboard.server.service.sync.exporting.data.EntityExportData;
import org.thingsboard.server.service.sync.importing.EntityImportResult; import org.thingsboard.server.service.sync.exporting.data.request.EntityExportSettings;
import org.thingsboard.server.service.sync.importing.EntityImportService; import org.thingsboard.server.service.sync.importing.EntityImportService;
import org.thingsboard.server.service.sync.importing.EntityImportSettings; import org.thingsboard.server.service.sync.importing.data.EntityImportResult;
import org.thingsboard.server.service.sync.importing.data.EntityImportSettings;
import org.thingsboard.server.utils.ThrowingRunnable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -48,10 +50,13 @@ import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@Service @Service
@TbCoreComponent @TbCoreComponent
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class DefaultEntitiesExportImportService implements EntitiesExportImportService, ExportableEntitiesService { public class DefaultEntitiesExportImportService implements EntitiesExportImportService, ExportableEntitiesService {
private final Map<EntityType, EntityExportService<?, ?, ?>> exportServices = new HashMap<>(); private final Map<EntityType, EntityExportService<?, ?, ?>> exportServices = new HashMap<>();
@ -77,7 +82,37 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public <E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(SecurityUser user, EntityExportData<E> exportData, EntityImportSettings importSettings) throws ThingsboardException { public List<EntityImportResult<ExportableEntity<EntityId>>> importEntities(SecurityUser user, List<EntityExportData<ExportableEntity<EntityId>>> exportDataList, EntityImportSettings importSettings) throws ThingsboardException {
exportDataList.sort(Comparator.comparing(exportData -> SUPPORTED_ENTITY_TYPES.indexOf(exportData.getEntityType())));
List<EntityImportResult<ExportableEntity<EntityId>>> importResults = new ArrayList<>();
for (EntityExportData<ExportableEntity<EntityId>> exportData : exportDataList) {
EntityImportResult<ExportableEntity<EntityId>> importResult = importEntity(user, exportData, importSettings);
importResults.add(importResult);
}
for (ThrowingRunnable saveReferencesCallback : importResults.stream()
.map(EntityImportResult::getSaveReferencesCallback)
.filter(Objects::nonNull)
.collect(Collectors.toList())) {
saveReferencesCallback.run();
}
importResults.stream()
.map(EntityImportResult::getPushEventsCallback)
.filter(Objects::nonNull)
.forEach(pushEventsCallback -> {
try {
pushEventsCallback.run();
} catch (Exception e) {
log.error("Failed to send event for entity", e);
}
});
return importResults;
}
private <E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(SecurityUser user, EntityExportData<E> exportData, EntityImportSettings importSettings) throws ThingsboardException {
if (exportData.getEntity() == null || exportData.getEntity().getId() == null) { if (exportData.getEntity() == null || exportData.getEntity().getId() == null) {
throw new DataValidationException("Invalid entity data"); throw new DataValidationException("Invalid entity data");
} }
@ -85,22 +120,9 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS
EntityType entityType = exportData.getEntityType(); EntityType entityType = exportData.getEntityType();
EntityImportService<I, E, EntityExportData<E>> importService = getImportService(entityType); EntityImportService<I, E, EntityExportData<E>> importService = getImportService(entityType);
// TODO [viacheslav]: might throw DataIntegrityViolationException with cause of ConstraintViolationException: need to give normal error
return importService.importEntity(user, exportData, importSettings); return importService.importEntity(user, exportData, importSettings);
} }
@Transactional(rollbackFor = Exception.class)
@Override
public List<EntityImportResult<ExportableEntity<EntityId>>> importEntities(SecurityUser user, List<EntityExportData<ExportableEntity<EntityId>>> exportDataList, EntityImportSettings importSettings) throws ThingsboardException {
exportDataList.sort(Comparator.comparing(exportData -> SUPPORTED_ENTITY_TYPES.indexOf(exportData.getEntityType())));
List<EntityImportResult<ExportableEntity<EntityId>>> importResults = new ArrayList<>();
for (EntityExportData<ExportableEntity<EntityId>> exportData : exportDataList) {
importResults.add(importEntity(user, exportData, importSettings));
}
return importResults;
}
@Override @Override
public <E extends ExportableEntity<I>, I extends EntityId> E findEntityByTenantIdAndExternalId(TenantId tenantId, I externalId) { public <E extends ExportableEntity<I>, I extends EntityId> E findEntityByTenantIdAndExternalId(TenantId tenantId, I externalId) {

View File

@ -19,10 +19,10 @@ import org.thingsboard.server.common.data.ExportableEntity;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.sync.exporting.data.request.EntityExportSettings;
import org.thingsboard.server.service.sync.exporting.data.EntityExportData; import org.thingsboard.server.service.sync.exporting.data.EntityExportData;
import org.thingsboard.server.service.sync.importing.EntityImportResult; import org.thingsboard.server.service.sync.exporting.data.request.EntityExportSettings;
import org.thingsboard.server.service.sync.importing.EntityImportSettings; import org.thingsboard.server.service.sync.importing.data.EntityImportResult;
import org.thingsboard.server.service.sync.importing.data.EntityImportSettings;
import java.util.List; import java.util.List;
@ -30,8 +30,6 @@ public interface EntitiesExportImportService {
<E extends ExportableEntity<I>, I extends EntityId> EntityExportData<E> exportEntity(SecurityUser user, I entityId, EntityExportSettings exportSettings) throws ThingsboardException; <E extends ExportableEntity<I>, I extends EntityId> EntityExportData<E> exportEntity(SecurityUser user, I entityId, EntityExportSettings exportSettings) throws ThingsboardException;
<E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(SecurityUser user, EntityExportData<E> exportData, EntityImportSettings importSettings) throws ThingsboardException;
List<EntityImportResult<ExportableEntity<EntityId>>> importEntities(SecurityUser user, List<EntityExportData<ExportableEntity<EntityId>>> exportDataList, EntityImportSettings importSettings) throws ThingsboardException; List<EntityImportResult<ExportableEntity<EntityId>>> importEntities(SecurityUser user, List<EntityExportData<ExportableEntity<EntityId>>> exportDataList, EntityImportSettings importSettings) throws ThingsboardException;
} }

View File

@ -21,6 +21,8 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.sync.exporting.data.EntityExportData; import org.thingsboard.server.service.sync.exporting.data.EntityExportData;
import org.thingsboard.server.service.sync.importing.data.EntityImportResult;
import org.thingsboard.server.service.sync.importing.data.EntityImportSettings;
public interface EntityImportService<I extends EntityId, E extends ExportableEntity<I>, D extends EntityExportData<E>> { public interface EntityImportService<I extends EntityId, E extends ExportableEntity<I>, D extends EntityExportData<E>> {

View File

@ -13,19 +13,32 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.service.sync.importing; package org.thingsboard.server.service.sync.importing.data;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data; import lombok.Getter;
import lombok.Setter;
import org.thingsboard.server.common.data.ExportableEntity; import org.thingsboard.server.common.data.ExportableEntity;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.utils.ThrowingRunnable; import org.thingsboard.server.utils.ThrowingRunnable;
@Data
public class EntityImportResult<E extends ExportableEntity<? extends EntityId>> { public class EntityImportResult<E extends ExportableEntity<? extends EntityId>> {
@Getter @Setter
private E savedEntity; private E savedEntity;
@Getter @Setter
private E oldEntity; private E oldEntity;
@JsonIgnore
private transient ThrowingRunnable callback; // to call when entity is successfully saved and transaction is committed @Getter @JsonIgnore
private ThrowingRunnable saveReferencesCallback = () -> {};
@Getter @JsonIgnore
private ThrowingRunnable pushEventsCallback = () -> {};
public void addSaveReferencesCallback(ThrowingRunnable callback) {
this.saveReferencesCallback = this.saveReferencesCallback.andThen(callback);
}
public void addPushEventsCallback(ThrowingRunnable callback) {
this.pushEventsCallback = this.pushEventsCallback.andThen(callback);
}
} }

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.service.sync.importing; package org.thingsboard.server.service.sync.importing.data;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;

View File

@ -19,7 +19,7 @@ import lombok.Data;
import org.thingsboard.server.common.data.ExportableEntity; import org.thingsboard.server.common.data.ExportableEntity;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.service.sync.exporting.data.EntityExportData; import org.thingsboard.server.service.sync.exporting.data.EntityExportData;
import org.thingsboard.server.service.sync.importing.EntityImportSettings; import org.thingsboard.server.service.sync.importing.data.EntityImportSettings;
import java.util.List; import java.util.List;

View File

@ -26,7 +26,6 @@ import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.sync.exporting.data.AssetExportData; import org.thingsboard.server.service.sync.exporting.data.AssetExportData;
import org.thingsboard.server.utils.ThrowingRunnable;
@Service @Service
@TbCoreComponent @TbCoreComponent
@ -47,12 +46,11 @@ public class AssetImportService extends BaseEntityImportService<AssetId, Asset,
} }
@Override @Override
protected ThrowingRunnable getCallback(SecurityUser user, Asset savedAsset, Asset oldAsset) { protected void onEntitySaved(SecurityUser user, Asset savedAsset, Asset oldAsset) {
return super.getCallback(user, savedAsset, oldAsset).andThen(() -> { super.onEntitySaved(user, savedAsset, oldAsset);
if (oldAsset != null) { if (oldAsset != null) {
entityActionService.sendEntityNotificationMsgToEdgeService(user.getTenantId(), savedAsset.getId(), EdgeEventActionType.UPDATED); entityActionService.sendEntityNotificationMsgToEdgeService(user.getTenantId(), savedAsset.getId(), EdgeEventActionType.UPDATED);
} }
});
} }
@Override @Override

View File

@ -37,10 +37,9 @@ import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.sync.exporting.ExportableEntitiesService; import org.thingsboard.server.service.sync.exporting.ExportableEntitiesService;
import org.thingsboard.server.service.sync.exporting.data.EntityExportData; 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.EntityImportService;
import org.thingsboard.server.service.sync.importing.EntityImportSettings; import org.thingsboard.server.service.sync.importing.data.EntityImportResult;
import org.thingsboard.server.utils.ThrowingRunnable; import org.thingsboard.server.service.sync.importing.data.EntityImportSettings;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
@ -81,12 +80,13 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
} }
E savedEntity = prepareAndSave(user.getTenantId(), entity, exportData, idProvider); E savedEntity = prepareAndSave(user.getTenantId(), entity, exportData, idProvider);
ThrowingRunnable callback = processAfterSavedAndGetCallback(user, savedEntity, existingEntity, exportData, importSettings, idProvider);
EntityImportResult<E> importResult = new EntityImportResult<>(); EntityImportResult<E> importResult = new EntityImportResult<>();
importResult.setSavedEntity(savedEntity); importResult.setSavedEntity(savedEntity);
importResult.setOldEntity(existingEntity); importResult.setOldEntity(existingEntity);
importResult.setCallback(callback);
processAfterSaved(user, importResult, exportData, idProvider, importSettings);
return importResult; return importResult;
} }
@ -94,8 +94,12 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
protected abstract E prepareAndSave(TenantId tenantId, E entity, D exportData, NewIdProvider idProvider); protected abstract E prepareAndSave(TenantId tenantId, E entity, D exportData, NewIdProvider idProvider);
protected ThrowingRunnable processAfterSavedAndGetCallback(SecurityUser user, E savedEntity, E oldEntity, D exportData, protected void processAfterSaved(SecurityUser user, EntityImportResult<E> importResult, D exportData,
EntityImportSettings importSettings, NewIdProvider idProvider) throws ThingsboardException { NewIdProvider idProvider, EntityImportSettings importSettings) throws ThingsboardException {
E savedEntity = importResult.getSavedEntity();
E oldEntity = importResult.getOldEntity();
importResult.addSaveReferencesCallback(() -> {
List<EntityRelation> newRelations = new LinkedList<>(); List<EntityRelation> newRelations = new LinkedList<>();
if (importSettings.isImportInboundRelations() && CollectionUtils.isNotEmpty(exportData.getInboundRelations())) { if (importSettings.isImportInboundRelations() && CollectionUtils.isNotEmpty(exportData.getInboundRelations())) {
@ -139,15 +143,17 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
relationService.saveRelation(user.getTenantId(), relation); relationService.saveRelation(user.getTenantId(), relation);
} }
});
return getCallback(user, savedEntity, oldEntity); importResult.addPushEventsCallback(() -> {
onEntitySaved(user, savedEntity, oldEntity);
});
} }
protected ThrowingRunnable getCallback(SecurityUser user, E savedEntity, E oldEntity) { protected void onEntitySaved(SecurityUser user, E savedEntity, E oldEntity) {
return () -> { entityActionService.logEntityAction(user, savedEntity.getId(), savedEntity,
entityActionService.logEntityAction(user, savedEntity.getId(), savedEntity, savedEntity instanceof HasCustomerId ? ((HasCustomerId) savedEntity).getCustomerId() : user.getCustomerId(), savedEntity instanceof HasCustomerId ? ((HasCustomerId) savedEntity).getCustomerId() : user.getCustomerId(),
oldEntity == null ? ActionType.ADDED : ActionType.UPDATED, null); oldEntity == null ? ActionType.ADDED : ActionType.UPDATED, null);
};
} }

View File

@ -20,15 +20,12 @@ import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType; 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.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.sync.exporting.data.CustomerExportData; import org.thingsboard.server.service.sync.exporting.data.CustomerExportData;
import org.thingsboard.server.service.sync.importing.EntityImportSettings;
import org.thingsboard.server.utils.ThrowingRunnable;
@Service @Service
@TbCoreComponent @TbCoreComponent
@ -48,12 +45,11 @@ public class CustomerImportService extends BaseEntityImportService<CustomerId, C
} }
@Override @Override
protected ThrowingRunnable getCallback(SecurityUser user, Customer savedCustomer, Customer oldCustomer) { protected void onEntitySaved(SecurityUser user, Customer savedCustomer, Customer oldCustomer) {
return super.getCallback(user, savedCustomer, oldCustomer).andThen(() -> { super.onEntitySaved(user, savedCustomer, oldCustomer);
if (oldCustomer != null) { if (oldCustomer != null) {
entityActionService.sendEntityNotificationMsgToEdgeService(user.getTenantId(), savedCustomer.getId(), EdgeEventActionType.UPDATED); entityActionService.sendEntityNotificationMsgToEdgeService(user.getTenantId(), savedCustomer.getId(), EdgeEventActionType.UPDATED);
} }
});
} }
@Override @Override

View File

@ -35,7 +35,6 @@ import org.thingsboard.server.dao.sql.query.DefaultEntityQueryRepository;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.sync.exporting.data.DashboardExportData; import org.thingsboard.server.service.sync.exporting.data.DashboardExportData;
import org.thingsboard.server.utils.ThrowingRunnable;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -111,12 +110,11 @@ public class DashboardImportService extends BaseEntityImportService<DashboardId,
} }
@Override @Override
protected ThrowingRunnable getCallback(SecurityUser user, Dashboard savedDashboard, Dashboard oldDashboard) { protected void onEntitySaved(SecurityUser user, Dashboard savedDashboard, Dashboard oldDashboard) {
return super.getCallback(user, savedDashboard, oldDashboard).andThen(() -> { super.onEntitySaved(user, savedDashboard, oldDashboard);
if (oldDashboard != null) { if (oldDashboard != null) {
entityActionService.sendEntityNotificationMsgToEdgeService(user.getTenantId(), savedDashboard.getId(), EdgeEventActionType.UPDATED); entityActionService.sendEntityNotificationMsgToEdgeService(user.getTenantId(), savedDashboard.getId(), EdgeEventActionType.UPDATED);
} }
});
} }
@Override @Override

View File

@ -25,7 +25,6 @@ import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.sync.exporting.data.DeviceExportData; import org.thingsboard.server.service.sync.exporting.data.DeviceExportData;
import org.thingsboard.server.utils.ThrowingRunnable;
@Service @Service
@TbCoreComponent @TbCoreComponent
@ -55,10 +54,9 @@ public class DeviceImportService extends BaseEntityImportService<DeviceId, Devic
} }
@Override @Override
protected ThrowingRunnable getCallback(SecurityUser user, Device savedDevice, Device oldDevice) { protected void onEntitySaved(SecurityUser user, Device savedDevice, Device oldDevice) {
return super.getCallback(user, savedDevice, oldDevice).andThen(() -> { super.onEntitySaved(user, savedDevice, oldDevice);
clusterService.onDeviceUpdated(savedDevice, oldDevice); clusterService.onDeviceUpdated(savedDevice, oldDevice);
});
} }
@Override @Override

View File

@ -28,7 +28,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.ota.OtaPackageStateService; import org.thingsboard.server.service.ota.OtaPackageStateService;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.sync.exporting.data.DeviceProfileExportData; import org.thingsboard.server.service.sync.exporting.data.DeviceProfileExportData;
import org.thingsboard.server.utils.ThrowingRunnable;
import java.util.Objects; import java.util.Objects;
@ -55,8 +54,8 @@ public class DeviceProfileImportService extends BaseEntityImportService<DevicePr
} }
@Override @Override
protected ThrowingRunnable getCallback(SecurityUser user, DeviceProfile savedDeviceProfile, DeviceProfile oldDeviceProfile) { protected void onEntitySaved(SecurityUser user, DeviceProfile savedDeviceProfile, DeviceProfile oldDeviceProfile) {
return super.getCallback(user, savedDeviceProfile, oldDeviceProfile).andThen(() -> { super.onEntitySaved(user, savedDeviceProfile, oldDeviceProfile);
clusterService.onDeviceProfileChange(savedDeviceProfile, null); clusterService.onDeviceProfileChange(savedDeviceProfile, null);
clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedDeviceProfile.getId(), clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedDeviceProfile.getId(),
oldDeviceProfile == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); oldDeviceProfile == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
@ -65,7 +64,6 @@ public class DeviceProfileImportService extends BaseEntityImportService<DevicePr
otaPackageStateService.update(savedDeviceProfile, otaPackageStateService.update(savedDeviceProfile,
oldDeviceProfile != null && !Objects.equals(oldDeviceProfile.getFirmwareId(), savedDeviceProfile.getFirmwareId()), oldDeviceProfile != null && !Objects.equals(oldDeviceProfile.getFirmwareId(), savedDeviceProfile.getFirmwareId()),
oldDeviceProfile != null && !Objects.equals(oldDeviceProfile.getSoftwareId(), savedDeviceProfile.getSoftwareId())); oldDeviceProfile != null && !Objects.equals(oldDeviceProfile.getSoftwareId(), savedDeviceProfile.getSoftwareId()));
});
} }
@Override @Override

View File

@ -32,7 +32,6 @@ import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.sync.exporting.data.RuleChainExportData; import org.thingsboard.server.service.sync.exporting.data.RuleChainExportData;
import org.thingsboard.server.utils.ThrowingRunnable;
import java.util.Collections; import java.util.Collections;
import java.util.Optional; import java.util.Optional;
@ -85,15 +84,14 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
} }
@Override @Override
protected ThrowingRunnable getCallback(SecurityUser user, RuleChain savedRuleChain, RuleChain oldRuleChain) { protected void onEntitySaved(SecurityUser user, RuleChain savedRuleChain, RuleChain oldRuleChain) {
return super.getCallback(user, savedRuleChain, oldRuleChain).andThen(() -> { super.onEntitySaved(user, savedRuleChain, oldRuleChain);
if (savedRuleChain.getType() == RuleChainType.CORE) { if (savedRuleChain.getType() == RuleChainType.CORE) {
clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedRuleChain.getId(), clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedRuleChain.getId(),
oldRuleChain == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); oldRuleChain == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
} else if (savedRuleChain.getType() == RuleChainType.EDGE && oldRuleChain != null) { } else if (savedRuleChain.getType() == RuleChainType.EDGE && oldRuleChain != null) {
entityActionService.sendEntityNotificationMsgToEdgeService(user.getTenantId(), savedRuleChain.getId(), EdgeEventActionType.UPDATED); entityActionService.sendEntityNotificationMsgToEdgeService(user.getTenantId(), savedRuleChain.getId(), EdgeEventActionType.UPDATED);
} }
});
} }
@Override @Override

View File

@ -48,7 +48,7 @@ import org.thingsboard.server.service.sync.exporting.ExportableEntitiesService;
import org.thingsboard.server.service.sync.exporting.data.DeviceExportData; import org.thingsboard.server.service.sync.exporting.data.DeviceExportData;
import org.thingsboard.server.service.sync.exporting.data.EntityExportData; import org.thingsboard.server.service.sync.exporting.data.EntityExportData;
import org.thingsboard.server.service.sync.exporting.data.RuleChainExportData; import org.thingsboard.server.service.sync.exporting.data.RuleChainExportData;
import org.thingsboard.server.service.sync.importing.EntityImportResult; import org.thingsboard.server.service.sync.importing.data.EntityImportResult;
import java.util.List; import java.util.List;

View File

@ -37,6 +37,8 @@ public interface Dao<T> {
T save(TenantId tenantId, T t); T save(TenantId tenantId, T t);
T saveAndFlush(TenantId tenantId, T t);
boolean removeById(TenantId tenantId, UUID id); boolean removeById(TenantId tenantId, UUID id);
void removeAllByIds(Collection<UUID> ids); void removeAllByIds(Collection<UUID> ids);

View File

@ -117,7 +117,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
assetValidator.validate(asset, Asset::getTenantId); assetValidator.validate(asset, Asset::getTenantId);
Asset savedAsset; Asset savedAsset;
try { try {
savedAsset = assetDao.save(asset.getTenantId(), asset); savedAsset = assetDao.saveAndFlush(asset.getTenantId(), asset);
} catch (Exception t) { } catch (Exception t) {
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("asset_name_unq_key")) { if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("asset_name_unq_key")) {

View File

@ -67,6 +67,14 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D>
return DaoUtil.getData(entity); return DaoUtil.getData(entity);
} }
@Override
@Transactional
public D saveAndFlush(TenantId tenantId, D domain) {
D d = save(tenantId, domain);
getRepository().flush();
return d;
}
@Override @Override
public D findById(TenantId tenantId, UUID key) { public D findById(TenantId tenantId, UUID key) {
log.debug("Get entity by key {}", key); log.debug("Get entity by key {}", key);