Merge branch 'feature/entities-version-control' of github.com:thingsboard/thingsboard into feature/entities-version-control
This commit is contained in:
commit
a1b0817e06
@ -36,6 +36,7 @@ import org.thingsboard.server.service.sync.ie.exporting.EntityExportService;
|
|||||||
import org.thingsboard.server.service.sync.ie.exporting.impl.BaseEntityExportService;
|
import org.thingsboard.server.service.sync.ie.exporting.impl.BaseEntityExportService;
|
||||||
import org.thingsboard.server.service.sync.ie.exporting.impl.DefaultEntityExportService;
|
import org.thingsboard.server.service.sync.ie.exporting.impl.DefaultEntityExportService;
|
||||||
import org.thingsboard.server.service.sync.ie.importing.EntityImportService;
|
import org.thingsboard.server.service.sync.ie.importing.EntityImportService;
|
||||||
|
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@ -74,9 +75,9 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(SecurityUser user, EntityExportData<E> exportData, EntityImportSettings importSettings,
|
public <E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(EntitiesImportCtx ctx, EntityExportData<E> exportData,
|
||||||
boolean saveReferences, boolean sendEvents) throws ThingsboardException {
|
boolean saveReferences, boolean sendEvents) throws ThingsboardException {
|
||||||
if (!rateLimitService.checkEntityImportLimit(user.getTenantId())) {
|
if (!rateLimitService.checkEntityImportLimit(ctx.getTenantId())) {
|
||||||
throw new ThingsboardException("Rate limit for entities import is exceeded", ThingsboardErrorCode.TOO_MANY_REQUESTS);
|
throw new ThingsboardException("Rate limit for entities import is exceeded", ThingsboardErrorCode.TOO_MANY_REQUESTS);
|
||||||
}
|
}
|
||||||
if (exportData.getEntity() == null || exportData.getEntity().getId() == null) {
|
if (exportData.getEntity() == null || exportData.getEntity().getId() == null) {
|
||||||
@ -86,7 +87,7 @@ 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);
|
||||||
|
|
||||||
EntityImportResult<E> importResult = importService.importEntity(user, exportData, importSettings);
|
EntityImportResult<E> importResult = importService.importEntity(ctx, exportData);
|
||||||
|
|
||||||
if (saveReferences) {
|
if (saveReferences) {
|
||||||
importResult.getSaveReferencesCallback().run();
|
importResult.getSaveReferencesCallback().run();
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.sync.ie.EntityExportSettings;
|
|||||||
import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
|
import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
|
||||||
import org.thingsboard.server.common.data.sync.ie.EntityImportSettings;
|
import org.thingsboard.server.common.data.sync.ie.EntityImportSettings;
|
||||||
import org.thingsboard.server.service.security.model.SecurityUser;
|
import org.thingsboard.server.service.security.model.SecurityUser;
|
||||||
|
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ 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,
|
<E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(EntitiesImportCtx ctx, EntityExportData<E> exportData,
|
||||||
boolean saveReferences, boolean sendEvents) throws ThingsboardException;
|
boolean saveReferences, boolean sendEvents) throws ThingsboardException;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -151,23 +151,6 @@ public class DefaultExportableEntitiesService implements ExportableEntitiesServi
|
|||||||
entityRemover.accept(tenantId, id);
|
entityRemover.accept(tenantId, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkPermission(SecurityUser user, HasId<? extends EntityId> entity, EntityType entityType, Operation operation) throws ThingsboardException {
|
|
||||||
if (entity instanceof HasTenantId) {
|
|
||||||
accessControlService.checkPermission(user, Resource.of(entityType), operation, entity.getId(), (HasTenantId) entity);
|
|
||||||
} else {
|
|
||||||
accessControlService.checkPermission(user, Resource.of(entityType), operation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkPermission(SecurityUser user, EntityId entityId, Operation operation) throws ThingsboardException {
|
|
||||||
HasId<EntityId> entity = findEntityByTenantIdAndId(user.getTenantId(), entityId);
|
|
||||||
checkPermission(user, entity, entityId.getEntityType(), operation);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <E> Dao<E> getDao(EntityType entityType) {
|
private <E> Dao<E> getDao(EntityType entityType) {
|
||||||
return (Dao<E>) daos.get(entityType);
|
return (Dao<E>) daos.get(entityType);
|
||||||
|
|||||||
@ -40,9 +40,4 @@ public interface ExportableEntitiesService {
|
|||||||
|
|
||||||
<I extends EntityId> void removeById(TenantId tenantId, I id);
|
<I extends EntityId> void removeById(TenantId tenantId, I id);
|
||||||
|
|
||||||
|
|
||||||
void checkPermission(SecurityUser user, HasId<? extends EntityId> entity, EntityType entityType, Operation operation) throws ThingsboardException;
|
|
||||||
|
|
||||||
void checkPermission(SecurityUser user, EntityId entityId, Operation operation) throws ThingsboardException;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,6 @@ public class DefaultEntityExportService<I extends EntityId, E extends Exportable
|
|||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
throw new IllegalArgumentException(entityId.getEntityType() + " [" + entityId.getId() + "] not found");
|
throw new IllegalArgumentException(entityId.getEntityType() + " [" + entityId.getId() + "] not found");
|
||||||
}
|
}
|
||||||
exportableEntitiesService.checkPermission(user, entity, entity.getId().getEntityType(), Operation.READ);
|
|
||||||
|
|
||||||
exportData.setEntity(entity);
|
exportData.setEntity(entity);
|
||||||
exportData.setEntityType(entityId.getEntityType());
|
exportData.setEntityType(entityId.getEntityType());
|
||||||
@ -90,22 +89,14 @@ public class DefaultEntityExportService<I extends EntityId, E extends Exportable
|
|||||||
List<EntityRelation> relations = new ArrayList<>();
|
List<EntityRelation> relations = new ArrayList<>();
|
||||||
|
|
||||||
List<EntityRelation> inboundRelations = relationService.findByTo(user.getTenantId(), entity.getId(), RelationTypeGroup.COMMON);
|
List<EntityRelation> inboundRelations = relationService.findByTo(user.getTenantId(), entity.getId(), RelationTypeGroup.COMMON);
|
||||||
for (EntityRelation relation : inboundRelations) {
|
|
||||||
exportableEntitiesService.checkPermission(user, relation.getFrom(), Operation.READ);
|
|
||||||
}
|
|
||||||
relations.addAll(inboundRelations);
|
relations.addAll(inboundRelations);
|
||||||
|
|
||||||
List<EntityRelation> outboundRelations = relationService.findByFrom(user.getTenantId(), entity.getId(), RelationTypeGroup.COMMON);
|
List<EntityRelation> outboundRelations = relationService.findByFrom(user.getTenantId(), entity.getId(), RelationTypeGroup.COMMON);
|
||||||
for (EntityRelation relation : outboundRelations) {
|
|
||||||
exportableEntitiesService.checkPermission(user, relation.getTo(), Operation.READ);
|
|
||||||
}
|
|
||||||
relations.addAll(outboundRelations);
|
relations.addAll(outboundRelations);
|
||||||
return relations;
|
return relations;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, List<AttributeExportData>> exportAttributes(SecurityUser user, E entity) throws ThingsboardException {
|
private Map<String, List<AttributeExportData>> exportAttributes(SecurityUser user, E entity) throws ThingsboardException {
|
||||||
exportableEntitiesService.checkPermission(user, entity, entity.getId().getEntityType(), Operation.READ_ATTRIBUTES);
|
|
||||||
|
|
||||||
List<String> scopes;
|
List<String> scopes;
|
||||||
if (entity.getId().getEntityType() == EntityType.DEVICE) {
|
if (entity.getId().getEntityType() == EntityType.DEVICE) {
|
||||||
scopes = List.of(DataConstants.SERVER_SCOPE, DataConstants.SHARED_SCOPE);
|
scopes = List.of(DataConstants.SERVER_SCOPE, DataConstants.SHARED_SCOPE);
|
||||||
|
|||||||
@ -23,10 +23,11 @@ import org.thingsboard.server.service.security.model.SecurityUser;
|
|||||||
import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
|
import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
|
||||||
import org.thingsboard.server.common.data.sync.ie.EntityImportSettings;
|
import org.thingsboard.server.common.data.sync.ie.EntityImportSettings;
|
||||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||||
|
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||||
|
|
||||||
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>> {
|
||||||
|
|
||||||
EntityImportResult<E> importEntity(SecurityUser user, D exportData, EntityImportSettings importSettings) throws ThingsboardException;
|
EntityImportResult<E> importEntity(EntitiesImportCtx ctx, D exportData) throws ThingsboardException;
|
||||||
|
|
||||||
EntityType getEntityType();
|
EntityType getEntityType();
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,7 @@ 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.common.data.sync.ie.EntityExportData;
|
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||||
|
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@TbCoreComponent
|
@TbCoreComponent
|
||||||
@ -43,7 +44,7 @@ public class AssetImportService extends BaseEntityImportService<AssetId, Asset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Asset prepareAndSave(TenantId tenantId, Asset asset, EntityExportData<Asset> exportData, IdProvider idProvider, EntityImportSettings importSettings) {
|
protected Asset prepareAndSave(EntitiesImportCtx ctx, Asset asset, EntityExportData<Asset> exportData, IdProvider idProvider) {
|
||||||
return assetService.saveAsset(asset);
|
return assetService.saveAsset(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -53,6 +53,7 @@ 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.ie.exporting.ExportableEntitiesService;
|
import org.thingsboard.server.service.sync.ie.exporting.ExportableEntitiesService;
|
||||||
import org.thingsboard.server.service.sync.ie.importing.EntityImportService;
|
import org.thingsboard.server.service.sync.ie.importing.EntityImportService;
|
||||||
|
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||||
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -81,54 +82,53 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
|
|||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@Override
|
@Override
|
||||||
public EntityImportResult<E> importEntity(SecurityUser user, D exportData, EntityImportSettings importSettings) throws ThingsboardException {
|
public EntityImportResult<E> importEntity(EntitiesImportCtx ctx, D exportData) throws ThingsboardException {
|
||||||
E entity = exportData.getEntity();
|
E entity = exportData.getEntity();
|
||||||
E existingEntity = findExistingEntity(user.getTenantId(), entity, importSettings);
|
E existingEntity = findExistingEntity(ctx, entity);
|
||||||
|
|
||||||
entity.setExternalId(entity.getId());
|
entity.setExternalId(entity.getId());
|
||||||
|
|
||||||
EntityImportResult<E> importResult = new EntityImportResult<>();
|
EntityImportResult<E> importResult = new EntityImportResult<>();
|
||||||
IdProvider idProvider = new IdProvider(user, importSettings, importResult);
|
IdProvider idProvider = new IdProvider(ctx, importResult);
|
||||||
setOwner(user.getTenantId(), entity, idProvider);
|
setOwner(ctx.getTenantId(), entity, idProvider);
|
||||||
if (existingEntity == null) {
|
if (existingEntity == null) {
|
||||||
entity.setId(null);
|
entity.setId(null);
|
||||||
exportableEntitiesService.checkPermission(user, entity, getEntityType(), Operation.CREATE);
|
|
||||||
} else {
|
} else {
|
||||||
entity.setId(existingEntity.getId());
|
entity.setId(existingEntity.getId());
|
||||||
entity.setCreatedTime(existingEntity.getCreatedTime());
|
entity.setCreatedTime(existingEntity.getCreatedTime());
|
||||||
exportableEntitiesService.checkPermission(user, existingEntity, getEntityType(), Operation.WRITE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
E savedEntity = prepareAndSave(user.getTenantId(), entity, exportData, idProvider, importSettings);
|
E savedEntity = prepareAndSave(ctx, entity, exportData, idProvider);
|
||||||
|
|
||||||
importResult.setSavedEntity(savedEntity);
|
importResult.setSavedEntity(savedEntity);
|
||||||
importResult.setOldEntity(existingEntity);
|
importResult.setOldEntity(existingEntity);
|
||||||
importResult.setEntityType(getEntityType());
|
importResult.setEntityType(getEntityType());
|
||||||
|
|
||||||
processAfterSaved(user, importResult, exportData, idProvider, importSettings);
|
processAfterSaved(ctx, importResult, exportData, idProvider);
|
||||||
|
|
||||||
|
ctx.putInternalId(exportData.getExternalId(), savedEntity.getId());
|
||||||
|
|
||||||
return importResult;
|
return importResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void setOwner(TenantId tenantId, E entity, IdProvider idProvider);
|
protected abstract void setOwner(TenantId tenantId, E entity, IdProvider idProvider);
|
||||||
|
|
||||||
protected abstract E prepareAndSave(TenantId tenantId, E entity, D exportData, IdProvider idProvider, EntityImportSettings importSettings);
|
protected abstract E prepareAndSave(EntitiesImportCtx ctx, E entity, D exportData, IdProvider idProvider);
|
||||||
|
|
||||||
|
|
||||||
protected void processAfterSaved(SecurityUser user, EntityImportResult<E> importResult, D exportData,
|
protected void processAfterSaved(EntitiesImportCtx ctx, EntityImportResult<E> importResult, D exportData, IdProvider idProvider) throws ThingsboardException {
|
||||||
IdProvider idProvider, EntityImportSettings importSettings) throws ThingsboardException {
|
|
||||||
E savedEntity = importResult.getSavedEntity();
|
E savedEntity = importResult.getSavedEntity();
|
||||||
E oldEntity = importResult.getOldEntity();
|
E oldEntity = importResult.getOldEntity();
|
||||||
|
|
||||||
importResult.addSendEventsCallback(() -> {
|
importResult.addSendEventsCallback(() -> {
|
||||||
onEntitySaved(user, savedEntity, oldEntity);
|
onEntitySaved(ctx.getUser(), savedEntity, oldEntity);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (importSettings.isUpdateRelations() && exportData.getRelations() != null) {
|
if (ctx.isUpdateRelations() && exportData.getRelations() != null) {
|
||||||
importRelations(user, exportData.getRelations(), importResult);
|
importRelations(ctx.getUser(), exportData.getRelations(), importResult);
|
||||||
}
|
}
|
||||||
if (importSettings.isSaveAttributes() && exportData.getAttributes() != null) {
|
if (ctx.isSaveAttributes() && exportData.getAttributes() != null) {
|
||||||
importAttributes(user, exportData.getAttributes(), importResult);
|
importAttributes(ctx.getUser(), exportData.getAttributes(), importResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,12 +138,10 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
|
|||||||
for (EntityRelation relation : relations) {
|
for (EntityRelation relation : relations) {
|
||||||
if (!relation.getTo().equals(entity.getId())) {
|
if (!relation.getTo().equals(entity.getId())) {
|
||||||
HasId<EntityId> to = findInternalEntity(user.getTenantId(), relation.getTo());
|
HasId<EntityId> to = findInternalEntity(user.getTenantId(), relation.getTo());
|
||||||
exportableEntitiesService.checkPermission(user, to, to.getId().getEntityType(), Operation.WRITE);
|
|
||||||
relation.setTo(to.getId());
|
relation.setTo(to.getId());
|
||||||
}
|
}
|
||||||
if (!relation.getFrom().equals(entity.getId())) {
|
if (!relation.getFrom().equals(entity.getId())) {
|
||||||
HasId<EntityId> from = findInternalEntity(user.getTenantId(), relation.getFrom());
|
HasId<EntityId> from = findInternalEntity(user.getTenantId(), relation.getFrom());
|
||||||
exportableEntitiesService.checkPermission(user, from, from.getId().getEntityType(), Operation.WRITE);
|
|
||||||
relation.setFrom(from.getId());
|
relation.setFrom(from.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,15 +153,6 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
|
|||||||
|
|
||||||
for (EntityRelation existingRelation : existingRelations) {
|
for (EntityRelation existingRelation : existingRelations) {
|
||||||
if (!relations.contains(existingRelation)) {
|
if (!relations.contains(existingRelation)) {
|
||||||
EntityId otherEntity = null;
|
|
||||||
if (!existingRelation.getTo().equals(entity.getId())) {
|
|
||||||
otherEntity = existingRelation.getTo();
|
|
||||||
} else if (!existingRelation.getFrom().equals(entity.getId())) {
|
|
||||||
otherEntity = existingRelation.getFrom();
|
|
||||||
}
|
|
||||||
if (otherEntity != null) {
|
|
||||||
exportableEntitiesService.checkPermission(user, otherEntity, Operation.WRITE);
|
|
||||||
}
|
|
||||||
relationService.deleteRelation(user.getTenantId(), existingRelation);
|
relationService.deleteRelation(user.getTenantId(), existingRelation);
|
||||||
importResult.addSendEventsCallback(() -> {
|
importResult.addSendEventsCallback(() -> {
|
||||||
entityActionService.logEntityAction(user, existingRelation.getFrom(), null, null,
|
entityActionService.logEntityAction(user, existingRelation.getFrom(), null, null,
|
||||||
@ -234,12 +223,12 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
|
|||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected E findExistingEntity(TenantId tenantId, E entity, EntityImportSettings importSettings) {
|
protected E findExistingEntity(EntitiesImportCtx ctx, E entity) {
|
||||||
return (E) Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndExternalId(tenantId, entity.getId()))
|
return (E) Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndExternalId(ctx.getTenantId(), entity.getId()))
|
||||||
.or(() -> Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndId(tenantId, entity.getId())))
|
.or(() -> Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndId(ctx.getTenantId(), entity.getId())))
|
||||||
.or(() -> {
|
.or(() -> {
|
||||||
if (importSettings.isFindExistingByName()) {
|
if (ctx.isFindExistingByName()) {
|
||||||
return Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndName(tenantId, getEntityType(), entity.getName()));
|
return Optional.ofNullable(exportableEntitiesService.findEntityByTenantIdAndName(ctx.getTenantId(), getEntityType(), entity.getName()));
|
||||||
} else {
|
} else {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@ -255,10 +244,10 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
protected class IdProvider {
|
protected class IdProvider {
|
||||||
private final SecurityUser user;
|
private final EntitiesImportCtx ctx;
|
||||||
private final EntityImportSettings importSettings;
|
|
||||||
private final EntityImportResult<E> importResult;
|
private final EntityImportResult<E> importResult;
|
||||||
|
|
||||||
public <ID extends EntityId> ID getInternalId(ID externalId) {
|
public <ID extends EntityId> ID getInternalId(ID externalId) {
|
||||||
@ -268,9 +257,14 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
|
|||||||
public <ID extends EntityId> ID getInternalId(ID externalId, boolean throwExceptionIfNotFound) {
|
public <ID extends EntityId> ID getInternalId(ID externalId, boolean throwExceptionIfNotFound) {
|
||||||
if (externalId == null || externalId.isNullUid()) return null;
|
if (externalId == null || externalId.isNullUid()) return null;
|
||||||
|
|
||||||
|
EntityId localId = ctx.getInternalId(externalId);
|
||||||
|
if (localId != null) {
|
||||||
|
return (ID) localId;
|
||||||
|
}
|
||||||
|
|
||||||
HasId<ID> entity;
|
HasId<ID> entity;
|
||||||
try {
|
try {
|
||||||
entity = findInternalEntity(user.getTenantId(), externalId);
|
entity = findInternalEntity(ctx.getTenantId(), externalId);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (throwExceptionIfNotFound) {
|
if (throwExceptionIfNotFound) {
|
||||||
throw e;
|
throw e;
|
||||||
@ -279,17 +273,26 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
ctx.putInternalId(externalId, entity.getId());
|
||||||
exportableEntitiesService.checkPermission(user, entity, entity.getId().getEntityType(), Operation.READ);
|
|
||||||
} catch (ThingsboardException e) {
|
|
||||||
throw new IllegalArgumentException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
return entity.getId();
|
return entity.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<EntityId> getInternalIdByUuid(UUID externalUuid) {
|
public Optional<EntityId> getInternalIdByUuid(UUID externalUuid) {
|
||||||
if (externalUuid.equals(EntityId.NULL_UUID)) return Optional.empty();
|
if (externalUuid.equals(EntityId.NULL_UUID)) return Optional.empty();
|
||||||
|
|
||||||
|
for (EntityType entityType : EntityType.values()) {
|
||||||
|
EntityId externalId;
|
||||||
|
try {
|
||||||
|
externalId = EntityIdFactory.getByTypeAndUuid(entityType, externalUuid);
|
||||||
|
} catch (Exception e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EntityId internalId = ctx.getInternalId(externalId);
|
||||||
|
if (internalId != null) {
|
||||||
|
return Optional.of(internalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (EntityType entityType : EntityType.values()) {
|
for (EntityType entityType : EntityType.values()) {
|
||||||
EntityId externalId;
|
EntityId externalId;
|
||||||
try {
|
try {
|
||||||
@ -301,12 +304,13 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
|
|||||||
EntityId internalId = getInternalId(externalId, false);
|
EntityId internalId = getInternalId(externalId, false);
|
||||||
if (internalId != null) {
|
if (internalId != null) {
|
||||||
return Optional.of(internalId);
|
return Optional.of(internalId);
|
||||||
} else if (importSettings.isResetExternalIdsOfAnotherTenant()) {
|
} else if (ctx.isResetExternalIdsOfAnotherTenant()) {
|
||||||
try {
|
try {
|
||||||
if (exportableEntitiesService.findEntityById(externalId) != null) {
|
if (exportableEntitiesService.findEntityById(externalId) != null) {
|
||||||
return Optional.of(EntityIdFactory.getByTypeAndUuid(entityType, EntityId.NULL_UUID));
|
return Optional.of(EntityIdFactory.getByTypeAndUuid(entityType, EntityId.NULL_UUID));
|
||||||
}
|
}
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@ 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.common.data.sync.ie.EntityExportData;
|
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||||
|
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@TbCoreComponent
|
@TbCoreComponent
|
||||||
@ -44,13 +45,13 @@ public class CustomerImportService extends BaseEntityImportService<CustomerId, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Customer prepareAndSave(TenantId tenantId, Customer customer, EntityExportData<Customer> exportData, IdProvider idProvider, EntityImportSettings importSettings) {
|
protected Customer prepareAndSave(EntitiesImportCtx ctx, Customer customer, EntityExportData<Customer> exportData, IdProvider idProvider) {
|
||||||
if (!customer.isPublic()) {
|
if (!customer.isPublic()) {
|
||||||
return customerService.saveCustomer(customer);
|
return customerService.saveCustomer(customer);
|
||||||
} else {
|
} else {
|
||||||
Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId);
|
Customer publicCustomer = customerService.findOrCreatePublicCustomer(ctx.getTenantId());
|
||||||
publicCustomer.setExternalId(customer.getExternalId());
|
publicCustomer.setExternalId(customer.getExternalId());
|
||||||
return customerDao.save(tenantId, publicCustomer);
|
return customerDao.save(ctx.getTenantId(), publicCustomer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.sync.ie.EntityImportSettings;
|
|||||||
import org.thingsboard.server.dao.dashboard.DashboardService;
|
import org.thingsboard.server.dao.dashboard.DashboardService;
|
||||||
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.vc.data.EntitiesImportCtx;
|
||||||
import org.thingsboard.server.utils.RegexUtils;
|
import org.thingsboard.server.utils.RegexUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -58,16 +59,17 @@ public class DashboardImportService extends BaseEntityImportService<DashboardId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dashboard findExistingEntity(TenantId tenantId, Dashboard dashboard, EntityImportSettings importSettings) {
|
protected Dashboard findExistingEntity(EntitiesImportCtx ctx, Dashboard dashboard) {
|
||||||
Dashboard existingDashboard = super.findExistingEntity(tenantId, dashboard, importSettings);
|
Dashboard existingDashboard = super.findExistingEntity(ctx, dashboard);
|
||||||
if (existingDashboard == null && importSettings.isFindExistingByName()) {
|
if (existingDashboard == null && ctx.isFindExistingByName()) {
|
||||||
existingDashboard = dashboardService.findTenantDashboardsByTitle(tenantId, dashboard.getName()).stream().findFirst().orElse(null);
|
existingDashboard = dashboardService.findTenantDashboardsByTitle(ctx.getTenantId(), dashboard.getName()).stream().findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
return existingDashboard;
|
return existingDashboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dashboard prepareAndSave(TenantId tenantId, Dashboard dashboard, EntityExportData<Dashboard> exportData, IdProvider idProvider, EntityImportSettings importSettings) {
|
protected Dashboard prepareAndSave(EntitiesImportCtx ctx, Dashboard dashboard, EntityExportData<Dashboard> exportData, IdProvider idProvider) {
|
||||||
|
var tenantId = ctx.getTenantId();
|
||||||
JsonNode configuration = dashboard.getConfiguration();
|
JsonNode configuration = dashboard.getConfiguration();
|
||||||
JsonNode entityAliases = configuration.get("entityAliases");
|
JsonNode entityAliases = configuration.get("entityAliases");
|
||||||
if (entityAliases != null && entityAliases.isObject()) {
|
if (entityAliases != null && entityAliases.isObject()) {
|
||||||
|
|||||||
@ -27,6 +27,7 @@ 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.common.data.sync.ie.DeviceExportData;
|
import org.thingsboard.server.common.data.sync.ie.DeviceExportData;
|
||||||
|
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@TbCoreComponent
|
@TbCoreComponent
|
||||||
@ -42,11 +43,11 @@ public class DeviceImportService extends BaseEntityImportService<DeviceId, Devic
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Device prepareAndSave(TenantId tenantId, Device device, DeviceExportData exportData, IdProvider idProvider, EntityImportSettings importSettings) {
|
protected Device prepareAndSave(EntitiesImportCtx ctx, Device device, DeviceExportData exportData, IdProvider idProvider) {
|
||||||
device.setDeviceProfileId(idProvider.getInternalId(device.getDeviceProfileId()));
|
device.setDeviceProfileId(idProvider.getInternalId(device.getDeviceProfileId()));
|
||||||
device.setFirmwareId(idProvider.getInternalId(device.getFirmwareId()));
|
device.setFirmwareId(idProvider.getInternalId(device.getFirmwareId()));
|
||||||
device.setSoftwareId(idProvider.getInternalId(device.getSoftwareId()));
|
device.setSoftwareId(idProvider.getInternalId(device.getSoftwareId()));
|
||||||
if (exportData.getCredentials() != null && importSettings.isSaveCredentials()) {
|
if (exportData.getCredentials() != null && ctx.isSaveCredentials()) {
|
||||||
exportData.getCredentials().setId(null);
|
exportData.getCredentials().setId(null);
|
||||||
exportData.getCredentials().setDeviceId(null);
|
exportData.getCredentials().setDeviceId(null);
|
||||||
return deviceService.saveDeviceWithCredentials(device, exportData.getCredentials());
|
return deviceService.saveDeviceWithCredentials(device, exportData.getCredentials());
|
||||||
|
|||||||
@ -30,6 +30,7 @@ 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.common.data.sync.ie.EntityExportData;
|
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||||
|
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ public class DeviceProfileImportService extends BaseEntityImportService<DevicePr
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DeviceProfile prepareAndSave(TenantId tenantId, DeviceProfile deviceProfile, EntityExportData<DeviceProfile> exportData, IdProvider idProvider, EntityImportSettings importSettings) {
|
protected DeviceProfile prepareAndSave(EntitiesImportCtx ctx, DeviceProfile deviceProfile, EntityExportData<DeviceProfile> exportData, IdProvider idProvider) {
|
||||||
deviceProfile.setDefaultRuleChainId(idProvider.getInternalId(deviceProfile.getDefaultRuleChainId()));
|
deviceProfile.setDefaultRuleChainId(idProvider.getInternalId(deviceProfile.getDefaultRuleChainId()));
|
||||||
deviceProfile.setDefaultDashboardId(idProvider.getInternalId(deviceProfile.getDefaultDashboardId()));
|
deviceProfile.setDefaultDashboardId(idProvider.getInternalId(deviceProfile.getDefaultDashboardId()));
|
||||||
deviceProfile.setFirmwareId(idProvider.getInternalId(deviceProfile.getFirmwareId()));
|
deviceProfile.setFirmwareId(idProvider.getInternalId(deviceProfile.getFirmwareId()));
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.sync.ie.RuleChainExportData;
|
|||||||
import org.thingsboard.server.dao.rule.RuleChainService;
|
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.vc.data.EntitiesImportCtx;
|
||||||
import org.thingsboard.server.utils.RegexUtils;
|
import org.thingsboard.server.utils.RegexUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -52,16 +53,16 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RuleChain findExistingEntity(TenantId tenantId, RuleChain ruleChain, EntityImportSettings importSettings) {
|
protected RuleChain findExistingEntity(EntitiesImportCtx ctx, RuleChain ruleChain) {
|
||||||
RuleChain existingRuleChain = super.findExistingEntity(tenantId, ruleChain, importSettings);
|
RuleChain existingRuleChain = super.findExistingEntity(ctx, ruleChain);
|
||||||
if (existingRuleChain == null && importSettings.isFindExistingByName()) {
|
if (existingRuleChain == null && ctx.isFindExistingByName()) {
|
||||||
existingRuleChain = ruleChainService.findTenantRuleChainsByTypeAndName(tenantId, ruleChain.getType(), ruleChain.getName()).stream().findFirst().orElse(null);
|
existingRuleChain = ruleChainService.findTenantRuleChainsByTypeAndName(ctx.getTenantId(), ruleChain.getType(), ruleChain.getName()).stream().findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
return existingRuleChain;
|
return existingRuleChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RuleChain prepareAndSave(TenantId tenantId, RuleChain ruleChain, RuleChainExportData exportData, IdProvider idProvider, EntityImportSettings importSettings) {
|
protected RuleChain prepareAndSave(EntitiesImportCtx ctx, RuleChain ruleChain, RuleChainExportData exportData, IdProvider idProvider) {
|
||||||
RuleChainMetaData metaData = exportData.getMetaData();
|
RuleChainMetaData metaData = exportData.getMetaData();
|
||||||
Optional.ofNullable(metaData.getNodes()).orElse(Collections.emptyList())
|
Optional.ofNullable(metaData.getNodes()).orElse(Collections.emptyList())
|
||||||
.forEach(ruleNode -> {
|
.forEach(ruleNode -> {
|
||||||
@ -85,8 +86,8 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
|
|||||||
|
|
||||||
ruleChain = ruleChainService.saveRuleChain(ruleChain);
|
ruleChain = ruleChainService.saveRuleChain(ruleChain);
|
||||||
exportData.getMetaData().setRuleChainId(ruleChain.getId());
|
exportData.getMetaData().setRuleChainId(ruleChain.getId());
|
||||||
ruleChainService.saveRuleChainMetaData(tenantId, exportData.getMetaData());
|
ruleChainService.saveRuleChainMetaData(ctx.getTenantId(), exportData.getMetaData());
|
||||||
return ruleChainService.findRuleChainById(tenantId, ruleChain.getId());
|
return ruleChainService.findRuleChainById(ctx.getTenantId(), ruleChain.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import org.thingsboard.server.dao.widget.WidgetTypeService;
|
|||||||
import org.thingsboard.server.dao.widget.WidgetsBundleService;
|
import org.thingsboard.server.dao.widget.WidgetsBundleService;
|
||||||
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.vc.data.EntitiesImportCtx;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -50,17 +51,17 @@ public class WidgetsBundleImportService extends BaseEntityImportService<WidgetsB
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WidgetsBundle prepareAndSave(TenantId tenantId, WidgetsBundle widgetsBundle, WidgetsBundleExportData exportData, IdProvider idProvider, EntityImportSettings importSettings) {
|
protected WidgetsBundle prepareAndSave(EntitiesImportCtx ctx, WidgetsBundle widgetsBundle, WidgetsBundleExportData exportData, IdProvider idProvider) {
|
||||||
WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
|
WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
|
||||||
if (widgetsBundle.getId() == null) {
|
if (widgetsBundle.getId() == null) {
|
||||||
for (WidgetTypeDetails widget : exportData.getWidgets()) {
|
for (WidgetTypeDetails widget : exportData.getWidgets()) {
|
||||||
widget.setId(null);
|
widget.setId(null);
|
||||||
widget.setTenantId(tenantId);
|
widget.setTenantId(ctx.getTenantId());
|
||||||
widget.setBundleAlias(savedWidgetsBundle.getAlias());
|
widget.setBundleAlias(savedWidgetsBundle.getAlias());
|
||||||
widgetTypeService.saveWidgetType(widget);
|
widgetTypeService.saveWidgetType(widget);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Map<String, WidgetTypeInfo> existingWidgets = widgetTypeService.findWidgetTypesInfosByTenantIdAndBundleAlias(tenantId, savedWidgetsBundle.getAlias()).stream()
|
Map<String, WidgetTypeInfo> existingWidgets = widgetTypeService.findWidgetTypesInfosByTenantIdAndBundleAlias(ctx.getTenantId(), savedWidgetsBundle.getAlias()).stream()
|
||||||
.collect(Collectors.toMap(BaseWidgetType::getAlias, w -> w));
|
.collect(Collectors.toMap(BaseWidgetType::getAlias, w -> w));
|
||||||
for (WidgetTypeDetails widget : exportData.getWidgets()) {
|
for (WidgetTypeDetails widget : exportData.getWidgets()) {
|
||||||
WidgetTypeInfo existingWidget;
|
WidgetTypeInfo existingWidget;
|
||||||
@ -70,13 +71,13 @@ public class WidgetsBundleImportService extends BaseEntityImportService<WidgetsB
|
|||||||
} else {
|
} else {
|
||||||
widget.setId(null);
|
widget.setId(null);
|
||||||
}
|
}
|
||||||
widget.setTenantId(tenantId);
|
widget.setTenantId(ctx.getTenantId());
|
||||||
widget.setBundleAlias(savedWidgetsBundle.getAlias());
|
widget.setBundleAlias(savedWidgetsBundle.getAlias());
|
||||||
widgetTypeService.saveWidgetType(widget);
|
widgetTypeService.saveWidgetType(widget);
|
||||||
}
|
}
|
||||||
existingWidgets.values().stream()
|
existingWidgets.values().stream()
|
||||||
.map(BaseWidgetType::getId)
|
.map(BaseWidgetType::getId)
|
||||||
.forEach(widgetTypeId -> widgetTypeService.deleteWidgetType(tenantId, widgetTypeId));
|
.forEach(widgetTypeId -> widgetTypeService.deleteWidgetType(ctx.getTenantId(), widgetTypeId));
|
||||||
}
|
}
|
||||||
return savedWidgetsBundle;
|
return savedWidgetsBundle;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,6 +77,7 @@ import org.thingsboard.server.service.sync.ie.exporting.ExportableEntitiesServic
|
|||||||
import org.thingsboard.server.service.sync.ie.importing.impl.MissingEntityException;
|
import org.thingsboard.server.service.sync.ie.importing.impl.MissingEntityException;
|
||||||
import org.thingsboard.server.service.sync.vc.autocommit.TbAutoCommitSettingsService;
|
import org.thingsboard.server.service.sync.vc.autocommit.TbAutoCommitSettingsService;
|
||||||
import org.thingsboard.server.service.sync.vc.data.CommitGitRequest;
|
import org.thingsboard.server.service.sync.vc.data.CommitGitRequest;
|
||||||
|
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||||
import org.thingsboard.server.service.sync.vc.repository.TbRepositorySettingsService;
|
import org.thingsboard.server.service.sync.vc.repository.TbRepositorySettingsService;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@ -244,13 +245,13 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
|||||||
|
|
||||||
private VersionLoadResult loadSingleEntity(SecurityUser user, VersionLoadConfig config, EntityExportData entityData) {
|
private VersionLoadResult loadSingleEntity(SecurityUser user, VersionLoadConfig config, EntityExportData entityData) {
|
||||||
try {
|
try {
|
||||||
EntityImportResult<?> importResult = exportImportService.importEntity(user, entityData,
|
var ctx = new EntitiesImportCtx(user, EntityImportSettings.builder()
|
||||||
EntityImportSettings.builder()
|
|
||||||
.updateRelations(config.isLoadRelations())
|
.updateRelations(config.isLoadRelations())
|
||||||
.saveAttributes(config.isLoadAttributes())
|
.saveAttributes(config.isLoadAttributes())
|
||||||
.saveCredentials(config.isLoadCredentials())
|
.saveCredentials(config.isLoadCredentials())
|
||||||
.findExistingByName(false)
|
.findExistingByName(false)
|
||||||
.build(), true, true);
|
.build());
|
||||||
|
EntityImportResult<?> importResult = exportImportService.importEntity(ctx, entityData, true, true);
|
||||||
return VersionLoadResult.success(EntityTypeLoadResult.builder()
|
return VersionLoadResult.success(EntityTypeLoadResult.builder()
|
||||||
.entityType(importResult.getEntityType())
|
.entityType(importResult.getEntityType())
|
||||||
.created(importResult.getOldEntity() == null ? 1 : 0)
|
.created(importResult.getOldEntity() == null ? 1 : 0)
|
||||||
@ -269,6 +270,8 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
|||||||
List<ThrowingRunnable> saveReferencesCallbacks = new ArrayList<>();
|
List<ThrowingRunnable> saveReferencesCallbacks = new ArrayList<>();
|
||||||
List<ThrowingRunnable> sendEventsCallbacks = new ArrayList<>();
|
List<ThrowingRunnable> sendEventsCallbacks = new ArrayList<>();
|
||||||
|
|
||||||
|
EntitiesImportCtx ctx = new EntitiesImportCtx(user);
|
||||||
|
|
||||||
List<EntityType> entityTypes = request.getEntityTypes().keySet().stream()
|
List<EntityType> entityTypes = request.getEntityTypes().keySet().stream()
|
||||||
.sorted(exportImportService.getEntityTypeComparatorForImport()).collect(Collectors.toList());
|
.sorted(exportImportService.getEntityTypeComparatorForImport()).collect(Collectors.toList());
|
||||||
for (EntityType entityType : entityTypes) {
|
for (EntityType entityType : entityTypes) {
|
||||||
@ -285,21 +288,20 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
|||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
EntityImportSettings importSettings = EntityImportSettings.builder()
|
ctx.setSettings(EntityImportSettings.builder()
|
||||||
.updateRelations(config.isLoadRelations())
|
.updateRelations(config.isLoadRelations())
|
||||||
.saveAttributes(config.isLoadAttributes())
|
.saveAttributes(config.isLoadAttributes())
|
||||||
.findExistingByName(config.isFindExistingEntityByName())
|
.findExistingByName(config.isFindExistingEntityByName())
|
||||||
.build();
|
.build());
|
||||||
for (EntityExportData entityData : entityDataList) {
|
for (EntityExportData entityData : entityDataList) {
|
||||||
EntityImportResult<?> importResult;
|
EntityImportResult<?> importResult;
|
||||||
try {
|
try {
|
||||||
importResult = exportImportService.importEntity(user, entityData,
|
importResult = exportImportService.importEntity(ctx, entityData, false, false);
|
||||||
importSettings, false, false);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new LoadEntityException(entityData, e);
|
throw new LoadEntityException(entityData, e);
|
||||||
}
|
}
|
||||||
if (importResult.getUpdatedAllExternalIds() != null && !importResult.getUpdatedAllExternalIds()) {
|
if (importResult.getUpdatedAllExternalIds() != null && !importResult.getUpdatedAllExternalIds()) {
|
||||||
toReimport.put(entityData.getEntity().getExternalId(), importSettings);
|
toReimport.put(entityData.getEntity().getExternalId(), ctx.getSettings());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,8 +326,8 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
|||||||
try {
|
try {
|
||||||
EntityExportData entityData = gitServiceQueue.getEntity(user.getTenantId(), request.getVersionId(), externalId).get();
|
EntityExportData entityData = gitServiceQueue.getEntity(user.getTenantId(), request.getVersionId(), externalId).get();
|
||||||
importSettings.setResetExternalIdsOfAnotherTenant(true);
|
importSettings.setResetExternalIdsOfAnotherTenant(true);
|
||||||
EntityImportResult<?> importResult = exportImportService.importEntity(user, entityData,
|
ctx.setSettings(importSettings);
|
||||||
importSettings, false, false);
|
EntityImportResult<?> importResult = exportImportService.importEntity(ctx, entityData, false, false);
|
||||||
|
|
||||||
EntityTypeLoadResult stats = results.get(externalId.getEntityType());
|
EntityTypeLoadResult stats = results.get(externalId.getEntityType());
|
||||||
if (importResult.getOldEntity() == null) stats.setCreated(stats.getCreated() + 1);
|
if (importResult.getOldEntity() == null) stats.setCreated(stats.getCreated() + 1);
|
||||||
@ -347,11 +349,6 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
|||||||
return exportableEntitiesService.findEntitiesByTenantId(user.getTenantId(), entityType, pageLink);
|
return exportableEntitiesService.findEntitiesByTenantId(user.getTenantId(), entityType, pageLink);
|
||||||
}, 100, entity -> {
|
}, 100, entity -> {
|
||||||
if (importedEntities.get(entityType) == null || !importedEntities.get(entityType).contains(entity.getId())) {
|
if (importedEntities.get(entityType) == null || !importedEntities.get(entityType).contains(entity.getId())) {
|
||||||
try {
|
|
||||||
exportableEntitiesService.checkPermission(user, entity, entityType, Operation.DELETE);
|
|
||||||
} catch (ThingsboardException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
exportableEntitiesService.removeById(user.getTenantId(), entity.getId());
|
exportableEntitiesService.removeById(user.getTenantId(), entity.getId());
|
||||||
|
|
||||||
sendEventsCallbacks.add(() -> {
|
sendEventsCallbacks.add(() -> {
|
||||||
|
|||||||
@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* 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.service.sync.vc.data;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
|
import org.thingsboard.server.common.data.sync.ie.EntityImportSettings;
|
||||||
|
import org.thingsboard.server.service.security.model.SecurityUser;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class EntitiesImportCtx {
|
||||||
|
|
||||||
|
private final SecurityUser user;
|
||||||
|
private EntityImportSettings settings;
|
||||||
|
|
||||||
|
private final Map<EntityId, EntityId> externalToInternalIdMap = new HashMap<>();
|
||||||
|
|
||||||
|
public EntitiesImportCtx(SecurityUser user) {
|
||||||
|
this(user, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntitiesImportCtx(SecurityUser user, EntityImportSettings settings) {
|
||||||
|
this.user = user;
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TenantId getTenantId() {
|
||||||
|
return user.getTenantId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFindExistingByName() {
|
||||||
|
return getSettings().isFindExistingByName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUpdateRelations() {
|
||||||
|
return getSettings().isUpdateRelations();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSaveAttributes() {
|
||||||
|
return getSettings().isSaveAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSaveCredentials() {
|
||||||
|
return getSettings().isSaveCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isResetExternalIdsOfAnotherTenant() {
|
||||||
|
return getSettings().isResetExternalIdsOfAnotherTenant();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityId getInternalId(EntityId externalId) {
|
||||||
|
return externalToInternalIdMap.get(externalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putInternalId(EntityId externalId, EntityId internalId) {
|
||||||
|
externalToInternalIdMap.put(externalId, internalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user