Commit dc8755083566b79cc878a2cb27668152a9f9ad78

Authored by ShvaykaD
Committed by GitHub
1 parent a207e318

Extract coap-server component to separate module to be used in coap transport an…

…d core (CoAP integrations).

* init commit: coap-server component

* move coap-server to separate module

* fix typo
Showing 19 changed files with 330 additions and 110 deletions
@@ -589,6 +589,10 @@ transport: @@ -589,6 +589,10 @@ transport:
589 dtls: 589 dtls:
590 # Enable/disable DTLS 1.2 support 590 # Enable/disable DTLS 1.2 support
591 enabled: "${COAP_DTLS_ENABLED:false}" 591 enabled: "${COAP_DTLS_ENABLED:false}"
  592 + # CoAP DTLS bind address
  593 + bind_address: "${COAP_DTLS_BIND_ADDRESS:0.0.0.0}"
  594 + # CoAP DTLS bind port
  595 + bind_port: "${COAP_DTLS_BIND_PORT:5684}"
592 # Secure mode. Allowed values: NO_AUTH, X509 596 # Secure mode. Allowed values: NO_AUTH, X509
593 mode: "${COAP_DTLS_SECURE_MODE:NO_AUTH}" 597 mode: "${COAP_DTLS_SECURE_MODE:NO_AUTH}"
594 # Path to the key store that holds the certificate 598 # Path to the key store that holds the certificate
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!--
  3 +
  4 + Copyright © 2016-2021 The Thingsboard Authors
  5 +
  6 + Licensed under the Apache License, Version 2.0 (the "License");
  7 + you may not use this file except in compliance with the License.
  8 + You may obtain a copy of the License at
  9 +
  10 + http://www.apache.org/licenses/LICENSE-2.0
  11 +
  12 + Unless required by applicable law or agreed to in writing, software
  13 + distributed under the License is distributed on an "AS IS" BASIS,
  14 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15 + See the License for the specific language governing permissions and
  16 + limitations under the License.
  17 +
  18 +-->
  19 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  20 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  21 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  22 + <modelVersion>4.0.0</modelVersion>
  23 + <parent>
  24 + <groupId>org.thingsboard</groupId>
  25 + <version>3.3.0-SNAPSHOT</version>
  26 + <artifactId>common</artifactId>
  27 + </parent>
  28 + <groupId>org.thingsboard.common</groupId>
  29 + <artifactId>coap-server</artifactId>
  30 + <packaging>jar</packaging>
  31 +
  32 + <name>Thingsboard CoAP server</name>
  33 + <url>https://thingsboard.io</url>
  34 +
  35 + <properties>
  36 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  37 + <main.dir>${basedir}/../..</main.dir>
  38 + </properties>
  39 +
  40 + <dependencies>
  41 + <dependency>
  42 + <groupId>org.thingsboard.common</groupId>
  43 + <artifactId>queue</artifactId>
  44 + </dependency>
  45 + <dependency>
  46 + <groupId>org.thingsboard.common</groupId>
  47 + <artifactId>data</artifactId>
  48 + </dependency>
  49 + <dependency>
  50 + <groupId>org.thingsboard.common.transport</groupId>
  51 + <artifactId>transport-api</artifactId>
  52 + </dependency>
  53 + <dependency>
  54 + <groupId>org.springframework</groupId>
  55 + <artifactId>spring-context</artifactId>
  56 + </dependency>
  57 + <dependency>
  58 + <groupId>org.springframework.boot</groupId>
  59 + <artifactId>spring-boot-starter-web</artifactId>
  60 + <scope>provided</scope>
  61 + </dependency>
  62 + <dependency>
  63 + <groupId>org.eclipse.californium</groupId>
  64 + <artifactId>californium-core</artifactId>
  65 + </dependency>
  66 + <dependency>
  67 + <groupId>org.eclipse.californium</groupId>
  68 + <artifactId>scandium</artifactId>
  69 + </dependency>
  70 + </dependencies>
  71 +
  72 +
  73 +</project>
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.coapserver;
  17 +
  18 +import lombok.Getter;
  19 +import lombok.extern.slf4j.Slf4j;
  20 +import org.springframework.beans.factory.annotation.Autowired;
  21 +import org.springframework.beans.factory.annotation.Value;
  22 +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  23 +import org.springframework.stereotype.Component;
  24 +
  25 +@Slf4j
  26 +@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.coap.enabled}'=='true')")
  27 +@Component
  28 +public class CoapServerContext {
  29 +
  30 + @Getter
  31 + @Value("${transport.coap.bind_address}")
  32 + private String host;
  33 +
  34 + @Getter
  35 + @Value("${transport.coap.bind_port}")
  36 + private Integer port;
  37 +
  38 + @Getter
  39 + @Value("${transport.coap.timeout}")
  40 + private Long timeout;
  41 +
  42 + @Getter
  43 + @Autowired(required = false)
  44 + private TbCoapDtlsSettings dtlsSettings;
  45 +
  46 +}
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.coapserver;
  17 +
  18 +import org.eclipse.californium.core.CoapServer;
  19 +
  20 +import java.net.UnknownHostException;
  21 +import java.util.concurrent.ConcurrentMap;
  22 +
  23 +public interface CoapServerService {
  24 +
  25 + CoapServer getCoapServer() throws UnknownHostException;
  26 +
  27 + ConcurrentMap<String, TbCoapDtlsSessionInfo> getDtlsSessionsMap();
  28 +
  29 + long getTimeout();
  30 +
  31 +}
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.coapserver;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.eclipse.californium.core.CoapServer;
  20 +import org.eclipse.californium.core.network.CoapEndpoint;
  21 +import org.eclipse.californium.core.network.config.NetworkConfig;
  22 +import org.eclipse.californium.core.server.resources.Resource;
  23 +import org.eclipse.californium.scandium.DTLSConnector;
  24 +import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
  25 +import org.springframework.beans.factory.annotation.Autowired;
  26 +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  27 +import org.springframework.stereotype.Component;
  28 +
  29 +import javax.annotation.PostConstruct;
  30 +import javax.annotation.PreDestroy;
  31 +import java.net.InetAddress;
  32 +import java.net.InetSocketAddress;
  33 +import java.net.UnknownHostException;
  34 +import java.util.Random;
  35 +import java.util.concurrent.ConcurrentMap;
  36 +import java.util.concurrent.Executors;
  37 +import java.util.concurrent.ScheduledExecutorService;
  38 +import java.util.concurrent.TimeUnit;
  39 +
  40 +@Slf4j
  41 +@Component
  42 +@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.coap.enabled}'=='true')")
  43 +public class DefaultCoapServerService implements CoapServerService {
  44 +
  45 + @Autowired
  46 + private CoapServerContext coapServerContext;
  47 +
  48 + private CoapServer server;
  49 +
  50 + private TbCoapDtlsCertificateVerifier tbDtlsCertificateVerifier;
  51 +
  52 + private ScheduledExecutorService dtlsSessionsExecutor;
  53 +
  54 + @PostConstruct
  55 + public void init() throws UnknownHostException {
  56 + createCoapServer();
  57 + }
  58 +
  59 + @PreDestroy
  60 + public void shutdown() {
  61 + if (dtlsSessionsExecutor != null) {
  62 + dtlsSessionsExecutor.shutdownNow();
  63 + }
  64 + log.info("Stopping CoAP server!");
  65 + server.destroy();
  66 + log.info("CoAP server stopped!");
  67 + }
  68 +
  69 + @Override
  70 + public CoapServer getCoapServer() throws UnknownHostException {
  71 + if (server != null) {
  72 + return server;
  73 + } else {
  74 + return createCoapServer();
  75 + }
  76 + }
  77 +
  78 + @Override
  79 + public ConcurrentMap<String, TbCoapDtlsSessionInfo> getDtlsSessionsMap() {
  80 + return tbDtlsCertificateVerifier != null ? tbDtlsCertificateVerifier.getTbCoapDtlsSessionIdsMap() : null;
  81 + }
  82 +
  83 + @Override
  84 + public long getTimeout() {
  85 + return coapServerContext.getTimeout();
  86 + }
  87 +
  88 + private CoapServer createCoapServer() throws UnknownHostException {
  89 + server = new CoapServer();
  90 +
  91 + CoapEndpoint.Builder noSecCoapEndpointBuilder = new CoapEndpoint.Builder();
  92 + InetAddress addr = InetAddress.getByName(coapServerContext.getHost());
  93 + InetSocketAddress sockAddr = new InetSocketAddress(addr, coapServerContext.getPort());
  94 + noSecCoapEndpointBuilder.setInetSocketAddress(sockAddr);
  95 + noSecCoapEndpointBuilder.setNetworkConfig(NetworkConfig.getStandard());
  96 + CoapEndpoint noSecCoapEndpoint = noSecCoapEndpointBuilder.build();
  97 + server.addEndpoint(noSecCoapEndpoint);
  98 +
  99 + if (isDtlsEnabled()) {
  100 + CoapEndpoint.Builder dtlsCoapEndpointBuilder = new CoapEndpoint.Builder();
  101 + TbCoapDtlsSettings dtlsSettings = coapServerContext.getDtlsSettings();
  102 + DtlsConnectorConfig dtlsConnectorConfig = dtlsSettings.dtlsConnectorConfig();
  103 + DTLSConnector connector = new DTLSConnector(dtlsConnectorConfig);
  104 + dtlsCoapEndpointBuilder.setConnector(connector);
  105 + CoapEndpoint dtlsCoapEndpoint = dtlsCoapEndpointBuilder.build();
  106 + server.addEndpoint(dtlsCoapEndpoint);
  107 + if (dtlsConnectorConfig.isClientAuthenticationRequired()) {
  108 + tbDtlsCertificateVerifier = (TbCoapDtlsCertificateVerifier) dtlsConnectorConfig.getAdvancedCertificateVerifier();
  109 + dtlsSessionsExecutor = Executors.newSingleThreadScheduledExecutor();
  110 + dtlsSessionsExecutor.scheduleAtFixedRate(this::evictTimeoutSessions, new Random().nextInt((int) getDtlsSessionReportTimeout()), getDtlsSessionReportTimeout(), TimeUnit.MILLISECONDS);
  111 + }
  112 + }
  113 + Resource root = server.getRoot();
  114 + TbCoapServerMessageDeliverer messageDeliverer = new TbCoapServerMessageDeliverer(root);
  115 + server.setMessageDeliverer(messageDeliverer);
  116 +
  117 + server.start();
  118 + return server;
  119 + }
  120 +
  121 + private boolean isDtlsEnabled() {
  122 + return coapServerContext.getDtlsSettings() != null;
  123 + }
  124 +
  125 + private void evictTimeoutSessions() {
  126 + tbDtlsCertificateVerifier.evictTimeoutSessions();
  127 + }
  128 +
  129 + private long getDtlsSessionReportTimeout() {
  130 + return tbDtlsCertificateVerifier.getDtlsSessionReportTimeout();
  131 + }
  132 +
  133 +}
common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsCertificateVerifier.java renamed from common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/TbCoapDtlsCertificateVerifier.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.transport.coap; 16 +package org.thingsboard.server.coapserver;
17 17
18 import lombok.Data; 18 import lombok.Data;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsSessionInMemoryStorage.java renamed from common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/TbCoapDtlsSessionInMemoryStorage.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.transport.coap; 16 +package org.thingsboard.server.coapserver;
17 17
18 import lombok.Data; 18 import lombok.Data;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsSessionInfo.java renamed from common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/TbCoapDtlsSessionInfo.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.transport.coap; 16 +package org.thingsboard.server.coapserver;
17 17
18 import lombok.Data; 18 import lombok.Data;
19 import org.thingsboard.server.common.data.DeviceProfile; 19 import org.thingsboard.server.common.data.DeviceProfile;
common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsSettings.java renamed from common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/TbCoapDtlsSettings.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.transport.coap; 16 +package org.thingsboard.server.coapserver;
17 17
18 import com.google.common.io.Resources; 18 import com.google.common.io.Resources;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
@@ -39,15 +39,15 @@ import java.util.Collections; @@ -39,15 +39,15 @@ import java.util.Collections;
39 import java.util.Optional; 39 import java.util.Optional;
40 40
41 @Slf4j 41 @Slf4j
  42 +@ConditionalOnExpression("'${transport.coap.enabled}'=='true'")
42 @ConditionalOnProperty(prefix = "transport.coap.dtls", value = "enabled", havingValue = "true", matchIfMissing = false) 43 @ConditionalOnProperty(prefix = "transport.coap.dtls", value = "enabled", havingValue = "true", matchIfMissing = false)
43 -@ConditionalOnExpression("'${transport.type:null}'=='null' || ('${transport.type}'=='local' && '${transport.coap.enabled}'=='true')")  
44 @Component 44 @Component
45 public class TbCoapDtlsSettings { 45 public class TbCoapDtlsSettings {
46 46
47 - @Value("${transport.coap.bind_address}") 47 + @Value("${transport.coap.dtls.bind_address}")
48 private String host; 48 private String host;
49 49
50 - @Value("${transport.coap.bind_port}") 50 + @Value("${transport.coap.dtls.bind_port}")
51 private Integer port; 51 private Integer port;
52 52
53 @Value("${transport.coap.dtls.mode}") 53 @Value("${transport.coap.dtls.mode}")
common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapServerMessageDeliverer.java renamed from common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/TbCoapServerMessageDeliverer.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.transport.coap; 16 +package org.thingsboard.server.coapserver;
17 17
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.eclipse.californium.core.coap.OptionSet; 19 import org.eclipse.californium.core.coap.OptionSet;
@@ -43,6 +43,7 @@ @@ -43,6 +43,7 @@
43 <module>dao-api</module> 43 <module>dao-api</module>
44 <module>stats</module> 44 <module>stats</module>
45 <module>cache</module> 45 <module>cache</module>
  46 + <module>coap-server</module>
46 </modules> 47 </modules>
47 48
48 </project> 49 </project>
@@ -41,6 +41,10 @@ @@ -41,6 +41,10 @@
41 <artifactId>transport-api</artifactId> 41 <artifactId>transport-api</artifactId>
42 </dependency> 42 </dependency>
43 <dependency> 43 <dependency>
  44 + <groupId>org.thingsboard.common</groupId>
  45 + <artifactId>coap-server</artifactId>
  46 + </dependency>
  47 + <dependency>
44 <groupId>org.eclipse.californium</groupId> 48 <groupId>org.eclipse.californium</groupId>
45 <artifactId>californium-core</artifactId> 49 <artifactId>californium-core</artifactId>
46 </dependency> 50 </dependency>
@@ -18,13 +18,12 @@ package org.thingsboard.server.transport.coap; @@ -18,13 +18,12 @@ package org.thingsboard.server.transport.coap;
18 import lombok.Getter; 18 import lombok.Getter;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
21 -import org.springframework.beans.factory.annotation.Value;  
22 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 21 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
23 import org.springframework.stereotype.Component; 22 import org.springframework.stereotype.Component;
24 import org.thingsboard.server.common.transport.TransportContext; 23 import org.thingsboard.server.common.transport.TransportContext;
25 -import org.thingsboard.server.transport.coap.efento.adaptor.EfentoCoapAdaptor;  
26 import org.thingsboard.server.transport.coap.adaptors.JsonCoapAdaptor; 24 import org.thingsboard.server.transport.coap.adaptors.JsonCoapAdaptor;
27 import org.thingsboard.server.transport.coap.adaptors.ProtoCoapAdaptor; 25 import org.thingsboard.server.transport.coap.adaptors.ProtoCoapAdaptor;
  26 +import org.thingsboard.server.transport.coap.efento.adaptor.EfentoCoapAdaptor;
28 27
29 28
30 /** 29 /**
@@ -36,22 +35,6 @@ import org.thingsboard.server.transport.coap.adaptors.ProtoCoapAdaptor; @@ -36,22 +35,6 @@ import org.thingsboard.server.transport.coap.adaptors.ProtoCoapAdaptor;
36 public class CoapTransportContext extends TransportContext { 35 public class CoapTransportContext extends TransportContext {
37 36
38 @Getter 37 @Getter
39 - @Value("${transport.coap.bind_address}")  
40 - private String host;  
41 -  
42 - @Getter  
43 - @Value("${transport.coap.bind_port}")  
44 - private Integer port;  
45 -  
46 - @Getter  
47 - @Value("${transport.coap.timeout}")  
48 - private Long timeout;  
49 -  
50 - @Getter  
51 - @Autowired(required = false)  
52 - private TbCoapDtlsSettings dtlsSettings;  
53 -  
54 - @Getter  
55 @Autowired 38 @Autowired
56 private JsonCoapAdaptor jsonCoapAdaptor; 39 private JsonCoapAdaptor jsonCoapAdaptor;
57 40
@@ -28,6 +28,8 @@ import org.eclipse.californium.core.server.resources.CoapExchange; @@ -28,6 +28,8 @@ import org.eclipse.californium.core.server.resources.CoapExchange;
28 import org.eclipse.californium.core.server.resources.Resource; 28 import org.eclipse.californium.core.server.resources.Resource;
29 import org.eclipse.californium.core.server.resources.ResourceObserver; 29 import org.eclipse.californium.core.server.resources.ResourceObserver;
30 import org.springframework.util.StringUtils; 30 import org.springframework.util.StringUtils;
  31 +import org.thingsboard.server.coapserver.CoapServerService;
  32 +import org.thingsboard.server.coapserver.TbCoapDtlsSessionInfo;
31 import org.thingsboard.server.common.data.DataConstants; 33 import org.thingsboard.server.common.data.DataConstants;
32 import org.thingsboard.server.common.data.DeviceProfile; 34 import org.thingsboard.server.common.data.DeviceProfile;
33 import org.thingsboard.server.common.data.DeviceTransportType; 35 import org.thingsboard.server.common.data.DeviceTransportType;
@@ -74,12 +76,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -74,12 +76,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
74 private final Set<UUID> attributeSubscriptions = ConcurrentHashMap.newKeySet(); 76 private final Set<UUID> attributeSubscriptions = ConcurrentHashMap.newKeySet();
75 77
76 private ConcurrentMap<String, TbCoapDtlsSessionInfo> dtlsSessionIdMap; 78 private ConcurrentMap<String, TbCoapDtlsSessionInfo> dtlsSessionIdMap;
  79 + private long timeout;
77 80
78 - public CoapTransportResource(CoapTransportContext coapTransportContext, ConcurrentMap<String, TbCoapDtlsSessionInfo> dtlsSessionIdMap, String name) { 81 + public CoapTransportResource(CoapTransportContext coapTransportContext, CoapServerService coapServerService, String name) {
79 super(coapTransportContext, name); 82 super(coapTransportContext, name);
80 this.setObservable(true); // enable observing 83 this.setObservable(true); // enable observing
81 this.addObserver(new CoapResourceObserver()); 84 this.addObserver(new CoapResourceObserver());
82 - this.dtlsSessionIdMap = dtlsSessionIdMap; 85 + this.dtlsSessionIdMap = coapServerService.getDtlsSessionsMap();
  86 + this.timeout = coapServerService.getTimeout();
83 // this.setObservable(false); // disable observing 87 // this.setObservable(false); // disable observing
84 // this.setObserveType(CoAP.Type.CON); // configure the notification type to CONs 88 // this.setObserveType(CoAP.Type.CON); // configure the notification type to CONs
85 // this.getAttributes().setObservable(); // mark observable in the Link-Format 89 // this.getAttributes().setObservable(); // mark observable in the Link-Format
@@ -303,13 +307,13 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -303,13 +307,13 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
303 new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR)); 307 new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
304 break; 308 break;
305 case TO_SERVER_RPC_REQUEST: 309 case TO_SERVER_RPC_REQUEST:
306 - transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), transportContext.getTimeout()); 310 + transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), timeout);
307 transportService.process(sessionInfo, 311 transportService.process(sessionInfo,
308 coapTransportAdaptor.convertToServerRpcRequest(sessionId, request), 312 coapTransportAdaptor.convertToServerRpcRequest(sessionId, request),
309 new CoapNoOpCallback(exchange)); 313 new CoapNoOpCallback(exchange));
310 break; 314 break;
311 case GET_ATTRIBUTES_REQUEST: 315 case GET_ATTRIBUTES_REQUEST:
312 - transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), transportContext.getTimeout()); 316 + transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), timeout);
313 transportService.process(sessionInfo, 317 transportService.process(sessionInfo,
314 coapTransportAdaptor.convertToGetAttributes(sessionId, request), 318 coapTransportAdaptor.convertToGetAttributes(sessionId, request),
315 new CoapNoOpCallback(exchange)); 319 new CoapNoOpCallback(exchange));
@@ -18,26 +18,15 @@ package org.thingsboard.server.transport.coap; @@ -18,26 +18,15 @@ package org.thingsboard.server.transport.coap;
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.eclipse.californium.core.CoapResource; 19 import org.eclipse.californium.core.CoapResource;
20 import org.eclipse.californium.core.CoapServer; 20 import org.eclipse.californium.core.CoapServer;
21 -import org.eclipse.californium.core.network.CoapEndpoint;  
22 -import org.eclipse.californium.core.network.config.NetworkConfig;  
23 -import org.eclipse.californium.core.server.resources.Resource;  
24 -import org.eclipse.californium.scandium.DTLSConnector;  
25 -import org.eclipse.californium.scandium.config.DtlsConnectorConfig;  
26 import org.springframework.beans.factory.annotation.Autowired; 21 import org.springframework.beans.factory.annotation.Autowired;
27 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 22 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
28 import org.springframework.stereotype.Service; 23 import org.springframework.stereotype.Service;
  24 +import org.thingsboard.server.coapserver.CoapServerService;
29 import org.thingsboard.server.transport.coap.efento.CoapEfentoTransportResource; 25 import org.thingsboard.server.transport.coap.efento.CoapEfentoTransportResource;
30 26
31 import javax.annotation.PostConstruct; 27 import javax.annotation.PostConstruct;
32 import javax.annotation.PreDestroy; 28 import javax.annotation.PreDestroy;
33 -import java.net.InetAddress;  
34 -import java.net.InetSocketAddress;  
35 import java.net.UnknownHostException; 29 import java.net.UnknownHostException;
36 -import java.util.Random;  
37 -import java.util.concurrent.ConcurrentMap;  
38 -import java.util.concurrent.Executors;  
39 -import java.util.concurrent.ScheduledExecutorService;  
40 -import java.util.concurrent.TimeUnit;  
41 30
42 @Service("CoapTransportService") 31 @Service("CoapTransportService")
43 @ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.coap.enabled}'=='true')") 32 @ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.coap.enabled}'=='true')")
@@ -50,87 +39,30 @@ public class CoapTransportService { @@ -50,87 +39,30 @@ public class CoapTransportService {
50 private static final String MEASUREMENTS = "m"; 39 private static final String MEASUREMENTS = "m";
51 40
52 @Autowired 41 @Autowired
53 - private CoapTransportContext coapTransportContext;  
54 -  
55 - private TbCoapDtlsCertificateVerifier tbDtlsCertificateVerifier; 42 + private CoapServerService coapServerService;
56 43
57 - private CoapServer server; 44 + @Autowired
  45 + private CoapTransportContext coapTransportContext;
58 46
59 - private ScheduledExecutorService dtlsSessionsExecutor; 47 + private CoapServer coapServer;
60 48
61 @PostConstruct 49 @PostConstruct
62 public void init() throws UnknownHostException { 50 public void init() throws UnknownHostException {
63 log.info("Starting CoAP transport..."); 51 log.info("Starting CoAP transport...");
64 - log.info("Starting CoAP transport server");  
65 -  
66 - this.server = new CoapServer();  
67 -  
68 - CoapEndpoint.Builder capEndpointBuilder = new CoapEndpoint.Builder();  
69 -  
70 - if (isDtlsEnabled()) {  
71 - TbCoapDtlsSettings dtlsSettings = coapTransportContext.getDtlsSettings();  
72 - DtlsConnectorConfig dtlsConnectorConfig = dtlsSettings.dtlsConnectorConfig();  
73 - DTLSConnector connector = new DTLSConnector(dtlsConnectorConfig);  
74 - capEndpointBuilder.setConnector(connector);  
75 - if (dtlsConnectorConfig.isClientAuthenticationRequired()) {  
76 - tbDtlsCertificateVerifier = (TbCoapDtlsCertificateVerifier) dtlsConnectorConfig.getAdvancedCertificateVerifier();  
77 - dtlsSessionsExecutor = Executors.newSingleThreadScheduledExecutor();  
78 - dtlsSessionsExecutor.scheduleAtFixedRate(this::evictTimeoutSessions, new Random().nextInt((int) getDtlsSessionReportTimeout()), getDtlsSessionReportTimeout(), TimeUnit.MILLISECONDS);  
79 - }  
80 - } else {  
81 - InetAddress addr = InetAddress.getByName(coapTransportContext.getHost());  
82 - InetSocketAddress sockAddr = new InetSocketAddress(addr, coapTransportContext.getPort());  
83 - capEndpointBuilder.setInetSocketAddress(sockAddr);  
84 - capEndpointBuilder.setNetworkConfig(NetworkConfig.getStandard());  
85 - }  
86 - CoapEndpoint coapEndpoint = capEndpointBuilder.build();  
87 -  
88 - server.addEndpoint(coapEndpoint);  
89 -  
90 - createResources();  
91 - Resource root = this.server.getRoot();  
92 - TbCoapServerMessageDeliverer messageDeliverer = new TbCoapServerMessageDeliverer(root);  
93 - this.server.setMessageDeliverer(messageDeliverer);  
94 -  
95 - server.start();  
96 - log.info("CoAP transport started!");  
97 - }  
98 -  
99 - private void createResources() { 52 + coapServer = coapServerService.getCoapServer();
100 CoapResource api = new CoapResource(API); 53 CoapResource api = new CoapResource(API);
101 - api.add(new CoapTransportResource(coapTransportContext, getDtlsSessionsMap(), V1)); 54 + api.add(new CoapTransportResource(coapTransportContext, coapServerService, V1));
102 55
103 CoapResource efento = new CoapResource(EFENTO); 56 CoapResource efento = new CoapResource(EFENTO);
104 CoapEfentoTransportResource efentoMeasurementsTransportResource = new CoapEfentoTransportResource(coapTransportContext, MEASUREMENTS); 57 CoapEfentoTransportResource efentoMeasurementsTransportResource = new CoapEfentoTransportResource(coapTransportContext, MEASUREMENTS);
105 efento.add(efentoMeasurementsTransportResource); 58 efento.add(efentoMeasurementsTransportResource);
106 -  
107 - server.add(api);  
108 - server.add(efento);  
109 - }  
110 -  
111 - private boolean isDtlsEnabled() {  
112 - return coapTransportContext.getDtlsSettings() != null;  
113 - }  
114 -  
115 - private ConcurrentMap<String, TbCoapDtlsSessionInfo> getDtlsSessionsMap() {  
116 - return tbDtlsCertificateVerifier != null ? tbDtlsCertificateVerifier.getTbCoapDtlsSessionIdsMap() : null;  
117 - }  
118 -  
119 - private void evictTimeoutSessions() {  
120 - tbDtlsCertificateVerifier.evictTimeoutSessions();  
121 - }  
122 -  
123 - private long getDtlsSessionReportTimeout() {  
124 - return tbDtlsCertificateVerifier.getDtlsSessionReportTimeout(); 59 + coapServer.add(api);
  60 + coapServer.add(efento);
  61 + log.info("CoAP transport started!");
125 } 62 }
126 63
127 @PreDestroy 64 @PreDestroy
128 public void shutdown() { 65 public void shutdown() {
129 - if (dtlsSessionsExecutor != null) {  
130 - dtlsSessionsExecutor.shutdownNow();  
131 - }  
132 - log.info("Stopping CoAP transport!");  
133 - this.server.destroy();  
134 log.info("CoAP transport stopped!"); 66 log.info("CoAP transport stopped!");
135 } 67 }
136 } 68 }
@@ -55,7 +55,7 @@ import java.util.concurrent.TimeUnit; @@ -55,7 +55,7 @@ import java.util.concurrent.TimeUnit;
55 */ 55 */
56 @Slf4j 56 @Slf4j
57 @Component("MqttSslHandlerProvider") 57 @Component("MqttSslHandlerProvider")
58 -@ConditionalOnExpression("'${transport.type:null}'=='null' || ('${transport.type}'=='local' && '${transport.mqtt.enabled}'=='true')") 58 +@ConditionalOnExpression("'${transport.mqtt.enabled}'=='true'")
59 @ConditionalOnProperty(prefix = "transport.mqtt.ssl", value = "enabled", havingValue = "true", matchIfMissing = false) 59 @ConditionalOnProperty(prefix = "transport.mqtt.ssl", value = "enabled", havingValue = "true", matchIfMissing = false)
60 public class MqttSslHandlerProvider { 60 public class MqttSslHandlerProvider {
61 61
@@ -934,6 +934,11 @@ @@ -934,6 +934,11 @@
934 <version>${project.version}</version> 934 <version>${project.version}</version>
935 </dependency> 935 </dependency>
936 <dependency> 936 <dependency>
  937 + <groupId>org.thingsboard.common</groupId>
  938 + <artifactId>coap-server</artifactId>
  939 + <version>${project.version}</version>
  940 + </dependency>
  941 + <dependency>
937 <groupId>org.thingsboard</groupId> 942 <groupId>org.thingsboard</groupId>
938 <artifactId>tools</artifactId> 943 <artifactId>tools</artifactId>
939 <version>${project.version}</version> 944 <version>${project.version}</version>
@@ -26,7 +26,7 @@ import java.util.Arrays; @@ -26,7 +26,7 @@ import java.util.Arrays;
26 @SpringBootConfiguration 26 @SpringBootConfiguration
27 @EnableAsync 27 @EnableAsync
28 @EnableScheduling 28 @EnableScheduling
29 -@ComponentScan({"org.thingsboard.server.coap", "org.thingsboard.server.common", "org.thingsboard.server.transport.coap", "org.thingsboard.server.queue"}) 29 +@ComponentScan({"org.thingsboard.server.coap", "org.thingsboard.server.common", "org.thingsboard.server.coapserver", "org.thingsboard.server.transport.coap", "org.thingsboard.server.queue"})
30 public class ThingsboardCoapTransportApplication { 30 public class ThingsboardCoapTransportApplication {
31 31
32 private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name"; 32 private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name";
@@ -49,6 +49,10 @@ transport: @@ -49,6 +49,10 @@ transport:
49 dtls: 49 dtls:
50 # Enable/disable DTLS 1.2 support 50 # Enable/disable DTLS 1.2 support
51 enabled: "${COAP_DTLS_ENABLED:false}" 51 enabled: "${COAP_DTLS_ENABLED:false}"
  52 + # CoAP DTLS bind address
  53 + bind_address: "${COAP_DTLS_BIND_ADDRESS:0.0.0.0}"
  54 + # CoAP DTLS bind port
  55 + bind_port: "${COAP_DTLS_BIND_PORT:5684}"
52 # Secure mode. Allowed values: NO_AUTH, X509 56 # Secure mode. Allowed values: NO_AUTH, X509
53 mode: "${COAP_DTLS_SECURE_MODE:NO_AUTH}" 57 mode: "${COAP_DTLS_SECURE_MODE:NO_AUTH}"
54 # Path to the key store that holds the certificate 58 # Path to the key store that holds the certificate