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:
|
dtls:
|
||||||
# Enable/disable DTLS 1.2 support
|
# Enable/disable DTLS 1.2 support
|
||||||
enabled: "${COAP_DTLS_ENABLED:false}"
|
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
|
# Secure mode. Allowed values: NO_AUTH, X509
|
||||||
mode: "${COAP_DTLS_SECURE_MODE:NO_AUTH}"
|
mode: "${COAP_DTLS_SECURE_MODE:NO_AUTH}"
|
||||||
# Path to the key store that holds the certificate
|
# 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.thingsboard.server.transport.coap;
|
package org.thingsboard.server.coapserver;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.thingsboard.server.transport.coap;
|
package org.thingsboard.server.coapserver;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.thingsboard.server.transport.coap;
|
package org.thingsboard.server.coapserver;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.thingsboard.server.common.data.DeviceProfile;
|
import org.thingsboard.server.common.data.DeviceProfile;
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.thingsboard.server.transport.coap;
|
package org.thingsboard.server.coapserver;
|
||||||
|
|
||||||
import com.google.common.io.Resources;
|
import com.google.common.io.Resources;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -39,15 +39,15 @@ import java.util.Collections;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ConditionalOnExpression("'${transport.coap.enabled}'=='true'")
|
||||||
@ConditionalOnProperty(prefix = "transport.coap.dtls", value = "enabled", havingValue = "true", matchIfMissing = false)
|
@ConditionalOnProperty(prefix = "transport.coap.dtls", value = "enabled", havingValue = "true", matchIfMissing = false)
|
||||||
@ConditionalOnExpression("'${transport.type:null}'=='null' || ('${transport.type}'=='local' && '${transport.coap.enabled}'=='true')")
|
|
||||||
@Component
|
@Component
|
||||||
public class TbCoapDtlsSettings {
|
public class TbCoapDtlsSettings {
|
||||||
|
|
||||||
@Value("${transport.coap.bind_address}")
|
@Value("${transport.coap.dtls.bind_address}")
|
||||||
private String host;
|
private String host;
|
||||||
|
|
||||||
@Value("${transport.coap.bind_port}")
|
@Value("${transport.coap.dtls.bind_port}")
|
||||||
private Integer port;
|
private Integer port;
|
||||||
|
|
||||||
@Value("${transport.coap.dtls.mode}")
|
@Value("${transport.coap.dtls.mode}")
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.thingsboard.server.transport.coap;
|
package org.thingsboard.server.coapserver;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.californium.core.coap.OptionSet;
|
import org.eclipse.californium.core.coap.OptionSet;
|
||||||
@ -43,6 +43,7 @@
|
|||||||
<module>dao-api</module>
|
<module>dao-api</module>
|
||||||
<module>stats</module>
|
<module>stats</module>
|
||||||
<module>cache</module>
|
<module>cache</module>
|
||||||
|
<module>coap-server</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@ -40,6 +40,10 @@
|
|||||||
<groupId>org.thingsboard.common.transport</groupId>
|
<groupId>org.thingsboard.common.transport</groupId>
|
||||||
<artifactId>transport-api</artifactId>
|
<artifactId>transport-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.thingsboard.common</groupId>
|
||||||
|
<artifactId>coap-server</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.californium</groupId>
|
<groupId>org.eclipse.californium</groupId>
|
||||||
<artifactId>californium-core</artifactId>
|
<artifactId>californium-core</artifactId>
|
||||||
|
|||||||
@ -18,13 +18,12 @@ package org.thingsboard.server.transport.coap;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.thingsboard.server.common.transport.TransportContext;
|
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.JsonCoapAdaptor;
|
||||||
import org.thingsboard.server.transport.coap.adaptors.ProtoCoapAdaptor;
|
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
|
@Component
|
||||||
public class CoapTransportContext extends TransportContext {
|
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
|
@Getter
|
||||||
@Autowired
|
@Autowired
|
||||||
private JsonCoapAdaptor jsonCoapAdaptor;
|
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.Resource;
|
||||||
import org.eclipse.californium.core.server.resources.ResourceObserver;
|
import org.eclipse.californium.core.server.resources.ResourceObserver;
|
||||||
import org.springframework.util.StringUtils;
|
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.DataConstants;
|
||||||
import org.thingsboard.server.common.data.DeviceProfile;
|
import org.thingsboard.server.common.data.DeviceProfile;
|
||||||
import org.thingsboard.server.common.data.DeviceTransportType;
|
import org.thingsboard.server.common.data.DeviceTransportType;
|
||||||
@ -74,12 +76,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
|
|||||||
private final Set<UUID> attributeSubscriptions = ConcurrentHashMap.newKeySet();
|
private final Set<UUID> attributeSubscriptions = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
private ConcurrentMap<String, TbCoapDtlsSessionInfo> dtlsSessionIdMap;
|
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);
|
super(coapTransportContext, name);
|
||||||
this.setObservable(true); // enable observing
|
this.setObservable(true); // enable observing
|
||||||
this.addObserver(new CoapResourceObserver());
|
this.addObserver(new CoapResourceObserver());
|
||||||
this.dtlsSessionIdMap = dtlsSessionIdMap;
|
this.dtlsSessionIdMap = coapServerService.getDtlsSessionsMap();
|
||||||
|
this.timeout = coapServerService.getTimeout();
|
||||||
// this.setObservable(false); // disable observing
|
// this.setObservable(false); // disable observing
|
||||||
// this.setObserveType(CoAP.Type.CON); // configure the notification type to CONs
|
// this.setObserveType(CoAP.Type.CON); // configure the notification type to CONs
|
||||||
// this.getAttributes().setObservable(); // mark observable in the Link-Format
|
// 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));
|
new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
|
||||||
break;
|
break;
|
||||||
case TO_SERVER_RPC_REQUEST:
|
case TO_SERVER_RPC_REQUEST:
|
||||||
transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), transportContext.getTimeout());
|
transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), timeout);
|
||||||
transportService.process(sessionInfo,
|
transportService.process(sessionInfo,
|
||||||
coapTransportAdaptor.convertToServerRpcRequest(sessionId, request),
|
coapTransportAdaptor.convertToServerRpcRequest(sessionId, request),
|
||||||
new CoapNoOpCallback(exchange));
|
new CoapNoOpCallback(exchange));
|
||||||
break;
|
break;
|
||||||
case GET_ATTRIBUTES_REQUEST:
|
case GET_ATTRIBUTES_REQUEST:
|
||||||
transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), transportContext.getTimeout());
|
transportService.registerSyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor), timeout);
|
||||||
transportService.process(sessionInfo,
|
transportService.process(sessionInfo,
|
||||||
coapTransportAdaptor.convertToGetAttributes(sessionId, request),
|
coapTransportAdaptor.convertToGetAttributes(sessionId, request),
|
||||||
new CoapNoOpCallback(exchange));
|
new CoapNoOpCallback(exchange));
|
||||||
|
|||||||
@ -18,26 +18,15 @@ package org.thingsboard.server.transport.coap;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.californium.core.CoapResource;
|
import org.eclipse.californium.core.CoapResource;
|
||||||
import org.eclipse.californium.core.CoapServer;
|
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.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.thingsboard.server.coapserver.CoapServerService;
|
||||||
import org.thingsboard.server.transport.coap.efento.CoapEfentoTransportResource;
|
import org.thingsboard.server.transport.coap.efento.CoapEfentoTransportResource;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.UnknownHostException;
|
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")
|
@Service("CoapTransportService")
|
||||||
@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${transport.coap.enabled}'=='true')")
|
@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 EFENTO = "efento";
|
||||||
private static final String MEASUREMENTS = "m";
|
private static final String MEASUREMENTS = "m";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CoapServerService coapServerService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CoapTransportContext coapTransportContext;
|
private CoapTransportContext coapTransportContext;
|
||||||
|
|
||||||
private TbCoapDtlsCertificateVerifier tbDtlsCertificateVerifier;
|
private CoapServer coapServer;
|
||||||
|
|
||||||
private CoapServer server;
|
|
||||||
|
|
||||||
private ScheduledExecutorService dtlsSessionsExecutor;
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() throws UnknownHostException {
|
public void init() throws UnknownHostException {
|
||||||
log.info("Starting CoAP transport...");
|
log.info("Starting CoAP transport...");
|
||||||
log.info("Starting CoAP transport server");
|
coapServer = coapServerService.getCoapServer();
|
||||||
|
|
||||||
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() {
|
|
||||||
CoapResource api = new CoapResource(API);
|
CoapResource api = new CoapResource(API);
|
||||||
api.add(new CoapTransportResource(coapTransportContext, getDtlsSessionsMap(), V1));
|
api.add(new CoapTransportResource(coapTransportContext, coapServerService, V1));
|
||||||
|
|
||||||
CoapResource efento = new CoapResource(EFENTO);
|
CoapResource efento = new CoapResource(EFENTO);
|
||||||
CoapEfentoTransportResource efentoMeasurementsTransportResource = new CoapEfentoTransportResource(coapTransportContext, MEASUREMENTS);
|
CoapEfentoTransportResource efentoMeasurementsTransportResource = new CoapEfentoTransportResource(coapTransportContext, MEASUREMENTS);
|
||||||
efento.add(efentoMeasurementsTransportResource);
|
efento.add(efentoMeasurementsTransportResource);
|
||||||
|
coapServer.add(api);
|
||||||
server.add(api);
|
coapServer.add(efento);
|
||||||
server.add(efento);
|
log.info("CoAP transport started!");
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
if (dtlsSessionsExecutor != null) {
|
|
||||||
dtlsSessionsExecutor.shutdownNow();
|
|
||||||
}
|
|
||||||
log.info("Stopping CoAP transport!");
|
|
||||||
this.server.destroy();
|
|
||||||
log.info("CoAP transport stopped!");
|
log.info("CoAP transport stopped!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component("MqttSslHandlerProvider")
|
@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)
|
@ConditionalOnProperty(prefix = "transport.mqtt.ssl", value = "enabled", havingValue = "true", matchIfMissing = false)
|
||||||
public class MqttSslHandlerProvider {
|
public class MqttSslHandlerProvider {
|
||||||
|
|
||||||
|
|||||||
5
pom.xml
5
pom.xml
@ -933,6 +933,11 @@
|
|||||||
<artifactId>stats</artifactId>
|
<artifactId>stats</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.thingsboard.common</groupId>
|
||||||
|
<artifactId>coap-server</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.thingsboard</groupId>
|
<groupId>org.thingsboard</groupId>
|
||||||
<artifactId>tools</artifactId>
|
<artifactId>tools</artifactId>
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import java.util.Arrays;
|
|||||||
@SpringBootConfiguration
|
@SpringBootConfiguration
|
||||||
@EnableAsync
|
@EnableAsync
|
||||||
@EnableScheduling
|
@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 {
|
public class ThingsboardCoapTransportApplication {
|
||||||
|
|
||||||
private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name";
|
private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name";
|
||||||
|
|||||||
@ -49,6 +49,10 @@ transport:
|
|||||||
dtls:
|
dtls:
|
||||||
# Enable/disable DTLS 1.2 support
|
# Enable/disable DTLS 1.2 support
|
||||||
enabled: "${COAP_DTLS_ENABLED:false}"
|
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
|
# Secure mode. Allowed values: NO_AUTH, X509
|
||||||
mode: "${COAP_DTLS_SECURE_MODE:NO_AUTH}"
|
mode: "${COAP_DTLS_SECURE_MODE:NO_AUTH}"
|
||||||
# Path to the key store that holds the certificate
|
# Path to the key store that holds the certificate
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user