added CF config marker interface
This commit is contained in:
		
							parent
							
								
									46a9d81a85
								
							
						
					
					
						commit
						90d34b5bd0
					
				@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.EntityType;
 | 
				
			|||||||
import org.thingsboard.server.common.data.ProfileEntityIdInfo;
 | 
					import org.thingsboard.server.common.data.ProfileEntityIdInfo;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
					import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.CalculatedFieldLink;
 | 
					import org.thingsboard.server.common.data.cf.CalculatedFieldLink;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration;
 | 
					import org.thingsboard.server.common.data.cf.configuration.ArgumentsBasedCalculatedFieldConfiguration;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.AssetId;
 | 
					import org.thingsboard.server.common.data.id.AssetId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.CalculatedFieldId;
 | 
					import org.thingsboard.server.common.data.id.CalculatedFieldId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.DeviceId;
 | 
					import org.thingsboard.server.common.data.id.DeviceId;
 | 
				
			||||||
@ -482,7 +482,9 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private void scheduleDynamicArgumentsRefreshTaskForCfIfNeeded(CalculatedFieldCtx cfCtx) {
 | 
					    private void scheduleDynamicArgumentsRefreshTaskForCfIfNeeded(CalculatedFieldCtx cfCtx) {
 | 
				
			||||||
        CalculatedField cf = cfCtx.getCalculatedField();
 | 
					        CalculatedField cf = cfCtx.getCalculatedField();
 | 
				
			||||||
        CalculatedFieldConfiguration cfConfig = cf.getConfiguration();
 | 
					        if (!(cf.getConfiguration() instanceof ArgumentsBasedCalculatedFieldConfiguration cfConfig)) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (!cfConfig.isScheduledUpdateEnabled()) {
 | 
					        if (!cfConfig.isScheduledUpdateEnabled()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -44,6 +44,7 @@ import org.thingsboard.script.api.tbel.TbelInvokeService;
 | 
				
			|||||||
import org.thingsboard.server.common.data.EntityType;
 | 
					import org.thingsboard.server.common.data.EntityType;
 | 
				
			||||||
import org.thingsboard.server.common.data.EventInfo;
 | 
					import org.thingsboard.server.common.data.EventInfo;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
					import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.cf.configuration.ArgumentsBasedCalculatedFieldConfiguration;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration;
 | 
					import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration;
 | 
				
			||||||
import org.thingsboard.server.common.data.event.EventType;
 | 
					import org.thingsboard.server.common.data.event.EventType;
 | 
				
			||||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
 | 
					import org.thingsboard.server.common.data.exception.ThingsboardException;
 | 
				
			||||||
@ -212,7 +213,8 @@ public class CalculatedFieldController extends BaseController {
 | 
				
			|||||||
            @RequestBody JsonNode inputParams) {
 | 
					            @RequestBody JsonNode inputParams) {
 | 
				
			||||||
        String expression = inputParams.get("expression").asText();
 | 
					        String expression = inputParams.get("expression").asText();
 | 
				
			||||||
        Map<String, TbelCfArg> arguments = Objects.requireNonNullElse(
 | 
					        Map<String, TbelCfArg> arguments = Objects.requireNonNullElse(
 | 
				
			||||||
                JacksonUtil.convertValue(inputParams.get("arguments"), new TypeReference<>() {}),
 | 
					                JacksonUtil.convertValue(inputParams.get("arguments"), new TypeReference<>() {
 | 
				
			||||||
 | 
					                }),
 | 
				
			||||||
                Collections.emptyMap()
 | 
					                Collections.emptyMap()
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -278,7 +280,8 @@ public class CalculatedFieldController extends BaseController {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void checkReferencedEntities(CalculatedFieldConfiguration calculatedFieldConfig) throws ThingsboardException {
 | 
					    private void checkReferencedEntities(CalculatedFieldConfiguration calculatedFieldConfig) throws ThingsboardException {
 | 
				
			||||||
        List<EntityId> referencedEntityIds = calculatedFieldConfig.getReferencedEntities();
 | 
					        if (calculatedFieldConfig instanceof ArgumentsBasedCalculatedFieldConfiguration config) {
 | 
				
			||||||
 | 
					            List<EntityId> referencedEntityIds = config.getReferencedEntities();
 | 
				
			||||||
            for (EntityId referencedEntityId : referencedEntityIds) {
 | 
					            for (EntityId referencedEntityId : referencedEntityIds) {
 | 
				
			||||||
                EntityType entityType = referencedEntityId.getEntityType();
 | 
					                EntityType entityType = referencedEntityId.getEntityType();
 | 
				
			||||||
                switch (entityType) {
 | 
					                switch (entityType) {
 | 
				
			||||||
@ -286,10 +289,11 @@ public class CalculatedFieldController extends BaseController {
 | 
				
			|||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    case CUSTOMER, ASSET, DEVICE -> checkEntityId(referencedEntityId, Operation.READ);
 | 
					                    case CUSTOMER, ASSET, DEVICE -> checkEntityId(referencedEntityId, Operation.READ);
 | 
				
			||||||
                default -> throw new IllegalArgumentException("Calculated fields do not support '" + entityType + "' for referenced entities.");
 | 
					                    default ->
 | 
				
			||||||
 | 
					                            throw new IllegalArgumentException("Calculated fields do not support '" + entityType + "' for referenced entities.");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
				
			|||||||
import org.thingsboard.server.common.data.cf.CalculatedFieldType;
 | 
					import org.thingsboard.server.common.data.cf.CalculatedFieldType;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.configuration.Argument;
 | 
					import org.thingsboard.server.common.data.cf.configuration.Argument;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.configuration.ArgumentType;
 | 
					import org.thingsboard.server.common.data.cf.configuration.ArgumentType;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration;
 | 
					import org.thingsboard.server.common.data.cf.configuration.ArgumentsBasedCalculatedFieldConfiguration;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.configuration.Output;
 | 
					import org.thingsboard.server.common.data.cf.configuration.Output;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.configuration.ReferencedEntityKey;
 | 
					import org.thingsboard.server.common.data.cf.configuration.ReferencedEntityKey;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.configuration.SimpleCalculatedFieldConfiguration;
 | 
					import org.thingsboard.server.common.data.cf.configuration.SimpleCalculatedFieldConfiguration;
 | 
				
			||||||
@ -83,10 +83,12 @@ public class CalculatedFieldCtx {
 | 
				
			|||||||
        this.tenantId = calculatedField.getTenantId();
 | 
					        this.tenantId = calculatedField.getTenantId();
 | 
				
			||||||
        this.entityId = calculatedField.getEntityId();
 | 
					        this.entityId = calculatedField.getEntityId();
 | 
				
			||||||
        this.cfType = calculatedField.getType();
 | 
					        this.cfType = calculatedField.getType();
 | 
				
			||||||
        CalculatedFieldConfiguration configuration = calculatedField.getConfiguration();
 | 
					        this.arguments = new HashMap<>();
 | 
				
			||||||
        this.arguments = configuration.getArguments();
 | 
					 | 
				
			||||||
        this.mainEntityArguments = new HashMap<>();
 | 
					        this.mainEntityArguments = new HashMap<>();
 | 
				
			||||||
        this.linkedEntityArguments = new HashMap<>();
 | 
					        this.linkedEntityArguments = new HashMap<>();
 | 
				
			||||||
 | 
					        this.argNames = new ArrayList<>();
 | 
				
			||||||
 | 
					        if (calculatedField.getConfiguration() instanceof ArgumentsBasedCalculatedFieldConfiguration configuration) {
 | 
				
			||||||
 | 
					            this.arguments.putAll(configuration.getArguments());
 | 
				
			||||||
            for (Map.Entry<String, Argument> entry : arguments.entrySet()) {
 | 
					            for (Map.Entry<String, Argument> entry : arguments.entrySet()) {
 | 
				
			||||||
                var refId = entry.getValue().getRefEntityId();
 | 
					                var refId = entry.getValue().getRefEntityId();
 | 
				
			||||||
                var refKey = entry.getValue().getRefEntityKey();
 | 
					                var refKey = entry.getValue().getRefEntityKey();
 | 
				
			||||||
@ -99,10 +101,11 @@ public class CalculatedFieldCtx {
 | 
				
			|||||||
                    linkedEntityArguments.computeIfAbsent(refId, key -> new HashMap<>()).put(refKey, entry.getKey());
 | 
					                    linkedEntityArguments.computeIfAbsent(refId, key -> new HashMap<>()).put(refKey, entry.getKey());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        this.argNames = new ArrayList<>(arguments.keySet());
 | 
					            this.argNames.addAll(arguments.keySet());
 | 
				
			||||||
            this.output = configuration.getOutput();
 | 
					            this.output = configuration.getOutput();
 | 
				
			||||||
            this.expression = configuration.getExpression();
 | 
					            this.expression = configuration.getExpression();
 | 
				
			||||||
            this.useLatestTs = CalculatedFieldType.SIMPLE.equals(calculatedField.getType()) && ((SimpleCalculatedFieldConfiguration) configuration).isUseLatestTs();
 | 
					            this.useLatestTs = CalculatedFieldType.SIMPLE.equals(calculatedField.getType()) && ((SimpleCalculatedFieldConfiguration) configuration).isUseLatestTs();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        this.tbelInvokeService = tbelInvokeService;
 | 
					        this.tbelInvokeService = tbelInvokeService;
 | 
				
			||||||
        this.relationService = relationService;
 | 
					        this.relationService = relationService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -316,12 +319,14 @@ public class CalculatedFieldCtx {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public boolean hasSchedulingConfigChanges(CalculatedFieldCtx other) {
 | 
					    public boolean hasSchedulingConfigChanges(CalculatedFieldCtx other) {
 | 
				
			||||||
        CalculatedFieldConfiguration thisConfig = calculatedField.getConfiguration();
 | 
					        if (calculatedField.getConfiguration() instanceof ArgumentsBasedCalculatedFieldConfiguration thisConfig
 | 
				
			||||||
        CalculatedFieldConfiguration otherConfig = other.calculatedField.getConfiguration();
 | 
					                && other.calculatedField.getConfiguration() instanceof ArgumentsBasedCalculatedFieldConfiguration otherConfig) {
 | 
				
			||||||
            boolean refreshTriggerChanged = thisConfig.isScheduledUpdateEnabled() != otherConfig.isScheduledUpdateEnabled();
 | 
					            boolean refreshTriggerChanged = thisConfig.isScheduledUpdateEnabled() != otherConfig.isScheduledUpdateEnabled();
 | 
				
			||||||
            boolean refreshIntervalChanged = thisConfig.getScheduledUpdateIntervalSec() != otherConfig.getScheduledUpdateIntervalSec();
 | 
					            boolean refreshIntervalChanged = thisConfig.getScheduledUpdateIntervalSec() != otherConfig.getScheduledUpdateIntervalSec();
 | 
				
			||||||
            return refreshTriggerChanged || refreshIntervalChanged;
 | 
					            return refreshTriggerChanged || refreshIntervalChanged;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public String getSizeExceedsLimitMessage() {
 | 
					    public String getSizeExceedsLimitMessage() {
 | 
				
			||||||
        return "Failed to init CF state. State size exceeds limit of " + (maxStateSize / 1024) + "Kb!";
 | 
					        return "Failed to init CF state. State size exceeds limit of " + (maxStateSize / 1024) + "Kb!";
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.EntityType;
 | 
				
			|||||||
import org.thingsboard.server.common.data.ExportableEntity;
 | 
					import org.thingsboard.server.common.data.ExportableEntity;
 | 
				
			||||||
import org.thingsboard.server.common.data.HasVersion;
 | 
					import org.thingsboard.server.common.data.HasVersion;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
					import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.cf.configuration.ArgumentsBasedCalculatedFieldConfiguration;
 | 
				
			||||||
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;
 | 
				
			||||||
@ -153,11 +154,13 @@ public class DefaultEntityExportService<I extends EntityId, E extends Exportable
 | 
				
			|||||||
        List<CalculatedField> calculatedFields = calculatedFieldService.findCalculatedFieldsByEntityId(ctx.getTenantId(), entityId);
 | 
					        List<CalculatedField> calculatedFields = calculatedFieldService.findCalculatedFieldsByEntityId(ctx.getTenantId(), entityId);
 | 
				
			||||||
        calculatedFields.forEach(calculatedField -> {
 | 
					        calculatedFields.forEach(calculatedField -> {
 | 
				
			||||||
            calculatedField.setEntityId(getExternalIdOrElseInternal(ctx, entityId));
 | 
					            calculatedField.setEntityId(getExternalIdOrElseInternal(ctx, entityId));
 | 
				
			||||||
            calculatedField.getConfiguration().getArguments().values().forEach(argument -> {
 | 
					            if (calculatedField.getConfiguration() instanceof ArgumentsBasedCalculatedFieldConfiguration configuration) {
 | 
				
			||||||
 | 
					                configuration.getArguments().values().forEach(argument -> {
 | 
				
			||||||
                    if (argument.getRefEntityId() != null) {
 | 
					                    if (argument.getRefEntityId() != null) {
 | 
				
			||||||
                        argument.setRefEntityId(getExternalIdOrElseInternal(ctx, argument.getRefEntityId()));
 | 
					                        argument.setRefEntityId(getExternalIdOrElseInternal(ctx, argument.getRefEntityId()));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        return calculatedFields;
 | 
					        return calculatedFields;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.HasVersion;
 | 
				
			|||||||
import org.thingsboard.server.common.data.User;
 | 
					import org.thingsboard.server.common.data.User;
 | 
				
			||||||
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.ArgumentsBasedCalculatedFieldConfiguration;
 | 
				
			||||||
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;
 | 
				
			||||||
@ -321,11 +322,13 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
 | 
				
			|||||||
                .peek(calculatedField -> {
 | 
					                .peek(calculatedField -> {
 | 
				
			||||||
                    calculatedField.setTenantId(ctx.getTenantId());
 | 
					                    calculatedField.setTenantId(ctx.getTenantId());
 | 
				
			||||||
                    calculatedField.setEntityId(savedEntity.getId());
 | 
					                    calculatedField.setEntityId(savedEntity.getId());
 | 
				
			||||||
                    calculatedField.getConfiguration().getArguments().values().forEach(argument -> {
 | 
					                    if (calculatedField.getConfiguration() instanceof ArgumentsBasedCalculatedFieldConfiguration configuration) {
 | 
				
			||||||
 | 
					                        configuration.getArguments().values().forEach(argument -> {
 | 
				
			||||||
                            if (argument.getRefEntityId() != null) {
 | 
					                            if (argument.getRefEntityId() != null) {
 | 
				
			||||||
                                argument.setRefEntityId(idProvider.getInternalId(argument.getRefEntityId(), ctx.isFinalImportAttempt()));
 | 
					                                argument.setRefEntityId(idProvider.getInternalId(argument.getRefEntityId(), ctx.isFinalImportAttempt()));
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }).toList();
 | 
					                }).toList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (CalculatedField existingField : existing) {
 | 
					        for (CalculatedField existingField : existing) {
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					package org.thingsboard.server.common.data.cf.configuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonIgnore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface ArgumentsBasedCalculatedFieldConfiguration extends CalculatedFieldConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Map<String, Argument> getArguments();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String getExpression();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setExpression(String expression);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Output getOutput();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void validate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonIgnore
 | 
				
			||||||
 | 
					    default boolean isScheduledUpdateEnabled() {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default void setScheduledUpdateIntervalSec(int scheduledUpdateIntervalSec) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default int getScheduledUpdateIntervalSec() {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -27,7 +27,7 @@ import java.util.Objects;
 | 
				
			|||||||
import java.util.stream.Collectors;
 | 
					import java.util.stream.Collectors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Data
 | 
					@Data
 | 
				
			||||||
public abstract class BaseCalculatedFieldConfiguration implements CalculatedFieldConfiguration {
 | 
					public abstract class BaseCalculatedFieldConfiguration implements ArgumentsBasedCalculatedFieldConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected Map<String, Argument> arguments;
 | 
					    protected Map<String, Argument> arguments;
 | 
				
			||||||
    protected String expression;
 | 
					    protected String expression;
 | 
				
			||||||
 | 
				
			|||||||
@ -25,8 +25,8 @@ 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.TenantId;
 | 
					import org.thingsboard.server.common.data.id.TenantId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Map;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@JsonTypeInfo(
 | 
					@JsonTypeInfo(
 | 
				
			||||||
        use = JsonTypeInfo.Id.NAME,
 | 
					        use = JsonTypeInfo.Id.NAME,
 | 
				
			||||||
@ -44,33 +44,13 @@ public interface CalculatedFieldConfiguration {
 | 
				
			|||||||
    @JsonIgnore
 | 
					    @JsonIgnore
 | 
				
			||||||
    CalculatedFieldType getType();
 | 
					    CalculatedFieldType getType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Map<String, Argument> getArguments();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    String getExpression();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void setExpression(String expression);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Output getOutput();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @JsonIgnore
 | 
					    @JsonIgnore
 | 
				
			||||||
    List<EntityId> getReferencedEntities();
 | 
					    default List<EntityId> getReferencedEntities() {
 | 
				
			||||||
 | 
					        return Collections.emptyList();
 | 
				
			||||||
    List<CalculatedFieldLink> buildCalculatedFieldLinks(TenantId tenantId, EntityId cfEntityId, CalculatedFieldId calculatedFieldId);
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CalculatedFieldLink buildCalculatedFieldLink(TenantId tenantId, EntityId referencedEntityId, CalculatedFieldId calculatedFieldId);
 | 
					    CalculatedFieldLink buildCalculatedFieldLink(TenantId tenantId, EntityId referencedEntityId, CalculatedFieldId calculatedFieldId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void validate();
 | 
					    List<CalculatedFieldLink> buildCalculatedFieldLinks(TenantId tenantId, EntityId cfEntityId, CalculatedFieldId calculatedFieldId);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    @JsonIgnore
 | 
					 | 
				
			||||||
    default boolean isScheduledUpdateEnabled() {
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    default void setScheduledUpdateIntervalSec(int scheduledUpdateIntervalSec) {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    default int getScheduledUpdateIntervalSec() {
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,7 @@ import java.util.stream.Collectors;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@Data
 | 
					@Data
 | 
				
			||||||
@EqualsAndHashCode(callSuper = true)
 | 
					@EqualsAndHashCode(callSuper = true)
 | 
				
			||||||
public class GeofencingCalculatedFieldConfiguration extends BaseCalculatedFieldConfiguration implements CalculatedFieldConfiguration {
 | 
					public class GeofencingCalculatedFieldConfiguration extends BaseCalculatedFieldConfiguration implements ArgumentsBasedCalculatedFieldConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final String ENTITY_ID_LATITUDE_ARGUMENT_KEY = "latitude";
 | 
					    public static final String ENTITY_ID_LATITUDE_ARGUMENT_KEY = "latitude";
 | 
				
			||||||
    public static final String ENTITY_ID_LONGITUDE_ARGUMENT_KEY = "longitude";
 | 
					    public static final String ENTITY_ID_LONGITUDE_ARGUMENT_KEY = "longitude";
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.cf.CalculatedFieldType;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@Data
 | 
					@Data
 | 
				
			||||||
@EqualsAndHashCode(callSuper = true)
 | 
					@EqualsAndHashCode(callSuper = true)
 | 
				
			||||||
public class ScriptCalculatedFieldConfiguration extends BaseCalculatedFieldConfiguration implements CalculatedFieldConfiguration {
 | 
					public class ScriptCalculatedFieldConfiguration extends BaseCalculatedFieldConfiguration implements ArgumentsBasedCalculatedFieldConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public CalculatedFieldType getType() {
 | 
					    public CalculatedFieldType getType() {
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.cf.CalculatedFieldType;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@Data
 | 
					@Data
 | 
				
			||||||
@EqualsAndHashCode(callSuper = true)
 | 
					@EqualsAndHashCode(callSuper = true)
 | 
				
			||||||
public class SimpleCalculatedFieldConfiguration extends BaseCalculatedFieldConfiguration implements CalculatedFieldConfiguration {
 | 
					public class SimpleCalculatedFieldConfiguration extends BaseCalculatedFieldConfiguration implements ArgumentsBasedCalculatedFieldConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean useLatestTs;
 | 
					    private boolean useLatestTs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,7 @@ import org.springframework.stereotype.Service;
 | 
				
			|||||||
import org.thingsboard.server.common.data.EntityType;
 | 
					import org.thingsboard.server.common.data.EntityType;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
					import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.CalculatedFieldLink;
 | 
					import org.thingsboard.server.common.data.cf.CalculatedFieldLink;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.cf.configuration.ArgumentsBasedCalculatedFieldConfiguration;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration;
 | 
					import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.CalculatedFieldId;
 | 
					import org.thingsboard.server.common.data.id.CalculatedFieldId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.CalculatedFieldLinkId;
 | 
					import org.thingsboard.server.common.data.id.CalculatedFieldLinkId;
 | 
				
			||||||
@ -93,7 +94,7 @@ public class BaseCalculatedFieldService extends AbstractEntityService implements
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void updatedSchedulingConfiguration(CalculatedField calculatedField) {
 | 
					    private void updatedSchedulingConfiguration(CalculatedField calculatedField) {
 | 
				
			||||||
        CalculatedFieldConfiguration configuration = calculatedField.getConfiguration();
 | 
					        if (calculatedField.getConfiguration() instanceof ArgumentsBasedCalculatedFieldConfiguration configuration) {
 | 
				
			||||||
            if (!configuration.isScheduledUpdateEnabled()) {
 | 
					            if (!configuration.isScheduledUpdateEnabled()) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -102,6 +103,7 @@ public class BaseCalculatedFieldService extends AbstractEntityService implements
 | 
				
			|||||||
                    .getMinAllowedScheduledUpdateIntervalInSecForCF();
 | 
					                    .getMinAllowedScheduledUpdateIntervalInSecForCF();
 | 
				
			||||||
            configuration.setScheduledUpdateIntervalSec(Math.max(configuration.getScheduledUpdateIntervalSec(), tenantProfileMinAllowedValue));
 | 
					            configuration.setScheduledUpdateIntervalSec(Math.max(configuration.getScheduledUpdateIntervalSec(), tenantProfileMinAllowedValue));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public CalculatedField findById(TenantId tenantId, CalculatedFieldId calculatedFieldId) {
 | 
					    public CalculatedField findById(TenantId tenantId, CalculatedFieldId calculatedFieldId) {
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 | 
				
			|||||||
import org.springframework.stereotype.Component;
 | 
					import org.springframework.stereotype.Component;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
					import org.thingsboard.server.common.data.cf.CalculatedField;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.CalculatedFieldType;
 | 
					import org.thingsboard.server.common.data.cf.CalculatedFieldType;
 | 
				
			||||||
import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration;
 | 
					import org.thingsboard.server.common.data.cf.configuration.ArgumentsBasedCalculatedFieldConfiguration;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
					import org.thingsboard.server.common.data.id.EntityId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
					import org.thingsboard.server.common.data.id.TenantId;
 | 
				
			||||||
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
 | 
					import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
 | 
				
			||||||
@ -75,13 +75,14 @@ public class CalculatedFieldDataValidator extends DataValidator<CalculatedField>
 | 
				
			|||||||
                    maxArgumentsPerCF + ". Contact your administrator to increase the limit."
 | 
					                    maxArgumentsPerCF + ". Contact your administrator to increase the limit."
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (calculatedField.getConfiguration().getArguments().size() > maxArgumentsPerCF) {
 | 
					        if (calculatedField.getConfiguration() instanceof ArgumentsBasedCalculatedFieldConfiguration configuration
 | 
				
			||||||
 | 
					                && configuration.getArguments().size() > maxArgumentsPerCF) {
 | 
				
			||||||
            throw new DataValidationException("Calculated field arguments limit reached!");
 | 
					            throw new DataValidationException("Calculated field arguments limit reached!");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void validateCalculatedFieldConfiguration(CalculatedField calculatedField) {
 | 
					    private void validateCalculatedFieldConfiguration(CalculatedField calculatedField) {
 | 
				
			||||||
        CalculatedFieldConfiguration configuration = calculatedField.getConfiguration();
 | 
					        if (calculatedField.getConfiguration() instanceof ArgumentsBasedCalculatedFieldConfiguration configuration) {
 | 
				
			||||||
            if (configuration.getArguments().containsKey("ctx")) {
 | 
					            if (configuration.getArguments().containsKey("ctx")) {
 | 
				
			||||||
                throw new DataValidationException("Argument name 'ctx' is reserved and cannot be used.");
 | 
					                throw new DataValidationException("Argument name 'ctx' is reserved and cannot be used.");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -91,5 +92,6 @@ public class CalculatedFieldDataValidator extends DataValidator<CalculatedField>
 | 
				
			|||||||
                throw new DataValidationException(e.getMessage(), e);
 | 
					                throw new DataValidationException(e.getMessage(), e);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user