diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/geofencing/GeofencingCalculatedFieldState.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/geofencing/GeofencingCalculatedFieldState.java index 5425fbe41f..506ddcff78 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/geofencing/GeofencingCalculatedFieldState.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/geofencing/GeofencingCalculatedFieldState.java @@ -42,7 +42,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Function; import java.util.stream.Collectors; import static org.thingsboard.server.common.data.cf.configuration.geofencing.EntityCoordinates.ENTITY_ID_LATITUDE_ARGUMENT_KEY; @@ -124,10 +123,7 @@ public class GeofencingCalculatedFieldState extends BaseCalculatedFieldState { Coordinates entityCoordinates = new Coordinates(latitude, longitude); var geofencingCfg = (GeofencingCalculatedFieldConfiguration) ctx.getCalculatedField().getConfiguration(); - Map zoneGroups = geofencingCfg - .getZoneGroups() - .stream() - .collect(Collectors.toMap(ZoneGroupConfiguration::getName, Function.identity())); + Map zoneGroups = geofencingCfg.getZoneGroups(); ObjectNode resultNode = JacksonUtil.newObjectNode(); List> relationFutures = new ArrayList<>(); 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 4bf1f496ea..2ba900ba7b 100644 --- a/application/src/test/java/org/thingsboard/server/cf/CalculatedFieldIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/cf/CalculatedFieldIntegrationTest.java @@ -51,7 +51,6 @@ import org.thingsboard.server.controller.CalculatedFieldControllerTest; import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -674,7 +673,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes cfg.setEntityCoordinates(entityCoordinates); // Zone groups: ATTRIBUTE on specific assets (one zone per group) - ZoneGroupConfiguration allowedZonesGroup = new ZoneGroupConfiguration("allowedZones", "zone", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + ZoneGroupConfiguration allowedZonesGroup = new ZoneGroupConfiguration("zone", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); var allowedZoneDynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); allowedZoneDynamicSourceConfiguration.setDirection(EntitySearchDirection.FROM); allowedZoneDynamicSourceConfiguration.setRelationType("AllowedZone"); @@ -682,7 +681,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes allowedZoneDynamicSourceConfiguration.setFetchLastLevelOnly(true); allowedZonesGroup.setRefDynamicSourceConfiguration(allowedZoneDynamicSourceConfiguration); - ZoneGroupConfiguration restrictedZonesGroup = new ZoneGroupConfiguration("restrictedZones", "zone", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + ZoneGroupConfiguration restrictedZonesGroup = new ZoneGroupConfiguration("zone", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); var restrictedZoneDynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); restrictedZoneDynamicSourceConfiguration.setDirection(EntitySearchDirection.FROM); restrictedZoneDynamicSourceConfiguration.setRelationType("RestrictedZone"); @@ -690,7 +689,7 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes restrictedZoneDynamicSourceConfiguration.setFetchLastLevelOnly(true); restrictedZonesGroup.setRefDynamicSourceConfiguration(restrictedZoneDynamicSourceConfiguration); - cfg.setZoneGroups(List.of(allowedZonesGroup, restrictedZonesGroup)); + cfg.setZoneGroups(Map.of("allowedZones", allowedZonesGroup, "restrictedZones", restrictedZonesGroup)); // Output to server attributes Output out = new Output(); @@ -783,14 +782,14 @@ public class CalculatedFieldIntegrationTest extends CalculatedFieldControllerTes GeofencingCalculatedFieldConfiguration cfg = new GeofencingCalculatedFieldConfiguration(); cfg.setEntityCoordinates(new EntityCoordinates(ENTITY_ID_LATITUDE_ARGUMENT_KEY, ENTITY_ID_LONGITUDE_ARGUMENT_KEY)); - var allowedZonesGroup = new ZoneGroupConfiguration("allowedZones", "zone", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + var allowedZonesGroup = new ZoneGroupConfiguration("zone", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); var allowedZoneDynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); allowedZoneDynamicSourceConfiguration.setDirection(EntitySearchDirection.FROM); allowedZoneDynamicSourceConfiguration.setRelationType("AllowedZone"); allowedZoneDynamicSourceConfiguration.setMaxLevel(1); allowedZoneDynamicSourceConfiguration.setFetchLastLevelOnly(true); allowedZonesGroup.setRefDynamicSourceConfiguration(allowedZoneDynamicSourceConfiguration); - cfg.setZoneGroups(List.of(allowedZonesGroup)); + cfg.setZoneGroups(Map.of("allowedZones", allowedZonesGroup)); // Server attributes output Output out = new Output(); 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 596f9f7b33..691a1f7ec4 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 @@ -452,7 +452,7 @@ public class GeofencingCalculatedFieldStateTest { EntityCoordinates entityCoordinates = new EntityCoordinates("latitude", "longitude"); config.setEntityCoordinates(entityCoordinates); - ZoneGroupConfiguration allowedZonesGroup = new ZoneGroupConfiguration("allowedZones", "zone", reportStrategy, true); + ZoneGroupConfiguration allowedZonesGroup = new ZoneGroupConfiguration("zone", reportStrategy, true); var allowedZoneDynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); allowedZoneDynamicSourceConfiguration.setDirection(EntitySearchDirection.TO); allowedZoneDynamicSourceConfiguration.setRelationType("AllowedZone"); @@ -462,7 +462,7 @@ public class GeofencingCalculatedFieldStateTest { allowedZonesGroup.setRelationType("CurrentZone"); allowedZonesGroup.setDirection(EntitySearchDirection.TO); - ZoneGroupConfiguration restrictedZonesGroup = new ZoneGroupConfiguration("restrictedZones", "zone", reportStrategy, true); + ZoneGroupConfiguration restrictedZonesGroup = new ZoneGroupConfiguration("zone", reportStrategy, true); var restrictedZoneDynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); restrictedZoneDynamicSourceConfiguration.setDirection(EntitySearchDirection.TO); restrictedZoneDynamicSourceConfiguration.setRelationType("RestrictedZone"); @@ -472,7 +472,7 @@ public class GeofencingCalculatedFieldStateTest { restrictedZonesGroup.setRelationType("CurrentZone"); restrictedZonesGroup.setDirection(EntitySearchDirection.TO); - config.setZoneGroups(List.of(allowedZonesGroup, restrictedZonesGroup)); + config.setZoneGroups(Map.of("allowedZones", allowedZonesGroup, "restrictedZones", restrictedZonesGroup)); Output output = new Output(); output.setType(OutputType.TIME_SERIES); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/geofencing/GeofencingCalculatedFieldConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/geofencing/GeofencingCalculatedFieldConfiguration.java index a3fdea3390..dc331f5876 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/geofencing/GeofencingCalculatedFieldConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/geofencing/GeofencingCalculatedFieldConfiguration.java @@ -25,17 +25,15 @@ import org.thingsboard.server.common.data.cf.configuration.ScheduledUpdateSuppor import org.thingsboard.server.common.data.id.EntityId; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; @Data public class GeofencingCalculatedFieldConfiguration implements ArgumentsBasedCalculatedFieldConfiguration, ScheduledUpdateSupportedCalculatedFieldConfiguration { private EntityCoordinates entityCoordinates; - private List zoneGroups; + private Map zoneGroups; private int scheduledUpdateInterval; private Output output; @@ -49,13 +47,13 @@ public class GeofencingCalculatedFieldConfiguration implements ArgumentsBasedCal @JsonIgnore public Map getArguments() { Map args = new HashMap<>(entityCoordinates.toArguments()); - zoneGroups.forEach(zg -> args.put(zg.getName(), zg.toArgument())); + zoneGroups.forEach((zgName, zgConfig) -> args.put(zgName, zgConfig.toArgument())); return args; } @Override public List getReferencedEntities() { - return zoneGroups.stream().map(ZoneGroupConfiguration::getRefEntityId).filter(Objects::nonNull).toList(); + return zoneGroups.values().stream().map(ZoneGroupConfiguration::getRefEntityId).filter(Objects::nonNull).toList(); } @Override @@ -65,7 +63,7 @@ public class GeofencingCalculatedFieldConfiguration implements ArgumentsBasedCal @Override public boolean isScheduledUpdateEnabled() { - return scheduledUpdateInterval > 0 && zoneGroups.stream().anyMatch(ZoneGroupConfiguration::hasDynamicSource); + return scheduledUpdateInterval > 0 && zoneGroups.values().stream().anyMatch(ZoneGroupConfiguration::hasDynamicSource); } @Override @@ -73,17 +71,11 @@ public class GeofencingCalculatedFieldConfiguration implements ArgumentsBasedCal if (entityCoordinates == null) { throw new IllegalArgumentException("Geofencing calculated field entity coordinates must be specified!"); } + entityCoordinates.validate(); if (zoneGroups == null || zoneGroups.isEmpty()) { throw new IllegalArgumentException("Geofencing calculated field must contain at least one geofencing zone group defined!"); } - entityCoordinates.validate(); - Set seen = new HashSet<>(); - for (var zg : zoneGroups) { - if (!seen.add(zg.getName())) { - throw new IllegalArgumentException("Geofencing calculated field zone group name must be unique!"); - } - zg.validate(); - } + zoneGroups.forEach((key, value) -> value.validate(key)); } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/geofencing/ZoneGroupConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/geofencing/ZoneGroupConfiguration.java index 7ac87db10d..43997c23fa 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/geofencing/ZoneGroupConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/geofencing/ZoneGroupConfiguration.java @@ -35,7 +35,6 @@ public class ZoneGroupConfiguration { private EntityId refEntityId; private CfArgumentDynamicSourceConfiguration refDynamicSourceConfiguration; - private final String name; private final String perimeterKeyName; private final GeofencingReportStrategy reportStrategy; @@ -44,10 +43,7 @@ public class ZoneGroupConfiguration { private String relationType; private EntitySearchDirection direction; - public void validate() { - if (StringUtils.isBlank(name)) { - throw new IllegalArgumentException("Zone group name must be specified!"); - } + public void validate(String name) { if (EntityCoordinates.ENTITY_ID_LATITUDE_ARGUMENT_KEY.equals(name) || EntityCoordinates.ENTITY_ID_LONGITUDE_ARGUMENT_KEY.equals(name)) { throw new IllegalArgumentException("Name '" + name + "' is reserved and cannot be used for zone group!"); } diff --git a/common/data/src/test/java/org/thingsboard/server/common/data/cf/configuration/geofencing/GeofencingCalculatedFieldConfigurationTest.java b/common/data/src/test/java/org/thingsboard/server/common/data/cf/configuration/geofencing/GeofencingCalculatedFieldConfigurationTest.java index 3997ad2404..91a47aac57 100644 --- a/common/data/src/test/java/org/thingsboard/server/common/data/cf/configuration/geofencing/GeofencingCalculatedFieldConfigurationTest.java +++ b/common/data/src/test/java/org/thingsboard/server/common/data/cf/configuration/geofencing/GeofencingCalculatedFieldConfigurationTest.java @@ -73,12 +73,12 @@ public class GeofencingCalculatedFieldConfigurationTest { EntityCoordinates entityCoordinatesMock = mock(EntityCoordinates.class); cfg.setEntityCoordinates(entityCoordinatesMock); var zoneGroupConfiguration = mock(ZoneGroupConfiguration.class); - cfg.setZoneGroups(List.of(zoneGroupConfiguration)); + cfg.setZoneGroups(Map.of("someGroupName", zoneGroupConfiguration)); cfg.validate(); verify(entityCoordinatesMock).validate(); - verify(zoneGroupConfiguration).validate(); + verify(zoneGroupConfiguration).validate("someGroupName"); } @Test @@ -89,38 +89,16 @@ public class GeofencingCalculatedFieldConfigurationTest { var zoneGroupConfigurationA = mock(ZoneGroupConfiguration.class); var zoneGroupConfigurationB = mock(ZoneGroupConfiguration.class); - when(zoneGroupConfigurationA.getName()).thenReturn("zoneGroupA"); - when(zoneGroupConfigurationB.getName()).thenReturn("zoneGroupB"); + String zoneGroupAName = "zoneGroupA"; + String zoneGroupBName = "zoneGroupB"; - cfg.setZoneGroups(List.of(zoneGroupConfigurationA, zoneGroupConfigurationB)); + cfg.setZoneGroups(Map.of("zoneGroupA", zoneGroupConfigurationA, "zoneGroupB", zoneGroupConfigurationB)); assertThatCode(cfg::validate).doesNotThrowAnyException(); verify(entityCoordinatesMock).validate(); - verify(zoneGroupConfigurationA).validate(); - verify(zoneGroupConfigurationB).validate(); - } - - @Test - void validateShouldThrowWhenZoneGroupNamesDuplicated() { - var cfg = new GeofencingCalculatedFieldConfiguration(); - EntityCoordinates entityCoordinatesMock = mock(EntityCoordinates.class); - cfg.setEntityCoordinates(entityCoordinatesMock); - var zoneGroupConfigurationA = mock(ZoneGroupConfiguration.class); - var zoneGroupConfigurationB = mock(ZoneGroupConfiguration.class); - - when(zoneGroupConfigurationA.getName()).thenReturn("zoneGroupDuplicated"); - when(zoneGroupConfigurationB.getName()).thenReturn("zoneGroupDuplicated"); - - cfg.setZoneGroups(List.of(zoneGroupConfigurationA, zoneGroupConfigurationB)); - - assertThatThrownBy(cfg::validate) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Geofencing calculated field zone group name must be unique!"); - - verify(entityCoordinatesMock).validate(); - verify(zoneGroupConfigurationA).validate(); - verify(zoneGroupConfigurationB, never()).validate(); + verify(zoneGroupConfigurationA).validate(zoneGroupAName); + verify(zoneGroupConfigurationB).validate(zoneGroupBName); } @Test @@ -135,7 +113,7 @@ public class GeofencingCalculatedFieldConfigurationTest { var cfg = new GeofencingCalculatedFieldConfiguration(); var zoneGroupConfigurationMock = mock(ZoneGroupConfiguration.class); when(zoneGroupConfigurationMock.hasDynamicSource()).thenReturn(false); - cfg.setZoneGroups(List.of(zoneGroupConfigurationMock)); + cfg.setZoneGroups(Map.of("someGroupName", zoneGroupConfigurationMock)); cfg.setScheduledUpdateInterval(60); assertThat(cfg.isScheduledUpdateEnabled()).isFalse(); } @@ -145,7 +123,7 @@ public class GeofencingCalculatedFieldConfigurationTest { var cfg = new GeofencingCalculatedFieldConfiguration(); var zoneGroupConfigurationMock = mock(ZoneGroupConfiguration.class); when(zoneGroupConfigurationMock.hasDynamicSource()).thenReturn(true); - cfg.setZoneGroups(List.of(zoneGroupConfigurationMock)); + cfg.setZoneGroups(Map.of("someGroupName", zoneGroupConfigurationMock)); cfg.setScheduledUpdateInterval(60); assertThat(cfg.isScheduledUpdateEnabled()).isTrue(); } @@ -154,7 +132,7 @@ public class GeofencingCalculatedFieldConfigurationTest { void testGetArgumentsOverride() { var cfg = new GeofencingCalculatedFieldConfiguration(); cfg.setEntityCoordinates(new EntityCoordinates(ENTITY_ID_LATITUDE_ARGUMENT_KEY, ENTITY_ID_LONGITUDE_ARGUMENT_KEY)); - cfg.setZoneGroups(List.of(new ZoneGroupConfiguration("allowedZones", "perimeter", GeofencingReportStrategy.REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false))); + cfg.setZoneGroups(Map.of("allowedZones", new ZoneGroupConfiguration("perimeter", GeofencingReportStrategy.REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false))); Map arguments = cfg.getArguments(); diff --git a/common/data/src/test/java/org/thingsboard/server/common/data/cf/configuration/geofencing/ZoneGroupConfigurationTest.java b/common/data/src/test/java/org/thingsboard/server/common/data/cf/configuration/geofencing/ZoneGroupConfigurationTest.java index 988995ddbe..4eb822d93c 100644 --- a/common/data/src/test/java/org/thingsboard/server/common/data/cf/configuration/geofencing/ZoneGroupConfigurationTest.java +++ b/common/data/src/test/java/org/thingsboard/server/common/data/cf/configuration/geofencing/ZoneGroupConfigurationTest.java @@ -35,21 +35,11 @@ import static org.thingsboard.server.common.data.cf.configuration.geofencing.Geo public class ZoneGroupConfigurationTest { - @ParameterizedTest - @ValueSource(strings = " ") - @NullAndEmptySource - void validateShouldThrowWhenNameIsNullEmptyOrBlank(String name) { - var zoneGroupConfiguration = new ZoneGroupConfiguration(name, "perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); - assertThatThrownBy(zoneGroupConfiguration::validate) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Zone group name must be specified!"); - } - @ParameterizedTest @ValueSource(strings = {EntityCoordinates.ENTITY_ID_LATITUDE_ARGUMENT_KEY, EntityCoordinates.ENTITY_ID_LONGITUDE_ARGUMENT_KEY}) void validateShouldThrowWhenUsedReservedEntityCoordinateNames(String name) { - var zoneGroupConfiguration = new ZoneGroupConfiguration(name, "perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); - assertThatThrownBy(zoneGroupConfiguration::validate) + var zoneGroupConfiguration = new ZoneGroupConfiguration("perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + assertThatThrownBy(() -> zoneGroupConfiguration.validate(name)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Name '" + name + "' is reserved and cannot be used for zone group!"); } @@ -58,16 +48,16 @@ public class ZoneGroupConfigurationTest { @ValueSource(strings = " ") @NullAndEmptySource void validateShouldThrowWhenPerimeterKeyNameIsNullEmptyOrBlank(String perimeterKeyName) { - var zoneGroupConfiguration = new ZoneGroupConfiguration("allowedZonesGroup", perimeterKeyName, REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); - assertThatThrownBy(zoneGroupConfiguration::validate) + var zoneGroupConfiguration = new ZoneGroupConfiguration(perimeterKeyName, REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + assertThatThrownBy(() -> zoneGroupConfiguration.validate("allowedZonesGroup")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Perimeter key name must be specified for 'allowedZonesGroup' zone group!"); } @Test void validateShouldThrowWhenReportStrategyIsNull() { - var zoneGroupConfiguration = new ZoneGroupConfiguration("allowedZonesGroup", "perimeter", null, false); - assertThatThrownBy(zoneGroupConfiguration::validate) + var zoneGroupConfiguration = new ZoneGroupConfiguration("perimeter", null, false); + assertThatThrownBy(() -> zoneGroupConfiguration.validate("allowedZonesGroup")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Report strategy must be specified for 'allowedZonesGroup' zone group!"); } @@ -76,40 +66,40 @@ public class ZoneGroupConfigurationTest { @ValueSource(strings = " ") @NullAndEmptySource void validateShouldThrowWhenRelationCreationEnabledAndRelationTypeIsNullEmptyOrBlank(String relationType) { - var zoneGroupConfiguration = new ZoneGroupConfiguration("allowedZonesGroup", "perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, true); + var zoneGroupConfiguration = new ZoneGroupConfiguration("perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, true); zoneGroupConfiguration.setRelationType(relationType); - assertThatThrownBy(zoneGroupConfiguration::validate) + assertThatThrownBy(() -> zoneGroupConfiguration.validate("allowedZonesGroup")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Relation type must be specified for 'allowedZonesGroup' zone group!"); } @Test void validateShouldThrowWhenRelationCreationEnabledAndDirectionIsNull() { - var zoneGroupConfiguration = new ZoneGroupConfiguration("allowedZonesGroup", "perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, true); + var zoneGroupConfiguration = new ZoneGroupConfiguration("perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, true); zoneGroupConfiguration.setRelationType(EntityRelation.CONTAINS_TYPE); zoneGroupConfiguration.setDirection(null); - assertThatThrownBy(zoneGroupConfiguration::validate) + assertThatThrownBy(() -> zoneGroupConfiguration.validate("allowedZonesGroup")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Relation direction must be specified for 'allowedZonesGroup' zone group!"); } @Test void validateShouldDoesNotThrowAnyExceptionWhenRelationCreationDisabledAndConfigValid() { - var zoneGroupConfiguration = new ZoneGroupConfiguration("allowedZonesGroup", "perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); - assertThatCode(zoneGroupConfiguration::validate).doesNotThrowAnyException(); + var zoneGroupConfiguration = new ZoneGroupConfiguration("perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + assertThatCode(() -> zoneGroupConfiguration.validate("allowedZonesGroup")).doesNotThrowAnyException(); } @Test void validateShouldDoesNotThrowAnyExceptionWhenRelationCreationEnabledAndConfigValid() { - var zoneGroupConfiguration = new ZoneGroupConfiguration("allowedZonesGroup", "perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, true); + var zoneGroupConfiguration = new ZoneGroupConfiguration("perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, true); zoneGroupConfiguration.setRelationType(EntityRelation.CONTAINS_TYPE); zoneGroupConfiguration.setDirection(EntitySearchDirection.TO); - assertThatCode(zoneGroupConfiguration::validate).doesNotThrowAnyException(); + assertThatCode(() -> zoneGroupConfiguration.validate("allowedZonesGroup")).doesNotThrowAnyException(); } @Test void whenHasDynamicSourceCalled_shouldReturnTrueIfDynamicSourceConfigurationIsNotNull() { - var zoneGroupConfiguration = new ZoneGroupConfiguration("allowedZonesGroup", "perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + var zoneGroupConfiguration = new ZoneGroupConfiguration("perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); zoneGroupConfiguration.setRefDynamicSourceConfiguration(new RelationQueryDynamicSourceConfiguration()); assertThat(zoneGroupConfiguration.hasDynamicSource()).isTrue(); } @@ -124,7 +114,7 @@ public class ZoneGroupConfigurationTest { @Test void validateToArgumentsMethodCallWithoutRefEntityId() { - var zoneGroupConfiguration = new ZoneGroupConfiguration("allowedZonesGroup", "perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + var zoneGroupConfiguration = new ZoneGroupConfiguration("perimeter", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); Argument zoneGroupArgument = zoneGroupConfiguration.toArgument(); assertThat(zoneGroupArgument).isNotNull(); assertThat(zoneGroupArgument.getRefEntityKey()).isEqualTo(new ReferencedEntityKey("perimeter", ArgumentType.ATTRIBUTE, AttributeScope.SERVER_SCOPE)); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/CalculatedFieldServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/CalculatedFieldServiceTest.java index 9783602086..49bdcca0fb 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/CalculatedFieldServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/CalculatedFieldServiceTest.java @@ -44,7 +44,6 @@ import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; -import java.util.List; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -112,9 +111,9 @@ public class CalculatedFieldServiceTest extends AbstractServiceTest { cfg.setEntityCoordinates(entityCoordinates); // Zone-group argument (ATTRIBUTE) — no DYNAMIC configuration, so no scheduling even if the scheduled interval is set - ZoneGroupConfiguration zoneGroupConfiguration = new ZoneGroupConfiguration("allowed", "allowed", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + ZoneGroupConfiguration zoneGroupConfiguration = new ZoneGroupConfiguration("allowed", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); zoneGroupConfiguration.setRefEntityId(device.getId()); - cfg.setZoneGroups(List.of(zoneGroupConfiguration)); + cfg.setZoneGroups(Map.of("allowed", zoneGroupConfiguration)); // Set a scheduled interval to some value cfg.setScheduledUpdateInterval(600); @@ -158,13 +157,13 @@ public class CalculatedFieldServiceTest extends AbstractServiceTest { cfg.setEntityCoordinates(entityCoordinates); // Zone-group argument (ATTRIBUTE) — make it DYNAMIC so scheduling is enabled - ZoneGroupConfiguration zoneGroupConfiguration = new ZoneGroupConfiguration("allowed", "allowed", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + ZoneGroupConfiguration zoneGroupConfiguration = new ZoneGroupConfiguration("allowed", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); var dynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); dynamicSourceConfiguration.setDirection(EntitySearchDirection.FROM); dynamicSourceConfiguration.setMaxLevel(1); dynamicSourceConfiguration.setRelationType(EntityRelation.CONTAINS_TYPE); zoneGroupConfiguration.setRefDynamicSourceConfiguration(dynamicSourceConfiguration); - cfg.setZoneGroups(List.of(zoneGroupConfiguration)); + cfg.setZoneGroups(Map.of("allowed", zoneGroupConfiguration)); // Enable scheduling with an interval below tenant min cfg.setScheduledUpdateInterval(600); @@ -198,13 +197,13 @@ public class CalculatedFieldServiceTest extends AbstractServiceTest { cfg.setEntityCoordinates(entityCoordinates); // Zone-group argument (ATTRIBUTE) — make it DYNAMIC so scheduling is enabled - ZoneGroupConfiguration zoneGroupConfiguration = new ZoneGroupConfiguration("allowed", "allowed", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + ZoneGroupConfiguration zoneGroupConfiguration = new ZoneGroupConfiguration( "allowed", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); var dynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); dynamicSourceConfiguration.setDirection(EntitySearchDirection.FROM); dynamicSourceConfiguration.setMaxLevel(Integer.MAX_VALUE); dynamicSourceConfiguration.setRelationType(EntityRelation.CONTAINS_TYPE); zoneGroupConfiguration.setRefDynamicSourceConfiguration(dynamicSourceConfiguration); - cfg.setZoneGroups(List.of(zoneGroupConfiguration)); + cfg.setZoneGroups(Map.of("allowed", zoneGroupConfiguration)); // Create & save Calculated Field CalculatedField cf = new CalculatedField(); @@ -234,13 +233,13 @@ public class CalculatedFieldServiceTest extends AbstractServiceTest { cfg.setEntityCoordinates(entityCoordinates); // Zone-group argument (ATTRIBUTE) — make it DYNAMIC so scheduling is enabled - ZoneGroupConfiguration zoneGroupConfiguration = new ZoneGroupConfiguration("allowed", "allowed", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + ZoneGroupConfiguration zoneGroupConfiguration = new ZoneGroupConfiguration( "allowed", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); var dynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); dynamicSourceConfiguration.setDirection(EntitySearchDirection.FROM); dynamicSourceConfiguration.setMaxLevel(1); dynamicSourceConfiguration.setRelationType(EntityRelation.CONTAINS_TYPE); zoneGroupConfiguration.setRefDynamicSourceConfiguration(dynamicSourceConfiguration); - cfg.setZoneGroups(List.of(zoneGroupConfiguration)); + cfg.setZoneGroups(Map.of("allowed", zoneGroupConfiguration)); // Get tenant profile min. int min = tbTenantProfileCache.get(tenantId) diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/cf/CalculatedFieldTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/cf/CalculatedFieldTest.java index 1693ee2763..7f2dfba937 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/cf/CalculatedFieldTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/cf/CalculatedFieldTest.java @@ -54,7 +54,6 @@ import org.thingsboard.server.msa.AbstractContainerTest; import org.thingsboard.server.msa.ui.utils.EntityPrototypes; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -366,7 +365,7 @@ public class CalculatedFieldTest extends AbstractContainerTest { cfg.setEntityCoordinates(entityCoordinates); // Dynamic groups via relations - ZoneGroupConfiguration allowedZoneGroupConfiguration = new ZoneGroupConfiguration("allowedZones", "zone", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + ZoneGroupConfiguration allowedZoneGroupConfiguration = new ZoneGroupConfiguration("zone", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); var allowedDynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); allowedDynamicSourceConfiguration.setDirection(EntitySearchDirection.FROM); allowedDynamicSourceConfiguration.setMaxLevel(1); @@ -374,7 +373,7 @@ public class CalculatedFieldTest extends AbstractContainerTest { allowedDynamicSourceConfiguration.setRelationType("AllowedZone"); allowedZoneGroupConfiguration.setRefDynamicSourceConfiguration(allowedDynamicSourceConfiguration); - ZoneGroupConfiguration restrictedZoneGroupConfiguration = new ZoneGroupConfiguration("restrictedZones", "zone", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); + ZoneGroupConfiguration restrictedZoneGroupConfiguration = new ZoneGroupConfiguration("zone", REPORT_TRANSITION_EVENTS_AND_PRESENCE_STATUS, false); var restrictedDynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); restrictedDynamicSourceConfiguration.setDirection(EntitySearchDirection.FROM); restrictedDynamicSourceConfiguration.setMaxLevel(1); @@ -382,7 +381,7 @@ public class CalculatedFieldTest extends AbstractContainerTest { restrictedDynamicSourceConfiguration.setRelationType("RestrictedZone"); restrictedZoneGroupConfiguration.setRefDynamicSourceConfiguration(restrictedDynamicSourceConfiguration); - cfg.setZoneGroups(List.of(allowedZoneGroupConfiguration, restrictedZoneGroupConfiguration)); + cfg.setZoneGroups(Map.of("allowedZones", allowedZoneGroupConfiguration, "restrictedZones", restrictedZoneGroupConfiguration)); Output out = new Output(); out.setType(OutputType.ATTRIBUTES);