From d6027bc5799a0f70081d73c45779cf84738a0915 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Tue, 18 Mar 2025 13:26:35 +0200 Subject: [PATCH 1/9] cf fixes --- .../CalculatedFieldManagerMessageProcessor.java | 9 +++++---- .../thingsboard/server/actors/tenant/TenantActor.java | 7 ++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java index fc48e9ad3e..f8c17bf84b 100644 --- a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java @@ -56,7 +56,6 @@ import java.util.concurrent.CopyOnWriteArrayList; import static org.thingsboard.server.utils.CalculatedFieldUtils.fromProto; - /** * @author Andrew Shvayka */ @@ -93,7 +92,7 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware } public void onFieldInitMsg(CalculatedFieldInitMsg msg) throws CalculatedFieldException { - log.info("[{}] Processing CF init message.", msg.getCf().getId()); + log.debug("[{}] Processing CF init message.", msg.getCf().getId()); var cf = msg.getCf(); var cfCtx = new CalculatedFieldCtx(cf, systemContext.getTbelInvokeService(), systemContext.getApiLimitService()); try { @@ -109,7 +108,7 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware } public void onLinkInitMsg(CalculatedFieldLinkInitMsg msg) { - log.info("[{}] Processing CF link init message for entity [{}].", msg.getLink().getCalculatedFieldId(), msg.getLink().getEntityId()); + log.debug("[{}] Processing CF link init message for entity [{}].", msg.getLink().getCalculatedFieldId(), msg.getLink().getEntityId()); var link = msg.getLink(); // We use copy on write lists to safely pass the reference to another actor for the iteration. // Alternative approach would be to use any list but avoid modifications to the list (change the complete map value instead) @@ -122,7 +121,9 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware var calculatedField = calculatedFields.get(cfId); if (calculatedField != null) { - msg.getState().setRequiredArguments(calculatedField.getArgNames()); + if (msg.getState() != null) { + msg.getState().setRequiredArguments(calculatedField.getArgNames()); + } log.debug("Pushing CF state restore msg to specific actor [{}]", msg.getId().entityId()); getOrCreateActor(msg.getId().entityId()).tell(msg); } else { diff --git a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java index 846bde508d..49994eaa1f 100644 --- a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java @@ -28,6 +28,7 @@ import org.thingsboard.server.actors.TbEntityActorId; import org.thingsboard.server.actors.TbEntityTypeActorIdPredicate; import org.thingsboard.server.actors.TbStringActorId; import org.thingsboard.server.actors.calculatedField.CalculatedFieldManagerActorCreator; +import org.thingsboard.server.actors.calculatedField.CalculatedFieldStateRestoreMsg; import org.thingsboard.server.actors.device.DeviceActorCreator; import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor; import org.thingsboard.server.actors.service.ContextBasedCreator; @@ -190,7 +191,11 @@ public class TenantActor extends RuleChainManagerActor { private void onToCalculatedFieldSystemActorMsg(ToCalculatedFieldSystemMsg msg, boolean priority) { if (cfActor == null) { - log.warn("[{}] CF Actor is not initialized.", tenantId); + if (msg instanceof CalculatedFieldStateRestoreMsg) { + log.warn("[{}] CF Actor is not initialized. ToCalculatedFieldSystemMsg: [{}]", tenantId, msg); + } else { + log.debug("[{}] CF Actor is not initialized. ToCalculatedFieldSystemMsg: [{}]", tenantId, msg); + } return; } if (priority) { From 5a5d1e2710c4115e8be82ccf18d2dc979d6842c3 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Tue, 18 Mar 2025 15:43:14 +0200 Subject: [PATCH 2/9] added implementation for cf notification producer --- .../server/queue/provider/TbRuleEngineProducerProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java index dcadf02d02..d3b507910a 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java @@ -50,6 +50,7 @@ public class TbRuleEngineProducerProvider implements TbQueueProducerProvider { private TbQueueProducer> toEdgeNotifications; private TbQueueProducer> toEdgeEvents; private TbQueueProducer> toCalculatedFields; + private TbQueueProducer> toCalculatedFieldNotifications; public TbRuleEngineProducerProvider(TbRuleEngineQueueFactory tbQueueProvider) { this.tbQueueProvider = tbQueueProvider; @@ -132,7 +133,7 @@ public class TbRuleEngineProducerProvider implements TbQueueProducerProvider { @Override public TbQueueProducer> getCalculatedFieldsNotificationsMsgProducer() { - throw new RuntimeException("Not Implemented! Should not be used by Rule Engine Service!"); + return toCalculatedFieldNotifications; } } From f88be5b86355ef6d51789a27f1b0e275a1e4e913 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Wed, 19 Mar 2025 15:07:48 +0200 Subject: [PATCH 3/9] added impl for cf notification producer --- .../DefaultTbCalculatedFieldConsumerService.java | 2 +- .../queue/provider/InMemoryMonolithQueueFactory.java | 2 +- .../queue/provider/KafkaMonolithQueueFactory.java | 2 +- .../provider/KafkaTbRuleEngineQueueFactory.java | 12 +++++++++++- .../queue/provider/TbRuleEngineProducerProvider.java | 1 + .../queue/provider/TbRuleEngineQueueFactory.java | 4 +++- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCalculatedFieldConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCalculatedFieldConsumerService.java index fe42684b2b..c91441347b 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCalculatedFieldConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCalculatedFieldConsumerService.java @@ -214,7 +214,7 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer @Override protected TbQueueConsumer> createNotificationsConsumer() { - return queueFactory.createToCalculatedFieldNotificationsMsgConsumer(); + return queueFactory.createToCalculatedFieldNotificationMsgConsumer(); } @Override diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java index e97af10ecc..b29a501c0e 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java @@ -144,7 +144,7 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE } @Override - public TbQueueConsumer> createToCalculatedFieldNotificationsMsgConsumer() { + public TbQueueConsumer> createToCalculatedFieldNotificationMsgConsumer() { return new InMemoryTbQueueConsumer<>(storage, topicService.getCalculatedFieldNotificationsTopic(serviceInfoProvider.getServiceId()).getFullTopicName()); } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java index f3d1e2d158..5d3d58cd46 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java @@ -537,7 +537,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi } @Override - public TbQueueConsumer> createToCalculatedFieldNotificationsMsgConsumer() { + public TbQueueConsumer> createToCalculatedFieldNotificationMsgConsumer() { TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> consumerBuilder = TbKafkaConsumerTemplate.builder(); consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(topicService.getCalculatedFieldNotificationsTopic(serviceInfoProvider.getServiceId()).getFullTopicName()); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java index 43fbb5efeb..3bdbfd2851 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java @@ -332,7 +332,7 @@ public class KafkaTbRuleEngineQueueFactory implements TbRuleEngineQueueFactory { } @Override - public TbQueueConsumer> createToCalculatedFieldNotificationsMsgConsumer() { + public TbQueueConsumer> createToCalculatedFieldNotificationMsgConsumer() { TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> consumerBuilder = TbKafkaConsumerTemplate.builder(); consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(topicService.getCalculatedFieldNotificationsTopic(serviceInfoProvider.getServiceId()).getFullTopicName()); @@ -344,6 +344,16 @@ public class KafkaTbRuleEngineQueueFactory implements TbRuleEngineQueueFactory { return consumerBuilder.build(); } + @Override + public TbQueueProducer> createToCalculatedFieldNotificationMsgProducer() { + TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder> requestBuilder = TbKafkaProducerTemplate.builder(); + requestBuilder.settings(kafkaSettings); + requestBuilder.clientId("tb-calculated-field-notifications-producer-" + serviceInfoProvider.getServiceId()); + requestBuilder.defaultTopic(topicService.getCalculatedFieldNotificationsTopic(serviceInfoProvider.getServiceId()).getFullTopicName()); + requestBuilder.admin(notificationAdmin); + return requestBuilder.build(); + } + @Override public TbQueueConsumer> createCalculatedFieldStateConsumer() { return TbKafkaConsumerTemplate.>builder() diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java index d3b507910a..8e1952fc14 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java @@ -69,6 +69,7 @@ public class TbRuleEngineProducerProvider implements TbQueueProducerProvider { this.toEdgeNotifications = tbQueueProvider.createEdgeNotificationsMsgProducer(); this.toEdgeEvents = tbQueueProvider.createEdgeEventMsgProducer(); this.toCalculatedFields = tbQueueProvider.createToCalculatedFieldMsgProducer(); + this.toCalculatedFieldNotifications = tbQueueProvider.createToCalculatedFieldNotificationMsgProducer(); } @Override diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineQueueFactory.java index 767fea9f0c..ad8ace6b6c 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineQueueFactory.java @@ -124,7 +124,9 @@ public interface TbRuleEngineQueueFactory extends TbUsageStatsClientQueueFactory TbQueueProducer> createToCalculatedFieldMsgProducer(); - TbQueueConsumer> createToCalculatedFieldNotificationsMsgConsumer(); + TbQueueConsumer> createToCalculatedFieldNotificationMsgConsumer(); + + TbQueueProducer> createToCalculatedFieldNotificationMsgProducer(); TbQueueConsumer> createCalculatedFieldStateConsumer(); From 705265c3036455f9aecf829174d9cd0361ca7744 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Wed, 19 Mar 2025 17:09:01 +0200 Subject: [PATCH 4/9] added test --- .../server/msa/cf/CalculatedFieldTest.java | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) 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 63faed41ab..2593e18a55 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 @@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.cf.configuration.ArgumentType; import org.thingsboard.server.common.data.cf.configuration.Output; import org.thingsboard.server.common.data.cf.configuration.OutputType; import org.thingsboard.server.common.data.cf.configuration.ReferencedEntityKey; +import org.thingsboard.server.common.data.cf.configuration.ScriptCalculatedFieldConfiguration; import org.thingsboard.server.common.data.cf.configuration.SimpleCalculatedFieldConfiguration; import org.thingsboard.server.common.data.debug.DebugSettings; import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration; @@ -73,7 +74,7 @@ public class CalculatedFieldTest extends AbstractContainerTest { " var airDensity = pressure / (287.05 * temperatureK);\n" + "\n" + " return {\n" + - " \"airDensity\": airDensity\n" + + " \"airDensity\": toFixed(airDensity, 2)\n" + " };"; private TenantId tenantId; @@ -280,6 +281,34 @@ public class CalculatedFieldTest extends AbstractContainerTest { testRestClient.deleteCalculatedFieldIfExists(savedCalculatedField.getId()); } + @Test + public void testEntityIdIsProfileAndRefEntityIsCommon() { + // login tenant admin + testRestClient.getAndSetUserToken(tenantAdminId); + + CalculatedField savedCalculatedField = createScriptCalculatedField(deviceProfileId); + + await().alias("create CF -> perform initial calculation for device by profile").atMost(TIMEOUT, TimeUnit.SECONDS) + .pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) + .untilAsserted(() -> { + JsonNode airDensity = testRestClient.getLatestTelemetry(device.getId()); + assertThat(airDensity).isNotNull(); + assertThat(airDensity.get("airDensity").get(0).get("value").asText()).isEqualTo("1.05"); + }); + + testRestClient.postTelemetryAttribute(asset.getId(), DataConstants.SERVER_SCOPE, JacksonUtil.toJsonNode("{\"altitude\":1531}")); + + await().alias("create CF -> update telemetry for common entity").atMost(TIMEOUT, TimeUnit.SECONDS) + .pollInterval(POLL_INTERVAL, TimeUnit.SECONDS) + .untilAsserted(() -> { + JsonNode airDensity = testRestClient.getLatestTelemetry(device.getId()); + assertThat(airDensity).isNotNull(); + assertThat(airDensity.get("airDensity").get(0).get("value").asText()).isEqualTo("0.99"); + }); + + testRestClient.deleteCalculatedFieldIfExists(savedCalculatedField.getId()); + } + private CalculatedField createSimpleCalculatedField() { return createSimpleCalculatedField(device.getId()); } @@ -323,19 +352,21 @@ public class CalculatedFieldTest extends AbstractContainerTest { calculatedField.setName("Air density" + RandomStringUtils.randomAlphabetic(5)); calculatedField.setDebugSettings(DebugSettings.all()); - SimpleCalculatedFieldConfiguration config = new SimpleCalculatedFieldConfiguration(); + ScriptCalculatedFieldConfiguration config = new ScriptCalculatedFieldConfiguration(); Argument argument1 = new Argument(); argument1.setRefEntityId(asset.getId()); ReferencedEntityKey refEntityKey1 = new ReferencedEntityKey("altitude", ArgumentType.ATTRIBUTE, AttributeScope.SERVER_SCOPE); argument1.setRefEntityKey(refEntityKey1); - config.setArguments(Map.of("altitude", argument1)); Argument argument2 = new Argument(); ReferencedEntityKey refEntityKey2 = new ReferencedEntityKey("temperatureInF", ArgumentType.TS_ROLLING, null); + argument2.setTimeWindow(30000L); + argument2.setLimit(5); argument2.setRefEntityKey(refEntityKey2); - config.setArguments(Map.of("temperature", argument2)); - config.setExpression("return {\"airDensity\": 5};"); + config.setArguments(Map.of("altitude", argument1, "temperature", argument2)); + + config.setExpression(exampleScript); Output output = new Output(); output.setType(OutputType.TIME_SERIES); From d4f7cb7df161df1a9834bea77e1e4838f698ea34 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Thu, 20 Mar 2025 09:38:10 +0200 Subject: [PATCH 5/9] added validation for arg name and implemented destroy methods --- .../calculatedField/CalculatedFieldEntityActor.java | 7 +++++++ .../CalculatedFieldEntityMessageProcessor.java | 6 ++++++ .../calculatedField/CalculatedFieldManagerActor.java | 7 +++++++ .../CalculatedFieldManagerMessageProcessor.java | 9 +++++++++ .../server/service/cf/ctx/state/CalculatedFieldCtx.java | 9 +++++++++ .../thingsboard/server/actors/DefaultTbActorSystem.java | 2 ++ .../service/validator/CalculatedFieldDataValidator.java | 8 ++++++++ 7 files changed, 48 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityActor.java b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityActor.java index 350a5776cf..2959bfc8eb 100644 --- a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityActor.java @@ -21,6 +21,7 @@ import org.thingsboard.server.actors.TbActorCtx; import org.thingsboard.server.actors.TbActorException; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.msg.TbActorStopReason; import org.thingsboard.server.common.msg.ToCalculatedFieldSystemMsg; import org.thingsboard.server.common.msg.cf.CalculatedFieldPartitionChangeMsg; @@ -47,6 +48,12 @@ public class CalculatedFieldEntityActor extends AbstractCalculatedFieldActor { } } + @Override + public void destroy(TbActorStopReason stopReason, Throwable cause) throws TbActorException { + log.debug("[{}] Stopping CF entity actor.", processor.tenantId); + processor.stop(); + } + @Override protected boolean doProcessCfMsg(ToCalculatedFieldSystemMsg msg) throws CalculatedFieldException { switch (msg.getMsgType()) { diff --git a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java index a185b71d56..4e15dba120 100644 --- a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java @@ -92,6 +92,12 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM this.ctx = ctx; } + public void stop() { + log.info("[{}][{}] Stopping entity actor.", tenantId, entityId); + states.clear(); + ctx.stop(ctx.getSelf()); + } + public void process(CalculatedFieldPartitionChangeMsg msg) { if (!systemContext.getPartitionService().resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME, tenantId, entityId).isMyPartition()) { log.info("[{}] Stopping entity actor due to change partition event.", entityId); diff --git a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerActor.java b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerActor.java index a5c935e83f..70ed2849e8 100644 --- a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerActor.java @@ -20,6 +20,7 @@ import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.TbActorCtx; import org.thingsboard.server.actors.TbActorException; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.msg.TbActorStopReason; import org.thingsboard.server.common.msg.ToCalculatedFieldSystemMsg; import org.thingsboard.server.common.msg.cf.CalculatedFieldEntityLifecycleMsg; import org.thingsboard.server.common.msg.cf.CalculatedFieldInitMsg; @@ -52,6 +53,12 @@ public class CalculatedFieldManagerActor extends AbstractCalculatedFieldActor { } } + @Override + public void destroy(TbActorStopReason stopReason, Throwable cause) throws TbActorException { + log.debug("[{}] Stopping CF manager actor.", processor.tenantId); + processor.stop(); + } + @Override protected boolean doProcessCfMsg(ToCalculatedFieldSystemMsg msg) throws CalculatedFieldException { switch (msg.getMsgType()) { diff --git a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java index f8c17bf84b..1dd5b01401 100644 --- a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java @@ -91,6 +91,15 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware this.ctx = ctx; } + public void stop() { + log.info("[{}] Stopping CF manager actor.", tenantId); + calculatedFields.values().forEach(CalculatedFieldCtx::stop); + calculatedFields.clear(); + entityIdCalculatedFields.clear(); + entityIdCalculatedFieldLinks.clear(); + ctx.stop(ctx.getSelf()); + } + public void onFieldInitMsg(CalculatedFieldInitMsg msg) throws CalculatedFieldException { log.debug("[{}] Processing CF init message.", msg.getCf().getId()); var cf = msg.getCf(); 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 0c4352dcea..fdbbb37568 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 @@ -122,6 +122,15 @@ public class CalculatedFieldCtx { } } + public void stop() { + if (calculatedFieldScriptEngine != null) { + calculatedFieldScriptEngine.destroy(); + } + if (customExpression != null) { + customExpression.remove(); + } + } + private CalculatedFieldScriptEngine initEngine(TenantId tenantId, String expression, TbelInvokeService tbelInvokeService) { if (tbelInvokeService == null) { throw new IllegalArgumentException("TBEL script engine is disabled!"); diff --git a/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java b/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java index 85638763b2..1588f0d2b5 100644 --- a/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java +++ b/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java @@ -23,6 +23,7 @@ import org.thingsboard.server.common.msg.TbActorMsg; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -225,6 +226,7 @@ public class DefaultTbActorSystem implements TbActorSystem { if (scheduler != null) { scheduler.shutdownNow(); } + actors.values().forEach(mailbox -> Optional.ofNullable(mailbox).ifPresent(m -> m.destroy(null))); actors.clear(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/CalculatedFieldDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/CalculatedFieldDataValidator.java index 187de20667..c9c7af1a89 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/CalculatedFieldDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/CalculatedFieldDataValidator.java @@ -39,6 +39,7 @@ public class CalculatedFieldDataValidator extends DataValidator protected void validateCreate(TenantId tenantId, CalculatedField calculatedField) { validateNumberOfCFsPerEntity(tenantId, calculatedField.getEntityId()); validateNumberOfArgumentsPerCF(tenantId, calculatedField); + validateArgumentNames(calculatedField); } @Override @@ -48,6 +49,7 @@ public class CalculatedFieldDataValidator extends DataValidator throw new DataValidationException("Can't update non existing calculated field!"); } validateNumberOfArgumentsPerCF(tenantId, calculatedField); + validateArgumentNames(calculatedField); return old; } @@ -71,4 +73,10 @@ public class CalculatedFieldDataValidator extends DataValidator } } + private void validateArgumentNames(CalculatedField calculatedField) { + if (calculatedField.getConfiguration().getArguments().containsKey("ctx")) { + throw new DataValidationException("Argument name 'ctx' is reserved and cannot be used."); + } + } + } From e2fdc5a4ba5dc5e03dd6a1443194ef24e50ba816 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Thu, 20 Mar 2025 14:13:43 +0200 Subject: [PATCH 6/9] added methods for check if point in polygon to tbel --- .../server/actors/DefaultTbActorSystem.java | 2 +- common/script/script-api/pom.xml | 4 ++ .../thingsboard/script/api/tbel/TbUtils.java | 25 ++++++++++ .../shared/models/ace/tbel-utils.models.ts | 50 +++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java b/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java index 1588f0d2b5..7fad1a329c 100644 --- a/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java +++ b/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java @@ -215,6 +215,7 @@ public class DefaultTbActorSystem implements TbActorSystem { @Override public void stop() { + actors.values().forEach(mailbox -> Optional.ofNullable(mailbox).ifPresent(m -> m.destroy(null))); dispatchers.values().forEach(dispatcher -> { dispatcher.getExecutor().shutdown(); try { @@ -226,7 +227,6 @@ public class DefaultTbActorSystem implements TbActorSystem { if (scheduler != null) { scheduler.shutdownNow(); } - actors.values().forEach(mailbox -> Optional.ofNullable(mailbox).ifPresent(m -> m.destroy(null))); actors.clear(); } diff --git a/common/script/script-api/pom.xml b/common/script/script-api/pom.xml index 3655692217..4b6c1ee21c 100644 --- a/common/script/script-api/pom.xml +++ b/common/script/script-api/pom.xml @@ -48,6 +48,10 @@ org.thingsboard.common util + + org.thingsboard.rule-engine + rule-engine-components + org.javadelight delight-nashorn-sandbox diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index 95fff48883..ecb47668f3 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -15,6 +15,7 @@ */ package org.thingsboard.script.api.tbel; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.primitives.Bytes; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; @@ -23,6 +24,10 @@ import org.mvel2.ParserConfiguration; import org.mvel2.execution.ExecutionArrayList; import org.mvel2.execution.ExecutionHashMap; import org.mvel2.util.MethodStub; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.geo.Coordinates; +import org.thingsboard.rule.engine.geo.GeoUtil; +import org.thingsboard.rule.engine.geo.RangeUnit; import org.thingsboard.server.common.data.StringUtils; import java.io.IOException; @@ -371,6 +376,10 @@ public class TbUtils { byte[].class, int.class))); parserConfig.addImport("parseBinaryArrayToInt", new MethodStub(TbUtils.class.getMethod("parseBinaryArrayToInt", byte[].class, int.class, int.class))); + parserConfig.addImport("isInsidePolygon", new MethodStub(TbUtils.class.getMethod("isInsidePolygon", + double.class, double.class, String.class))); + parserConfig.addImport("isInsideCircle", new MethodStub(TbUtils.class.getMethod("isInsideCircle", + double.class, double.class, String.class))); } public static String btoa(String input) { @@ -1437,6 +1446,22 @@ public class TbUtils { return result; } + public static boolean isInsidePolygon(double latitude, double longitude, String perimeter) { + return GeoUtil.contains(perimeter, new Coordinates(latitude, longitude)); + } + + public static boolean isInsideCircle(double latitude, double longitude, String perimeter) { + JsonNode perimeterJson = JacksonUtil.toJsonNode(perimeter); + double centerLatitude = Double.parseDouble(perimeterJson.get("latitude").asText()); + double centerLongitude = Double.parseDouble(perimeterJson.get("longitude").asText()); + double range = Double.parseDouble(perimeterJson.get("radius").asText()); + RangeUnit rangeUnit = perimeterJson.has("radiusUnit") ? RangeUnit.valueOf(perimeterJson.get("radiusUnit").asText()) : RangeUnit.METER; + + Coordinates entityCoordinates = new Coordinates(latitude, longitude); + Coordinates perimeterCoordinates = new Coordinates(centerLatitude, centerLongitude); + return range > GeoUtil.distance(entityCoordinates, perimeterCoordinates, rangeUnit); + } + private static byte isValidIntegerToByte(Integer val) { if (val > 255 || val < -128) { throw new NumberFormatException("The value '" + val + "' could not be correctly converted to a byte. " + diff --git a/ui-ngx/src/app/shared/models/ace/tbel-utils.models.ts b/ui-ngx/src/app/shared/models/ace/tbel-utils.models.ts index f29ae083be..c988f5ca0a 100644 --- a/ui-ngx/src/app/shared/models/ace/tbel-utils.models.ts +++ b/ui-ngx/src/app/shared/models/ace/tbel-utils.models.ts @@ -1245,6 +1245,56 @@ const tbelEditorCompletions:TbEditorCompletions = { type: 'boolean' } }, + isInsidePolygon: { + meta: 'function', + description: 'Checks if a given point is inside a polygon.', + args: [ + { + name: 'latitude', + description: 'The latitude of the point', + type: 'number' + }, + { + name: 'longitude', + description: 'The longitude of the point', + type: 'number' + }, + { + name: 'perimeter', + description: 'The polygon perimeter represented as a string', + type: 'string' + } + ], + return: { + description: 'True if the point is inside the polygon, false otherwise.', + type: 'boolean' + } + }, + isInsideCircle: { + meta: 'function', + description: 'Checks if a given point is inside a circular area.', + args: [ + { + name: 'latitude', + description: 'The latitude of the point', + type: 'number' + }, + { + name: 'longitude', + description: 'The longitude of the point', + type: 'number' + }, + { + name: 'perimeter', + description: 'A string representation of the circle, containing center coordinates and radius', + type: 'string' + } + ], + return: { + description: 'True if the point is inside the circle, false otherwise.', + type: 'boolean' + } + } } export const tbelUtilsAutocompletes = new TbEditorCompleter(tbelEditorCompletions); From f0bfea12c0cf404741c44610f500eaf4407a5771 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Thu, 20 Mar 2025 16:06:56 +0200 Subject: [PATCH 7/9] moved geoutils to script api --- .../server/actors/tenant/TenantActor.java | 3 +++ .../server/actors/DefaultTbActorSystem.java | 2 -- common/script/script-api/pom.xml | 12 ++++++--- .../thingsboard/script/api}/Coordinates.java | 2 +- .../org/thingsboard/script/api}/GeoUtil.java | 2 +- .../thingsboard/script/api}/Perimeter.java | 2 +- .../script/api}/PerimeterType.java | 2 +- .../thingsboard/script/api}/RangeUnit.java | 2 +- .../thingsboard/script/api/tbel/TbUtils.java | 6 ++--- rule-engine/rule-engine-components/pom.xml | 12 +++------ .../engine/geo/AbstractGeofencingNode.java | 7 ++++- ...bGpsGeofencingActionNodeConfiguration.java | 1 + ...bGpsGeofencingFilterNodeConfiguration.java | 2 ++ .../rule/engine/geo/GeoUtilTest.java | 26 ++++++++++--------- .../geo/TbGpsGeofencingFilterNodeTest.java | 3 +++ 15 files changed, 49 insertions(+), 35 deletions(-) rename {rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo => common/script/script-api/src/main/java/org/thingsboard/script/api}/Coordinates.java (94%) rename {rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo => common/script/script-api/src/main/java/org/thingsboard/script/api}/GeoUtil.java (99%) rename {rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo => common/script/script-api/src/main/java/org/thingsboard/script/api}/Perimeter.java (95%) rename {rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo => common/script/script-api/src/main/java/org/thingsboard/script/api}/PerimeterType.java (94%) rename {rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo => common/script/script-api/src/main/java/org/thingsboard/script/api}/RangeUnit.java (95%) diff --git a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java index 49994eaa1f..728f715af4 100644 --- a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java @@ -127,6 +127,9 @@ public class TenantActor extends RuleChainManagerActor { @Override public void destroy(TbActorStopReason stopReason, Throwable cause) { log.info("[{}] Stopping tenant actor.", tenantId); + if (cfActor != null) { + ctx.stop(cfActor.getActorId()); + } } @Override diff --git a/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java b/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java index 7fad1a329c..85638763b2 100644 --- a/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java +++ b/common/actor/src/main/java/org/thingsboard/server/actors/DefaultTbActorSystem.java @@ -23,7 +23,6 @@ import org.thingsboard.server.common.msg.TbActorMsg; import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -215,7 +214,6 @@ public class DefaultTbActorSystem implements TbActorSystem { @Override public void stop() { - actors.values().forEach(mailbox -> Optional.ofNullable(mailbox).ifPresent(m -> m.destroy(null))); dispatchers.values().forEach(dispatcher -> { dispatcher.getExecutor().shutdown(); try { diff --git a/common/script/script-api/pom.xml b/common/script/script-api/pom.xml index 4b6c1ee21c..da60567814 100644 --- a/common/script/script-api/pom.xml +++ b/common/script/script-api/pom.xml @@ -48,10 +48,6 @@ org.thingsboard.common util - - org.thingsboard.rule-engine - rule-engine-components - org.javadelight delight-nashorn-sandbox @@ -115,6 +111,14 @@ awaitility test + + org.locationtech.spatial4j + spatial4j + + + org.locationtech.jts + jts-core + diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/Coordinates.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/Coordinates.java similarity index 94% rename from rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/Coordinates.java rename to common/script/script-api/src/main/java/org/thingsboard/script/api/Coordinates.java index c3b91e39bb..671ab58d5c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/Coordinates.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/Coordinates.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.rule.engine.geo; +package org.thingsboard.script.api; import lombok.Data; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/GeoUtil.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/GeoUtil.java similarity index 99% rename from rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/GeoUtil.java rename to common/script/script-api/src/main/java/org/thingsboard/script/api/GeoUtil.java index f92a345362..408b051303 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/GeoUtil.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/GeoUtil.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.rule.engine.geo; +package org.thingsboard.script.api; import com.google.gson.JsonArray; import com.google.gson.JsonElement; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/Perimeter.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/Perimeter.java similarity index 95% rename from rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/Perimeter.java rename to common/script/script-api/src/main/java/org/thingsboard/script/api/Perimeter.java index 3474683c6c..e05486bee0 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/Perimeter.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/Perimeter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.rule.engine.geo; +package org.thingsboard.script.api; import lombok.Data; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/PerimeterType.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/PerimeterType.java similarity index 94% rename from rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/PerimeterType.java rename to common/script/script-api/src/main/java/org/thingsboard/script/api/PerimeterType.java index 2df6cf796c..f6a0eea77e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/PerimeterType.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/PerimeterType.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.rule.engine.geo; +package org.thingsboard.script.api; public enum PerimeterType { CIRCLE, POLYGON diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/RangeUnit.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/RangeUnit.java similarity index 95% rename from rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/RangeUnit.java rename to common/script/script-api/src/main/java/org/thingsboard/script/api/RangeUnit.java index 090d251b33..6a594d1668 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/RangeUnit.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/RangeUnit.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.rule.engine.geo; +package org.thingsboard.script.api; public enum RangeUnit { METER(1000.0), KILOMETER(1.0), FOOT(3280.84), MILE(0.62137), NAUTICAL_MILE(0.539957); diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index ecb47668f3..12eb308fee 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -25,9 +25,9 @@ import org.mvel2.execution.ExecutionArrayList; import org.mvel2.execution.ExecutionHashMap; import org.mvel2.util.MethodStub; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.rule.engine.geo.Coordinates; -import org.thingsboard.rule.engine.geo.GeoUtil; -import org.thingsboard.rule.engine.geo.RangeUnit; +import org.thingsboard.script.api.Coordinates; +import org.thingsboard.script.api.GeoUtil; +import org.thingsboard.script.api.RangeUnit; import org.thingsboard.server.common.data.StringUtils; import java.io.IOException; diff --git a/rule-engine/rule-engine-components/pom.xml b/rule-engine/rule-engine-components/pom.xml index eb568f9cc7..4eb76727ef 100644 --- a/rule-engine/rule-engine-components/pom.xml +++ b/rule-engine/rule-engine-components/pom.xml @@ -53,6 +53,10 @@ transport-api provided + + org.thingsboard.common.script + script-api + ch.qos.logback logback-core @@ -120,14 +124,6 @@ org.bouncycastle bcpkix-jdk18on - - org.locationtech.spatial4j - spatial4j - - - org.locationtech.jts - jts-core - com.sun.mail jakarta.mail diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/AbstractGeofencingNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/AbstractGeofencingNode.java index 8025baeec7..ea0d62ebc0 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/AbstractGeofencingNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/AbstractGeofencingNode.java @@ -26,6 +26,11 @@ import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; +import org.thingsboard.script.api.Coordinates; +import org.thingsboard.script.api.GeoUtil; +import org.thingsboard.script.api.Perimeter; +import org.thingsboard.script.api.PerimeterType; +import org.thingsboard.script.api.RangeUnit; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.msg.TbMsg; @@ -74,7 +79,7 @@ public abstract class AbstractGeofencingNode Date: Fri, 21 Mar 2025 13:17:03 +0200 Subject: [PATCH 8/9] added tests and moved to common util --- ...alculatedFieldManagerMessageProcessor.java | 2 +- common/script/script-api/pom.xml | 8 -------- .../thingsboard/script/api/tbel/TbUtils.java | 6 +++--- .../script/api/tbel/TbUtilsTest.java | 20 +++++++++++++++++++ common/util/pom.xml | 8 ++++++++ .../common/util/geo}/Coordinates.java | 2 +- .../thingsboard/common/util/geo}/GeoUtil.java | 2 +- .../common/util/geo}/Perimeter.java | 2 +- .../common/util/geo}/PerimeterType.java | 2 +- .../common/util/geo}/RangeUnit.java | 2 +- .../engine/geo/AbstractGeofencingNode.java | 10 +++++----- ...bGpsGeofencingActionNodeConfiguration.java | 2 +- ...bGpsGeofencingFilterNodeConfiguration.java | 4 ++-- .../rule/engine/geo/GeoUtilTest.java | 4 ++-- .../geo/TbGpsGeofencingFilterNodeTest.java | 6 +++--- 15 files changed, 50 insertions(+), 30 deletions(-) rename common/{script/script-api/src/main/java/org/thingsboard/script/api => util/src/main/java/org/thingsboard/common/util/geo}/Coordinates.java (94%) rename common/{script/script-api/src/main/java/org/thingsboard/script/api => util/src/main/java/org/thingsboard/common/util/geo}/GeoUtil.java (99%) rename common/{script/script-api/src/main/java/org/thingsboard/script/api => util/src/main/java/org/thingsboard/common/util/geo}/Perimeter.java (95%) rename common/{script/script-api/src/main/java/org/thingsboard/script/api => util/src/main/java/org/thingsboard/common/util/geo}/PerimeterType.java (94%) rename common/{script/script-api/src/main/java/org/thingsboard/script/api => util/src/main/java/org/thingsboard/common/util/geo}/RangeUnit.java (95%) diff --git a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java index 1dd5b01401..0990365748 100644 --- a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java @@ -141,7 +141,7 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware } public void onEntityLifecycleMsg(CalculatedFieldEntityLifecycleMsg msg) throws CalculatedFieldException { - log.info("Processing entity lifecycle event: [{}] for entity: [{}]", msg.getData().getEvent(), msg.getData().getEntityId()); + log.debug("Processing entity lifecycle event: [{}] for entity: [{}]", msg.getData().getEvent(), msg.getData().getEntityId()); var entityType = msg.getData().getEntityId().getEntityType(); var event = msg.getData().getEvent(); switch (entityType) { diff --git a/common/script/script-api/pom.xml b/common/script/script-api/pom.xml index da60567814..3655692217 100644 --- a/common/script/script-api/pom.xml +++ b/common/script/script-api/pom.xml @@ -111,14 +111,6 @@ awaitility test - - org.locationtech.spatial4j - spatial4j - - - org.locationtech.jts - jts-core - diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index 12eb308fee..72792c1093 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -25,9 +25,9 @@ import org.mvel2.execution.ExecutionArrayList; import org.mvel2.execution.ExecutionHashMap; import org.mvel2.util.MethodStub; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.script.api.Coordinates; -import org.thingsboard.script.api.GeoUtil; -import org.thingsboard.script.api.RangeUnit; +import org.thingsboard.common.util.geo.Coordinates; +import org.thingsboard.common.util.geo.GeoUtil; +import org.thingsboard.common.util.geo.RangeUnit; import org.thingsboard.server.common.data.StringUtils; import java.io.IOException; diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java index e3860ed89a..1063a8e8de 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java @@ -1150,6 +1150,26 @@ public class TbUtilsTest { Assertions.assertTrue(TbUtils.isNaN(Double.NaN)); } + @Test + public void isInsidePolygon() { + // outside the polygon + String perimeter = "[[[50.75581142688204,29.097910166341073],[50.16785158177623,29.35066098977171],[50.164329922384674,29.773743889862114],[50.16785158177623,30.801230932938843],[50.459245308833495,30.92760634465418],[50.486522489629564,30.68548421850448],[50.703612031034005,30.872660513473573]],[[50.606017492632766,29.36165015600782],[50.54317104075835,29.762754723626013],[50.41021974600505,29.455058069014804]]]"; + Assertions.assertFalse(TbUtils.isInsidePolygon(50.50869555168039, 30.80123093293884, perimeter)); + // inside the polygon + Assertions.assertTrue(TbUtils.isInsidePolygon(50.50520628167696, 30.339685951022016, perimeter)); + // inside the hole + Assertions.assertFalse(TbUtils.isInsidePolygon(50.52265651287081, 29.488025567723156, perimeter)); + } + + @Test + public void isInsideCircle() { + // outside the circle + String perimeter = "{\"latitude\":50.32254778825905,\"longitude\":28.207787701215757,\"radius\":47477.33130420423}"; + Assertions.assertFalse(TbUtils.isInsideCircle(50.81490715736681, 28.05943395702824, perimeter)); + // inside the circle + Assertions.assertTrue(TbUtils.isInsideCircle(50.599397971892444, 28.086906872618542, perimeter)); + } + private static List toList(byte[] data) { List result = new ArrayList<>(data.length); for (Byte b : data) { diff --git a/common/util/pom.xml b/common/util/pom.xml index 430a6e7df9..82768cdb68 100644 --- a/common/util/pom.xml +++ b/common/util/pom.xml @@ -103,6 +103,14 @@ com.fasterxml.jackson.datatype jackson-datatype-jdk8 + + org.locationtech.spatial4j + spatial4j + + + org.locationtech.jts + jts-core + diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/Coordinates.java b/common/util/src/main/java/org/thingsboard/common/util/geo/Coordinates.java similarity index 94% rename from common/script/script-api/src/main/java/org/thingsboard/script/api/Coordinates.java rename to common/util/src/main/java/org/thingsboard/common/util/geo/Coordinates.java index 671ab58d5c..dc1998bff1 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/Coordinates.java +++ b/common/util/src/main/java/org/thingsboard/common/util/geo/Coordinates.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.script.api; +package org.thingsboard.common.util.geo; import lombok.Data; diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/GeoUtil.java b/common/util/src/main/java/org/thingsboard/common/util/geo/GeoUtil.java similarity index 99% rename from common/script/script-api/src/main/java/org/thingsboard/script/api/GeoUtil.java rename to common/util/src/main/java/org/thingsboard/common/util/geo/GeoUtil.java index 408b051303..11a6799348 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/GeoUtil.java +++ b/common/util/src/main/java/org/thingsboard/common/util/geo/GeoUtil.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.script.api; +package org.thingsboard.common.util.geo; import com.google.gson.JsonArray; import com.google.gson.JsonElement; diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/Perimeter.java b/common/util/src/main/java/org/thingsboard/common/util/geo/Perimeter.java similarity index 95% rename from common/script/script-api/src/main/java/org/thingsboard/script/api/Perimeter.java rename to common/util/src/main/java/org/thingsboard/common/util/geo/Perimeter.java index e05486bee0..238fa19af5 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/Perimeter.java +++ b/common/util/src/main/java/org/thingsboard/common/util/geo/Perimeter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.script.api; +package org.thingsboard.common.util.geo; import lombok.Data; diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/PerimeterType.java b/common/util/src/main/java/org/thingsboard/common/util/geo/PerimeterType.java similarity index 94% rename from common/script/script-api/src/main/java/org/thingsboard/script/api/PerimeterType.java rename to common/util/src/main/java/org/thingsboard/common/util/geo/PerimeterType.java index f6a0eea77e..c3b334abd7 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/PerimeterType.java +++ b/common/util/src/main/java/org/thingsboard/common/util/geo/PerimeterType.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.script.api; +package org.thingsboard.common.util.geo; public enum PerimeterType { CIRCLE, POLYGON diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/RangeUnit.java b/common/util/src/main/java/org/thingsboard/common/util/geo/RangeUnit.java similarity index 95% rename from common/script/script-api/src/main/java/org/thingsboard/script/api/RangeUnit.java rename to common/util/src/main/java/org/thingsboard/common/util/geo/RangeUnit.java index 6a594d1668..56883ca43f 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/RangeUnit.java +++ b/common/util/src/main/java/org/thingsboard/common/util/geo/RangeUnit.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.script.api; +package org.thingsboard.common.util.geo; public enum RangeUnit { METER(1000.0), KILOMETER(1.0), FOOT(3280.84), MILE(0.62137), NAUTICAL_MILE(0.539957); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/AbstractGeofencingNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/AbstractGeofencingNode.java index ea0d62ebc0..ff6b3acb88 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/AbstractGeofencingNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/AbstractGeofencingNode.java @@ -21,16 +21,16 @@ import com.google.gson.JsonParser; import org.locationtech.spatial4j.context.jts.JtsSpatialContext; import org.locationtech.spatial4j.context.jts.JtsSpatialContextFactory; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.common.util.geo.Coordinates; +import org.thingsboard.common.util.geo.GeoUtil; +import org.thingsboard.common.util.geo.Perimeter; +import org.thingsboard.common.util.geo.PerimeterType; +import org.thingsboard.common.util.geo.RangeUnit; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; -import org.thingsboard.script.api.Coordinates; -import org.thingsboard.script.api.GeoUtil; -import org.thingsboard.script.api.Perimeter; -import org.thingsboard.script.api.PerimeterType; -import org.thingsboard.script.api.RangeUnit; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.msg.TbMsg; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java index edd60d422b..bf195b44cc 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java @@ -16,7 +16,7 @@ package org.thingsboard.rule.engine.geo; import lombok.Data; -import org.thingsboard.script.api.PerimeterType; +import org.thingsboard.common.util.geo.PerimeterType; import java.util.concurrent.TimeUnit; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNodeConfiguration.java index 68a1299fc4..32a161635f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNodeConfiguration.java @@ -16,9 +16,9 @@ package org.thingsboard.rule.engine.geo; import lombok.Data; +import org.thingsboard.common.util.geo.PerimeterType; +import org.thingsboard.common.util.geo.RangeUnit; import org.thingsboard.rule.engine.api.NodeConfiguration; -import org.thingsboard.script.api.PerimeterType; -import org.thingsboard.script.api.RangeUnit; /** * Created by ashvayka on 19.01.18. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/geo/GeoUtilTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/geo/GeoUtilTest.java index 2fb5523c1e..b5438fe529 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/geo/GeoUtilTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/geo/GeoUtilTest.java @@ -19,8 +19,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; -import org.thingsboard.script.api.Coordinates; -import org.thingsboard.script.api.GeoUtil; +import org.thingsboard.common.util.geo.Coordinates; +import org.thingsboard.common.util.geo.GeoUtil; @ExtendWith(MockitoExtension.class) public class GeoUtilTest { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNodeTest.java index 54f1384d10..71c35d27f4 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNodeTest.java @@ -21,12 +21,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.common.util.geo.Coordinates; +import org.thingsboard.common.util.geo.PerimeterType; +import org.thingsboard.common.util.geo.RangeUnit; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.script.api.Coordinates; -import org.thingsboard.script.api.PerimeterType; -import org.thingsboard.script.api.RangeUnit; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.msg.TbMsgType; From 0920eede513e022d6cc87e880a5df51d7e8de272 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Fri, 21 Mar 2025 13:36:36 +0200 Subject: [PATCH 9/9] removed unnecessary dependency --- rule-engine/rule-engine-components/pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rule-engine/rule-engine-components/pom.xml b/rule-engine/rule-engine-components/pom.xml index 4eb76727ef..7ee5ab1496 100644 --- a/rule-engine/rule-engine-components/pom.xml +++ b/rule-engine/rule-engine-components/pom.xml @@ -53,10 +53,6 @@ transport-api provided - - org.thingsboard.common.script - script-api - ch.qos.logback logback-core