thingsboard-gateway从thingsboard获取拓展配置源码分析

2022-03-28 20:42:13 浏览数 (1)

本文基于thingsboard-gateway的早期java版本,现在thingsboard-gateway已改为python语言,下图为thingsboard-gateway配置示意图:

一切缘起remoteConfiguration这个配置,当remoteConfiguration设置为true时网关就会向thingsboard(下面简称tb)发送获取设备共享属性configuration的请求,如果tb端针对该网关有configuration这个共享属性,那么就会将这个配置下发到gateway,gateway就会使用下发的配置创建对应的服务(比如mqtt、opc、modbus等),如果remoteConfiguration配置为false,那么gateway就会使用extensions部分配置的扩展进行初始化,下面是DefaultTenantManagerService初始化相关代码:

代码语言:javascript复制
    @PostConstruct
    public void init() {
        gateways = new HashMap<>();
        httpServices = new ArrayList<>();
        for (TbTenantConfiguration configuration : configuration.getTenants()) {
            isRemoteConfiguration = configuration.getRemoteConfiguration();
            if (isRemoteConfiguration) {
                String label = configuration.getLabel();
                log.info("[{}] Initializing gateway", configuration.getLabel());
                TenantServiceRegistry tenantServiceRegistry = new TenantServiceRegistry();
                GatewayService service = null;
                try {
                     // isRemoteConfiguration为true时,会响应服务端返回的配置信息
                    service = getGatewayService(configuration, c -> tenantServiceRegistry.updateExtensionConfiguration(c));
                    tenantServiceRegistry.setService(service);
                    gateways.put(label, tenantServiceRegistry);
                } catch (Exception e) {
                    log.info("[{}] Failed to initialize the service ", label, e);
                    try {
                        if (service != null) {
                            service.destroy();
                        }
                    } catch (Exception exc) {
                        log.info("[{}] Failed to stop the service ", label, exc);
                    }
                }
            } else {
                String label = configuration.getLabel();
                log.info("[{}] Initializing gateway", configuration.getLabel());
                GatewayService service = null;
                try {
                    TenantServiceRegistry tenantServiceRegistry = new TenantServiceRegistry();
                    // isRemoteConfiguration为false时,会忽略服务端返回的配置信息
                    service = getGatewayService(configuration, c -> {});
                    tenantServiceRegistry.setService(service);
                    for (TbExtensionConfiguration extensionConfiguration : configuration.getExtensions()) {
                        log.info("[{}] Initializing extension: [{}]", configuration.getLabel(), extensionConfiguration.getType());
                        ExtensionService extension = tenantServiceRegistry.createExtensionServiceByType(service, extensionConfiguration.getType());
                        extension.init(extensionConfiguration, isRemoteConfiguration);
                        if (extensionConfiguration.getType().equals("HTTP")) {
                            httpServices.add((HttpService) extension);
                        }
                    }
                    gateways.put(label, (TenantServiceRegistry) tenantServiceRegistry);
                } catch (Exception e) {
                    log.info("[{}] Failed to initialize the service ", label, e);
                    try {
                        if (service != null) {
                            service.destroy();
                        }
                    } catch (Exception exc) {
                        log.info("[{}] Failed to stop the service ", label, exc);
                    }
                }
            }
        }
    }

gateway通过mqtt连接上tb后,会向tb发送获取configuration配置的rpc请求,具体在MqttGatewayService的initMqttClient方法中:

代码语言:javascript复制
    private MqttClient initMqttClient() {
        try {
            MqttClientConfig mqttClientConfig = getMqttClientConfig();
            mqttClientConfig.setUsername(connection.getSecurity().getAccessToken());
            tbClient = MqttClient.create(mqttClientConfig, this);
            tbClient.setCallback(this);
            tbClient.setEventLoop(nioEventLoopGroup);
            Promise<MqttConnectResult> connectResult = (Promise<MqttConnectResult>) tbClient.connect(connection.getHost(), connection.getPort());
            connectResult.addListener(future -> {
                if (future.isSuccess()) {
                    MqttConnectResult result = (MqttConnectResult) future.getNow();
                    log.debug("Gateway connect result code: [{}]", result.getReturnCode());
                } else {
                    log.error("Unable to connect to mqtt server!");
                    if (future.cause() != null) {
                        log.error(future.cause().getMessage(), future.cause());
                    }
                }
            });
            connectResult.get(connection.getConnectionTimeout(), TimeUnit.MILLISECONDS);


            tbClient.on(DEVICE_ATTRIBUTES_TOPIC, this).await(connection.getConnectionTimeout(), TimeUnit.MILLISECONDS);
            tbClient.on(DEVICE_GET_ATTRIBUTES_RESPONSE_PLUS_TOPIC, this).await(connection.getConnectionTimeout(), TimeUnit.MILLISECONDS);

            tbClient.on(GATEWAY_RESPONSES_ATTRIBUTES_TOPIC, this).await(connection.getConnectionTimeout(), TimeUnit.MILLISECONDS);
            tbClient.on(GATEWAY_ATTRIBUTES_TOPIC, this).await(connection.getConnectionTimeout(), TimeUnit.MILLISECONDS);
            tbClient.on(GATEWAY_RPC_TOPIC, this).await(connection.getConnectionTimeout(), TimeUnit.MILLISECONDS);

            // 向tb索取该网关对应的configuration配置,注意一定是共享属性
            byte[] msgData = toBytes(newNode().put("sharedKeys", "configuration"));
            persistMessage(DEVICE_GET_ATTRIBUTES_REQUEST_TOPIC, msgIdSeq.incrementAndGet(), msgData, null,
                    null,
                    error -> log.warn("Error getiing attributes", error));
            return tbClient;
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
            Thread.currentThread().interrupt();
            return null;
        } catch (ExecutionException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        } catch (TimeoutException e) {
            String message = "Unable to connect to ThingsBoard. Connection timed out after ["   connection.getConnectionTimeout()   "] milliseconds";
            log.error(message, e);
            throw new RuntimeException(message);
        }
    }

共享属性查看页面

PS:

java版本thingsboard-gateway可以通过https://gitee.com/johnHust/thingsboard-gateway下载

0 人点赞