diff --git a/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldProcessingService.java b/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldProcessingService.java index ade1d3eefd..995180e507 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldProcessingService.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldProcessingService.java @@ -35,7 +35,6 @@ import org.thingsboard.server.common.data.StringUtils; 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.ArgumentType; -import org.thingsboard.server.common.data.cf.configuration.CFArgumentDynamicSourceType; import org.thingsboard.server.common.data.cf.configuration.OutputType; import org.thingsboard.server.common.data.cf.configuration.RelationQueryDynamicSourceConfiguration; import org.thingsboard.server.common.data.id.CalculatedFieldId; @@ -162,7 +161,7 @@ public class DefaultCalculatedFieldProcessingService implements CalculatedFieldP Set> entries = ctx.getArguments().entrySet(); if (dynamicArgumentsOnly) { entries = entries.stream() - .filter(entry -> CFArgumentDynamicSourceType.RELATION_QUERY.equals(entry.getValue().getRefDynamicSource())) + .filter(entry -> entry.getValue().hasDynamicSource()) .collect(Collectors.toSet()); } for (var entry : entries) { @@ -293,13 +292,13 @@ public class DefaultCalculatedFieldProcessingService implements CalculatedFieldP if (value.getRefEntityId() != null) { return Futures.immediateFuture(List.of(value.getRefEntityId())); } - var refDynamicSource = value.getRefDynamicSource(); - if (refDynamicSource == null) { + if (!value.hasDynamicSource()) { return Futures.immediateFuture(List.of(entityId)); } - return switch (value.getRefDynamicSource()) { + var refDynamicSourceConfiguration = value.getRefDynamicSourceConfiguration(); + return switch (refDynamicSourceConfiguration.getType()) { case RELATION_QUERY -> { - var configuration = (RelationQueryDynamicSourceConfiguration) value.getRefDynamicSourceConfiguration(); + var configuration = (RelationQueryDynamicSourceConfiguration) refDynamicSourceConfiguration; if (configuration.isSimpleRelation()) { yield switch (configuration.getDirection()) { case FROM -> diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldCtx.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldCtx.java index 334ec18266..a5d9fe4b3a 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldCtx.java @@ -90,7 +90,7 @@ public class CalculatedFieldCtx { for (Map.Entry entry : arguments.entrySet()) { var refId = entry.getValue().getRefEntityId(); var refKey = entry.getValue().getRefEntityKey(); - if (refId == null && entry.getValue().getRefDynamicSource() != null) { + if (refId == null && entry.getValue().hasDynamicSource()) { continue; } if (refId == null || refId.equals(calculatedField.getEntityId())) { diff --git a/application/src/test/java/org/thingsboard/server/cf/CalculatedFieldIntegrationTest.java b/application/src/test/java/org/thingsboard/server/cf/CalculatedFieldIntegrationTest.java index da40cd4c5d..1980ea26cd 100644 --- a/application/src/test/java/org/thingsboard/server/cf/CalculatedFieldIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/cf/CalculatedFieldIntegrationTest.java @@ -30,7 +30,6 @@ import org.thingsboard.server.common.data.cf.CalculatedField; 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.ArgumentType; -import org.thingsboard.server.common.data.cf.configuration.CFArgumentDynamicSourceType; import org.thingsboard.server.common.data.cf.configuration.GeofencingCalculatedFieldConfiguration; import org.thingsboard.server.common.data.cf.configuration.GeofencingEvent; import org.thingsboard.server.common.data.cf.configuration.GeofencingZoneGroupConfiguration; @@ -681,7 +680,6 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes allowedZonesRefDynamicSourceConfiguration.setMaxLevel(1); allowedZonesRefDynamicSourceConfiguration.setFetchLastLevelOnly(true); allowedZones.setRefEntityKey(new ReferencedEntityKey("zone", ArgumentType.ATTRIBUTE, AttributeScope.SERVER_SCOPE)); - allowedZones.setRefDynamicSource(CFArgumentDynamicSourceType.RELATION_QUERY); allowedZones.setRefDynamicSourceConfiguration(allowedZonesRefDynamicSourceConfiguration); Argument restrictedZones = new Argument(); @@ -691,7 +689,6 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes restrictedZonesRefDynamicSourceConfiguration.setMaxLevel(1); restrictedZonesRefDynamicSourceConfiguration.setFetchLastLevelOnly(true); restrictedZones.setRefEntityKey(new ReferencedEntityKey("zone", ArgumentType.ATTRIBUTE, AttributeScope.SERVER_SCOPE)); - restrictedZones.setRefDynamicSource(CFArgumentDynamicSourceType.RELATION_QUERY); restrictedZones.setRefDynamicSourceConfiguration(restrictedZonesRefDynamicSourceConfiguration); cfg.setArguments(Map.of( diff --git a/application/src/test/java/org/thingsboard/server/service/cf/ctx/state/GeofencingCalculatedFieldStateTest.java b/application/src/test/java/org/thingsboard/server/service/cf/ctx/state/GeofencingCalculatedFieldStateTest.java index 1850efcd11..218742539c 100644 --- a/application/src/test/java/org/thingsboard/server/service/cf/ctx/state/GeofencingCalculatedFieldStateTest.java +++ b/application/src/test/java/org/thingsboard/server/service/cf/ctx/state/GeofencingCalculatedFieldStateTest.java @@ -27,7 +27,6 @@ import org.thingsboard.server.common.data.cf.CalculatedField; 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.ArgumentType; -import org.thingsboard.server.common.data.cf.configuration.CFArgumentDynamicSourceType; import org.thingsboard.server.common.data.cf.configuration.CalculatedFieldConfiguration; import org.thingsboard.server.common.data.cf.configuration.GeofencingCalculatedFieldConfiguration; import org.thingsboard.server.common.data.cf.configuration.GeofencingEvent; @@ -323,7 +322,6 @@ public class GeofencingCalculatedFieldStateTest { refDynamicSourceConfiguration3.setMaxLevel(1); refDynamicSourceConfiguration3.setFetchLastLevelOnly(true); argument3.setRefEntityKey(refEntityKey3); - argument3.setRefDynamicSource(CFArgumentDynamicSourceType.RELATION_QUERY); argument3.setRefDynamicSourceConfiguration(refDynamicSourceConfiguration3); Argument argument4 = new Argument(); @@ -334,7 +332,6 @@ public class GeofencingCalculatedFieldStateTest { refDynamicSourceConfiguration4.setMaxLevel(1); refDynamicSourceConfiguration4.setFetchLastLevelOnly(true); argument4.setRefEntityKey(refEntityKey4); - argument4.setRefDynamicSource(CFArgumentDynamicSourceType.RELATION_QUERY); argument4.setRefDynamicSourceConfiguration(refDynamicSourceConfiguration4); config.setArguments(Map.of("latitude", argument1, "longitude", argument2, "allowedZones", argument3, "restrictedZones", argument4)); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/Argument.java b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/Argument.java index 6fc8c46961..3b8ec3308a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/Argument.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/Argument.java @@ -26,7 +26,7 @@ public class Argument { @Nullable private EntityId refEntityId; - private CFArgumentDynamicSourceType refDynamicSource; + // TODO: add upgrade in PE version -> CFArgumentDynamicSourceType to CFArgumentDynamicSourceConfiguration private CfArgumentDynamicSourceConfiguration refDynamicSourceConfiguration; private ReferencedEntityKey refEntityKey; private String defaultValue; @@ -34,4 +34,8 @@ public class Argument { private Integer limit; private Long timeWindow; + public boolean hasDynamicSource() { + return refDynamicSourceConfiguration != null; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/BaseCalculatedFieldConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/BaseCalculatedFieldConfiguration.java index 7053add5a7..ef6450f5b3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/BaseCalculatedFieldConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/BaseCalculatedFieldConfiguration.java @@ -58,14 +58,10 @@ public abstract class BaseCalculatedFieldConfiguration implements CalculatedFiel return link; } - // TODO: update validate method in PE version. @Override public void validate() { - boolean hasDynamicSourceRelationQuery = arguments.values() - .stream() - .anyMatch(arg -> CFArgumentDynamicSourceType.RELATION_QUERY.equals(arg.getRefDynamicSource())); - if (hasDynamicSourceRelationQuery) { - throw new IllegalArgumentException("Calculated field with type: '" + getType() + "' doesn't support arguments with 'RELATION_QUERY' dynamic source type!"); + if (arguments.values().stream().anyMatch(Argument::hasDynamicSource)) { + throw new IllegalArgumentException("Calculated field with type: '" + getType() + "' doesn't support dynamic source configuration!"); } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/GeofencingCalculatedFieldConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/GeofencingCalculatedFieldConfiguration.java index 32cbe6baa3..39780f09a6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/GeofencingCalculatedFieldConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/GeofencingCalculatedFieldConfiguration.java @@ -27,8 +27,6 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import static org.thingsboard.server.common.data.cf.configuration.CFArgumentDynamicSourceType.RELATION_QUERY; - @Data @EqualsAndHashCode(callSuper = true) public class GeofencingCalculatedFieldConfiguration extends BaseCalculatedFieldConfiguration implements CalculatedFieldConfiguration { @@ -55,7 +53,7 @@ public class GeofencingCalculatedFieldConfiguration extends BaseCalculatedFieldC @Override public boolean isScheduledUpdateEnabled() { - return scheduledUpdateIntervalSec > 0 && arguments.values().stream().anyMatch(arg -> arg.getRefDynamicSource() != null); + return scheduledUpdateIntervalSec > 0 && arguments.values().stream().anyMatch(Argument::hasDynamicSource); } // TODO: update validate method in PE version. @@ -67,9 +65,6 @@ public class GeofencingCalculatedFieldConfiguration extends BaseCalculatedFieldC if (arguments.size() < 3) { throw new IllegalArgumentException("Geofencing calculated field must contain at least 3 arguments!"); } - if (arguments.size() > 5) { - throw new IllegalArgumentException("Geofencing calculated field size exceeds limit of 5 arguments!"); - } validateCoordinateArguments(); Map zoneGroupsArguments = getZoneGroupArguments(); @@ -129,7 +124,7 @@ public class GeofencingCalculatedFieldConfiguration extends BaseCalculatedFieldC if (!ArgumentType.TS_LATEST.equals(refEntityKey.getType())) { throw new IllegalArgumentException("Argument '" + coordinateKey + "' must be of type TS_LATEST."); } - if (argument.getRefDynamicSource() != null) { + if (argument.hasDynamicSource()) { throw new IllegalArgumentException("Dynamic source is not allowed for argument: '" + coordinateKey + "'."); } } @@ -144,17 +139,9 @@ public class GeofencingCalculatedFieldConfiguration extends BaseCalculatedFieldC if (!ArgumentType.ATTRIBUTE.equals(refEntityKey.getType())) { throw new IllegalArgumentException("Argument '" + argumentKey + "' must be of type ATTRIBUTE."); } - var dynamicSource = argument.getRefDynamicSource(); - if (dynamicSource == null) { - return; + if (argument.hasDynamicSource()) { + argument.getRefDynamicSourceConfiguration().validate(); } - if (!RELATION_QUERY.equals(dynamicSource)) { - throw new IllegalArgumentException("Only relation query dynamic source is supported for argument: '" + argumentKey + "'."); - } - if (argument.getRefDynamicSourceConfiguration() == null) { - throw new IllegalArgumentException("Missing dynamic source configuration for argument: '" + argumentKey + "'."); - } - argument.getRefDynamicSourceConfiguration().validate(); }); }