VC support for calculated fields

This commit is contained in:
Andrii Landiak 2025-02-17 16:32:59 +02:00
parent 8568bb93a8
commit dfb0549424
8 changed files with 174 additions and 4 deletions

View File

@ -69,7 +69,8 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS
EntityType.DASHBOARD, EntityType.ASSET_PROFILE, EntityType.ASSET, EntityType.DASHBOARD, EntityType.ASSET_PROFILE, EntityType.ASSET,
EntityType.DEVICE_PROFILE, EntityType.DEVICE, EntityType.DEVICE_PROFILE, EntityType.DEVICE,
EntityType.ENTITY_VIEW, EntityType.WIDGET_TYPE, EntityType.WIDGETS_BUNDLE, EntityType.ENTITY_VIEW, EntityType.WIDGET_TYPE, EntityType.WIDGETS_BUNDLE,
EntityType.NOTIFICATION_TEMPLATE, EntityType.NOTIFICATION_TARGET, EntityType.NOTIFICATION_RULE EntityType.NOTIFICATION_TEMPLATE, EntityType.NOTIFICATION_TARGET, EntityType.NOTIFICATION_RULE,
EntityType.CALCULATED_FIELD
); );

View File

@ -0,0 +1,42 @@
/**
* Copyright © 2016-2024 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.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()));
}
@Override
public Set<EntityType> getSupportedEntityTypes() {
return Set.of(EntityType.CALCULATED_FIELD);
}
}

View File

@ -0,0 +1,78 @@
/**
* Copyright © 2016-2024 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.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()));
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;
}
}

View File

@ -37,11 +37,14 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.Length;
import org.thingsboard.server.common.data.validation.NoXss; import org.thingsboard.server.common.data.validation.NoXss;
import java.io.Serial;
@Schema @Schema
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class CalculatedField extends BaseData<CalculatedFieldId> implements HasName, HasTenantId, HasVersion, ExportableEntity<CalculatedFieldId>, HasDebugSettings { public class CalculatedField extends BaseData<CalculatedFieldId> implements HasName, HasTenantId, HasVersion, ExportableEntity<CalculatedFieldId>, HasDebugSettings {
@Serial
private static final long serialVersionUID = 4491966747773381420L; private static final long serialVersionUID = 4491966747773381420L;
private TenantId tenantId; private TenantId tenantId;
@ -78,6 +81,20 @@ public class CalculatedField extends BaseData<CalculatedFieldId> implements HasN
super(id); super(id);
} }
public CalculatedField(CalculatedField other) {
super(other);
this.tenantId = other.tenantId;
this.entityId = other.entityId;
this.type = other.type;
this.name = other.name;
this.configurationVersion = other.configurationVersion;
this.configuration = other.configuration;
this.version = other.version;
this.externalId = other.externalId;
this.debugMode = other.debugMode;
this.debugSettings = other.debugSettings;
}
public CalculatedField(TenantId tenantId, EntityId entityId, CalculatedFieldType type, String name, int configurationVersion, CalculatedFieldConfiguration configuration, Long version, CalculatedFieldId externalId) { public CalculatedField(TenantId tenantId, EntityId entityId, CalculatedFieldType type, String name, int configurationVersion, CalculatedFieldConfiguration configuration, Long version, CalculatedFieldId externalId) {
this.tenantId = tenantId; this.tenantId = tenantId;
this.entityId = entityId; this.entityId = entityId;

View File

@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetProfile; import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.cf.CalculatedField;
import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRule;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget; import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
@ -58,7 +59,8 @@ import java.lang.annotation.Target;
@Type(name = "NOTIFICATION_TEMPLATE", value = NotificationTemplate.class), @Type(name = "NOTIFICATION_TEMPLATE", value = NotificationTemplate.class),
@Type(name = "NOTIFICATION_TARGET", value = NotificationTarget.class), @Type(name = "NOTIFICATION_TARGET", value = NotificationTarget.class),
@Type(name = "NOTIFICATION_RULE", value = NotificationRule.class), @Type(name = "NOTIFICATION_RULE", value = NotificationRule.class),
@Type(name = "TB_RESOURCE", value = TbResource.class) @Type(name = "TB_RESOURCE", value = TbResource.class),
@Type(name = "CALCULATED_FIELD", value = CalculatedField.class)
}) })
@JsonIgnoreProperties(value = {"tenantId", "createdTime", "version"}, ignoreUnknown = true) @JsonIgnoreProperties(value = {"tenantId", "createdTime", "version"}, ignoreUnknown = true)
public @interface JsonTbEntity { public @interface JsonTbEntity {

View File

@ -22,10 +22,11 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.Dao; import org.thingsboard.server.dao.Dao;
import org.thingsboard.server.dao.ExportableEntityDao;
import java.util.List; import java.util.List;
public interface CalculatedFieldDao extends Dao<CalculatedField> { public interface CalculatedFieldDao extends Dao<CalculatedField>, ExportableEntityDao<CalculatedFieldId, CalculatedField> {
List<CalculatedField> findAllByTenantId(TenantId tenantId); List<CalculatedField> findAllByTenantId(TenantId tenantId);

View File

@ -18,13 +18,16 @@ package org.thingsboard.server.dao.sql.cf;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import org.thingsboard.server.common.data.id.CalculatedFieldId; import org.thingsboard.server.common.data.id.CalculatedFieldId;
import org.thingsboard.server.dao.ExportableEntityRepository;
import org.thingsboard.server.dao.model.sql.CalculatedFieldEntity; import org.thingsboard.server.dao.model.sql.CalculatedFieldEntity;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
public interface CalculatedFieldRepository extends JpaRepository<CalculatedFieldEntity, UUID> { @Repository
public interface CalculatedFieldRepository extends JpaRepository<CalculatedFieldEntity, UUID>, ExportableEntityRepository<CalculatedFieldEntity> {
boolean existsByTenantIdAndEntityId(UUID tenantId, UUID entityId); boolean existsByTenantIdAndEntityId(UUID tenantId, UUID entityId);
@ -34,10 +37,16 @@ public interface CalculatedFieldRepository extends JpaRepository<CalculatedField
Page<CalculatedFieldEntity> findAllByTenantIdAndEntityId(UUID tenantId, UUID entityId, Pageable pageable); Page<CalculatedFieldEntity> findAllByTenantIdAndEntityId(UUID tenantId, UUID entityId, Pageable pageable);
Page<CalculatedFieldEntity> findByTenantId(UUID tenantId, Pageable pageable);
List<CalculatedFieldEntity> findAllByTenantId(UUID tenantId); List<CalculatedFieldEntity> findAllByTenantId(UUID tenantId);
List<CalculatedFieldEntity> removeAllByTenantIdAndEntityId(UUID tenantId, UUID entityId); List<CalculatedFieldEntity> removeAllByTenantIdAndEntityId(UUID tenantId, UUID entityId);
long countByTenantIdAndEntityId(UUID tenantId, UUID entityId); long countByTenantIdAndEntityId(UUID tenantId, UUID entityId);
CalculatedFieldId findExternalIdById(UUID id);
CalculatedFieldEntity findByTenantIdAndName(UUID tenantId, String name);
} }

View File

@ -93,6 +93,26 @@ public class JpaCalculatedFieldDao extends JpaAbstractDao<CalculatedFieldEntity,
return calculatedFieldRepository.countByTenantIdAndEntityId(tenantId.getId(), entityId.getId()); return calculatedFieldRepository.countByTenantIdAndEntityId(tenantId.getId(), entityId.getId());
} }
@Override
public PageData<CalculatedField> findByTenantId(UUID tenantId, PageLink pageLink) {
return DaoUtil.toPageData(calculatedFieldRepository.findByTenantId(tenantId, DaoUtil.toPageable(pageLink)));
}
@Override
public CalculatedField findByTenantIdAndName(UUID tenantId, String name) {
return DaoUtil.getData(calculatedFieldRepository.findByTenantIdAndName(tenantId, name));
}
@Override
public CalculatedField findByTenantIdAndExternalId(UUID tenantId, UUID externalId) {
return DaoUtil.getData(calculatedFieldRepository.findByTenantIdAndExternalId(tenantId, externalId));
}
@Override
public CalculatedFieldId getExternalIdByInternal(CalculatedFieldId internalId) {
return calculatedFieldRepository.findExternalIdById(internalId.getId());
}
@Override @Override
protected Class<CalculatedFieldEntity> getEntityClass() { protected Class<CalculatedFieldEntity> getEntityClass() {
return CalculatedFieldEntity.class; return CalculatedFieldEntity.class;