Change cf strategy for vc
This commit is contained in:
parent
94ec82ea6d
commit
2b51451896
@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
|
||||
import org.thingsboard.server.common.data.util.ThrowingRunnable;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||
import org.thingsboard.server.dao.relation.RelationService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
@ -61,6 +62,7 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS
|
||||
private final Map<EntityType, EntityImportService<?, ?, ?>> importServices = new HashMap<>();
|
||||
|
||||
private final RelationService relationService;
|
||||
private final CalculatedFieldService calculatedFieldService;
|
||||
private final RateLimitService rateLimitService;
|
||||
private final TbLogEntityActionService logEntityActionService;
|
||||
|
||||
@ -69,11 +71,9 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS
|
||||
EntityType.DASHBOARD, EntityType.ASSET_PROFILE, EntityType.ASSET,
|
||||
EntityType.DEVICE_PROFILE, EntityType.DEVICE,
|
||||
EntityType.ENTITY_VIEW, EntityType.WIDGET_TYPE, EntityType.WIDGETS_BUNDLE,
|
||||
EntityType.NOTIFICATION_TEMPLATE, EntityType.NOTIFICATION_TARGET, EntityType.NOTIFICATION_RULE,
|
||||
EntityType.CALCULATED_FIELD
|
||||
EntityType.NOTIFICATION_TEMPLATE, EntityType.NOTIFICATION_TARGET, EntityType.NOTIFICATION_RULE
|
||||
);
|
||||
|
||||
|
||||
@Override
|
||||
public <E extends ExportableEntity<I>, I extends EntityId> EntityExportData<E> exportEntity(EntitiesExportCtx<?> ctx, I entityId) throws ThingsboardException {
|
||||
if (!rateLimitService.checkRateLimit(LimitedApi.ENTITY_EXPORT, ctx.getTenantId())) {
|
||||
@ -128,15 +128,18 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS
|
||||
logEntityActionService.logEntityRelationAction(ctx.getTenantId(), null,
|
||||
relation, ctx.getUser(), ActionType.RELATION_ADD_OR_UPDATE, null, relation);
|
||||
}
|
||||
}
|
||||
|
||||
ctx.getCalculatedFields().forEach((calculatedField, created) -> {
|
||||
var savedCalculatedField = calculatedFieldService.save(calculatedField);
|
||||
logEntityActionService.logEntityAction(ctx.getTenantId(), savedCalculatedField.getId(), savedCalculatedField, created ? ActionType.ADDED : ActionType.UPDATED, ctx.getUser());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<EntityType> getEntityTypeComparatorForImport() {
|
||||
return Comparator.comparing(SUPPORTED_ENTITY_TYPES::indexOf);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <I extends EntityId, E extends ExportableEntity<I>, D extends EntityExportData<E>> EntityExportService<I, E, D> getExportService(EntityType entityType) {
|
||||
EntityExportService<?, ?, ?> exportService = exportServices.get(entityType);
|
||||
|
||||
@ -32,7 +32,6 @@ public interface EntitiesExportImportService {
|
||||
|
||||
<E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(EntitiesImportCtx ctx, EntityExportData<E> exportData) throws ThingsboardException;
|
||||
|
||||
|
||||
void saveReferencesAndRelations(EntitiesImportCtx ctx) throws ThingsboardException;
|
||||
|
||||
Comparator<EntityType> getEntityTypeComparatorForImport();
|
||||
|
||||
@ -19,7 +19,8 @@ import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.common.data.id.AssetId;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.AssetExportData;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
|
||||
|
||||
@ -27,12 +28,22 @@ import java.util.Set;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
public class AssetExportService extends BaseEntityExportService<AssetId, Asset, EntityExportData<Asset>> {
|
||||
public class AssetExportService extends BaseCalculatedFieldsExportService<AssetId, Asset, AssetExportData> {
|
||||
|
||||
protected AssetExportService(CalculatedFieldService calculatedFieldService) {
|
||||
super(calculatedFieldService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setRelatedEntities(EntitiesExportCtx<?> ctx, Asset asset, EntityExportData<Asset> exportData) {
|
||||
protected void setRelatedEntities(EntitiesExportCtx<?> ctx, Asset asset, AssetExportData exportData) {
|
||||
asset.setCustomerId(getExternalIdOrElseInternal(ctx, asset.getCustomerId()));
|
||||
asset.setAssetProfileId(getExternalIdOrElseInternal(ctx, asset.getAssetProfileId()));
|
||||
setCalculatedFields(ctx, asset, exportData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AssetExportData newExportData() {
|
||||
return new AssetExportData();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -19,7 +19,8 @@ import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.asset.AssetProfile;
|
||||
import org.thingsboard.server.common.data.id.AssetProfileId;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.AssetProfileExportData;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
|
||||
|
||||
@ -27,13 +28,23 @@ import java.util.Set;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
public class AssetProfileExportService extends BaseEntityExportService<AssetProfileId, AssetProfile, EntityExportData<AssetProfile>> {
|
||||
public class AssetProfileExportService extends BaseCalculatedFieldsExportService<AssetProfileId, AssetProfile, AssetProfileExportData> {
|
||||
|
||||
protected AssetProfileExportService(CalculatedFieldService calculatedFieldService) {
|
||||
super(calculatedFieldService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setRelatedEntities(EntitiesExportCtx<?> ctx, AssetProfile assetProfile, EntityExportData<AssetProfile> exportData) {
|
||||
protected void setRelatedEntities(EntitiesExportCtx<?> ctx, AssetProfile assetProfile, AssetProfileExportData exportData) {
|
||||
assetProfile.setDefaultDashboardId(getExternalIdOrElseInternal(ctx, assetProfile.getDefaultDashboardId()));
|
||||
assetProfile.setDefaultRuleChainId(getExternalIdOrElseInternal(ctx, assetProfile.getDefaultRuleChainId()));
|
||||
assetProfile.setDefaultEdgeRuleChainId(getExternalIdOrElseInternal(ctx, assetProfile.getDefaultEdgeRuleChainId()));
|
||||
setCalculatedFields(ctx, assetProfile, exportData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AssetProfileExportData newExportData() {
|
||||
return new AssetProfileExportData();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.ie.exporting.impl;
|
||||
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
import org.thingsboard.server.common.data.HasTenantId;
|
||||
import org.thingsboard.server.common.data.cf.CalculatedField;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.sync.ie.CalculatedFieldExportData;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseCalculatedFieldsExportService<ID extends EntityId, E extends ExportableEntity<ID> & HasTenantId, D extends CalculatedFieldExportData<E>> extends BaseEntityExportService<ID, E, D> {
|
||||
|
||||
protected final CalculatedFieldService calculatedFieldService;
|
||||
|
||||
protected BaseCalculatedFieldsExportService(CalculatedFieldService calculatedFieldService) {
|
||||
this.calculatedFieldService = calculatedFieldService;
|
||||
}
|
||||
|
||||
protected void setCalculatedFields(EntitiesExportCtx<?> ctx, E entity, D exportData) {
|
||||
if (ctx.getSettings().isExportCalculatedFields()) {
|
||||
List<CalculatedField> calculatedFields = calculatedFieldService.findCalculatedFieldsByEntityId(ctx.getTenantId(), entity.getId());
|
||||
calculatedFields.forEach(calculatedField -> {
|
||||
calculatedField.getConfiguration().getArguments().values().forEach(argument -> {
|
||||
if (argument.getRefEntityId() != null) {
|
||||
EntityId externalId = getExternalIdOrElseInternal(ctx, argument.getRefEntityId());
|
||||
argument.setRefEntityId(externalId);
|
||||
}
|
||||
});
|
||||
});
|
||||
exportData.setCalculatedFields(calculatedFields);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.ie.exporting.impl;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.cf.CalculatedField;
|
||||
import org.thingsboard.server.common.data.id.CalculatedFieldId;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
public class CalculatedFieldExportService extends BaseEntityExportService<CalculatedFieldId, CalculatedField, EntityExportData<CalculatedField>> {
|
||||
|
||||
@Override
|
||||
protected void setRelatedEntities(EntitiesExportCtx<?> ctx, CalculatedField calculatedField, EntityExportData<CalculatedField> exportData) {
|
||||
calculatedField.setEntityId(getExternalIdOrElseInternal(ctx, calculatedField.getEntityId()));
|
||||
calculatedField.getConfiguration().getArguments().values().forEach(argument -> {
|
||||
if (argument.getRefEntityId() != null) {
|
||||
EntityId internalEntityId = getExternalIdOrElseInternal(ctx, argument.getRefEntityId());
|
||||
argument.setRefEntityId(internalEntityId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<EntityType> getSupportedEntityTypes() {
|
||||
return Set.of(EntityType.CALCULATED_FIELD);
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,12 +15,12 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.ie.exporting.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.common.data.sync.ie.DeviceExportData;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.dao.device.DeviceCredentialsService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
|
||||
@ -29,11 +29,15 @@ import java.util.Set;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceExportService extends BaseEntityExportService<DeviceId, Device, DeviceExportData> {
|
||||
public class DeviceExportService extends BaseCalculatedFieldsExportService<DeviceId, Device, DeviceExportData> {
|
||||
|
||||
private final DeviceCredentialsService deviceCredentialsService;
|
||||
|
||||
public DeviceExportService(CalculatedFieldService calculatedFieldService, DeviceCredentialsService deviceCredentialsService) {
|
||||
super(calculatedFieldService);
|
||||
this.deviceCredentialsService = deviceCredentialsService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setRelatedEntities(EntitiesExportCtx<?> ctx, Device device, DeviceExportData exportData) {
|
||||
device.setCustomerId(getExternalIdOrElseInternal(ctx, device.getCustomerId()));
|
||||
@ -44,6 +48,7 @@ public class DeviceExportService extends BaseEntityExportService<DeviceId, Devic
|
||||
credentials.setDeviceId(null);
|
||||
exportData.setCredentials(credentials);
|
||||
}
|
||||
setCalculatedFields(ctx, device, exportData);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -19,7 +19,8 @@ import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.DeviceProfileExportData;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
|
||||
|
||||
@ -27,13 +28,23 @@ import java.util.Set;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
public class DeviceProfileExportService extends BaseEntityExportService<DeviceProfileId, DeviceProfile, EntityExportData<DeviceProfile>> {
|
||||
public class DeviceProfileExportService extends BaseCalculatedFieldsExportService<DeviceProfileId, DeviceProfile, DeviceProfileExportData> {
|
||||
|
||||
protected DeviceProfileExportService(CalculatedFieldService calculatedFieldService) {
|
||||
super(calculatedFieldService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setRelatedEntities(EntitiesExportCtx<?> ctx, DeviceProfile deviceProfile, EntityExportData<DeviceProfile> exportData) {
|
||||
protected void setRelatedEntities(EntitiesExportCtx<?> ctx, DeviceProfile deviceProfile, DeviceProfileExportData exportData) {
|
||||
deviceProfile.setDefaultDashboardId(getExternalIdOrElseInternal(ctx, deviceProfile.getDefaultDashboardId()));
|
||||
deviceProfile.setDefaultRuleChainId(getExternalIdOrElseInternal(ctx, deviceProfile.getDefaultRuleChainId()));
|
||||
deviceProfile.setDefaultEdgeRuleChainId(getExternalIdOrElseInternal(ctx, deviceProfile.getDefaultEdgeRuleChainId()));
|
||||
setCalculatedFields(ctx, deviceProfile, exportData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DeviceProfileExportData newExportData() {
|
||||
return new DeviceProfileExportData();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -15,24 +15,28 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.ie.importing.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.common.data.id.AssetId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.AssetExportData;
|
||||
import org.thingsboard.server.dao.asset.AssetService;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
@RequiredArgsConstructor
|
||||
public class AssetImportService extends BaseEntityImportService<AssetId, Asset, EntityExportData<Asset>> {
|
||||
public class AssetImportService extends BaseCalculatedFieldsImportService<AssetId, Asset, AssetExportData> {
|
||||
|
||||
private final AssetService assetService;
|
||||
|
||||
public AssetImportService(CalculatedFieldService calculatedFieldService, AssetService assetService) {
|
||||
super(calculatedFieldService);
|
||||
this.assetService = assetService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setOwner(TenantId tenantId, Asset asset, IdProvider idProvider) {
|
||||
asset.setTenantId(tenantId);
|
||||
@ -40,14 +44,14 @@ public class AssetImportService extends BaseEntityImportService<AssetId, Asset,
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Asset prepare(EntitiesImportCtx ctx, Asset asset, Asset old, EntityExportData<Asset> exportData, IdProvider idProvider) {
|
||||
protected Asset prepare(EntitiesImportCtx ctx, Asset asset, Asset old, AssetExportData exportData, IdProvider idProvider) {
|
||||
asset.setAssetProfileId(idProvider.getInternalId(asset.getAssetProfileId()));
|
||||
return asset;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Asset saveOrUpdate(EntitiesImportCtx ctx, Asset asset, EntityExportData<Asset> exportData, IdProvider idProvider) {
|
||||
return assetService.saveAsset(asset);
|
||||
protected Asset saveOrUpdate(EntitiesImportCtx ctx, Asset asset, AssetExportData exportData, IdProvider idProvider) {
|
||||
return saveOrUpdateEntity(ctx, asset, exportData, idProvider, assetService::saveAsset);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.ie.importing.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
@ -23,25 +22,30 @@ import org.thingsboard.server.common.data.asset.AssetProfile;
|
||||
import org.thingsboard.server.common.data.audit.ActionType;
|
||||
import org.thingsboard.server.common.data.id.AssetProfileId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.AssetProfileExportData;
|
||||
import org.thingsboard.server.dao.asset.AssetProfileService;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
@RequiredArgsConstructor
|
||||
public class AssetProfileImportService extends BaseEntityImportService<AssetProfileId, AssetProfile, EntityExportData<AssetProfile>> {
|
||||
public class AssetProfileImportService extends BaseCalculatedFieldsImportService<AssetProfileId, AssetProfile, AssetProfileExportData> {
|
||||
|
||||
private final AssetProfileService assetProfileService;
|
||||
|
||||
public AssetProfileImportService(CalculatedFieldService calculatedFieldService, AssetProfileService assetProfileService) {
|
||||
super(calculatedFieldService);
|
||||
this.assetProfileService = assetProfileService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setOwner(TenantId tenantId, AssetProfile assetProfile, IdProvider idProvider) {
|
||||
assetProfile.setTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AssetProfile prepare(EntitiesImportCtx ctx, AssetProfile assetProfile, AssetProfile old, EntityExportData<AssetProfile> exportData, IdProvider idProvider) {
|
||||
protected AssetProfile prepare(EntitiesImportCtx ctx, AssetProfile assetProfile, AssetProfile old, AssetProfileExportData exportData, IdProvider idProvider) {
|
||||
assetProfile.setDefaultRuleChainId(idProvider.getInternalId(assetProfile.getDefaultRuleChainId()));
|
||||
assetProfile.setDefaultDashboardId(idProvider.getInternalId(assetProfile.getDefaultDashboardId()));
|
||||
assetProfile.setDefaultEdgeRuleChainId(idProvider.getInternalId(assetProfile.getDefaultEdgeRuleChainId()));
|
||||
@ -49,8 +53,8 @@ public class AssetProfileImportService extends BaseEntityImportService<AssetProf
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AssetProfile saveOrUpdate(EntitiesImportCtx ctx, AssetProfile assetProfile, EntityExportData<AssetProfile> exportData, IdProvider idProvider) {
|
||||
return assetProfileService.saveAssetProfile(assetProfile);
|
||||
protected AssetProfile saveOrUpdate(EntitiesImportCtx ctx, AssetProfile assetProfile, AssetProfileExportData exportData, IdProvider idProvider) {
|
||||
return saveOrUpdateEntity(ctx, assetProfile, exportData, idProvider, assetProfileService::saveAssetProfile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.ie.importing.impl;
|
||||
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
import org.thingsboard.server.common.data.HasTenantId;
|
||||
import org.thingsboard.server.common.data.cf.CalculatedField;
|
||||
import org.thingsboard.server.common.data.id.CalculatedFieldId;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.sync.ie.CalculatedFieldExportData;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class BaseCalculatedFieldsImportService<ID extends EntityId, E extends ExportableEntity<ID> & HasTenantId, D extends CalculatedFieldExportData<E>> extends BaseEntityImportService<ID, E, D> {
|
||||
|
||||
private final CalculatedFieldService calculatedFieldService;
|
||||
|
||||
protected BaseCalculatedFieldsImportService(CalculatedFieldService calculatedFieldService) {
|
||||
this.calculatedFieldService = calculatedFieldService;
|
||||
}
|
||||
|
||||
protected E saveOrUpdateEntity(EntitiesImportCtx ctx, E entity, D exportData, IdProvider idProvider, Function<E, E> saveFunction) {
|
||||
E savedEntity = saveFunction.apply(entity);
|
||||
|
||||
if (ctx.isFinalImportAttempt() || ctx.getCurrentImportResult().isUpdatedAllExternalIds()) {
|
||||
saveCalculatedFields(ctx, savedEntity, exportData, idProvider);
|
||||
}
|
||||
return savedEntity;
|
||||
}
|
||||
|
||||
protected void saveCalculatedFields(EntitiesImportCtx ctx, E savedEntity, D exportData, IdProvider idProvider) {
|
||||
if (exportData.getCalculatedFields() == null || !ctx.isSaveCalculatedFields()) {
|
||||
return;
|
||||
}
|
||||
|
||||
exportData.getCalculatedFields().forEach(calculatedField -> {
|
||||
calculatedField.setTenantId(savedEntity.getTenantId());
|
||||
calculatedField.setExternalId(calculatedField.getId());
|
||||
calculatedField.setId(idProvider.getInternalId(calculatedField.getId(), false));
|
||||
calculatedField.setEntityId(savedEntity.getId());
|
||||
|
||||
calculatedField.getConfiguration().getArguments().values().forEach(argument -> {
|
||||
if (argument.getRefEntityId() != null) {
|
||||
argument.setRefEntityId(idProvider.getInternalId(argument.getRefEntityId(), false));
|
||||
}
|
||||
});
|
||||
|
||||
calculatedFieldService.save(calculatedField);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateRelatedEntitiesIfUnmodified(EntitiesImportCtx ctx, E prepared, D exportData, IdProvider idProvider) {
|
||||
boolean updated = super.updateRelatedEntitiesIfUnmodified(ctx, prepared, exportData, idProvider);
|
||||
updated |= updateCalculatedFields(ctx, prepared, exportData, idProvider);
|
||||
return updated;
|
||||
}
|
||||
|
||||
private boolean updateCalculatedFields(EntitiesImportCtx ctx, E prepared, D exportData, IdProvider idProvider) {
|
||||
var calculatedFields = exportData.getCalculatedFields();
|
||||
if (calculatedFields == null || !ctx.isSaveCalculatedFields()) {
|
||||
return false;
|
||||
}
|
||||
Map<CalculatedFieldId, CalculatedField> calculatedFieldMap = calculatedFields.stream()
|
||||
.peek(newField -> {
|
||||
newField.setTenantId(ctx.getTenantId());
|
||||
newField.setExternalId(newField.getId());
|
||||
newField.setId(idProvider.getInternalId(newField.getId(), false));
|
||||
newField.setEntityId(prepared.getId());
|
||||
newField.getConfiguration().getArguments().values().forEach(argument -> {
|
||||
argument.setRefEntityId(idProvider.getInternalId(argument.getRefEntityId(), false));
|
||||
});
|
||||
})
|
||||
.collect(Collectors.toMap(CalculatedField::getId, field -> field));
|
||||
|
||||
List<CalculatedField> existingFields = calculatedFieldService.findCalculatedFieldsByEntityId(ctx.getTenantId(), prepared.getId());
|
||||
boolean updated = false;
|
||||
|
||||
Map<CalculatedField, Boolean> result = new LinkedHashMap<>();
|
||||
for (CalculatedField existingField : existingFields) {
|
||||
if (calculatedFieldMap.containsKey(existingField.getId())) {
|
||||
CalculatedField newField = calculatedFieldMap.get(existingField.getId());
|
||||
if (!newField.equals(existingField)) {
|
||||
result.put(newField, false);
|
||||
}
|
||||
calculatedFieldMap.remove(existingField.getId());
|
||||
} else {
|
||||
updated = true;
|
||||
calculatedFieldService.deleteCalculatedField(ctx.getTenantId(), existingField.getId());
|
||||
}
|
||||
}
|
||||
|
||||
for (CalculatedField newField : calculatedFieldMap.values()) {
|
||||
result.put(newField, true);
|
||||
}
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
updated = true;
|
||||
ctx.addCalculatedFields(result);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,85 +0,0 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.ie.importing.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.audit.ActionType;
|
||||
import org.thingsboard.server.common.data.cf.CalculatedField;
|
||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||
import org.thingsboard.server.common.data.id.CalculatedFieldId;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.dao.service.ConstraintValidator;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
@RequiredArgsConstructor
|
||||
public class CalculatedFieldImportService extends BaseEntityImportService<CalculatedFieldId, CalculatedField, EntityExportData<CalculatedField>> {
|
||||
|
||||
private final CalculatedFieldService calculatedFieldService;
|
||||
|
||||
@Override
|
||||
protected void setOwner(TenantId tenantId, CalculatedField calculatedField, IdProvider idProvider) {
|
||||
calculatedField.setTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CalculatedField prepare(EntitiesImportCtx ctx, CalculatedField calculatedField, CalculatedField oldEntity, EntityExportData<CalculatedField> exportData, IdProvider idProvider) {
|
||||
calculatedField.setEntityId(idProvider.getInternalId(calculatedField.getEntityId()));
|
||||
calculatedField.getConfiguration().getArguments().values().forEach(argument -> {
|
||||
if (argument.getRefEntityId() != null) {
|
||||
EntityId internalEntityId = idProvider.getInternalId(argument.getRefEntityId());
|
||||
argument.setRefEntityId(internalEntityId);
|
||||
}
|
||||
});
|
||||
return calculatedField;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CalculatedField saveOrUpdate(EntitiesImportCtx ctx, CalculatedField calculatedField, EntityExportData<CalculatedField> exportData, IdProvider idProvider) {
|
||||
ConstraintValidator.validateFields(calculatedField);
|
||||
return calculatedFieldService.save(calculatedField);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CalculatedField deepCopy(CalculatedField calculatedField) {
|
||||
return new CalculatedField(calculatedField);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEntitySaved(User user, CalculatedField savedEntity, CalculatedField oldEntity) throws ThingsboardException {
|
||||
entityActionService.logEntityAction(user, savedEntity.getId(), savedEntity, null,
|
||||
oldEntity == null ? ActionType.ADDED : ActionType.UPDATED, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanupForComparison(CalculatedField e) {
|
||||
super.cleanupForComparison(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntityType() {
|
||||
return EntityType.CALCULATED_FIELD;
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,13 +15,13 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.ie.importing.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.sync.ie.DeviceExportData;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.dao.device.DeviceCredentialsService;
|
||||
import org.thingsboard.server.dao.device.DeviceService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
@ -29,12 +29,17 @@ import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceImportService extends BaseEntityImportService<DeviceId, Device, DeviceExportData> {
|
||||
public class DeviceImportService extends BaseCalculatedFieldsImportService<DeviceId, Device, DeviceExportData> {
|
||||
|
||||
private final DeviceService deviceService;
|
||||
private final DeviceCredentialsService credentialsService;
|
||||
|
||||
public DeviceImportService(CalculatedFieldService calculatedFieldService, DeviceService deviceService, DeviceCredentialsService credentialsService) {
|
||||
super(calculatedFieldService);
|
||||
this.deviceService = deviceService;
|
||||
this.credentialsService = credentialsService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setOwner(TenantId tenantId, Device device, IdProvider idProvider) {
|
||||
device.setTenantId(tenantId);
|
||||
@ -64,31 +69,44 @@ public class DeviceImportService extends BaseEntityImportService<DeviceId, Devic
|
||||
|
||||
@Override
|
||||
protected Device saveOrUpdate(EntitiesImportCtx ctx, Device device, DeviceExportData exportData, IdProvider idProvider) {
|
||||
Device savedDevice;
|
||||
if (exportData.getCredentials() != null && ctx.isSaveCredentials()) {
|
||||
exportData.getCredentials().setId(null);
|
||||
exportData.getCredentials().setDeviceId(null);
|
||||
return deviceService.saveDeviceWithCredentials(device, exportData.getCredentials());
|
||||
savedDevice = deviceService.saveDeviceWithCredentials(device, exportData.getCredentials());
|
||||
} else {
|
||||
return deviceService.saveDevice(device);
|
||||
savedDevice = deviceService.saveDevice(device);
|
||||
}
|
||||
if (ctx.isFinalImportAttempt() || ctx.getCurrentImportResult().isUpdatedAllExternalIds()) {
|
||||
saveCalculatedFields(ctx, savedDevice, exportData, idProvider);
|
||||
}
|
||||
return savedDevice;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateRelatedEntitiesIfUnmodified(EntitiesImportCtx ctx, Device prepared, DeviceExportData exportData, IdProvider idProvider) {
|
||||
boolean updated = super.updateRelatedEntitiesIfUnmodified(ctx, prepared, exportData, idProvider);
|
||||
var credentials = exportData.getCredentials();
|
||||
if (credentials != null && ctx.isSaveCredentials()) {
|
||||
var existing = credentialsService.findDeviceCredentialsByDeviceId(ctx.getTenantId(), prepared.getId());
|
||||
credentials.setId(existing.getId());
|
||||
credentials.setDeviceId(prepared.getId());
|
||||
if (!existing.equals(credentials)) {
|
||||
credentialsService.updateDeviceCredentials(ctx.getTenantId(), credentials);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
updated |= updateCredentials(ctx, prepared, exportData);
|
||||
return updated;
|
||||
}
|
||||
|
||||
private boolean updateCredentials(EntitiesImportCtx ctx, Device prepared, DeviceExportData exportData) {
|
||||
var credentials = exportData.getCredentials();
|
||||
if (credentials == null || !ctx.isSaveCredentials()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var existing = credentialsService.findDeviceCredentialsByDeviceId(ctx.getTenantId(), prepared.getId());
|
||||
credentials.setId(existing.getId());
|
||||
credentials.setDeviceId(prepared.getId());
|
||||
|
||||
if (!existing.equals(credentials)) {
|
||||
credentialsService.updateDeviceCredentials(ctx.getTenantId(), credentials);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntityType() {
|
||||
return EntityType.DEVICE;
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.ie.importing.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
@ -23,25 +22,30 @@ import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.audit.ActionType;
|
||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.DeviceProfileExportData;
|
||||
import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
||||
import org.thingsboard.server.dao.device.DeviceProfileService;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||
|
||||
@Service
|
||||
@TbCoreComponent
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceProfileImportService extends BaseEntityImportService<DeviceProfileId, DeviceProfile, EntityExportData<DeviceProfile>> {
|
||||
public class DeviceProfileImportService extends BaseCalculatedFieldsImportService<DeviceProfileId, DeviceProfile, DeviceProfileExportData> {
|
||||
|
||||
private final DeviceProfileService deviceProfileService;
|
||||
|
||||
public DeviceProfileImportService(CalculatedFieldService calculatedFieldService, DeviceProfileService deviceProfileService) {
|
||||
super(calculatedFieldService);
|
||||
this.deviceProfileService = deviceProfileService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setOwner(TenantId tenantId, DeviceProfile deviceProfile, IdProvider idProvider) {
|
||||
deviceProfile.setTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DeviceProfile prepare(EntitiesImportCtx ctx, DeviceProfile deviceProfile, DeviceProfile old, EntityExportData<DeviceProfile> exportData, IdProvider idProvider) {
|
||||
protected DeviceProfile prepare(EntitiesImportCtx ctx, DeviceProfile deviceProfile, DeviceProfile old, DeviceProfileExportData exportData, IdProvider idProvider) {
|
||||
deviceProfile.setDefaultRuleChainId(idProvider.getInternalId(deviceProfile.getDefaultRuleChainId()));
|
||||
deviceProfile.setDefaultEdgeRuleChainId(idProvider.getInternalId(deviceProfile.getDefaultEdgeRuleChainId()));
|
||||
deviceProfile.setDefaultDashboardId(idProvider.getInternalId(deviceProfile.getDefaultDashboardId()));
|
||||
@ -51,8 +55,8 @@ public class DeviceProfileImportService extends BaseEntityImportService<DevicePr
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DeviceProfile saveOrUpdate(EntitiesImportCtx ctx, DeviceProfile deviceProfile, EntityExportData<DeviceProfile> exportData, IdProvider idProvider) {
|
||||
return deviceProfileService.saveDeviceProfile(deviceProfile);
|
||||
protected DeviceProfile saveOrUpdate(EntitiesImportCtx ctx, DeviceProfile deviceProfile, DeviceProfileExportData exportData, IdProvider idProvider) {
|
||||
return saveOrUpdateEntity(ctx, deviceProfile, exportData, idProvider, deviceProfileService::saveDeviceProfile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -94,7 +94,6 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.google.common.util.concurrent.Futures.transform;
|
||||
import static org.thingsboard.server.common.data.sync.vc.VcUtils.checkBranchName;
|
||||
@ -304,6 +303,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
.updateRelations(config.isLoadRelations())
|
||||
.saveAttributes(config.isLoadAttributes())
|
||||
.saveCredentials(config.isLoadCredentials())
|
||||
.saveCalculatedFields(config.isLoadCalculatedFields())
|
||||
.findExistingByName(false)
|
||||
.build());
|
||||
ctx.setFinalImportAttempt(true);
|
||||
@ -327,7 +327,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
var sw = TbStopWatch.create("before");
|
||||
|
||||
List<EntityType> entityTypes = request.getEntityTypes().keySet().stream()
|
||||
.sorted(exportImportService.getEntityTypeComparatorForImport()).collect(Collectors.toList());
|
||||
.sorted(exportImportService.getEntityTypeComparatorForImport()).toList();
|
||||
for (EntityType entityType : entityTypes) {
|
||||
log.debug("[{}] Loading {} entities", ctx.getTenantId(), entityType);
|
||||
sw.startNew("Entities " + entityType.name());
|
||||
@ -362,6 +362,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
.updateRelations(config.isLoadRelations())
|
||||
.saveAttributes(config.isLoadAttributes())
|
||||
.saveCredentials(config.isLoadCredentials())
|
||||
.saveCalculatedFields(config.isLoadCalculatedFields())
|
||||
.findExistingByName(config.isFindExistingEntityByName())
|
||||
.build();
|
||||
}
|
||||
@ -471,7 +472,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<EntityDataDiff> compareEntityDataToVersion(User user, EntityId entityId, String versionId) throws Exception {
|
||||
public ListenableFuture<EntityDataDiff> compareEntityDataToVersion(User user, EntityId entityId, String versionId) {
|
||||
HasId<EntityId> entity = exportableEntitiesService.findEntityByTenantIdAndId(user.getTenantId(), entityId);
|
||||
if (!(entity instanceof ExportableEntity)) throw new IllegalArgumentException("Unsupported entity type");
|
||||
|
||||
@ -484,6 +485,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
.exportRelations(otherVersion.hasRelations())
|
||||
.exportAttributes(otherVersion.hasAttributes())
|
||||
.exportCredentials(otherVersion.hasCredentials())
|
||||
.exportCalculatedFields(otherVersion.hasCalculatedFields())
|
||||
.build());
|
||||
EntityExportData<?> currentVersion;
|
||||
try {
|
||||
@ -503,7 +505,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
|
||||
|
||||
@Override
|
||||
public ListenableFuture<List<BranchInfo>> listBranches(TenantId tenantId) throws Exception {
|
||||
public ListenableFuture<List<BranchInfo>> listBranches(TenantId tenantId) {
|
||||
return gitServiceQueue.listBranches(tenantId);
|
||||
}
|
||||
|
||||
|
||||
@ -69,6 +69,7 @@ public abstract class EntitiesExportCtx<R extends VersionCreateRequest> {
|
||||
.exportRelations(config.isSaveRelations())
|
||||
.exportAttributes(config.isSaveAttributes())
|
||||
.exportCredentials(config.isSaveCredentials())
|
||||
.exportCalculatedFields(config.isSaveCalculatedFields())
|
||||
.build();
|
||||
}
|
||||
|
||||
@ -85,4 +86,5 @@ public abstract class EntitiesExportCtx<R extends VersionCreateRequest> {
|
||||
log.debug("[{}][{}] Local cache put: {}", internalId.getEntityType(), internalId.getId(), externalId);
|
||||
externalIdMap.put(internalId, externalId != null ? externalId : internalId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.cf.CalculatedField;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||
@ -31,6 +32,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -54,6 +56,7 @@ public class EntitiesImportCtx {
|
||||
private final Set<EntityId> notFoundIds = new HashSet<>();
|
||||
|
||||
private final Set<EntityRelation> relations = new LinkedHashSet<>();
|
||||
private final Map<CalculatedField, Boolean> calculatedFields = new LinkedHashMap<>();
|
||||
|
||||
private boolean finalImportAttempt = false;
|
||||
private EntityImportSettings settings;
|
||||
@ -91,6 +94,10 @@ public class EntitiesImportCtx {
|
||||
return getSettings().isSaveCredentials();
|
||||
}
|
||||
|
||||
public boolean isSaveCalculatedFields() {
|
||||
return getSettings().isSaveCalculatedFields();
|
||||
}
|
||||
|
||||
public EntityId getInternalId(EntityId externalId) {
|
||||
var result = externalToInternalIdMap.get(externalId);
|
||||
log.debug("[{}][{}] Local cache {} for id", externalId.getEntityType(), externalId.getId(), result != null ? "hit" : "miss");
|
||||
@ -120,6 +127,10 @@ public class EntitiesImportCtx {
|
||||
relations.addAll(values);
|
||||
}
|
||||
|
||||
public void addCalculatedFields(Map<CalculatedField, Boolean> calculatedFieldMap) {
|
||||
calculatedFields.putAll(calculatedFieldMap);
|
||||
}
|
||||
|
||||
public void addReferenceCallback(EntityId externalId, ThrowingRunnable tr) {
|
||||
if (tr != null) {
|
||||
referenceCallbacks.put(externalId, tr);
|
||||
@ -140,5 +151,4 @@ public class EntitiesImportCtx {
|
||||
return notFoundIds.contains(externalId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ public class EntityTypeExportCtx extends EntitiesExportCtx<VersionCreateRequest>
|
||||
.exportRelations(config.isSaveRelations())
|
||||
.exportAttributes(config.isSaveAttributes())
|
||||
.exportCredentials(config.isSaveCredentials())
|
||||
.exportCalculatedFields(config.isSaveCalculatedFields())
|
||||
.build();
|
||||
this.overwrite = ObjectUtils.defaultIfNull(config.getSyncStrategy(), defaultSyncStrategy) == SyncStrategy.OVERWRITE;
|
||||
}
|
||||
|
||||
@ -80,6 +80,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainType;
|
||||
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||
import org.thingsboard.server.common.data.security.Authority;
|
||||
import org.thingsboard.server.common.data.sync.ie.DeviceExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportSettings;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
|
||||
@ -207,11 +208,12 @@ public class ExportImportServiceSqlTest extends AbstractControllerTest {
|
||||
CalculatedField calculatedField = createCalculatedField(tenantId1, device.getId(), asset.getId());
|
||||
|
||||
Map<EntityType, EntityExportData> entitiesExportData = Stream.of(customer.getId(), asset.getId(), device.getId(),
|
||||
ruleChain.getId(), dashboard.getId(), assetProfile.getId(), deviceProfile.getId(), calculatedField.getId())
|
||||
ruleChain.getId(), dashboard.getId(), assetProfile.getId(), deviceProfile.getId())
|
||||
.map(entityId -> {
|
||||
try {
|
||||
return exportEntity(tenantAdmin1, entityId, EntityExportSettings.builder()
|
||||
.exportCredentials(false)
|
||||
.exportCalculatedFields(true)
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@ -281,23 +283,28 @@ public class ExportImportServiceSqlTest extends AbstractControllerTest {
|
||||
importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.DEVICE));
|
||||
verify(tbClusterService, Mockito.never()).onDeviceUpdated(eq(importedDevice), eq(importedDevice));
|
||||
|
||||
// calculated field of imported device:
|
||||
List<CalculatedField> calculatedFields = calculatedFieldService.findCalculatedFieldsByEntityId(tenantId2, importedDevice.getId());
|
||||
assertThat(calculatedFields.size()).isOne();
|
||||
var importedCalculatedField = calculatedFields.get(0);
|
||||
assertThat(importedCalculatedField.getName()).isEqualTo(calculatedField.getName());
|
||||
assertThat(importedCalculatedField.getExternalId()).isEqualTo(calculatedField.getId());
|
||||
|
||||
EntityExportData<Device> updatedDeviceEntity = getAndClone(entitiesExportData, EntityType.DEVICE);
|
||||
updatedDeviceEntity.getEntity().setLabel("t" + updatedDeviceEntity.getEntity().getLabel());
|
||||
Device updatedDevice = importEntity(tenantAdmin2, updatedDeviceEntity).getSavedEntity();
|
||||
verify(tbClusterService).onDeviceUpdated(eq(updatedDevice), eq(importedDevice));
|
||||
|
||||
CalculatedField importedCalculatedField = (CalculatedField) importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.CALCULATED_FIELD)).getSavedEntity();
|
||||
verify(entityActionService).logEntityAction(any(), eq(importedCalculatedField.getId()), eq(importedCalculatedField),
|
||||
any(), eq(ActionType.ADDED), isNull());
|
||||
importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.CALCULATED_FIELD));
|
||||
verify(entityActionService, Mockito.never()).logEntityAction(any(), eq(importedCalculatedField.getId()), eq(importedCalculatedField),
|
||||
any(), eq(ActionType.UPDATED), isNull());
|
||||
// update calculated field:
|
||||
DeviceExportData deviceExportData = (DeviceExportData) getAndClone(entitiesExportData, EntityType.DEVICE);
|
||||
deviceExportData.setCalculatedFields(deviceExportData.getCalculatedFields().stream().peek(field -> field.setName("t_" + field.getName())).toList());
|
||||
importEntity(tenantAdmin2, deviceExportData).getSavedEntity();
|
||||
|
||||
EntityExportData<CalculatedField> updatedCalculatedFieldEntity = getAndClone(entitiesExportData, EntityType.CALCULATED_FIELD);
|
||||
updatedCalculatedFieldEntity.getEntity().setName("t" + updatedCalculatedFieldEntity.getEntity().getName());
|
||||
CalculatedField updatedCalculatedField = importEntity(tenantAdmin2, updatedCalculatedFieldEntity).getSavedEntity();
|
||||
verify(entityActionService).logEntityAction(any(), eq(updatedCalculatedField.getId()), eq(updatedCalculatedField),
|
||||
any(), eq(ActionType.UPDATED), isNull());
|
||||
calculatedFields = calculatedFieldService.findCalculatedFieldsByEntityId(tenantId2, importedDevice.getId());
|
||||
assertThat(calculatedFields.size()).isOne();
|
||||
importedCalculatedField = calculatedFields.get(0);
|
||||
assertThat(importedCalculatedField.getExternalId()).isEqualTo(calculatedField.getId());
|
||||
assertThat(importedCalculatedField.getName()).startsWith("t_");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -320,10 +327,11 @@ public class ExportImportServiceSqlTest extends AbstractControllerTest {
|
||||
|
||||
Map<EntityId, EntityId> ids = new HashMap<>();
|
||||
for (EntityId entityId : List.of(customer.getId(), ruleChain.getId(), dashboard.getId(), assetProfile.getId(), asset.getId(),
|
||||
deviceProfile.getId(), device.getId(), entityView.getId(), ruleChain.getId(), dashboard.getId(), calculatedField.getId())) {
|
||||
deviceProfile.getId(), device.getId(), entityView.getId(), ruleChain.getId(), dashboard.getId())) {
|
||||
EntityExportData exportData = exportEntity(getSecurityUser(tenantAdmin1), entityId);
|
||||
EntityImportResult importResult = importEntity(getSecurityUser(tenantAdmin2), exportData, EntityImportSettings.builder()
|
||||
.saveCredentials(false)
|
||||
.saveCalculatedFields(true)
|
||||
.build());
|
||||
ids.put(entityId, (EntityId) importResult.getSavedEntity().getId());
|
||||
}
|
||||
@ -353,19 +361,20 @@ public class ExportImportServiceSqlTest extends AbstractControllerTest {
|
||||
assertThat(exportedDeviceProfile.getDefaultRuleChainId()).isEqualTo(ruleChain.getId());
|
||||
assertThat(exportedDeviceProfile.getDefaultDashboardId()).isEqualTo(dashboard.getId());
|
||||
|
||||
Device exportedDevice = (Device) exportEntity(tenantAdmin2, (DeviceId) ids.get(device.getId())).getEntity();
|
||||
EntityExportData<Device> entityExportData = exportEntity(tenantAdmin2, (DeviceId) ids.get(device.getId()));
|
||||
Device exportedDevice = entityExportData.getEntity();
|
||||
assertThat(exportedDevice.getCustomerId()).isEqualTo(customer.getId());
|
||||
assertThat(exportedDevice.getDeviceProfileId()).isEqualTo(deviceProfile.getId());
|
||||
|
||||
List<CalculatedField> calculatedFields = ((DeviceExportData) entityExportData).getCalculatedFields();
|
||||
assertThat(calculatedFields.size()).isOne();
|
||||
CalculatedField field = calculatedFields.get(0);
|
||||
assertThat(field.getName()).isEqualTo(calculatedField.getName());
|
||||
|
||||
EntityView exportedEntityView = (EntityView) exportEntity(tenantAdmin2, (EntityViewId) ids.get(entityView.getId())).getEntity();
|
||||
assertThat(exportedEntityView.getCustomerId()).isEqualTo(customer.getId());
|
||||
assertThat(exportedEntityView.getEntityId()).isEqualTo(device.getId());
|
||||
|
||||
CalculatedField exportedCalculatedField = (CalculatedField) exportEntity(tenantAdmin2, (CalculatedFieldId) ids.get(calculatedField.getId())).getEntity();
|
||||
assertThat(exportedCalculatedField.getName()).isEqualTo(calculatedField.getName());
|
||||
assertThat(exportedCalculatedField.getEntityId()).isEqualTo(device.getId());
|
||||
assertThat(exportedCalculatedField.getConfiguration().getReferencedEntities()).isEqualTo(calculatedField.getConfiguration().getReferencedEntities());
|
||||
|
||||
deviceProfile.setDefaultDashboardId(null);
|
||||
deviceProfileService.saveDeviceProfile(deviceProfile);
|
||||
DeviceProfile importedDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId2, (DeviceProfileId) ids.get(deviceProfile.getId()));
|
||||
@ -373,7 +382,6 @@ public class ExportImportServiceSqlTest extends AbstractControllerTest {
|
||||
deviceProfileService.saveDeviceProfile(importedDeviceProfile);
|
||||
}
|
||||
|
||||
|
||||
protected Device createDevice(TenantId tenantId, CustomerId customerId, DeviceProfileId deviceProfileId, String name) {
|
||||
Device device = new Device();
|
||||
device.setTenantId(tenantId);
|
||||
@ -618,6 +626,7 @@ public class ExportImportServiceSqlTest extends AbstractControllerTest {
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityExportData<E> exportEntity(User user, I entityId) throws Exception {
|
||||
return exportEntity(user, entityId, EntityExportSettings.builder()
|
||||
.exportCredentials(true)
|
||||
.exportCalculatedFields(true)
|
||||
.build());
|
||||
}
|
||||
|
||||
@ -628,6 +637,7 @@ public class ExportImportServiceSqlTest extends AbstractControllerTest {
|
||||
protected <E extends ExportableEntity<I>, I extends EntityId> EntityImportResult<E> importEntity(User user, EntityExportData<E> exportData) throws Exception {
|
||||
return importEntity(user, exportData, EntityImportSettings.builder()
|
||||
.saveCredentials(true)
|
||||
.saveCalculatedFields(true)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
@ -576,12 +576,12 @@ public class VersionControlTest extends AbstractControllerTest {
|
||||
Asset asset = createAsset(null, null, "Asset 1");
|
||||
Device device = createDevice(null, null, "Device 1", "test1");
|
||||
CalculatedField calculatedField = createCalculatedField("CalculatedField1", device.getId(), asset.getId());
|
||||
String versionId = createVersion("calculated fields of asset and device", EntityType.ASSET, EntityType.DEVICE, EntityType.DEVICE_PROFILE, EntityType.ASSET_PROFILE, EntityType.CALCULATED_FIELD);
|
||||
String versionId = createVersion("calculated fields of asset and device", EntityType.ASSET, EntityType.DEVICE, EntityType.DEVICE_PROFILE, EntityType.ASSET_PROFILE);
|
||||
|
||||
loginTenant2();
|
||||
loadVersion(versionId, config -> {
|
||||
config.setLoadCredentials(false);
|
||||
}, EntityType.ASSET, EntityType.DEVICE, EntityType.DEVICE_PROFILE, EntityType.ASSET_PROFILE, EntityType.CALCULATED_FIELD);
|
||||
}, EntityType.ASSET, EntityType.DEVICE, EntityType.DEVICE_PROFILE, EntityType.ASSET_PROFILE);
|
||||
|
||||
Asset importedAsset = findAsset(asset.getName());
|
||||
Device importedDevice = findDevice(device.getName());
|
||||
@ -602,9 +602,9 @@ public class VersionControlTest extends AbstractControllerTest {
|
||||
public void testVcWithCalculatedFields_sameTenant() throws Exception {
|
||||
Asset asset = createAsset(null, null, "Asset 1");
|
||||
CalculatedField calculatedField = createCalculatedField("CalculatedField", asset.getId(), asset.getId());
|
||||
String versionId = createVersion("asset and field", EntityType.ASSET, EntityType.CALCULATED_FIELD);
|
||||
String versionId = createVersion("asset and field", EntityType.ASSET);
|
||||
|
||||
loadVersion(versionId, EntityType.ASSET, EntityType.CALCULATED_FIELD);
|
||||
loadVersion(versionId, EntityType.ASSET);
|
||||
CalculatedField importedCalculatedField = findCalculatedFieldByEntityId(asset.getId());
|
||||
checkImportedEntity(tenantId1, calculatedField, tenantId1, importedCalculatedField);
|
||||
assertThat(importedCalculatedField.getName()).isEqualTo(calculatedField.getName());
|
||||
@ -676,10 +676,10 @@ public class VersionControlTest extends AbstractControllerTest {
|
||||
request.setEntityTypes(Arrays.stream(entityTypes).collect(Collectors.toMap(t -> t, entityType -> {
|
||||
EntityTypeVersionCreateConfig config = new EntityTypeVersionCreateConfig();
|
||||
config.setAllEntities(true);
|
||||
|
||||
config.setSaveRelations(true);
|
||||
config.setSaveAttributes(true);
|
||||
config.setSaveCredentials(true);
|
||||
config.setSaveCalculatedFields(true);
|
||||
return config;
|
||||
})));
|
||||
|
||||
@ -745,6 +745,7 @@ public class VersionControlTest extends AbstractControllerTest {
|
||||
config.setLoadAttributes(true);
|
||||
config.setLoadRelations(true);
|
||||
config.setLoadCredentials(true);
|
||||
config.setLoadCalculatedFields(true);
|
||||
config.setRemoveOtherEntities(false);
|
||||
config.setFindExistingEntityByName(true);
|
||||
configModifier.accept(config);
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.common.data.sync.ie;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Data
|
||||
public class AssetExportData extends CalculatedFieldExportData<Asset> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.common.data.sync.ie;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.thingsboard.server.common.data.asset.AssetProfile;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Data
|
||||
public class AssetProfileExportData extends CalculatedFieldExportData<AssetProfile> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.common.data.sync.ie;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
import org.thingsboard.server.common.data.cf.CalculatedField;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CalculatedFieldExportData<E extends ExportableEntity<?>> extends EntityExportData<E> {
|
||||
|
||||
public static final Comparator<CalculatedField> calculatedFieldsComparator = Comparator.comparing(CalculatedField::getName);
|
||||
|
||||
@JsonProperty(index = 102)
|
||||
@JsonIgnoreProperties({"entityId", "createdTime", "version"})
|
||||
private List<CalculatedField> calculatedFields;
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean hasCalculatedFields() {
|
||||
return calculatedFields != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatedFieldExportData<E> sort() {
|
||||
super.sort();
|
||||
if (calculatedFields != null && !calculatedFields.isEmpty()) {
|
||||
calculatedFields.sort(calculatedFieldsComparator);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Data
|
||||
public class DeviceExportData extends EntityExportData<Device> {
|
||||
public class DeviceExportData extends CalculatedFieldExportData<Device> {
|
||||
|
||||
@JsonProperty(index = 3)
|
||||
@JsonIgnoreProperties({"id", "deviceId", "createdTime", "version"})
|
||||
@ -38,4 +38,5 @@ public class DeviceExportData extends EntityExportData<Device> {
|
||||
public boolean hasCredentials() {
|
||||
return credentials != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 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.common.data.sync.ie;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Data
|
||||
public class DeviceProfileExportData extends CalculatedFieldExportData<DeviceProfile> {
|
||||
|
||||
}
|
||||
@ -37,7 +37,10 @@ import java.util.Map;
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "entityType", include = As.EXISTING_PROPERTY, visible = true, defaultImpl = EntityExportData.class)
|
||||
@JsonSubTypes({
|
||||
@Type(name = "DEVICE_PROFILE", value = DeviceProfileExportData.class),
|
||||
@Type(name = "ASSET_PROFILE", value = AssetProfileExportData.class),
|
||||
@Type(name = "DEVICE", value = DeviceExportData.class),
|
||||
@Type(name = "ASSET", value = AssetExportData.class),
|
||||
@Type(name = "RULE_CHAIN", value = RuleChainExportData.class),
|
||||
@Type(name = "WIDGET_TYPE", value = WidgetTypeExportData.class),
|
||||
@Type(name = "WIDGETS_BUNDLE", value = WidgetsBundleExportData.class)
|
||||
@ -96,4 +99,9 @@ public class EntityExportData<E extends ExportableEntity<? extends EntityId>> {
|
||||
return relations != null;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public boolean hasCalculatedFields() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -25,7 +25,10 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class EntityExportSettings {
|
||||
|
||||
private boolean exportRelations;
|
||||
private boolean exportAttributes;
|
||||
private boolean exportCredentials;
|
||||
private boolean exportCalculatedFields;
|
||||
|
||||
}
|
||||
|
||||
@ -25,8 +25,11 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class EntityImportSettings {
|
||||
|
||||
private boolean findExistingByName;
|
||||
private boolean updateRelations;
|
||||
private boolean saveAttributes;
|
||||
private boolean saveCredentials;
|
||||
private boolean saveCalculatedFields;
|
||||
|
||||
}
|
||||
|
||||
@ -17,13 +17,18 @@ package org.thingsboard.server.common.data.sync.vc.request.create;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class VersionCreateConfig implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1223723167716612772L;
|
||||
|
||||
private boolean saveRelations;
|
||||
private boolean saveAttributes;
|
||||
private boolean saveCredentials;
|
||||
private boolean saveCalculatedFields;
|
||||
|
||||
}
|
||||
|
||||
@ -23,5 +23,6 @@ public class VersionLoadConfig {
|
||||
private boolean loadRelations;
|
||||
private boolean loadAttributes;
|
||||
private boolean loadCredentials;
|
||||
private boolean loadCalculatedFields;
|
||||
|
||||
}
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.thingsboard.server.dao.cf;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -15,9 +15,7 @@
|
||||
*/
|
||||
package org.thingsboard.server.dao.model.sql;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Data;
|
||||
@ -60,6 +58,15 @@ public class CalculatedFieldLinkEntity extends BaseSqlEntity<CalculatedFieldLink
|
||||
super();
|
||||
}
|
||||
|
||||
public CalculatedFieldLinkEntity(CalculatedFieldLink calculatedFieldLink) {
|
||||
this.setUuid(calculatedFieldLink.getUuidId());
|
||||
this.createdTime = calculatedFieldLink.getCreatedTime();
|
||||
this.tenantId = calculatedFieldLink.getTenantId().getId();
|
||||
this.entityType = calculatedFieldLink.getEntityId().getEntityType().name();
|
||||
this.entityId = calculatedFieldLink.getEntityId().getId();
|
||||
this.calculatedFieldId = calculatedFieldLink.getCalculatedFieldId().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatedFieldLink toData() {
|
||||
CalculatedFieldLink calculatedFieldLink = new CalculatedFieldLink(new CalculatedFieldLinkId(id));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user