Browse Source
* init commit: coap-server component * move coap-server to separate module * fix typopull/4493/head
committed by
GitHub
19 changed files with 330 additions and 110 deletions
@ -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(); |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue