|
|
|
@ -19,26 +19,25 @@ import com.fasterxml.jackson.databind.JsonNode; |
|
|
|
import com.fasterxml.jackson.databind.node.ArrayNode; |
|
|
|
import com.fasterxml.jackson.databind.node.ObjectNode; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.apache.commons.io.FileUtils; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.core.io.ClassPathResource; |
|
|
|
import org.springframework.core.io.Resource; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
|
import org.thingsboard.server.common.data.Device; |
|
|
|
import org.thingsboard.server.common.data.DeviceProfile; |
|
|
|
import org.thingsboard.server.common.data.DeviceTransportType; |
|
|
|
import org.thingsboard.server.common.data.ResourceUtils; |
|
|
|
import org.thingsboard.server.common.data.StringUtils; |
|
|
|
import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; |
|
|
|
import org.thingsboard.server.common.data.id.DeviceId; |
|
|
|
import org.thingsboard.server.common.data.security.DeviceCredentials; |
|
|
|
import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
|
|
|
import org.thingsboard.server.dao.util.DeviceConnectivityUtil; |
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
import java.io.IOException; |
|
|
|
import java.net.URI; |
|
|
|
import java.net.URISyntaxException; |
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Optional; |
|
|
|
|
|
|
|
@ -49,17 +48,12 @@ import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.COAPS; |
|
|
|
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.DOCKER; |
|
|
|
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.HTTP; |
|
|
|
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.HTTPS; |
|
|
|
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.LINUX; |
|
|
|
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.MQTT; |
|
|
|
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.MQTTS; |
|
|
|
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.getCoapClientCommand; |
|
|
|
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.getCurlCommand; |
|
|
|
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.getDockerMosquittoClientsPublishCommand; |
|
|
|
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.getMosquittoPubPublishCommand; |
|
|
|
|
|
|
|
@Service("DeviceConnectivityDaoService") |
|
|
|
@Slf4j |
|
|
|
public class DeviceСonnectivityServiceImpl implements DeviceConnectivityService { |
|
|
|
public class DeviceConnectivityServiceImpl implements DeviceConnectivityService { |
|
|
|
|
|
|
|
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
|
|
|
public static final String INCORRECT_DEVICE_ID = "Incorrect deviceId "; |
|
|
|
@ -113,12 +107,13 @@ public class DeviceСonnectivityServiceImpl implements DeviceConnectivityService |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public String getSslServerChain(String protocol) throws IOException { |
|
|
|
String mqttSslPemPath = deviceConnectivityConfiguration.getConnectivity() |
|
|
|
public Resource getPemCertFile(String protocol) { |
|
|
|
String certFilePath = deviceConnectivityConfiguration.getConnectivity() |
|
|
|
.get(protocol) |
|
|
|
.getSslServerPemPath(); |
|
|
|
if (!mqttSslPemPath.isEmpty() && ResourceUtils.resourceExists(this, mqttSslPemPath)) { |
|
|
|
return FileUtils.readFileToString(new File(mqttSslPemPath), StandardCharsets.UTF_8); |
|
|
|
.getPemCertFile(); |
|
|
|
|
|
|
|
if (StringUtils.isNotBlank(certFilePath) && ResourceUtils.resourceExists(this, certFilePath)) { |
|
|
|
return new ClassPathResource(certFilePath); |
|
|
|
} else { |
|
|
|
return null; |
|
|
|
} |
|
|
|
@ -134,15 +129,15 @@ public class DeviceСonnectivityServiceImpl implements DeviceConnectivityService |
|
|
|
} |
|
|
|
|
|
|
|
private String getHttpPublishCommand(String protocol, String baseUrl, DeviceCredentials deviceCredentials) throws URISyntaxException { |
|
|
|
DeviceConnectivityInfo httpProps = deviceConnectivityConfiguration.getConnectivity().get(protocol); |
|
|
|
if (httpProps == null || !httpProps.getEnabled() || |
|
|
|
DeviceConnectivityInfo properties = deviceConnectivityConfiguration.getConnectivity().get(protocol); |
|
|
|
if (properties == null || !properties.isEnabled() || |
|
|
|
deviceCredentials.getCredentialsType() != DeviceCredentialsType.ACCESS_TOKEN) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
String hostName = httpProps.getHost().isEmpty() ? new URI(baseUrl).getHost() : httpProps.getHost(); |
|
|
|
String port = httpProps.getPort().isEmpty() ? "" : ":" + httpProps.getPort(); |
|
|
|
String hostName = getHost(baseUrl, properties); |
|
|
|
String port = properties.getPort().isEmpty() ? "" : ":" + properties.getPort(); |
|
|
|
|
|
|
|
return getCurlCommand(protocol, hostName, port, deviceCredentials); |
|
|
|
return DeviceConnectivityUtil.getHttpPublishCommand(protocol, hostName, port, deviceCredentials); |
|
|
|
} |
|
|
|
|
|
|
|
private JsonNode getMqttTransportPublishCommands(String baseUrl, DeviceCredentials deviceCredentials) throws URISyntaxException { |
|
|
|
@ -152,23 +147,31 @@ public class DeviceСonnectivityServiceImpl implements DeviceConnectivityService |
|
|
|
private JsonNode getMqttTransportPublishCommands(String baseUrl, String topic, DeviceCredentials deviceCredentials) throws URISyntaxException { |
|
|
|
ObjectNode mqttCommands = JacksonUtil.newObjectNode(); |
|
|
|
|
|
|
|
Optional.ofNullable(getMqttPublishCommand(baseUrl, topic, deviceCredentials)) |
|
|
|
.ifPresent(v -> mqttCommands.put(MQTT, v)); |
|
|
|
List<String> mqttsPublishCommand = getMqttsPublishCommand(baseUrl, topic, deviceCredentials); |
|
|
|
if (mqttsPublishCommand != null){ |
|
|
|
if (mqttsPublishCommand.size() > 1) { |
|
|
|
if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) { |
|
|
|
mqttCommands.put(MQTTS, CHECK_DOCUMENTATION); |
|
|
|
return mqttCommands; |
|
|
|
} |
|
|
|
|
|
|
|
ObjectNode dockerMqttCommands = JacksonUtil.newObjectNode(); |
|
|
|
|
|
|
|
if (deviceConnectivityConfiguration.isEnabled(MQTT)) { |
|
|
|
Optional.ofNullable(getMqttPublishCommand(baseUrl, topic, deviceCredentials)). |
|
|
|
ifPresent(v -> mqttCommands.put(MQTT, v)); |
|
|
|
|
|
|
|
Optional.ofNullable(getDockerMqttPublishCommand(MQTT, baseUrl, topic, deviceCredentials)) |
|
|
|
.ifPresent(v -> dockerMqttCommands.put(MQTT, v)); |
|
|
|
} |
|
|
|
|
|
|
|
if (deviceConnectivityConfiguration.isEnabled(MQTTS)) { |
|
|
|
List<String> mqttsPublishCommand = getMqttsPublishCommand(baseUrl, topic, deviceCredentials); |
|
|
|
if (mqttsPublishCommand != null) { |
|
|
|
ArrayNode arrayNode = mqttCommands.putArray(MQTTS); |
|
|
|
mqttsPublishCommand.forEach(arrayNode::add); |
|
|
|
} else { |
|
|
|
mqttCommands.put(MQTTS, mqttsPublishCommand.get(0)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ObjectNode dockerMqttCommands = JacksonUtil.newObjectNode(); |
|
|
|
Optional.ofNullable(getDockerMqttPublishCommand(MQTT,baseUrl, topic, deviceCredentials)) |
|
|
|
.ifPresent(v -> dockerMqttCommands.put(MQTT, v)); |
|
|
|
Optional.ofNullable(getDockerMqttPublishCommand(MQTTS, baseUrl, topic, deviceCredentials)) |
|
|
|
.ifPresent(v -> dockerMqttCommands.put(MQTTS, v)); |
|
|
|
Optional.ofNullable(getDockerMqttPublishCommand(MQTTS, baseUrl, topic, deviceCredentials)) |
|
|
|
.ifPresent(v -> dockerMqttCommands.put(MQTTS, v)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!dockerMqttCommands.isEmpty()) { |
|
|
|
mqttCommands.set(DOCKER, dockerMqttCommands); |
|
|
|
@ -178,70 +181,81 @@ public class DeviceСonnectivityServiceImpl implements DeviceConnectivityService |
|
|
|
|
|
|
|
private String getMqttPublishCommand(String baseUrl, String deviceTelemetryTopic, DeviceCredentials deviceCredentials) throws URISyntaxException { |
|
|
|
DeviceConnectivityInfo properties = deviceConnectivityConfiguration.getConnectivity().get(MQTT); |
|
|
|
if (properties == null || !properties.getEnabled()) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
String mqttHost = properties.getHost().isEmpty() ? new URI(baseUrl).getHost() : properties.getHost(); |
|
|
|
String mqttHost = getHost(baseUrl, properties); |
|
|
|
String mqttPort = properties.getPort().isEmpty() ? null : properties.getPort(); |
|
|
|
return getMosquittoPubPublishCommand(MQTT, mqttHost, mqttPort, deviceTelemetryTopic, deviceCredentials); |
|
|
|
return DeviceConnectivityUtil.getMqttPublishCommand(MQTT, mqttHost, mqttPort, deviceTelemetryTopic, deviceCredentials); |
|
|
|
} |
|
|
|
|
|
|
|
private List<String> getMqttsPublishCommand(String baseUrl, String deviceTelemetryTopic, DeviceCredentials deviceCredentials) throws URISyntaxException { |
|
|
|
String pubCommand; |
|
|
|
if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) { |
|
|
|
return List.of(CHECK_DOCUMENTATION); |
|
|
|
} else { |
|
|
|
DeviceConnectivityInfo properties = deviceConnectivityConfiguration.getConnectivity().get(MQTTS); |
|
|
|
if (properties == null || !properties.getEnabled()) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
String mqttHost = properties.getHost().isEmpty() ? new URI(baseUrl).getHost() : properties.getHost(); |
|
|
|
String mqttPort = properties.getPort().isEmpty() ? null : properties.getPort(); |
|
|
|
pubCommand = getMosquittoPubPublishCommand(MQTTS, mqttHost, mqttPort, deviceTelemetryTopic, deviceCredentials); |
|
|
|
} |
|
|
|
DeviceConnectivityInfo properties = deviceConnectivityConfiguration.getConnectivity().get(MQTTS); |
|
|
|
String mqttHost = getHost(baseUrl, properties); |
|
|
|
String mqttPort = properties.getPort().isEmpty() ? null : properties.getPort(); |
|
|
|
String pubCommand = DeviceConnectivityUtil.getMqttPublishCommand(MQTTS, mqttHost, mqttPort, deviceTelemetryTopic, deviceCredentials); |
|
|
|
|
|
|
|
ArrayList<String> commands = new ArrayList<>(); |
|
|
|
if (pubCommand != null) { |
|
|
|
commands.add("curl " + baseUrl + "/api/device-connectivity/mqtts/certificate/download -o /tmp/tb-server-chain.pem"); |
|
|
|
commands.add(DeviceConnectivityUtil.getCurlPemCertCommand(baseUrl, MQTTS)); |
|
|
|
commands.add(pubCommand); |
|
|
|
return commands; |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private String getDockerMqttPublishCommand(String protocol, String baseUrl, String deviceTelemetryTopic, DeviceCredentials deviceCredentials) throws URISyntaxException { |
|
|
|
DeviceConnectivityInfo properties = deviceConnectivityConfiguration.getConnectivity().get(protocol); |
|
|
|
if (properties == null || !properties.getEnabled()) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
String mqttHost = properties.getHost().isEmpty() ? new URI(baseUrl).getHost() : properties.getHost(); |
|
|
|
String mqttHost = getHost(baseUrl, properties); |
|
|
|
String mqttPort = properties.getPort().isEmpty() ? null : properties.getPort(); |
|
|
|
return getDockerMosquittoClientsPublishCommand(protocol, baseUrl, mqttHost, mqttPort, deviceTelemetryTopic, deviceCredentials); |
|
|
|
return DeviceConnectivityUtil.getDockerMqttPublishCommand(protocol, baseUrl, mqttHost, mqttPort, deviceTelemetryTopic, deviceCredentials); |
|
|
|
} |
|
|
|
|
|
|
|
private JsonNode getCoapTransportPublishCommands(String baseUrl, DeviceCredentials deviceCredentials) throws URISyntaxException { |
|
|
|
ObjectNode coapCommands = JacksonUtil.newObjectNode(); |
|
|
|
|
|
|
|
Optional.ofNullable(getCoapPublishCommand(COAP, baseUrl, deviceCredentials)) |
|
|
|
.ifPresent(v -> coapCommands.put(COAP, v)); |
|
|
|
Optional.ofNullable(getCoapPublishCommand(COAPS, baseUrl, deviceCredentials)) |
|
|
|
.ifPresent(v -> coapCommands.put(COAPS, v)); |
|
|
|
if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) { |
|
|
|
coapCommands.put(COAPS, CHECK_DOCUMENTATION); |
|
|
|
return coapCommands; |
|
|
|
} |
|
|
|
|
|
|
|
ObjectNode dockerCoapCommands = JacksonUtil.newObjectNode(); |
|
|
|
|
|
|
|
if (deviceConnectivityConfiguration.isEnabled(COAP)) { |
|
|
|
Optional.ofNullable(getCoapPublishCommand(COAP, baseUrl, deviceCredentials)) |
|
|
|
.ifPresent(v -> coapCommands.put(COAP, v)); |
|
|
|
|
|
|
|
Optional.ofNullable(getDockerCoapPublishCommand(COAP, baseUrl, deviceCredentials)) |
|
|
|
.ifPresent(v -> dockerCoapCommands.put(COAP, v)); |
|
|
|
} |
|
|
|
|
|
|
|
if (deviceConnectivityConfiguration.isEnabled(COAPS)) { |
|
|
|
Optional.ofNullable(getCoapPublishCommand(COAPS, baseUrl, deviceCredentials)) |
|
|
|
.ifPresent(v -> coapCommands.put(COAPS, v)); |
|
|
|
|
|
|
|
Optional.ofNullable(getDockerCoapPublishCommand(COAPS, baseUrl, deviceCredentials)) |
|
|
|
.ifPresent(v -> dockerCoapCommands.put(COAPS, v)); |
|
|
|
} |
|
|
|
|
|
|
|
if (!dockerCoapCommands.isEmpty()) { |
|
|
|
coapCommands.set(DOCKER, dockerCoapCommands); |
|
|
|
} |
|
|
|
|
|
|
|
return coapCommands.isEmpty() ? null : coapCommands; |
|
|
|
} |
|
|
|
|
|
|
|
private String getCoapPublishCommand(String protocol, String baseUrl, DeviceCredentials deviceCredentials) throws URISyntaxException { |
|
|
|
if (COAPS.equals(protocol) && deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) { |
|
|
|
return CHECK_DOCUMENTATION; |
|
|
|
} |
|
|
|
DeviceConnectivityInfo properties = deviceConnectivityConfiguration.getConnectivity().get(protocol); |
|
|
|
if (properties == null || !properties.getEnabled()) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
String hostName = properties.getHost().isEmpty() ? new URI(baseUrl).getHost() : properties.getHost(); |
|
|
|
String hostName = getHost(baseUrl, properties); |
|
|
|
String port = properties.getPort().isEmpty() ? "" : ":" + properties.getPort(); |
|
|
|
return DeviceConnectivityUtil.getCoapPublishCommand(protocol, hostName, port, deviceCredentials); |
|
|
|
} |
|
|
|
|
|
|
|
private String getDockerCoapPublishCommand(String protocol, String baseUrl, DeviceCredentials deviceCredentials) throws URISyntaxException { |
|
|
|
DeviceConnectivityInfo properties = deviceConnectivityConfiguration.getConnectivity().get(protocol); |
|
|
|
String host = getHost(baseUrl, properties); |
|
|
|
String port = properties.getPort().isEmpty() ? "" : ":" + properties.getPort(); |
|
|
|
return DeviceConnectivityUtil.getDockerCoapPublishCommand(protocol, host, port, deviceCredentials); |
|
|
|
} |
|
|
|
|
|
|
|
return getCoapClientCommand(protocol, hostName, port, deviceCredentials); |
|
|
|
private String getHost(String baseUrl, DeviceConnectivityInfo properties) throws URISyntaxException { |
|
|
|
return properties.getHost().isEmpty() ? new URI(baseUrl).getHost() : properties.getHost(); |
|
|
|
} |
|
|
|
} |