如何将 Spring Boot YAML 中的配置注入 ThingsBoard 自定义规则节点?

问题描述 投票:0回答:1

我正在为ThingsBoard开发自定义规则节点,需要通过thingsboard.yml文件配置各种Kafka相关参数。我不想直接使用 @Value 注释,而是想将这些值读取到单独的配置类中,然后在我的自定义规则节点中使用其对象。

thingsboard.yml

custom:
  node.enabled: true
  config:
    bootstrap.server: localhost:9092
    topic.pattern: custom-*
    retries: 3
    batch.size: 16384
    linger.ms: 0
    buffer.memory: 33554432

CustomNodeConfig.java

package com.example;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import lombok.Data;

@Data
@Configuration
public class CustomNodeConfig {

     @Value("${custom.node.enabled}")
    private boolean enabled;

    @Value("${custom.config.bootstrap.server}")
    private String bootstrapServers;

    @Value("${custom.config.topic.pattern}")
    private String topicPattern;

    @Value("${custom.config.retries}")
    private int retries;

    @Value("${custom.config.batch.size}")
    private int batchSize;

    @Value("${custom.config.linger.ms}")
    private int linger;

    @Value("${custom.config.buffer.memory}")
    private int bufferMemory;

自定义节点.java

package com.example;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.thingsboard.rule.engine.api.*;

import javax.annotation.PostConstruct;

@Slf4j
@Data
@RuleNode(
    type = ComponentType.EXTERNAL,
    name = "Custom Node",
    configClazz = CustomRuleNodeConfiguration.class,
    nodeDescription = "Publish messages to Kafka server",
    nodeDetails = "Outbound message will contain response fields from Kafka in the Message Metadata.",
    uiResources = {"static/rulenode/rulenode-core-config.js"}
)
@Component
public class CustomNode implements TbNode {

    @Autowired
    private CustomNodeConfig kafkaConfig;

    @PostConstruct
    public void init() {
        log.info("CustomRuleNode initialized with retries: {}, lingerMs: {}, bootstrapServers: {}, topicPattern: {}",
                kafkaConfig.getRetries(), kafkaConfig.getLingerMs(), kafkaConfig.getBootstrapServers(), kafkaConfig.getTopicPattern());
    }

    @Override
    public void init(TbNodeConfiguration configuration) throws TbNodeException 
        log.info("CustomRuleNode configuration initialized");
    }

    @Override
    protected void onMsg(TbContext ctx, TbMsg msg) {
        log.info("Received message: {}", msg.getData());
    }

    @Override
    public void destroy() {
        log.info("CustomRuleNode destroyed!");
    }
}

上述实现未按预期工作,节点参与者未初始化,并在尝试 10 次重试后抛出以下异常,因为 Autowired 变量未初始化。

2024-07-04 11:36:03.060  INFO 356309 --- [-dispatcher-3-3] o.t.server.actors.TbActorMailbox         : [RULE_NODE|8ad08a10-39f8-11ef-8131-5d958a56f0d4] Failed to init actor, attempt 10, going to stop attempts.

org.thingsboard.server.actors.TbActorException: Failed to init actor
    at org.thingsboard.server.actors.service.ComponentActor.initProcessor(ComponentActor.java:72) ~[classes!/:3.5.1]
    at org.thingsboard.server.actors.service.ComponentActor.init(ComponentActor.java:57) ~[classes!/:3.5.1]
    at org.thingsboard.server.actors.TbActorMailbox.tryInit(TbActorMailbox.java:66) ~[actor-3.5.1.jar!/:3.5.1]
    at org.thingsboard.server.actors.TbActorMailbox.lambda$tryInit$1(TbActorMailbox.java:85) ~[actor-3.5.1.jar!/:3.5.1]
    at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426) ~[na:na]
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) ~[na:na]
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) ~[na:na]
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) ~[na:na]
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) ~[na:na]
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183) ~[na:na]
Caused by: java.lang.NullPointerException: null
    at org.thingsboard.rule.engine.custom.CustomNode.init(CustomNode.java:92) ~[rule-engine-components-3.5.1.jar!/:3.5.1]
    at org.thingsboard.server.actors.ruleChain.RuleNodeActorMessageProcessor.initComponent(RuleNodeActorMessageProcessor.java:173) ~[classes!/:3.5.1]
    at org.thingsboard.server.actors.ruleChain.RuleNodeActorMessageProcessor.start(RuleNodeActorMessageProcessor.java:64) ~[classes!/:3.5.1]
    at org.thingsboard.server.actors.service.ComponentActor.initProcessor(ComponentActor.java:63) ~[classes!/:3.5.1]
    ... 9 common frames omitted

问题

  1. 是否有更好或更标准的方法来使用 Spring Boot 管理 ThingsBoard 中自定义规则节点的配置?
  2. 我使用单独的配置类 (CustomNodeConfig) 并将其自动装配到规则节点 (CustomNode) 的方法对于从 application.yml 注入配置值是否正确?
java spring spring-boot thingsboard
1个回答
0
投票

我认为您无法从 TbNode 对象访问 Spring 应用程序上下文,因为整个规则链执行都是沙盒的。我认为,您能做的最好的事情就是从规则链编辑器中填写您的配置类值。

© www.soinside.com 2019 - 2024. All rights reserved.