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