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.common.util.JacksonUtil;
|
||||||
import org.thingsboard.script.api.tbel.TbelCfArg;
|
import org.thingsboard.script.api.tbel.TbelCfArg;
|
||||||
import org.thingsboard.script.api.tbel.TbelInvokeService;
|
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.CalculatedField;
|
||||||
|
import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration;
|
||||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||||
import org.thingsboard.server.common.data.id.CalculatedFieldId;
|
import org.thingsboard.server.common.data.id.CalculatedFieldId;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
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.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.config.annotations.ApiOperation;
|
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.CalculatedFieldScriptEngine;
|
||||||
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldTbelScriptEngine;
|
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldTbelScriptEngine;
|
||||||
import org.thingsboard.server.service.entitiy.cf.TbCalculatedFieldService;
|
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 org.thingsboard.server.service.security.permission.Operation;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -122,6 +128,7 @@ public class CalculatedFieldController extends BaseController {
|
|||||||
@RequestBody CalculatedField calculatedField) throws Exception {
|
@RequestBody CalculatedField calculatedField) throws Exception {
|
||||||
calculatedField.setTenantId(getTenantId());
|
calculatedField.setTenantId(getTenantId());
|
||||||
checkEntityId(calculatedField.getEntityId(), Operation.WRITE_CALCULATED_FIELD);
|
checkEntityId(calculatedField.getEntityId(), Operation.WRITE_CALCULATED_FIELD);
|
||||||
|
checkReferencedEntities(calculatedField.getConfiguration(), getCurrentUser());
|
||||||
return tbCalculatedFieldService.save(calculatedField, getCurrentUser());
|
return tbCalculatedFieldService.save(calculatedField, getCurrentUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,4 +229,16 @@ public class CalculatedFieldController extends BaseController {
|
|||||||
return result;
|
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.springframework.core.env.Environment;
|
||||||
import org.thingsboard.server.cluster.TbClusterService;
|
import org.thingsboard.server.cluster.TbClusterService;
|
||||||
import org.thingsboard.server.common.data.EntityType;
|
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.User;
|
||||||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
|
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
|
||||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
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.alarm.AlarmService;
|
||||||
import org.thingsboard.server.dao.asset.AssetProfileService;
|
import org.thingsboard.server.dao.asset.AssetProfileService;
|
||||||
import org.thingsboard.server.dao.asset.AssetService;
|
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.model.ModelConstants;
|
||||||
import org.thingsboard.server.dao.tenant.TenantService;
|
import org.thingsboard.server.dao.tenant.TenantService;
|
||||||
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
|
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.sync.vc.EntitiesVersionControlService;
|
||||||
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
|
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
|
||||||
|
|
||||||
@ -58,8 +49,6 @@ import java.util.Optional;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static org.thingsboard.server.dao.service.Validator.validateId;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public abstract class AbstractTbEntityService {
|
public abstract class AbstractTbEntityService {
|
||||||
|
|
||||||
@ -89,8 +78,6 @@ public abstract class AbstractTbEntityService {
|
|||||||
@Lazy
|
@Lazy
|
||||||
private EntitiesVersionControlService vcService;
|
private EntitiesVersionControlService vcService;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected AccessControlService accessControlService;
|
|
||||||
@Autowired
|
|
||||||
protected TenantService tenantService;
|
protected TenantService tenantService;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected AssetService assetService;
|
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.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.thingsboard.server.common.data.EntityType;
|
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.audit.ActionType;
|
||||||
import org.thingsboard.server.common.data.cf.CalculatedField;
|
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.exception.ThingsboardException;
|
||||||
import org.thingsboard.server.common.data.id.CalculatedFieldId;
|
import org.thingsboard.server.common.data.id.CalculatedFieldId;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
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.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;
|
||||||
@ -35,13 +32,9 @@ import org.thingsboard.server.dao.cf.CalculatedFieldService;
|
|||||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||||
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
|
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
|
||||||
import org.thingsboard.server.service.security.model.SecurityUser;
|
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 java.util.Optional;
|
||||||
|
|
||||||
import static org.thingsboard.server.dao.service.Validator.validateEntityId;
|
|
||||||
|
|
||||||
@TbCoreComponent
|
@TbCoreComponent
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -60,7 +53,6 @@ public class DefaultTbCalculatedFieldService extends AbstractTbEntityService imp
|
|||||||
checkForEntityChange(existingCf, calculatedField);
|
checkForEntityChange(existingCf, calculatedField);
|
||||||
}
|
}
|
||||||
checkEntityExistence(tenantId, calculatedField.getEntityId());
|
checkEntityExistence(tenantId, calculatedField.getEntityId());
|
||||||
checkReferencedEntities(calculatedField.getConfiguration(), user);
|
|
||||||
CalculatedField savedCalculatedField = checkNotNull(calculatedFieldService.save(calculatedField));
|
CalculatedField savedCalculatedField = checkNotNull(calculatedFieldService.save(calculatedField));
|
||||||
logEntityActionService.logEntityAction(tenantId, savedCalculatedField.getId(), savedCalculatedField, actionType, user);
|
logEntityActionService.logEntityAction(tenantId, savedCalculatedField.getId(), savedCalculatedField, actionType, user);
|
||||||
return savedCalculatedField;
|
return savedCalculatedField;
|
||||||
@ -105,31 +97,10 @@ public class DefaultTbCalculatedFieldService extends AbstractTbEntityService imp
|
|||||||
|
|
||||||
private void checkEntityExistence(TenantId tenantId, EntityId entityId) {
|
private void checkEntityExistence(TenantId tenantId, EntityId entityId) {
|
||||||
switch (entityId.getEntityType()) {
|
switch (entityId.getEntityType()) {
|
||||||
case ASSET, DEVICE, ASSET_PROFILE, DEVICE_PROFILE ->
|
case ASSET, DEVICE, ASSET_PROFILE, DEVICE_PROFILE -> Optional.ofNullable(entityService.fetchEntity(tenantId, entityId))
|
||||||
Optional.ofNullable(entityService.fetchEntity(tenantId, entityId))
|
|
||||||
.orElseThrow(() -> new IllegalArgumentException(entityId.getEntityType().getNormalName() + " with id [" + entityId.getId() + "] does not exist."));
|
.orElseThrow(() -> new IllegalArgumentException(entityId.getEntityType().getNormalName() + " with id [" + entityId.getId() + "] does not exist."));
|
||||||
default ->
|
default -> throw new IllegalArgumentException("Entity type '" + entityId.getEntityType() + "' does not support calculated fields.");
|
||||||
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_RULE_ENGINE("TB Rule Engine"),
|
||||||
TB_TRANSPORT("TB Transport"),
|
TB_TRANSPORT("TB Transport"),
|
||||||
JS_EXECUTOR("JS Executor"),
|
JS_EXECUTOR("JS Executor"),
|
||||||
TB_VC_EXECUTOR("TB VC Executor"),
|
TB_VC_EXECUTOR("TB VC Executor");
|
||||||
TB_CF_ENGINE("TB Calculated Fields Engine");
|
|
||||||
|
|
||||||
private final String label;
|
private final String label;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user