Fixes for CF
This commit is contained in:
		
							parent
							
								
									8d161382e6
								
							
						
					
					
						commit
						45a3730708
					
				@ -35,11 +35,15 @@ import org.springframework.web.bind.annotation.RestController;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
import org.thingsboard.script.api.tbel.TbelCfArg;
 | 
			
		||||
import org.thingsboard.script.api.tbel.TbelInvokeService;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.HasTenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration;
 | 
			
		||||
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.EntityIdFactory;
 | 
			
		||||
import org.thingsboard.server.common.data.id.HasId;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.config.annotations.ApiOperation;
 | 
			
		||||
@ -47,10 +51,12 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldScriptEngine;
 | 
			
		||||
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldTbelScriptEngine;
 | 
			
		||||
import org.thingsboard.server.service.entitiy.cf.TbCalculatedFieldService;
 | 
			
		||||
import org.thingsboard.server.service.security.model.SecurityUser;
 | 
			
		||||
import org.thingsboard.server.service.security.permission.Operation;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
@ -122,6 +128,7 @@ public class CalculatedFieldController extends BaseController {
 | 
			
		||||
                                               @RequestBody CalculatedField calculatedField) throws Exception {
 | 
			
		||||
        calculatedField.setTenantId(getTenantId());
 | 
			
		||||
        checkEntityId(calculatedField.getEntityId(), Operation.WRITE_CALCULATED_FIELD);
 | 
			
		||||
        checkReferencedEntities(calculatedField.getConfiguration(), getCurrentUser());
 | 
			
		||||
        return tbCalculatedFieldService.save(calculatedField, getCurrentUser());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -222,4 +229,16 @@ public class CalculatedFieldController extends BaseController {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private <E extends HasId<I> & HasTenantId, I extends EntityId> void checkReferencedEntities(CalculatedFieldConfiguration calculatedFieldConfig, SecurityUser user) throws ThingsboardException {
 | 
			
		||||
        List<EntityId> referencedEntityIds = calculatedFieldConfig.getReferencedEntities();
 | 
			
		||||
        for (EntityId referencedEntityId : referencedEntityIds) {
 | 
			
		||||
            EntityType entityType = referencedEntityId.getEntityType();
 | 
			
		||||
            switch (entityType) {
 | 
			
		||||
                case TENANT, CUSTOMER, ASSET, DEVICE -> checkEntityId(referencedEntityId, Operation.READ);
 | 
			
		||||
                default -> throw new IllegalArgumentException("Calculated fields do not support '" + entityType + "' for referenced entities.");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,16 +25,11 @@ import org.springframework.context.annotation.Lazy;
 | 
			
		||||
import org.springframework.core.env.Environment;
 | 
			
		||||
import org.thingsboard.server.cluster.TbClusterService;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.HasTenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.User;
 | 
			
		||||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
 | 
			
		||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
 | 
			
		||||
import org.thingsboard.server.common.data.id.HasId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.UUIDBased;
 | 
			
		||||
import org.thingsboard.server.common.data.util.ThrowingBiFunction;
 | 
			
		||||
import org.thingsboard.server.dao.alarm.AlarmService;
 | 
			
		||||
import org.thingsboard.server.dao.asset.AssetProfileService;
 | 
			
		||||
import org.thingsboard.server.dao.asset.AssetService;
 | 
			
		||||
@ -46,10 +41,6 @@ import org.thingsboard.server.dao.entity.EntityService;
 | 
			
		||||
import org.thingsboard.server.dao.model.ModelConstants;
 | 
			
		||||
import org.thingsboard.server.dao.tenant.TenantService;
 | 
			
		||||
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
 | 
			
		||||
import org.thingsboard.server.service.security.model.SecurityUser;
 | 
			
		||||
import org.thingsboard.server.service.security.permission.AccessControlService;
 | 
			
		||||
import org.thingsboard.server.service.security.permission.Operation;
 | 
			
		||||
import org.thingsboard.server.service.security.permission.Resource;
 | 
			
		||||
import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService;
 | 
			
		||||
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
 | 
			
		||||
 | 
			
		||||
@ -58,8 +49,6 @@ import java.util.Optional;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import static org.thingsboard.server.dao.service.Validator.validateId;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
public abstract class AbstractTbEntityService {
 | 
			
		||||
 | 
			
		||||
@ -89,8 +78,6 @@ public abstract class AbstractTbEntityService {
 | 
			
		||||
    @Lazy
 | 
			
		||||
    private EntitiesVersionControlService vcService;
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected AccessControlService accessControlService;
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected TenantService tenantService;
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected AssetService assetService;
 | 
			
		||||
@ -152,22 +139,4 @@ public abstract class AbstractTbEntityService {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected <E extends HasId<I> & HasTenantId, I extends EntityId> E checkEntityId(I entityId, ThrowingBiFunction<TenantId, I, E> findingFunction, Operation operation, SecurityUser user) throws Exception {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId((UUIDBased) entityId, "Invalid entity id");
 | 
			
		||||
            E entity = findingFunction.apply(user.getTenantId(), entityId);
 | 
			
		||||
            checkNotNull(entity, entityId.getEntityType().getNormalName() + " with id [" + entityId + "] is not found");
 | 
			
		||||
            return checkEntity(user, entity, operation);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected <E extends HasId<I> & HasTenantId, I extends EntityId> E checkEntity(SecurityUser user, E entity, Operation operation) throws ThingsboardException {
 | 
			
		||||
        checkNotNull(entity, "Entity not found");
 | 
			
		||||
        accessControlService.checkPermission(user, Resource.of(entity.getId().getEntityType()), operation, entity.getId(), entity);
 | 
			
		||||
        return entity;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -20,14 +20,11 @@ import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.HasTenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.audit.ActionType;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
			
		||||
import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration;
 | 
			
		||||
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.HasId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
@ -35,13 +32,9 @@ import org.thingsboard.server.dao.cf.CalculatedFieldService;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
 | 
			
		||||
import org.thingsboard.server.service.security.model.SecurityUser;
 | 
			
		||||
import org.thingsboard.server.service.security.permission.Operation;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
import static org.thingsboard.server.dao.service.Validator.validateEntityId;
 | 
			
		||||
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
@Service
 | 
			
		||||
@Slf4j
 | 
			
		||||
@ -60,7 +53,6 @@ public class DefaultTbCalculatedFieldService extends AbstractTbEntityService imp
 | 
			
		||||
                checkForEntityChange(existingCf, calculatedField);
 | 
			
		||||
            }
 | 
			
		||||
            checkEntityExistence(tenantId, calculatedField.getEntityId());
 | 
			
		||||
            checkReferencedEntities(calculatedField.getConfiguration(), user);
 | 
			
		||||
            CalculatedField savedCalculatedField = checkNotNull(calculatedFieldService.save(calculatedField));
 | 
			
		||||
            logEntityActionService.logEntityAction(tenantId, savedCalculatedField.getId(), savedCalculatedField, actionType, user);
 | 
			
		||||
            return savedCalculatedField;
 | 
			
		||||
@ -105,31 +97,10 @@ public class DefaultTbCalculatedFieldService extends AbstractTbEntityService imp
 | 
			
		||||
 | 
			
		||||
    private void checkEntityExistence(TenantId tenantId, EntityId entityId) {
 | 
			
		||||
        switch (entityId.getEntityType()) {
 | 
			
		||||
            case ASSET, DEVICE, ASSET_PROFILE, DEVICE_PROFILE ->
 | 
			
		||||
                    Optional.ofNullable(entityService.fetchEntity(tenantId, entityId))
 | 
			
		||||
                            .orElseThrow(() -> new IllegalArgumentException(entityId.getEntityType().getNormalName() + " with id [" + entityId.getId() + "] does not exist."));
 | 
			
		||||
            default ->
 | 
			
		||||
                    throw new IllegalArgumentException("Entity type '" + entityId.getEntityType() + "' does not support calculated fields.");
 | 
			
		||||
            case ASSET, DEVICE, ASSET_PROFILE, DEVICE_PROFILE -> Optional.ofNullable(entityService.fetchEntity(tenantId, entityId))
 | 
			
		||||
                    .orElseThrow(() -> new IllegalArgumentException(entityId.getEntityType().getNormalName() + " with id [" + entityId.getId() + "] does not exist."));
 | 
			
		||||
            default -> throw new IllegalArgumentException("Entity type '" + entityId.getEntityType() + "' does not support calculated fields.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private <E extends HasId<I> & HasTenantId, I extends EntityId> void checkReferencedEntities(CalculatedFieldConfiguration calculatedFieldConfig, SecurityUser user) throws ThingsboardException {
 | 
			
		||||
        List<EntityId> referencedEntityIds = calculatedFieldConfig.getReferencedEntities();
 | 
			
		||||
        for (EntityId referencedEntityId : referencedEntityIds) {
 | 
			
		||||
            validateEntityId(referencedEntityId, id -> "Invalid entity id " + id);
 | 
			
		||||
            E entity = findEntity(user.getTenantId(), referencedEntityId);
 | 
			
		||||
            checkNotNull(entity);
 | 
			
		||||
            checkEntity(user, entity, Operation.READ);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private <E extends HasId<I> & HasTenantId, I extends EntityId> E findEntity(TenantId tenantId, EntityId entityId) {
 | 
			
		||||
        return switch (entityId.getEntityType()) {
 | 
			
		||||
            case TENANT, CUSTOMER, ASSET, DEVICE -> (E) entityService.fetchEntity(tenantId, entityId).orElse(null);
 | 
			
		||||
            default ->
 | 
			
		||||
                    throw new IllegalArgumentException("Calculated fields do not support entity type '" + entityId.getEntityType() + "' for referenced entities.");
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,8 +26,7 @@ public enum ServiceType {
 | 
			
		||||
    TB_RULE_ENGINE("TB Rule Engine"),
 | 
			
		||||
    TB_TRANSPORT("TB Transport"),
 | 
			
		||||
    JS_EXECUTOR("JS Executor"),
 | 
			
		||||
    TB_VC_EXECUTOR("TB VC Executor"),
 | 
			
		||||
    TB_CF_ENGINE("TB Calculated Fields Engine");
 | 
			
		||||
    TB_VC_EXECUTOR("TB VC Executor");
 | 
			
		||||
 | 
			
		||||
    private final String label;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user