Commit dc8755083566b79cc878a2cb27668152a9f9ad78
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 |
common/coap-server/pom.xml
0 → 100644
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> |
common/coap-server/src/main/java/org/thingsboard/server/coapserver/CoapServerContext.java
0 → 100644
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 | +} |
common/coap-server/src/main/java/org/thingsboard/server/coapserver/CoapServerService.java
0 → 100644
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 | +} |
common/coap-server/src/main/java/org/thingsboard/server/coapserver/DefaultCoapServerService.java
0 → 100644
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; |
@@ -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 |
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java
@@ -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 |