Extract coap-server component to separate module to be used in coap transport and core (CoAP integrations).
* init commit: coap-server component * move coap-server to separate module * fix typo
This commit is contained in:
		
							parent
							
								
									a207e31841
								
							
						
					
					
						commit
						dc87550835
					
				@ -589,6 +589,10 @@ transport:
 | 
			
		||||
    dtls:
 | 
			
		||||
      # Enable/disable DTLS 1.2 support
 | 
			
		||||
      enabled: "${COAP_DTLS_ENABLED:false}"
 | 
			
		||||
      # CoAP DTLS bind address
 | 
			
		||||
      bind_address: "${COAP_DTLS_BIND_ADDRESS:0.0.0.0}"
 | 
			
		||||
      # CoAP DTLS bind port
 | 
			
		||||
      bind_port: "${COAP_DTLS_BIND_PORT:5684}"
 | 
			
		||||
      # Secure mode. Allowed values: NO_AUTH, X509
 | 
			
		||||
      mode: "${COAP_DTLS_SECURE_MODE:NO_AUTH}"
 | 
			
		||||
      # Path to the key store that holds the certificate
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										73
									
								
								common/coap-server/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								common/coap-server/pom.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,73 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!--
 | 
			
		||||
 | 
			
		||||
    Copyright © 2016-2021 The Thingsboard Authors
 | 
			
		||||
 | 
			
		||||
    Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
    you may not use this file except in compliance with the License.
 | 
			
		||||
    You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
        http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
    Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
    distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
    See the License for the specific language governing permissions and
 | 
			
		||||
    limitations under the License.
 | 
			
		||||
 | 
			
		||||
-->
 | 
			
		||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
 | 
			
		||||
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 | 
			
		||||
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>3.3.0-SNAPSHOT</version>
 | 
			
		||||
        <artifactId>common</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.common</groupId>
 | 
			
		||||
    <artifactId>coap-server</artifactId>
 | 
			
		||||
    <packaging>jar</packaging>
 | 
			
		||||
 | 
			
		||||
    <name>Thingsboard CoAP server</name>
 | 
			
		||||
    <url>https://thingsboard.io</url>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 | 
			
		||||
        <main.dir>${basedir}/../..</main.dir>
 | 
			
		||||
    </properties>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.thingsboard.common</groupId>
 | 
			
		||||
            <artifactId>queue</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.thingsboard.common</groupId>
 | 
			
		||||
            <artifactId>data</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.thingsboard.common.transport</groupId>
 | 
			
		||||
            <artifactId>transport-api</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.springframework</groupId>
 | 
			
		||||
            <artifactId>spring-context</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.springframework.boot</groupId>
 | 
			
		||||
            <artifactId>spring-boot-starter-web</artifactId>
 | 
			
		||||
            <scope>provided</scope>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.eclipse.californium</groupId>
 | 
			
		||||
            <artifactId>californium-core</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.eclipse.californium</groupId>
 | 
			
		||||
            <artifactId>scandium</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
    </dependencies>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</project>
 | 
			
		||||
@ -0,0 +1,46 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2021 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.coapserver;
 | 
			
		||||
 | 
			
		||||
import lombok.Getter;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Value;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.coap.enabled}'=='true')")
 | 
			
		||||
@Component
 | 
			
		||||
public class CoapServerContext {
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.coap.bind_address}")
 | 
			
		||||
    private String host;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.coap.bind_port}")
 | 
			
		||||
    private Integer port;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.coap.timeout}")
 | 
			
		||||
    private Long timeout;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Autowired(required = false)
 | 
			
		||||
    private TbCoapDtlsSettings dtlsSettings;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,31 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2021 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.coapserver;
 | 
			
		||||
 | 
			
		||||
import org.eclipse.californium.core.CoapServer;
 | 
			
		||||
 | 
			
		||||
import java.net.UnknownHostException;
 | 
			
		||||
import java.util.concurrent.ConcurrentMap;
 | 
			
		||||
 | 
			
		||||
public interface CoapServerService {
 | 
			
		||||
 | 
			
		||||
    CoapServer getCoapServer() throws UnknownHostException;
 | 
			
		||||
 | 
			
		||||
    ConcurrentMap<String, TbCoapDtlsSessionInfo> getDtlsSessionsMap();
 | 
			
		||||
 | 
			
		||||
    long getTimeout();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,133 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2021 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.coapserver;
 | 
			
		||||
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.eclipse.californium.core.CoapServer;
 | 
			
		||||
import org.eclipse.californium.core.network.CoapEndpoint;
 | 
			
		||||
import org.eclipse.californium.core.network.config.NetworkConfig;
 | 
			
		||||
import org.eclipse.californium.core.server.resources.Resource;
 | 
			
		||||
import org.eclipse.californium.scandium.DTLSConnector;
 | 
			
		||||
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
import javax.annotation.PreDestroy;
 | 
			
		||||
import java.net.InetAddress;
 | 
			
		||||
import java.net.InetSocketAddress;
 | 
			
		||||
import java.net.UnknownHostException;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.concurrent.ConcurrentMap;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
import java.util.concurrent.ScheduledExecutorService;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@Component
 | 
			
		||||
@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.coap.enabled}'=='true')")
 | 
			
		||||
public class DefaultCoapServerService implements CoapServerService {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private CoapServerContext coapServerContext;
 | 
			
		||||
 | 
			
		||||
    private CoapServer server;
 | 
			
		||||
 | 
			
		||||
    private TbCoapDtlsCertificateVerifier tbDtlsCertificateVerifier;
 | 
			
		||||
 | 
			
		||||
    private ScheduledExecutorService dtlsSessionsExecutor;
 | 
			
		||||
 | 
			
		||||
    @PostConstruct
 | 
			
		||||
    public void init() throws UnknownHostException {
 | 
			
		||||
        createCoapServer();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PreDestroy
 | 
			
		||||
    public void shutdown() {
 | 
			
		||||
        if (dtlsSessionsExecutor != null) {
 | 
			
		||||
            dtlsSessionsExecutor.shutdownNow();
 | 
			
		||||
        }
 | 
			
		||||
        log.info("Stopping CoAP server!");
 | 
			
		||||
        server.destroy();
 | 
			
		||||
        log.info("CoAP server stopped!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public CoapServer getCoapServer() throws UnknownHostException {
 | 
			
		||||
        if (server != null) {
 | 
			
		||||
            return server;
 | 
			
		||||
        } else {
 | 
			
		||||
            return createCoapServer();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ConcurrentMap<String, TbCoapDtlsSessionInfo> getDtlsSessionsMap() {
 | 
			
		||||
        return tbDtlsCertificateVerifier != null ? tbDtlsCertificateVerifier.getTbCoapDtlsSessionIdsMap() : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public long getTimeout() {
 | 
			
		||||
        return coapServerContext.getTimeout();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private CoapServer createCoapServer() throws UnknownHostException {
 | 
			
		||||
        server = new CoapServer();
 | 
			
		||||
 | 
			
		||||
        CoapEndpoint.Builder noSecCoapEndpointBuilder = new CoapEndpoint.Builder();
 | 
			
		||||
        InetAddress addr = InetAddress.getByName(coapServerContext.getHost());
 | 
			
		||||
        InetSocketAddress sockAddr = new InetSocketAddress(addr, coapServerContext.getPort());
 | 
			
		||||
        noSecCoapEndpointBuilder.setInetSocketAddress(sockAddr);
 | 
			
		||||
        noSecCoapEndpointBuilder.setNetworkConfig(NetworkConfig.getStandard());
 | 
			
		||||
        CoapEndpoint noSecCoapEndpoint = noSecCoapEndpointBuilder.build();
 | 
			
		||||
        server.addEndpoint(noSecCoapEndpoint);
 | 
			
		||||
 | 
			
		||||
        if (isDtlsEnabled()) {
 | 
			
		||||
            CoapEndpoint.Builder dtlsCoapEndpointBuilder = new CoapEndpoint.Builder();
 | 
			
		||||
            TbCoapDtlsSettings dtlsSettings = coapServerContext.getDtlsSettings();
 | 
			
		||||
            DtlsConnectorConfig dtlsConnectorConfig = dtlsSettings.dtlsConnectorConfig();
 | 
			
		||||
            DTLSConnector connector = new DTLSConnector(dtlsConnectorConfig);
 | 
			
		||||
            dtlsCoapEndpointBuilder.setConnector(connector);
 | 
			
		||||
            CoapEndpoint dtlsCoapEndpoint = dtlsCoapEndpointBuilder.build();
 | 
			
		||||
            server.addEndpoint(dtlsCoapEndpoint);
 | 
			
		||||
            if (dtlsConnectorConfig.isClientAuthenticationRequired()) {
 | 
			
		||||
                tbDtlsCertificateVerifier = (TbCoapDtlsCertificateVerifier) dtlsConnectorConfig.getAdvancedCertificateVerifier();
 | 
			
		||||
                dtlsSessionsExecutor = Executors.newSingleThreadScheduledExecutor();
 | 
			
		||||
                dtlsSessionsExecutor.scheduleAtFixedRate(this::evictTimeoutSessions, new Random().nextInt((int) getDtlsSessionReportTimeout()), getDtlsSessionReportTimeout(), TimeUnit.MILLISECONDS);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Resource root = server.getRoot();
 | 
			
		||||
        TbCoapServerMessageDeliverer messageDeliverer = new TbCoapServerMessageDeliverer(root);
 | 
			
		||||
        server.setMessageDeliverer(messageDeliverer);
 | 
			
		||||
 | 
			
		||||
        server.start();
 | 
			
		||||
        return server;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isDtlsEnabled() {
 | 
			
		||||
        return coapServerContext.getDtlsSettings() != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void evictTimeoutSessions() {
 | 
			
		||||
        tbDtlsCertificateVerifier.evictTimeoutSessions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private long getDtlsSessionReportTimeout() {
 | 
			
		||||
        return tbDtlsCertificateVerifier.getDtlsSessionReportTimeout();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.transport.coap;
 | 
			
		||||
package org.thingsboard.server.coapserver;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.transport.coap;
 | 
			
		||||
package org.thingsboard.server.coapserver;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.transport.coap;
 | 
			
		||||
package org.thingsboard.server.coapserver;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import org.thingsboard.server.common.data.DeviceProfile;
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.transport.coap;
 | 
			
		||||
package org.thingsboard.server.coapserver;
 | 
			
		||||
 | 
			
		||||
import com.google.common.io.Resources;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
@ -39,15 +39,15 @@ import java.util.Collections;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@ConditionalOnExpression("'${transport.coap.enabled}'=='true'")
 | 
			
		||||
@ConditionalOnProperty(prefix = "transport.coap.dtls", value = "enabled", havingValue = "true", matchIfMissing = false)
 | 
			
		||||
@ConditionalOnExpression("'${transport.type:null}'=='null' || ('${transport.type}'=='local' && '${transport.coap.enabled}'=='true')")
 | 
			
		||||
@Component
 | 
			
		||||
public class TbCoapDtlsSettings {
 | 
			
		||||
 | 
			
		||||
    @Value("${transport.coap.bind_address}")
 | 
			
		||||
    @Value("${transport.coap.dtls.bind_address}")
 | 
			
		||||
    private String host;
 | 
			
		||||
 | 
			
		||||
    @Value("${transport.coap.bind_port}")
 | 
			
		||||
    @Value("${transport.coap.dtls.bind_port}")
 | 
			
		||||
    private Integer port;
 | 
			
		||||
 | 
			
		||||
    @Value("${transport.coap.dtls.mode}")
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.transport.coap;
 | 
			
		||||
package org.thingsboard.server.coapserver;
 | 
			
		||||
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.eclipse.californium.core.coap.OptionSet;
 | 
			
		||||
@ -43,6 +43,7 @@
 | 
			
		||||
        <module>dao-api</module>
 | 
			
		||||
        <module>stats</module>
 | 
			
		||||
        <module>cache</module>
 | 
			
		||||
        <module>coap-server</module>
 | 
			
		||||
    </modules>
 | 
			
		||||
 | 
			
		||||
</project>
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,10 @@
 | 
			
		||||
            <groupId>org.thingsboard.common.transport</groupId>
 | 
			
		||||
            <artifactId>transport-api</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.thingsboard.common</groupId>
 | 
			
		||||
            <artifactId>coap-server</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.eclipse.californium</groupId>
 | 
			
		||||
            <artifactId>californium-core</artifactId>
 | 
			
		||||
 | 
			
		||||
@ -18,13 +18,12 @@ package org.thingsboard.server.transport.coap;
 | 
			
		||||
import lombok.Getter;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Value;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.thingsboard.server.common.transport.TransportContext;
 | 
			
		||||
import org.thingsboard.server.transport.coap.efento.adaptor.EfentoCoapAdaptor;
 | 
			
		||||
import org.thingsboard.server.transport.coap.adaptors.JsonCoapAdaptor;
 | 
			
		||||
import org.thingsboard.server.transport.coap.adaptors.ProtoCoapAdaptor;
 | 
			
		||||
import org.thingsboard.server.transport.coap.efento.adaptor.EfentoCoapAdaptor;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -35,22 +34,6 @@ import org.thingsboard.server.transport.coap.adaptors.ProtoCoapAdaptor;
 | 
			
		||||
@Component
 | 
			
		||||
public class CoapTransportContext extends TransportContext {
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.coap.bind_address}")
 | 
			
		||||
    private String host;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.coap.bind_port}")
 | 
			
		||||
    private Integer port;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Value("${transport.coap.timeout}")
 | 
			
		||||
    private Long timeout;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Autowired(required = false)
 | 
			
		||||
    private TbCoapDtlsSettings dtlsSettings;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private JsonCoapAdaptor jsonCoapAdaptor;
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,8 @@ import org.eclipse.californium.core.server.resources.CoapExchange;
 | 
			
		||||
import org.eclipse.californium.core.server.resources.Resource;
 | 
			
		||||
import org.eclipse.californium.core.server.resources.ResourceObserver;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
import org.thingsboard.server.coapserver.CoapServerService;
 | 
			
		||||
import org.thingsboard.server.coapserver.TbCoapDtlsSessionInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.DataConstants;
 | 
			
		||||
import org.thingsboard.server.common.data.DeviceProfile;
 | 
			
		||||
import org.thingsboard.server.common.data.DeviceTransportType;
 | 
			
		||||
@ -74,12 +76,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
 | 
			
		||||
    private final Set<UUID> attributeSubscriptions = ConcurrentHashMap.newKeySet();
 | 
			
		||||
 | 
			
		||||
    private ConcurrentMap<String, TbCoapDtlsSessionInfo> dtlsSessionIdMap;
 | 
			
		||||
    private long timeout;
 | 
			
		||||
 | 
			
		||||
    public CoapTransportResource(CoapTransportContext coapTransportContext, ConcurrentMap<String, TbCoapDtlsSessionInfo> dtlsSessionIdMap, String name) {
 | 
			
		||||
    public CoapTransportResource(CoapTransportContext coapTransportContext, CoapServerService coapServerService, String name) {
 | 
			
		||||
        super(coapTransportContext, name);
 | 
			
		||||
        this.setObservable(true); // enable observing
 | 
			
		||||
        this.addObserver(new CoapResourceObserver());
 | 
			
		||||
        this.dtlsSessionIdMap = dtlsSessionIdMap;
 | 
			
		||||
        this.dtlsSessionIdMap = coapServerService.getDtlsSessionsMap();
 | 
			
		||||
        this.timeout = coapServerService.getTimeout();
 | 
			
		||||
//        this.setObservable(false); // disable observing
 | 
			
		||||
//        this.setObserveType(CoAP.Type.CON); // configure the notification type to CONs
 | 
			
		||||
//        this.getAttributes().setObservable(); // mark observable in the Link-Format
 | 
			
		||||
@ -303,13 +307,13 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
 | 
			
		||||
                            new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
 | 
			
		||||
                    break;
 | 
			
		||||
                case TO_SERVER_RPC_REQUEST:
 | 
			
		||||
                    transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), transportContext.getTimeout());
 | 
			
		||||
                    transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), timeout);
 | 
			
		||||
                    transportService.process(sessionInfo,
 | 
			
		||||
                            coapTransportAdaptor.convertToServerRpcRequest(sessionId, request),
 | 
			
		||||
                            new CoapNoOpCallback(exchange));
 | 
			
		||||
                    break;
 | 
			
		||||
                case GET_ATTRIBUTES_REQUEST:
 | 
			
		||||
                    transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), transportContext.getTimeout());
 | 
			
		||||
                    transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), timeout);
 | 
			
		||||
                    transportService.process(sessionInfo,
 | 
			
		||||
                            coapTransportAdaptor.convertToGetAttributes(sessionId, request),
 | 
			
		||||
                            new CoapNoOpCallback(exchange));
 | 
			
		||||
 | 
			
		||||
@ -18,26 +18,15 @@ package org.thingsboard.server.transport.coap;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.eclipse.californium.core.CoapResource;
 | 
			
		||||
import org.eclipse.californium.core.CoapServer;
 | 
			
		||||
import org.eclipse.californium.core.network.CoapEndpoint;
 | 
			
		||||
import org.eclipse.californium.core.network.config.NetworkConfig;
 | 
			
		||||
import org.eclipse.californium.core.server.resources.Resource;
 | 
			
		||||
import org.eclipse.californium.scandium.DTLSConnector;
 | 
			
		||||
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.thingsboard.server.coapserver.CoapServerService;
 | 
			
		||||
import org.thingsboard.server.transport.coap.efento.CoapEfentoTransportResource;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
import javax.annotation.PreDestroy;
 | 
			
		||||
import java.net.InetAddress;
 | 
			
		||||
import java.net.InetSocketAddress;
 | 
			
		||||
import java.net.UnknownHostException;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.concurrent.ConcurrentMap;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
import java.util.concurrent.ScheduledExecutorService;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
@Service("CoapTransportService")
 | 
			
		||||
@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.coap.enabled}'=='true')")
 | 
			
		||||
@ -49,88 +38,31 @@ public class CoapTransportService {
 | 
			
		||||
    private static final String EFENTO = "efento";
 | 
			
		||||
    private static final String MEASUREMENTS = "m";
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private CoapServerService coapServerService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private CoapTransportContext coapTransportContext;
 | 
			
		||||
 | 
			
		||||
    private TbCoapDtlsCertificateVerifier tbDtlsCertificateVerifier;
 | 
			
		||||
 | 
			
		||||
    private CoapServer server;
 | 
			
		||||
 | 
			
		||||
    private ScheduledExecutorService dtlsSessionsExecutor;
 | 
			
		||||
    private CoapServer coapServer;
 | 
			
		||||
 | 
			
		||||
    @PostConstruct
 | 
			
		||||
    public void init() throws UnknownHostException {
 | 
			
		||||
        log.info("Starting CoAP transport...");
 | 
			
		||||
        log.info("Starting CoAP transport server");
 | 
			
		||||
 | 
			
		||||
        this.server = new CoapServer();
 | 
			
		||||
 | 
			
		||||
        CoapEndpoint.Builder capEndpointBuilder = new CoapEndpoint.Builder();
 | 
			
		||||
 | 
			
		||||
        if (isDtlsEnabled()) {
 | 
			
		||||
            TbCoapDtlsSettings dtlsSettings = coapTransportContext.getDtlsSettings();
 | 
			
		||||
            DtlsConnectorConfig dtlsConnectorConfig = dtlsSettings.dtlsConnectorConfig();
 | 
			
		||||
            DTLSConnector connector = new DTLSConnector(dtlsConnectorConfig);
 | 
			
		||||
            capEndpointBuilder.setConnector(connector);
 | 
			
		||||
            if (dtlsConnectorConfig.isClientAuthenticationRequired()) {
 | 
			
		||||
                tbDtlsCertificateVerifier = (TbCoapDtlsCertificateVerifier) dtlsConnectorConfig.getAdvancedCertificateVerifier();
 | 
			
		||||
                dtlsSessionsExecutor = Executors.newSingleThreadScheduledExecutor();
 | 
			
		||||
                dtlsSessionsExecutor.scheduleAtFixedRate(this::evictTimeoutSessions, new Random().nextInt((int) getDtlsSessionReportTimeout()), getDtlsSessionReportTimeout(), TimeUnit.MILLISECONDS);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            InetAddress addr = InetAddress.getByName(coapTransportContext.getHost());
 | 
			
		||||
            InetSocketAddress sockAddr = new InetSocketAddress(addr, coapTransportContext.getPort());
 | 
			
		||||
            capEndpointBuilder.setInetSocketAddress(sockAddr);
 | 
			
		||||
            capEndpointBuilder.setNetworkConfig(NetworkConfig.getStandard());
 | 
			
		||||
        }
 | 
			
		||||
        CoapEndpoint coapEndpoint = capEndpointBuilder.build();
 | 
			
		||||
 | 
			
		||||
        server.addEndpoint(coapEndpoint);
 | 
			
		||||
 | 
			
		||||
        createResources();
 | 
			
		||||
        Resource root = this.server.getRoot();
 | 
			
		||||
        TbCoapServerMessageDeliverer messageDeliverer = new TbCoapServerMessageDeliverer(root);
 | 
			
		||||
        this.server.setMessageDeliverer(messageDeliverer);
 | 
			
		||||
 | 
			
		||||
        server.start();
 | 
			
		||||
        log.info("CoAP transport started!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createResources() {
 | 
			
		||||
        coapServer = coapServerService.getCoapServer();
 | 
			
		||||
        CoapResource api = new CoapResource(API);
 | 
			
		||||
        api.add(new CoapTransportResource(coapTransportContext, getDtlsSessionsMap(), V1));
 | 
			
		||||
        api.add(new CoapTransportResource(coapTransportContext, coapServerService, V1));
 | 
			
		||||
 | 
			
		||||
        CoapResource efento = new CoapResource(EFENTO);
 | 
			
		||||
        CoapEfentoTransportResource efentoMeasurementsTransportResource = new CoapEfentoTransportResource(coapTransportContext, MEASUREMENTS);
 | 
			
		||||
        efento.add(efentoMeasurementsTransportResource);
 | 
			
		||||
 | 
			
		||||
        server.add(api);
 | 
			
		||||
        server.add(efento);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isDtlsEnabled() {
 | 
			
		||||
        return coapTransportContext.getDtlsSettings() != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ConcurrentMap<String, TbCoapDtlsSessionInfo> getDtlsSessionsMap() {
 | 
			
		||||
        return tbDtlsCertificateVerifier != null ? tbDtlsCertificateVerifier.getTbCoapDtlsSessionIdsMap() : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void evictTimeoutSessions() {
 | 
			
		||||
        tbDtlsCertificateVerifier.evictTimeoutSessions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private long getDtlsSessionReportTimeout() {
 | 
			
		||||
        return tbDtlsCertificateVerifier.getDtlsSessionReportTimeout();
 | 
			
		||||
        coapServer.add(api);
 | 
			
		||||
        coapServer.add(efento);
 | 
			
		||||
        log.info("CoAP transport started!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PreDestroy
 | 
			
		||||
    public void shutdown() {
 | 
			
		||||
        if (dtlsSessionsExecutor != null) {
 | 
			
		||||
            dtlsSessionsExecutor.shutdownNow();
 | 
			
		||||
        }
 | 
			
		||||
        log.info("Stopping CoAP transport!");
 | 
			
		||||
        this.server.destroy();
 | 
			
		||||
        log.info("CoAP transport stopped!");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -55,7 +55,7 @@ import java.util.concurrent.TimeUnit;
 | 
			
		||||
 */
 | 
			
		||||
@Slf4j
 | 
			
		||||
@Component("MqttSslHandlerProvider")
 | 
			
		||||
@ConditionalOnExpression("'${transport.type:null}'=='null' || ('${transport.type}'=='local' && '${transport.mqtt.enabled}'=='true')")
 | 
			
		||||
@ConditionalOnExpression("'${transport.mqtt.enabled}'=='true'")
 | 
			
		||||
@ConditionalOnProperty(prefix = "transport.mqtt.ssl", value = "enabled", havingValue = "true", matchIfMissing = false)
 | 
			
		||||
public class MqttSslHandlerProvider {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								pom.xml
									
									
									
									
									
								
							@ -933,6 +933,11 @@
 | 
			
		||||
                <artifactId>stats</artifactId>
 | 
			
		||||
                <version>${project.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>org.thingsboard.common</groupId>
 | 
			
		||||
                <artifactId>coap-server</artifactId>
 | 
			
		||||
                <version>${project.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>org.thingsboard</groupId>
 | 
			
		||||
                <artifactId>tools</artifactId>
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@ import java.util.Arrays;
 | 
			
		||||
@SpringBootConfiguration
 | 
			
		||||
@EnableAsync
 | 
			
		||||
@EnableScheduling
 | 
			
		||||
@ComponentScan({"org.thingsboard.server.coap", "org.thingsboard.server.common", "org.thingsboard.server.transport.coap", "org.thingsboard.server.queue"})
 | 
			
		||||
@ComponentScan({"org.thingsboard.server.coap", "org.thingsboard.server.common", "org.thingsboard.server.coapserver", "org.thingsboard.server.transport.coap", "org.thingsboard.server.queue"})
 | 
			
		||||
public class ThingsboardCoapTransportApplication {
 | 
			
		||||
 | 
			
		||||
    private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name";
 | 
			
		||||
 | 
			
		||||
@ -49,6 +49,10 @@ transport:
 | 
			
		||||
    dtls:
 | 
			
		||||
      # Enable/disable DTLS 1.2 support
 | 
			
		||||
      enabled: "${COAP_DTLS_ENABLED:false}"
 | 
			
		||||
      # CoAP DTLS bind address
 | 
			
		||||
      bind_address: "${COAP_DTLS_BIND_ADDRESS:0.0.0.0}"
 | 
			
		||||
      # CoAP DTLS bind port
 | 
			
		||||
      bind_port: "${COAP_DTLS_BIND_PORT:5684}"
 | 
			
		||||
      # Secure mode. Allowed values: NO_AUTH, X509
 | 
			
		||||
      mode: "${COAP_DTLS_SECURE_MODE:NO_AUTH}"
 | 
			
		||||
      # Path to the key store that holds the certificate
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user