@ -15,6 +15,8 @@
* /
package org.thingsboard.server.dao.util ;
import org.springframework.core.io.ByteArrayResource ;
import org.springframework.core.io.Resource ;
import org.thingsboard.common.util.JacksonUtil ;
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials ;
import org.thingsboard.server.common.data.security.DeviceCredentials ;
@ -25,6 +27,7 @@ import java.net.InetAddress;
import java.net.URI ;
import java.net.URISyntaxException ;
import java.net.UnknownHostException ;
import java.nio.charset.StandardCharsets ;
import java.util.regex.Pattern ;
public class DeviceConnectivityUtil {
@ -40,13 +43,10 @@ public class DeviceConnectivityUtil {
public static final String COAP = "coap" ;
public static final String COAPS = "coaps" ;
public static final String CA_ROOT_CERT_PEM = "ca-root.pem" ;
public static final String CA_ROOT_GATEWAY_CERT_PEM_PATH = "{gatewayVolumePathPrefix}config{pathSep}" + CA_ROOT_CERT_PEM ;
public static final String DOCKER_COMPOSE_YML = "docker-compose.yml" ;
public static final String CHECK_DOCUMENTATION = "Check documentation" ;
public static final String JSON_EXAMPLE_PAYLOAD = "\"{temperature:25}\"" ;
public static final String DOCKER_RUN = "docker run --rm -it " ;
public static final String GATEWAY_DOCKER_RUN = "docker run -it " ;
public static final String NETWORK_HOST_PARAM = "--network=host " ;
public static final String HOST_DOCKER_INTERNAL = "host.docker.internal" ;
public static final String ADD_DOCKER_INTERNAL_HOST = "--add-host=" + HOST_DOCKER_INTERNAL + ":host-gateway " ;
public static final String MQTT_IMAGE = "thingsboard/mosquitto-clients " ;
@ -94,75 +94,72 @@ public class DeviceConnectivityUtil {
return command . toString ( ) ;
}
public static String getGatewayLaunchCommand ( String os , String deviceName , DeviceConnectivityInfo properties , DeviceCredentials deviceCredentials , String mqttType , String baseUrl ) throws URISyntaxException {
public static Resource getGatewayDockerComposeFile ( String baseUrl , DeviceConnectivityInfo properties , DeviceCredentials deviceCredentials , String mqttType ) throws URISyntaxException {
String host = getHost ( baseUrl , properties , mqttType ) ;
String port = properties . getPort ( ) . isEmpty ( ) ? null : properties . getPort ( ) ;
String gatewayVolumePathPrefix = "~/.tb-gateway/" ;
String pathSep = "/" ;
if ( WINDOWS . equals ( os ) ) {
gatewayVolumePathPrefix = "%HOMEDRIVE%%HOMEPATH%\\tb-gateway\\" ;
pathSep = "\\" ;
}
String gatewayContainerName = deviceName . replace ( " " , "_" ) . replaceAll ( "[^A-Za-z0-9_.-]" , "" ) ;
StringBuilder command = new StringBuilder ( ) ;
String caRootGatewayCertPemPath = CA_ROOT_GATEWAY_CERT_PEM_PATH
. replace ( "{gatewayVolumePathPrefix}" , gatewayVolumePathPrefix )
. replace ( "{pathSep}" , pathSep ) ;
if ( MQTTS . equals ( mqttType ) ) {
command . append ( getCurlPemCertCommand ( baseUrl , MQTTS , caRootGatewayCertPemPath ) ) ;
command . append ( " && " ) ;
}
command . append ( GATEWAY_DOCKER_RUN ) ;
command . append ( "-v {gatewayVolumePathPrefix}logs:/thingsboard_gateway/logs " . replace ( "{gatewayVolumePathPrefix}" , gatewayVolumePathPrefix ) ) ;
command . append ( "-v {gatewayVolumePathPrefix}extensions:/thingsboard_gateway/extensions " . replace ( "{gatewayVolumePathPrefix}" , gatewayVolumePathPrefix ) ) ;
command . append ( "-v {gatewayVolumePathPrefix}config:/thingsboard_gateway/config " . replace ( "{gatewayVolumePathPrefix}" , gatewayVolumePathPrefix ) ) ;
command . append ( "--name " ) . append ( gatewayContainerName ) . append ( " " ) ;
if ( LINUX . equals ( os ) ) {
command . append ( NETWORK_HOST_PARAM ) ;
command . append ( isLocalhost ( host ) ? ADD_DOCKER_INTERNAL_HOST : "" ) ;
} else {
command . append ( "-p 6400-6420:6400-6420 " ) ;
}
command . append ( "-e host=" ) . append ( isLocalhost ( host ) ? HOST_DOCKER_INTERNAL : host ) ;
if ( port ! = null & & ! "1883" . equals ( port ) ) {
command . append ( " -e port=" ) . append ( port ) ;
}
StringBuilder dockerComposeBuilder = new StringBuilder ( ) ;
dockerComposeBuilder . append ( "version: '3.4'\n" ) ;
dockerComposeBuilder . append ( "services:\n" ) ;
dockerComposeBuilder . append ( " # ThingsBoard IoT Gateway Service Configuration\n" ) ;
dockerComposeBuilder . append ( " tb-gateway:\n" ) ;
dockerComposeBuilder . append ( " image: thingsboard/tb-gateway\n" ) ;
dockerComposeBuilder . append ( " container_name: tb-gateway\n" ) ;
dockerComposeBuilder . append ( " restart: always\n" ) ;
dockerComposeBuilder . append ( "\n" ) ;
dockerComposeBuilder . append ( " # Ports bindings - required by some connectors\n" ) ;
dockerComposeBuilder . append ( " ports:\n" ) ;
dockerComposeBuilder . append ( " - \"5000:5000\" # Comment if you don't use REST connector and change if you use another port\n" ) ;
dockerComposeBuilder . append ( " # Uncomment and modify the following ports based on connector usage:\n" ) ;
dockerComposeBuilder . append ( "# - \"1052:1052\" # BACnet connector\n" ) ;
dockerComposeBuilder . append ( "# - \"5026:5026\" # Modbus TCP connector (Modbus Slave)\n" ) ;
dockerComposeBuilder . append ( "# - \"50000:50000/tcp\" # Socket connector with type TCP\n" ) ;
dockerComposeBuilder . append ( "# - \"50000:50000/udp\" # Socket connector with type UDP\n" ) ;
dockerComposeBuilder . append ( "\n" ) ;
dockerComposeBuilder . append ( " # Necessary mapping for Linux\n" ) ;
dockerComposeBuilder . append ( " extra_hosts:\n" ) ;
dockerComposeBuilder . append ( " - \"host.docker.internal:host-gateway\"\n" ) ;
dockerComposeBuilder . append ( "\n" ) ;
dockerComposeBuilder . append ( " # Environment variables\n" ) ;
dockerComposeBuilder . append ( " environment:\n" ) ;
dockerComposeBuilder . append ( " - host=" ) . append ( isLocalhost ( host ) ? HOST_DOCKER_INTERNAL : host ) . append ( "\n" ) ;
dockerComposeBuilder . append ( " - port=1883\n" ) ;
switch ( deviceCredentials . getCredentialsType ( ) ) {
case ACCESS_TOKEN :
command . append ( " -e accessToken=" ) . append ( deviceCredentials . getCredentialsId ( ) ) ;
dockerComposeBuilder . append ( " - accessToken=" ) . append ( deviceCredentials . getCredentialsId ( ) ) . append ( "\n" ) ;
break ;
case MQTT_BASIC :
BasicMqttCredentials credentials = JacksonUtil . fromString ( deviceCredentials . getCredentialsValue ( ) ,
BasicMqttCredentials . class ) ;
if ( credentials ! = null ) {
if ( credentials . getClientId ( ) ! = null ) {
command . append ( " -e clientId=" ) . append ( credentials . getClientId ( ) ) ;
dockerComposeBuilder . append ( " - clientId=" ) . append ( credentials . getClientId ( ) ) . append ( "\n" ) ;
}
if ( credentials . getUserName ( ) ! = null ) {
command . append ( " -e username=" ) . append ( credentials . getUserName ( ) ) ;
dockerComposeBuilder . append ( " - username=" ) . append ( credentials . getUserName ( ) ) . append ( "\n" ) ;
}
if ( credentials . getPassword ( ) ! = null ) {
command . append ( " -e password=" ) . append ( credentials . getPassword ( ) ) ;
dockerComposeBuilder . append ( " - password=" ) . append ( credentials . getPassword ( ) ) . append ( "\n" ) ;
}
} else {
return null ;
}
break ;
default :
return null ;
}
if ( MQTTS . equals ( mqttType ) ) {
command . append ( " -e caCert=/thingsboard_gateway/config/" ) . append ( CA_ROOT_CERT_PEM ) ;
}
command . append ( " --restart always" ) ;
command . append ( " thingsboard/tb-gateway" ) ;
return command . toString ( ) ;
dockerComposeBuilder . append ( "\n" ) ;
dockerComposeBuilder . append ( " # Volumes bind\n" ) ;
dockerComposeBuilder . append ( " volumes:\n" ) ;
dockerComposeBuilder . append ( " - tb-gw-config:/thingsboard_gateway/config\n" ) ;
dockerComposeBuilder . append ( " - tb-gw-logs:/thingsboard_gateway/logs\n" ) ;
dockerComposeBuilder . append ( " - tb-gw-extensions:/thingsboard_gateway/extensions\n" ) ;
dockerComposeBuilder . append ( "\n" ) ;
dockerComposeBuilder . append ( "# Volumes declaration for configurations, extensions and configuration\n" ) ;
dockerComposeBuilder . append ( "volumes:\n" ) ;
dockerComposeBuilder . append ( " tb-gw-config:\n" ) ;
dockerComposeBuilder . append ( " name: tb-gw-config\n" ) ;
dockerComposeBuilder . append ( " tb-gw-logs:\n" ) ;
dockerComposeBuilder . append ( " name: tb-gw-logs\n" ) ;
dockerComposeBuilder . append ( " tb-gw-extensions:\n" ) ;
dockerComposeBuilder . append ( " name: tb-gw-extensions\n" ) ;
return new ByteArrayResource ( dockerComposeBuilder . toString ( ) . getBytes ( StandardCharsets . UTF_8 ) ) ;
}
public static String getDockerMqttPublishCommand ( String protocol , String baseUrl , String host , String port , String deviceTelemetryTopic , DeviceCredentials deviceCredentials ) {