Browse Source

refactored code to take into account operating system

pull/8803/head
dashevchenko 3 years ago
parent
commit
db46b7988d
  1. 9
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  2. 2
      application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
  3. 108
      application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java
  4. 33
      application/src/main/java/org/thingsboard/server/controller/DeviceController.java
  5. 2
      application/src/main/resources/thingsboard.yml
  6. 398
      application/src/test/java/org/thingsboard/server/controller/DeviceConnectivityControllerTest.java
  7. 184
      application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java
  8. 13
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityService.java
  9. 3
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
  10. 2
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityInfo.java
  11. 53
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityMqttSslCertService.java
  12. 109
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
  13. 224
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceСonnectivityServiceImpl.java
  14. 51
      dao/src/main/java/org/thingsboard/server/dao/util/DeviceConnectivityUtil.java

9
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -113,6 +113,7 @@ import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.device.ClaimDevicesService;
import org.thingsboard.server.dao.device.DeviceConnectivityService;
import org.thingsboard.server.dao.device.DeviceCredentialsService;
import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService;
@ -163,6 +164,7 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@ -208,6 +210,9 @@ public abstract class BaseController {
@Autowired
protected DeviceService deviceService;
@Autowired
protected DeviceConnectivityService deviceConnectivityService;
@Autowired
protected DeviceProfileService deviceProfileService;
@ -755,6 +760,10 @@ public abstract class BaseController {
return checkEntityId(resourceId, resourceService::findResourceInfoById, operation);
}
String checkSslServerPemFile(String protocol) throws ThingsboardException, IOException {
return checkNotNull(deviceConnectivityService.getSslServerChain(protocol), "Mqtt ssl server chain pem file is not found");
}
OtaPackage checkOtaPackageId(OtaPackageId otaPackageId, Operation operation) throws ThingsboardException {
return checkEntityId(otaPackageId, otaPackageService::findOtaPackageById, operation);
}

2
application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java

@ -24,6 +24,7 @@ public class ControllerConstants {
protected static final String CUSTOMER_ID = "customerId";
protected static final String TENANT_ID = "tenantId";
protected static final String DEVICE_ID = "deviceId";
protected static final String PROTOCOL = "protocol";
protected static final String EDGE_ID = "edgeId";
protected static final String RPC_ID = "rpcId";
protected static final String ENTITY_ID = "entityId";
@ -34,6 +35,7 @@ public class ControllerConstants {
protected static final String DASHBOARD_ID_PARAM_DESCRIPTION = "A string value representing the dashboard id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
protected static final String RPC_ID_PARAM_DESCRIPTION = "A string value representing the rpc id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
protected static final String DEVICE_ID_PARAM_DESCRIPTION = "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
protected static final String PROTOCOL_PARAM_DESCRIPTION = "A string value representing the device connectivity protocol. Possible values: 'mqtt', 'mqtts', 'http', 'https', 'coap', 'coaps'";
protected static final String ENTITY_VIEW_ID_PARAM_DESCRIPTION = "A string value representing the entity view id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
protected static final String DEVICE_PROFILE_ID_PARAM_DESCRIPTION = "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";

108
application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java

@ -0,0 +1,108 @@
/**
* Copyright © 2016-2023 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.controller;
import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.system.SystemSecurityService;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Map;
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID;
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.PROTOCOL;
import static org.thingsboard.server.controller.ControllerConstants.PROTOCOL_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH;
import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.MQTT_SSL_PEM_FILE_NAME;
@RestController
@TbCoreComponent
@RequestMapping("/api")
@RequiredArgsConstructor
@Slf4j
public class DeviceConnectivityController extends BaseController {
private final SystemSecurityService systemSecurityService;
@ApiOperation(value = "Get commands to publish device telemetry (getDevicePublishTelemetryCommands)",
notes = "Fetch the list of commands to publish device telemetry based on device profile " +
"If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. " +
"If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. " +
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK",
examples = @io.swagger.annotations.Example(
value = {
@io.swagger.annotations.ExampleProperty(
mediaType="application/json",
value="{\"http\":\"curl -v -X POST http://localhost:8080/api/v1/0ySs4FTOn5WU15XLmal8/telemetry --header Content-Type:application/json --data {temperature:25}\"," +
"\"mqtt\":\"mosquitto_pub -d -q 1 -h localhost -t v1/devices/me/telemetry -i myClient1 -u myUsername1 -P myPassword -m {temperature:25}\"," +
"\"coap\":\"coap-client -m POST coap://localhost:5683/api/v1/0ySs4FTOn5WU15XLmal8/telemetry -t json -e {temperature:25}\"}")}))})
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/device-connectivity/{deviceId}", method = RequestMethod.GET)
@ResponseBody
public JsonNode getDevicePublishTelemetryCommands(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
@PathVariable(DEVICE_ID) String strDeviceId, HttpServletRequest request) throws ThingsboardException, URISyntaxException {
checkParameter(DEVICE_ID, strDeviceId);
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
Device device = checkDeviceId(deviceId, Operation.READ_CREDENTIALS);
String baseUrl = systemSecurityService.getBaseUrl(getTenantId(), getCurrentUser().getCustomerId(), request);
return deviceConnectivityService.findDevicePublishTelemetryCommands(baseUrl, device);
}
@ApiOperation(value = "Download mqtt ssl certificate using file path defined in device.connectivity properties (downloadMqttServerCertificate)", notes = "Download Mqtt server certificate." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/device-connectivity/{protocol}/certificate/download", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<org.springframework.core.io.Resource> downloadMqttServerCertificate(@ApiParam(value = PROTOCOL_PARAM_DESCRIPTION)
@PathVariable(PROTOCOL) String protocol) throws ThingsboardException, IOException {
String certificate = checkSslServerPemFile(protocol);
ByteArrayResource cert = new ByteArrayResource(certificate.getBytes());
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + MQTT_SSL_PEM_FILE_NAME)
.header("x-filename", MQTT_SSL_PEM_FILE_NAME)
.contentLength(cert.contentLength())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(cert);
}
}

33
application/src/main/java/org/thingsboard/server/controller/DeviceController.java

@ -21,11 +21,8 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@ -79,12 +76,9 @@ import org.thingsboard.server.service.security.permission.Resource;
import org.thingsboard.server.service.security.system.SystemSecurityService;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import java.net.URISyntaxException;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
@ -173,33 +167,6 @@ public class DeviceController extends BaseController {
return checkDeviceInfoId(deviceId, Operation.READ);
}
@ApiOperation(value = "Get commands to publish device telemetry (getDevicePublishTelemetryCommands)",
notes = "Fetch the list of commands to publish device telemetry based on device profile " +
"If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. " +
"If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. " +
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK",
examples = @io.swagger.annotations.Example(
value = {
@io.swagger.annotations.ExampleProperty(
mediaType="application/json",
value="{\"http\":\"curl -v -X POST http://localhost:8080/api/v1/0ySs4FTOn5WU15XLmal8/telemetry --header Content-Type:application/json --data {temperature:25}\"," +
"\"mqtt\":\"mosquitto_pub -d -q 1 -h localhost -t v1/devices/me/telemetry -i myClient1 -u myUsername1 -P myPassword -m {temperature:25}\"," +
"\"coap\":\"coap-client -m POST coap://localhost:5683/api/v1/0ySs4FTOn5WU15XLmal8/telemetry -t json -e {temperature:25}\"}")}))})
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/device/{deviceId}/commands", method = RequestMethod.GET)
@ResponseBody
public Map<String, String> getDevicePublishTelemetryCommands(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION)
@PathVariable(DEVICE_ID) String strDeviceId, HttpServletRequest request) throws ThingsboardException, URISyntaxException {
checkParameter(DEVICE_ID, strDeviceId);
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
Device device = checkDeviceId(deviceId, Operation.READ_CREDENTIALS);
String baseUrl = systemSecurityService.getBaseUrl(getTenantId(), getCurrentUser().getCustomerId(), request);
return deviceService.findDevicePublishTelemetryCommands(baseUrl, device);
}
@ApiOperation(value = "Create Or Update Device (saveDevice)",
notes = "Create or update the Device. When creating device, platform generates Device Id as " + UUID_WIKI_LINK +
"Device credentials are also generated if not provided in the 'accessToken' request parameter. " +

2
application/src/main/resources/thingsboard.yml

@ -1004,7 +1004,7 @@ device:
enabled: "${DEVICE_CONNECTIVITY_MQTTS_ENABLED:false}"
host: "${DEVICE_CONNECTIVITY_MQTTS_HOST:}"
port: "${DEVICE_CONNECTIVITY_MQTTS_PORT:8883}"
tb_server_chain_path: "${DEVICE_CONNECTIVITY_MQTTS_SERVER_CHAIN_PATH:}"
ssl_server_pem_path: "${DEVICE_CONNECTIVITY_MQTTS_SERVER_CHAIN_PATH:}"
coap:
enabled: "${DEVICE_CONNECTIVITY_COAP_ENABLED:true}"
host: "${DEVICE_CONNECTIVITY_COAP_HOST:}"

398
application/src/test/java/org/thingsboard/server/controller/DeviceConnectivityControllerTest.java

@ -0,0 +1,398 @@
/**
* Copyright © 2016-2023 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.controller;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.AdditionalAnswers;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceInfo;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest;
import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceCredentialsId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportColumnType;
import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportRequest;
import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportResult;
import org.thingsboard.server.dao.device.DeviceDao;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.service.gateway_device.GatewayNotificationsService;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE;
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.COAP;
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.WINDOWS;
@TestPropertySource(properties = {
"device.connectivity.https.enabled=true",
"device.connectivity.mqtts.enabled=true",
"device.connectivity.coaps.enabled=true",
})
@ContextConfiguration(classes = {DeviceConnectivityControllerTest.Config.class})
@DaoSqlTest
public class DeviceConnectivityControllerTest extends AbstractControllerTest {
static final TypeReference<PageData<Device>> PAGE_DATA_DEVICE_TYPE_REF = new TypeReference<>() {
};
private static final String DEVICE_TELEMETRY_TOPIC = "v1/devices/customTopic";
private static final String CHECK_DOCUMENTATION = "Check documentation";
ListeningExecutorService executor;
private Tenant savedTenant;
private User tenantAdmin;
private DeviceProfileId mqttDeviceProfileId;
private DeviceProfileId coapDeviceProfileId;
static class Config {
@Bean
@Primary
public DeviceDao deviceDao(DeviceDao deviceDao) {
return Mockito.mock(DeviceDao.class, AdditionalAnswers.delegatesTo(deviceDao));
}
}
@Before
public void beforeTest() throws Exception {
executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass()));
loginSysAdmin();
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
savedTenant = doPost("/api/tenant", tenant, Tenant.class);
Assert.assertNotNull(savedTenant);
tenantAdmin = new User();
tenantAdmin.setAuthority(Authority.TENANT_ADMIN);
tenantAdmin.setTenantId(savedTenant.getId());
tenantAdmin.setEmail("tenant2@thingsboard.org");
tenantAdmin.setFirstName("Joe");
tenantAdmin.setLastName("Downs");
tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1");
DeviceProfile mqttProfile = new DeviceProfile();
mqttProfile.setName("Mqtt device profile");
mqttProfile.setType(DeviceProfileType.DEFAULT);
mqttProfile.setTransportType(DeviceTransportType.MQTT);
DeviceProfileData deviceProfileData = new DeviceProfileData();
deviceProfileData.setConfiguration(new DefaultDeviceProfileConfiguration());
MqttDeviceProfileTransportConfiguration transportConfiguration = new MqttDeviceProfileTransportConfiguration();
transportConfiguration.setDeviceTelemetryTopic(DEVICE_TELEMETRY_TOPIC);
deviceProfileData.setTransportConfiguration(transportConfiguration);
mqttProfile.setProfileData(deviceProfileData);
mqttProfile.setDefault(false);
mqttProfile.setDefaultRuleChainId(null);
mqttDeviceProfileId = doPost("/api/deviceProfile", mqttProfile, DeviceProfile.class).getId();
DeviceProfile coapProfile = new DeviceProfile();
coapProfile.setName("Coap device profile");
coapProfile.setType(DeviceProfileType.DEFAULT);
coapProfile.setTransportType(DeviceTransportType.COAP);
DeviceProfileData deviceProfileData2 = new DeviceProfileData();
deviceProfileData2.setConfiguration(new DefaultDeviceProfileConfiguration());
deviceProfileData2.setTransportConfiguration(new CoapDeviceProfileTransportConfiguration());
coapProfile.setProfileData(deviceProfileData);
coapProfile.setDefault(false);
coapProfile.setDefaultRuleChainId(null);
coapDeviceProfileId = doPost("/api/deviceProfile", coapProfile, DeviceProfile.class).getId();
}
@After
public void afterTest() throws Exception {
executor.shutdownNow();
loginSysAdmin();
doDelete("/api/tenant/" + savedTenant.getId().getId())
.andExpect(status().isOk());
}
@Test
public void testFetchPublishTelemetryCommandsForDefaultDevice() throws Exception {
Device device = new Device();
device.setName("My device");
device.setType("default");
Device savedDevice = doPost("/api/device", device, Device.class);
JsonNode commands =
doGetTyped("/api/device-connectivity/" + savedDevice.getId().getId(), new TypeReference<>() {});
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
assertThat(commands).hasSize(3);
JsonNode httpCommands = commands.get(HTTP);
assertThat(httpCommands.get(HTTP).asText()).isEqualTo(String.format("curl -v -X POST http://localhost:8080/api/v1/%s/telemetry " +
"--header Content-Type:application/json --data \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(httpCommands.get(HTTPS).asText()).isEqualTo(String.format("curl -v -X POST https://localhost:443/api/v1/%s/telemetry " +
"--header Content-Type:application/json --data \"{temperature:25}\"",
credentials.getCredentialsId()));
JsonNode linuxMqttCommands = commands.get(MQTT).get(LINUX);
assertThat(linuxMqttCommands.get(MQTT).asText()).isEqualTo(String.format("mosquitto_pub -d -q 1 -h localhost -p 1883 -t v1/devices/me/telemetry " +
"-u %s -m \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(linuxMqttCommands.get(MQTTS).asText()).isEqualTo(String.format("mosquitto_pub -d -q 1 --cafile pathToFile/tb-server-chain.pem -h localhost -p 8883 " +
"-t v1/devices/me/telemetry -u %s -m \"{temperature:25}\"",
credentials.getCredentialsId()));
JsonNode windowsMqttCommands = commands.get(MQTT).get(WINDOWS);
assertThat(windowsMqttCommands.get(MQTT).asText()).isEqualTo(String.format("mosquitto_pub -d -q 1 -h localhost -p 1883 -t v1/devices/me/telemetry " +
"-u %s -m \"{temperature:25}\"",
credentials.getCredentialsId()));
JsonNode dockerMqttCommands = commands.get(MQTT).get(DOCKER);
assertThat(dockerMqttCommands.get(MQTT).asText()).isEqualTo(String.format("docker run -it --rm thingsboard/mosquitto-clients pub -h localhost" +
" -p 1883 -t v1/devices/me/telemetry -u %s -m \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(dockerMqttCommands.get(MQTTS).asText()).isEqualTo(String.format("docker run --volume pathToFile/tb-server-chain.pem:/tmp/tb-server-chain.pem " +
"-it --rm thingsboard/mosquitto-clients pub --cafile tmp/tb-server-chain.pem -h localhost -p 8883 -t v1/devices/me/telemetry -u %s -m \"{temperature:25}\"",
credentials.getCredentialsId()));
JsonNode linuxCoapCommands = commands.get(COAP).get(LINUX);
assertThat(linuxCoapCommands.get(COAP).asText()).isEqualTo(String.format("coap-client -m POST coap://localhost:5683/api/v1/%s/telemetry " +
"-t json -e \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(linuxCoapCommands.get(COAPS).asText()).isEqualTo(String.format("coap-client-openssl -m POST coaps://localhost:5684/api/v1/%s/telemetry" +
" -t json -e \"{temperature:25}\"",
credentials.getCredentialsId()));
}
@Test
public void testFetchPublishTelemetryCommandsForMqttDeviceWithAccessToken() throws Exception {
Device device = new Device();
device.setName("My device");
device.setDeviceProfileId(mqttDeviceProfileId);
Device savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
JsonNode commands =
doGetTyped("/api/device-connectivity/" + savedDevice.getId().getId() , new TypeReference<>() {});
assertThat(commands).hasSize(1);
JsonNode linuxMqttCommands = commands.get(MQTT).get(LINUX);
assertThat(linuxMqttCommands.get(MQTT).asText()).isEqualTo(String.format("mosquitto_pub -d -q 1 -h localhost -p 1883 -t %s " +
"-u %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, credentials.getCredentialsId()));
assertThat(linuxMqttCommands.get(MQTTS).asText()).isEqualTo(String.format("mosquitto_pub -d -q 1 --cafile pathToFile/tb-server-chain.pem -h localhost -p 8883 " +
"-t %s -u %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, credentials.getCredentialsId()));
JsonNode windowsMqttCommands = commands.get(MQTT).get(WINDOWS);
assertThat(windowsMqttCommands.get(MQTT).asText()).isEqualTo(String.format("mosquitto_pub -d -q 1 -h localhost -p 1883 -t %s " +
"-u %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, credentials.getCredentialsId()));
JsonNode dockerMqttCommands = commands.get(MQTT).get(DOCKER);
assertThat(dockerMqttCommands.get(MQTT).asText()).isEqualTo(String.format("docker run -it --rm thingsboard/mosquitto-clients pub -h localhost" +
" -p 1883 -t %s -u %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, credentials.getCredentialsId()));
assertThat(dockerMqttCommands.get(MQTTS).asText()).isEqualTo(String.format("docker run --volume pathToFile/tb-server-chain.pem:/tmp/tb-server-chain.pem " +
"-it --rm thingsboard/mosquitto-clients pub --cafile tmp/tb-server-chain.pem -h localhost -p 8883 -t %s -u %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, credentials.getCredentialsId()));
}
@Test
public void testFetchPublishTelemetryCommandsForDeviceWithMqttBasicCreds() throws Exception {
Device device = new Device();
device.setName("My device");
device.setDeviceProfileId(mqttDeviceProfileId);
Device savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
credentials.setCredentialsId(null);
credentials.setCredentialsType(DeviceCredentialsType.MQTT_BASIC);
BasicMqttCredentials basicMqttCredentials = new BasicMqttCredentials();
String clientId = "testClientId";
String userName = "testUsername";
String password = "testPassword";
basicMqttCredentials.setClientId(clientId);
basicMqttCredentials.setUserName(userName);
basicMqttCredentials.setPassword(password);
credentials.setCredentialsValue(JacksonUtil.toString(basicMqttCredentials));
doPost("/api/device/credentials", credentials)
.andExpect(status().isOk());
JsonNode commands =
doGetTyped("/api/device-connectivity/" + savedDevice.getId().getId() , new TypeReference<>() {});
assertThat(commands).hasSize(1);
JsonNode linuxMqttCommands = commands.get(MQTT).get(LINUX);
assertThat(linuxMqttCommands.get(MQTT).asText()).isEqualTo(String.format("mosquitto_pub -d -q 1 -h localhost -p 1883 -t %s " +
"-i %s -u %s -P %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, clientId, userName, password));
assertThat(linuxMqttCommands.get(MQTTS).asText()).isEqualTo(String.format("mosquitto_pub -d -q 1 --cafile pathToFile/tb-server-chain.pem -h localhost -p 8883 " +
"-t %s -i %s -u %s -P %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, clientId, userName, password));
JsonNode windowsMqttCommands = commands.get(MQTT).get(WINDOWS);
assertThat(windowsMqttCommands.get(MQTT).asText()).isEqualTo(String.format("mosquitto_pub -d -q 1 -h localhost -p 1883 -t %s " +
"-i %s -u %s -P %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, clientId, userName, password));
JsonNode dockerMqttCommands = commands.get(MQTT).get(DOCKER);
assertThat(dockerMqttCommands.get(MQTT).asText()).isEqualTo(String.format("docker run -it --rm thingsboard/mosquitto-clients pub -h localhost" +
" -p 1883 -t %s -i %s -u %s -P %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, clientId, userName, password));
assertThat(dockerMqttCommands.get(MQTTS).asText()).isEqualTo(String.format("docker run --volume pathToFile/tb-server-chain.pem:/tmp/tb-server-chain.pem " +
"-it --rm thingsboard/mosquitto-clients pub --cafile tmp/tb-server-chain.pem -h localhost -p 8883 -t %s -i %s -u %s -P %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, clientId, userName, password));
}
@Test
public void testFetchPublishTelemetryCommandsForDeviceWithX509Creds() throws Exception {
Device device = new Device();
device.setName("My device");
device.setDeviceProfileId(mqttDeviceProfileId);
Device savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
credentials.setCredentialsId(null);
credentials.setCredentialsType(DeviceCredentialsType.X509_CERTIFICATE);
credentials.setCredentialsValue("testValue");
doPost("/api/device/credentials", credentials)
.andExpect(status().isOk());
JsonNode commands =
doGetTyped("/api/device-connectivity/" + savedDevice.getId().getId(), new TypeReference<>() {});
assertThat(commands).hasSize(1);
assertThat(commands.get(MQTT).get(LINUX).get(MQTTS).asText()).isEqualTo(CHECK_DOCUMENTATION);
assertThat(commands.get(MQTT).get(WINDOWS).get(MQTTS).asText()).isEqualTo(CHECK_DOCUMENTATION);
assertThat(commands.get(MQTT).get(DOCKER).get(MQTTS).asText()).isEqualTo(CHECK_DOCUMENTATION);
}
@Test
public void testFetchPublishTelemetryCommandsForСoapDevice() throws Exception {
Device device = new Device();
device.setName("My device");
device.setDeviceProfileId(coapDeviceProfileId);
Device savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
JsonNode commands =
doGetTyped("/api/device-connectivity/" + savedDevice.getId().getId(), new TypeReference<>() {});
assertThat(commands).hasSize(1);
JsonNode linuxCommands = commands.get(COAP).get(LINUX);
assertThat(linuxCommands.get(COAP).asText()).isEqualTo(String.format("coap-client -m POST coap://localhost:5683/api/v1/%s/telemetry -t json -e \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(linuxCommands.get(COAPS).asText()).isEqualTo(String.format("coap-client-openssl -m POST coaps://localhost:5684/api/v1/%s/telemetry -t json -e \"{temperature:25}\"",
credentials.getCredentialsId()));
}
@Test
public void testFetchPublishTelemetryCommandsForСoapDeviceWithX509Creds() throws Exception {
Device device = new Device();
device.setName("My device");
device.setDeviceProfileId(coapDeviceProfileId);
Device savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
credentials.setCredentialsId(null);
credentials.setCredentialsType(DeviceCredentialsType.X509_CERTIFICATE);
credentials.setCredentialsValue("testValue");
doPost("/api/device/credentials", credentials)
.andExpect(status().isOk());
JsonNode commands =
doGetTyped("/api/device-connectivity/" + savedDevice.getId().getId(), new TypeReference<>() {});
assertThat(commands).hasSize(1);
assertThat(commands.get(COAP).get(LINUX).get(COAPS).asText()).isEqualTo(CHECK_DOCUMENTATION);
}
}

184
application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java

@ -93,27 +93,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE;
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.COAP;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.COAPS;
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.MQTT;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.MQTTS;
@TestPropertySource(properties = {
"device.connectivity.https.enabled=true",
"device.connectivity.mqtts.enabled=true",
"device.connectivity.coaps.enabled=true",
})
@ContextConfiguration(classes = {DeviceControllerTest.Config.class})
@DaoSqlTest
public class DeviceControllerTest extends AbstractControllerTest {
static final TypeReference<PageData<Device>> PAGE_DATA_DEVICE_TYPE_REF = new TypeReference<>() {
};
private static final String DEVICE_TELEMETRY_TOPIC = "v1/devices/customTopic";
private static final String CHECK_DOCUMENTATION = "Check documentation";
ListeningExecutorService executor;
List<ListenableFuture<Device>> futures;
@ -121,8 +107,6 @@ public class DeviceControllerTest extends AbstractControllerTest {
private Tenant savedTenant;
private User tenantAdmin;
private DeviceProfileId mqttDeviceProfileId;
private DeviceProfileId coapDeviceProfileId;
@SpyBean
private GatewayNotificationsService gatewayNotificationsService;
@ -157,34 +141,6 @@ public class DeviceControllerTest extends AbstractControllerTest {
tenantAdmin.setLastName("Downs");
tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1");
DeviceProfile mqttProfile = new DeviceProfile();
mqttProfile.setName("Mqtt device profile");
mqttProfile.setType(DeviceProfileType.DEFAULT);
mqttProfile.setTransportType(DeviceTransportType.MQTT);
DeviceProfileData deviceProfileData = new DeviceProfileData();
deviceProfileData.setConfiguration(new DefaultDeviceProfileConfiguration());
MqttDeviceProfileTransportConfiguration transportConfiguration = new MqttDeviceProfileTransportConfiguration();
transportConfiguration.setDeviceTelemetryTopic(DEVICE_TELEMETRY_TOPIC);
deviceProfileData.setTransportConfiguration(transportConfiguration);
mqttProfile.setProfileData(deviceProfileData);
mqttProfile.setDefault(false);
mqttProfile.setDefaultRuleChainId(null);
mqttDeviceProfileId = doPost("/api/deviceProfile", mqttProfile, DeviceProfile.class).getId();
DeviceProfile coapProfile = new DeviceProfile();
coapProfile.setName("Coap device profile");
coapProfile.setType(DeviceProfileType.DEFAULT);
coapProfile.setTransportType(DeviceTransportType.COAP);
DeviceProfileData deviceProfileData2 = new DeviceProfileData();
deviceProfileData2.setConfiguration(new DefaultDeviceProfileConfiguration());
deviceProfileData2.setTransportConfiguration(new CoapDeviceProfileTransportConfiguration());
coapProfile.setProfileData(deviceProfileData);
coapProfile.setDefault(false);
coapProfile.setDefaultRuleChainId(null);
coapDeviceProfileId = doPost("/api/deviceProfile", coapProfile, DeviceProfile.class).getId();
}
@After
@ -743,144 +699,6 @@ public class DeviceControllerTest extends AbstractControllerTest {
Assert.assertEquals(savedDevice.getId(), deviceCredentials.getDeviceId());
}
@Test
public void testFetchPublishTelemetryCommandsForDefaultDevice() throws Exception {
Device device = new Device();
device.setName("My device");
device.setType("default");
Device savedDevice = doPost("/api/device", device, Device.class);
Map<String, String> commands =
doGetTyped("/api/device/" + savedDevice.getId().getId() + "/commands", new TypeReference<>() {});
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
assertThat(commands).hasSize(6);
assertThat(commands.get(HTTP)).isEqualTo(String.format("curl -v -X POST http://localhost:8080/api/v1/%s/telemetry --header Content-Type:application/json --data \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(commands.get(HTTPS)).isEqualTo(String.format("curl -v -X POST https://localhost:443/api/v1/%s/telemetry --header Content-Type:application/json --data \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(commands.get(MQTT)).isEqualTo(String.format("mosquitto_pub -d -q 1 -h localhost -p 1883 -t v1/devices/me/telemetry -u %s -m \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(commands.get(MQTTS)).isEqualTo(String.format("mosquitto_pub -d -q 1 --cafile tb-server-chain.pem -h localhost -p 8883 -t v1/devices/me/telemetry -u %s -m \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(commands.get(COAP)).isEqualTo(String.format("coap-client -m POST coap://localhost:5683/api/v1/%s/telemetry -t json -e \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(commands.get(COAPS)).isEqualTo(String.format("coap-client-openssl -m POST coaps://localhost:5684/api/v1/%s/telemetry -t json -e \"{temperature:25}\"",
credentials.getCredentialsId()));
}
@Test
public void testFetchPublishTelemetryCommandsForMqttDeviceWithAccessToken() throws Exception {
Device device = new Device();
device.setName("My device");
device.setDeviceProfileId(mqttDeviceProfileId);
Device savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
Map<String, String> commands =
doGetTyped("/api/device/" + savedDevice.getId().getId() + "/commands", new TypeReference<>() {});
assertThat(commands).hasSize(2);
assertThat(commands.get(MQTT)).isEqualTo(String.format("mosquitto_pub -d -q 1 -h localhost -p 1883 -t %s -u %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, credentials.getCredentialsId()));
assertThat(commands.get(MQTTS)).isEqualTo(String.format("mosquitto_pub -d -q 1 --cafile tb-server-chain.pem -h localhost -p 8883 -t %s -u %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, credentials.getCredentialsId()));
}
@Test
public void testFetchPublishTelemetryCommandsForDeviceWithMqttBasicCreds() throws Exception {
Device device = new Device();
device.setName("My device");
device.setDeviceProfileId(mqttDeviceProfileId);
Device savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
credentials.setCredentialsId(null);
credentials.setCredentialsType(DeviceCredentialsType.MQTT_BASIC);
BasicMqttCredentials basicMqttCredentials = new BasicMqttCredentials();
String clientId = "testClientId";
String userName = "testUsername";
String password = "testPassword";
basicMqttCredentials.setClientId(clientId);
basicMqttCredentials.setUserName(userName);
basicMqttCredentials.setPassword(password);
credentials.setCredentialsValue(JacksonUtil.toString(basicMqttCredentials));
doPost("/api/device/credentials", credentials)
.andExpect(status().isOk());
Map<String, String> commands =
doGetTyped("/api/device/" + savedDevice.getId().getId() + "/commands", new TypeReference<>() {});
assertThat(commands).hasSize(2);
assertThat(commands.get(MQTT)).isEqualTo(String.format("mosquitto_pub -d -q 1 -h localhost -p 1883 -t %s -i %s -u %s -P %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, clientId, userName, password));
assertThat(commands.get(MQTTS)).isEqualTo(String.format("mosquitto_pub -d -q 1 --cafile tb-server-chain.pem -h localhost -p 8883 -t %s -i %s -u %s -P %s -m \"{temperature:25}\"",
DEVICE_TELEMETRY_TOPIC, clientId, userName, password));
}
@Test
public void testFetchPublishTelemetryCommandsForDeviceWithX509Creds() throws Exception {
Device device = new Device();
device.setName("My device");
device.setDeviceProfileId(mqttDeviceProfileId);
Device savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
credentials.setCredentialsId(null);
credentials.setCredentialsType(DeviceCredentialsType.X509_CERTIFICATE);
credentials.setCredentialsValue("testValue");
doPost("/api/device/credentials", credentials)
.andExpect(status().isOk());
Map<String, String> commands =
doGetTyped("/api/device/" + savedDevice.getId().getId() + "/commands", new TypeReference<>() {});
assertThat(commands).hasSize(1);
assertThat(commands.get(MQTTS)).isEqualTo(CHECK_DOCUMENTATION);
}
@Test
public void testFetchPublishTelemetryCommandsForСoapDevice() throws Exception {
Device device = new Device();
device.setName("My device");
device.setDeviceProfileId(coapDeviceProfileId);
Device savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
Map<String, String> commands =
doGetTyped("/api/device/" + savedDevice.getId().getId() + "/commands", new TypeReference<>() {});
assertThat(commands).hasSize(2);
assertThat(commands.get(COAP)).isEqualTo(String.format("coap-client -m POST coap://localhost:5683/api/v1/%s/telemetry -t json -e \"{temperature:25}\"",
credentials.getCredentialsId()));
assertThat(commands.get(COAPS)).isEqualTo(String.format("coap-client-openssl -m POST coaps://localhost:5684/api/v1/%s/telemetry -t json -e \"{temperature:25}\"",
credentials.getCredentialsId()));
}
@Test
public void testFetchPublishTelemetryCommandsForСoapDeviceWithX509Creds() throws Exception {
Device device = new Device();
device.setName("My device");
device.setDeviceProfileId(coapDeviceProfileId);
Device savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials credentials =
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class);
credentials.setCredentialsId(null);
credentials.setCredentialsType(DeviceCredentialsType.X509_CERTIFICATE);
credentials.setCredentialsValue("testValue");
doPost("/api/device/credentials", credentials)
.andExpect(status().isOk());
Map<String, String> commands =
doGetTyped("/api/device/" + savedDevice.getId().getId() + "/commands", new TypeReference<>() {});
assertThat(commands).hasSize(1);
assertThat(commands.get(COAPS)).isEqualTo(CHECK_DOCUMENTATION);
}
@Test
public void testSaveDeviceCredentials() throws Exception {
Device device = new Device();

13
dao/src/main/java/org/thingsboard/server/dao/device/TbDeviceConnectivitySslCertService.java → common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityService.java

@ -15,7 +15,16 @@
*/
package org.thingsboard.server.dao.device;
import com.fasterxml.jackson.databind.JsonNode;
import org.thingsboard.server.common.data.Device;
public interface TbDeviceConnectivitySslCertService {
String getMqttSslCertificate();
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Map;
public interface DeviceConnectivityService {
JsonNode findDevicePublishTelemetryCommands(String baseUrl, Device device) throws URISyntaxException;
String getSslServerChain(String protocol) throws IOException;
}

3
common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.dao.device;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceIdInfo;
@ -46,8 +45,6 @@ public interface DeviceService extends EntityDaoService {
DeviceInfo findDeviceInfoById(TenantId tenantId, DeviceId deviceId);
Map<String, String> findDevicePublishTelemetryCommands(String baseUrl, Device device) throws URISyntaxException;
Device findDeviceById(TenantId tenantId, DeviceId deviceId);
ListenableFuture<Device> findDeviceByIdAsync(TenantId tenantId, DeviceId deviceId);

2
dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityInfo.java

@ -22,5 +22,5 @@ public class DeviceConnectivityInfo {
private Boolean enabled;
private String host;
private String port;
private String sslCertPath;
private String sslServerPemPath;
}

53
dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityMqttSslCertService.java

@ -1,53 +0,0 @@
/**
* Copyright © 2016-2023 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.dao.device;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.ResourceUtils;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.MQTTS;
@Service
@Slf4j
public class DeviceConnectivityMqttSslCertService implements TbDeviceConnectivitySslCertService {
private String certificate;
@Autowired
private DeviceConnectivityConfiguration deviceConnectivityConfiguration;
@PostConstruct
private void postConstruct() throws IOException {
String sslCertPath = deviceConnectivityConfiguration.getConnectivity()
.get(MQTTS)
.getSslCertPath();
if (sslCertPath != null && ResourceUtils.resourceExists(this, sslCertPath)) {
certificate = FileUtils.readFileToString(new File(sslCertPath), StandardCharsets.UTF_8);
}
}
@Override
public String getMqttSslCertificate() {
return certificate;
}
}

109
dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java

@ -38,7 +38,6 @@ import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TransportPayloadType;
import org.thingsboard.server.common.data.device.DeviceSearchQuery;
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
import org.thingsboard.server.common.data.device.data.CoapDeviceTransportConfiguration;
@ -48,7 +47,6 @@ import org.thingsboard.server.common.data.device.data.DeviceData;
import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration;
import org.thingsboard.server.common.data.device.data.MqttDeviceTransportConfiguration;
import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
@ -76,13 +74,9 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@ -91,18 +85,6 @@ import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.service.Validator.validateIds;
import static org.thingsboard.server.dao.service.Validator.validatePageLink;
import static org.thingsboard.server.dao.service.Validator.validateString;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.COAP;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.COAPS;
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.JSON_EXAMPLE_PAYLOAD;
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.CHECK_DOCUMENTATION;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.SERVER_CHAIN_PEM;
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.getMosquittoPublishCommand;
@Service("DeviceDaoService")
@Slf4j
@ -134,12 +116,6 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
@Autowired
private EntityCountService countService;
@Autowired
private DeviceConnectivityConfiguration deviceConnectivityConfiguration;
@Autowired
private DeviceConnectivityMqttSslCertService deviceConnectivityMqttSslCertService;
@Override
public DeviceInfo findDeviceInfoById(TenantId tenantId, DeviceId deviceId) {
log.trace("Executing findDeviceInfoById [{}]", deviceId);
@ -147,51 +123,6 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
return deviceDao.findDeviceInfoById(tenantId, deviceId.getId());
}
@Override
public Map<String, String> findDevicePublishTelemetryCommands(String baseUrl, Device device) throws URISyntaxException {
DeviceId deviceId = device.getId();
log.trace("Executing findDevicePublishTelemetryCommands [{}]", deviceId);
validateId(deviceId, INCORRECT_DEVICE_ID + deviceId);
String defaultHostname = new URI(baseUrl).getHost();
DeviceCredentials creds = deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getTenantId(), deviceId);
DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId());
DeviceTransportType transportType = deviceProfile.getTransportType();
Map<String, String> commands = new HashMap<>();
switch (transportType) {
case DEFAULT:
Optional.ofNullable(getHttpPublishCommand(HTTP, defaultHostname, creds)).ifPresent(v -> commands.put(HTTP, v));
Optional.ofNullable(getHttpPublishCommand(HTTPS, defaultHostname, creds)).ifPresent(v -> commands.put(HTTPS, v));
Optional.ofNullable(getMqttPublishCommand(MQTT, defaultHostname, creds)).ifPresent(v -> commands.put(MQTT, v));
Optional.ofNullable(getMqttPublishCommand(MQTTS, defaultHostname, creds)).ifPresent(v -> commands.put(MQTTS, v));
Optional.ofNullable(getCoapPublishCommand(COAP, defaultHostname, creds)).ifPresent(v -> commands.put(COAP, v));
Optional.ofNullable(getCoapPublishCommand(COAPS, defaultHostname, creds)).ifPresent(v -> commands.put(COAPS, v));
break;
case MQTT:
MqttDeviceProfileTransportConfiguration transportConfiguration =
(MqttDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration();
String topicName = transportConfiguration.getDeviceTelemetryTopic();
TransportPayloadType payloadType = transportConfiguration.getTransportPayloadTypeConfiguration().getTransportPayloadType();
String payload = (payloadType == TransportPayloadType.PROTOBUF) ? " -f protobufFileName" : " -m " + JSON_EXAMPLE_PAYLOAD;
Optional.ofNullable(getMqttPublishCommand(MQTT, defaultHostname, topicName, creds, payload)).ifPresent(v -> commands.put(MQTT, v));
Optional.ofNullable(getMqttPublishCommand(MQTTS, defaultHostname, topicName, creds, payload)).ifPresent(v -> commands.put(MQTTS, v));
break;
case COAP:
Optional.ofNullable(getCoapPublishCommand(COAP, defaultHostname, creds)).ifPresent(v -> commands.put(COAP, v));
Optional.ofNullable(getCoapPublishCommand(COAPS, defaultHostname, creds)).ifPresent(v -> commands.put(COAPS, v));
break;
default:
commands.put(transportType.name(), CHECK_DOCUMENTATION);
}
if (commands.containsKey(MQTTS) && deviceConnectivityMqttSslCertService.getMqttSslCertificate() != null) {
commands.put(SERVER_CHAIN_PEM, deviceConnectivityMqttSslCertService.getMqttSslCertificate());
}
return commands;
}
@Override
public Device findDeviceById(TenantId tenantId, DeviceId deviceId) {
log.trace("Executing findDeviceById [{}]", deviceId);
@ -747,44 +678,4 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
return EntityType.DEVICE;
}
private String getHttpPublishCommand(String protocol, String defaultHostname, DeviceCredentials deviceCredentials) {
DeviceConnectivityInfo httpProps = deviceConnectivityConfiguration.getConnectivity().get(protocol);
if (httpProps == null || !httpProps.getEnabled() ||
deviceCredentials.getCredentialsType() != DeviceCredentialsType.ACCESS_TOKEN) {
return null;
}
String hostName = httpProps.getHost().isEmpty() ? defaultHostname : httpProps.getHost();
String port = httpProps.getPort().isEmpty() ? "" : ":" + httpProps.getPort();
return getCurlCommand(protocol, hostName, port, deviceCredentials);
}
private String getMqttPublishCommand(String protocol, String defaultHostname, DeviceCredentials deviceCredentials) {
return getMqttPublishCommand(protocol, defaultHostname, DEFAULT_DEVICE_TELEMETRY_TOPIC, deviceCredentials, " -m " + JSON_EXAMPLE_PAYLOAD);
}
private String getMqttPublishCommand(String protocol, String defaultHostname, String deviceTelemetryTopic, DeviceCredentials deviceCredentials, String payload) {
if (MQTTS.equals(protocol) && deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) {
return CHECK_DOCUMENTATION;
}
DeviceConnectivityInfo properties = deviceConnectivityConfiguration.getConnectivity().get(protocol);
if (properties == null || !properties.getEnabled()) {
return null;
}
String mqttHost = properties.getHost().isEmpty() ? defaultHostname : properties.getHost();
String mqttPort = properties.getPort().isEmpty() ? null : properties.getPort();
return getMosquittoPublishCommand(protocol, mqttHost, mqttPort, deviceTelemetryTopic, deviceCredentials, payload);
}
private String getCoapPublishCommand(String protocol, String defaultHostname, DeviceCredentials deviceCredentials) {
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() ? defaultHostname : properties.getHost();
String port = properties.getPort().isEmpty() ? "" : ":" + properties.getPort();
return getCoapClientCommand(protocol, hostName, port, deviceCredentials);
}
}

224
dao/src/main/java/org/thingsboard/server/dao/device/DeviceСonnectivityServiceImpl.java

@ -0,0 +1,224 @@
/**
* Copyright © 2016-2023 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.dao.device;
import com.fasterxml.jackson.databind.JsonNode;
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.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.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 java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.CHECK_DOCUMENTATION;
import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.COAP;
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.WINDOWS;
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 static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
public static final String INCORRECT_DEVICE_ID = "Incorrect deviceId ";
public static final String DEFAULT_DEVICE_TELEMETRY_TOPIC = "v1/devices/me/telemetry";
@Autowired
private DeviceCredentialsService deviceCredentialsService;
@Autowired
private DeviceProfileService deviceProfileService;
@Autowired
private DeviceConnectivityConfiguration deviceConnectivityConfiguration;
@Override
public JsonNode findDevicePublishTelemetryCommands(String baseUrl, Device device) throws URISyntaxException {
DeviceId deviceId = device.getId();
log.trace("Executing findDevicePublishTelemetryCommands [{}]", deviceId);
validateId(deviceId, INCORRECT_DEVICE_ID + deviceId);
String defaultHostname = new URI(baseUrl).getHost();
DeviceCredentials creds = deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getTenantId(), deviceId);
DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId());
DeviceTransportType transportType = deviceProfile.getTransportType();
ObjectNode commands = JacksonUtil.newObjectNode();
switch (transportType) {
case DEFAULT:
commands.set(HTTP, getHttpTransportPublishCommands(defaultHostname, creds));
commands.set(MQTT, getMqttTransportPublishCommands(defaultHostname, creds));
commands.set(COAP, getCoapTransportPublishCommands(defaultHostname, creds));
break;
case MQTT:
MqttDeviceProfileTransportConfiguration transportConfiguration =
(MqttDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration();
String topicName = transportConfiguration.getDeviceTelemetryTopic();
commands.set(MQTT, getMqttTransportPublishCommands(defaultHostname, topicName, creds));
break;
case COAP:
commands.set(COAP, getCoapTransportPublishCommands(defaultHostname, creds));
break;
default:
commands.set(transportType.name(), JacksonUtil.toJsonNode(CHECK_DOCUMENTATION));
}
return commands;
}
@Override
public String getSslServerChain(String protocol) throws IOException {
String mqttSslPemPath = deviceConnectivityConfiguration.getConnectivity()
.get(protocol)
.getSslServerPemPath();
if (!mqttSslPemPath.isEmpty() && ResourceUtils.resourceExists(this, mqttSslPemPath)) {
return FileUtils.readFileToString(new File(mqttSslPemPath), StandardCharsets.UTF_8);
} else {
return null;
}
}
private JsonNode getHttpTransportPublishCommands(String defaultHostname, DeviceCredentials deviceCredentials) {
ObjectNode httpCommands = JacksonUtil.newObjectNode();
httpCommands.put(HTTP, getHttpPublishCommand(HTTP, defaultHostname, deviceCredentials));
httpCommands.put(HTTPS, getHttpPublishCommand(HTTPS, defaultHostname, deviceCredentials));
return httpCommands;
}
private String getHttpPublishCommand(String protocol, String defaultHostname, DeviceCredentials deviceCredentials) {
DeviceConnectivityInfo httpProps = deviceConnectivityConfiguration.getConnectivity().get(protocol);
if (httpProps == null || !httpProps.getEnabled() ||
deviceCredentials.getCredentialsType() != DeviceCredentialsType.ACCESS_TOKEN) {
return null;
}
String hostName = httpProps.getHost().isEmpty() ? defaultHostname : httpProps.getHost();
String port = httpProps.getPort().isEmpty() ? "" : ":" + httpProps.getPort();
return getCurlCommand(protocol, hostName, port, deviceCredentials);
}
private JsonNode getMqttTransportPublishCommands(String defaultHostname, DeviceCredentials deviceCredentials) {
return getMqttTransportPublishCommands(defaultHostname, DEFAULT_DEVICE_TELEMETRY_TOPIC, deviceCredentials);
}
private JsonNode getMqttTransportPublishCommands(String defaultHostname, String topic, DeviceCredentials deviceCredentials) {
ObjectNode mqttCommands = JacksonUtil.newObjectNode();
ObjectNode linuxMqttCommands = JacksonUtil.newObjectNode();
Optional.ofNullable(getMqttPublishCommand(LINUX, MQTT, defaultHostname, topic, deviceCredentials))
.ifPresent(v -> linuxMqttCommands.put(MQTT, v));
Optional.ofNullable(getMqttPublishCommand(LINUX, MQTTS, defaultHostname, topic, deviceCredentials))
.ifPresent(v -> linuxMqttCommands.put(MQTTS, v));
ObjectNode windowsMqttCommands = JacksonUtil.newObjectNode();
Optional.ofNullable(getMqttPublishCommand(WINDOWS, MQTT, defaultHostname, topic, deviceCredentials))
.ifPresent(v -> windowsMqttCommands.put(MQTT, v));
Optional.ofNullable(getMqttPublishCommand(WINDOWS, MQTTS, defaultHostname, topic, deviceCredentials))
.ifPresent(v -> windowsMqttCommands.put(MQTTS, v));
ObjectNode dockerMqttCommands = JacksonUtil.newObjectNode();
Optional.ofNullable(getMqttPublishCommand(DOCKER, MQTT, defaultHostname, topic, deviceCredentials))
.ifPresent(v -> dockerMqttCommands.put(MQTT, v));
Optional.ofNullable(getMqttPublishCommand(DOCKER, MQTTS, defaultHostname, topic, deviceCredentials))
.ifPresent(v -> dockerMqttCommands.put(MQTTS, v));
mqttCommands.set(LINUX, linuxMqttCommands);
mqttCommands.set(WINDOWS, windowsMqttCommands);
mqttCommands.set(DOCKER, dockerMqttCommands);
return mqttCommands;
}
private String getMqttPublishCommand(String os, String protocol, String defaultHostname, String deviceTelemetryTopic, DeviceCredentials deviceCredentials) {
if (MQTTS.equals(protocol) && deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) {
return CHECK_DOCUMENTATION;
}
DeviceConnectivityInfo properties = deviceConnectivityConfiguration.getConnectivity().get(protocol);
if (properties == null || !properties.getEnabled()) {
return null;
}
String mqttHost = properties.getHost().isEmpty() ? defaultHostname : properties.getHost();
String mqttPort = properties.getPort().isEmpty() ? null : properties.getPort();
switch (os) {
case LINUX:
return getMosquittoPubPublishCommand(protocol, mqttHost, mqttPort, deviceTelemetryTopic, deviceCredentials);
case WINDOWS:
return getMosquittoPubPublishCommand(protocol, mqttHost, mqttPort, deviceTelemetryTopic, deviceCredentials);
case DOCKER:
return getDockerMosquittoClientsPublishCommand(protocol, mqttHost, mqttPort, deviceTelemetryTopic, deviceCredentials);
default:
throw new IllegalArgumentException("Unsupported operating system: " + os);
}
}
private JsonNode getCoapTransportPublishCommands(String defaultHostname, DeviceCredentials deviceCredentials) {
ObjectNode coapCommands = JacksonUtil.newObjectNode();
ObjectNode linuxCoapCommands = JacksonUtil.newObjectNode();
Optional.ofNullable(getCoapPublishCommand(LINUX, COAP, defaultHostname, deviceCredentials))
.ifPresent(v -> linuxCoapCommands.put(COAP, v));
Optional.ofNullable(getCoapPublishCommand(LINUX, COAPS, defaultHostname, deviceCredentials))
.ifPresent(v -> linuxCoapCommands.put(COAPS, v));
coapCommands.set(LINUX, linuxCoapCommands);
return coapCommands;
}
private String getCoapPublishCommand(String os, String protocol, String defaultHostname, DeviceCredentials deviceCredentials) {
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() ? defaultHostname : properties.getHost();
String port = properties.getPort().isEmpty() ? "" : ":" + properties.getPort();
switch (os) {
case LINUX:
return getCoapClientCommand(protocol, hostName, port, deviceCredentials);
default:
throw new IllegalArgumentException("Unsupported operating system: " + os);
}
}
}

51
dao/src/main/java/org/thingsboard/server/dao/util/DeviceConnectivityUtil.java

@ -24,10 +24,13 @@ public class DeviceConnectivityUtil {
public static final String HTTP = "http";
public static final String HTTPS = "https";
public static final String MQTT = "mqtt";
public static final String LINUX = "linux";
public static final String WINDOWS = "windows";
public static final String DOCKER = "docker";
public static final String MQTTS = "mqtts";
public static final String COAP = "coap";
public static final String COAPS = "coaps";
public static final String SERVER_CHAIN_PEM = "serverChainPem";
public static final String MQTT_SSL_PEM_FILE_NAME = "tb-server-chain.pem";
public static final String CHECK_DOCUMENTATION = "Check documentation";
public static final String JSON_EXAMPLE_PAYLOAD = "\"{temperature:25}\"";
@ -36,10 +39,10 @@ public class DeviceConnectivityUtil {
protocol, host, port, deviceCredentials.getCredentialsId());
}
public static String getMosquittoPublishCommand(String protocol, String host, String port, String deviceTelemetryTopic, DeviceCredentials deviceCredentials, String payload) {
public static String getMosquittoPubPublishCommand(String protocol, String host, String port, String deviceTelemetryTopic, DeviceCredentials deviceCredentials) {
StringBuilder command = new StringBuilder("mosquitto_pub -d -q 1");
if (MQTTS.equals(protocol)) {
command.append(" --cafile tb-server-chain.pem");
command.append(" --cafile pathToFile/" + MQTT_SSL_PEM_FILE_NAME);
}
command.append(" -h ").append(host).append(port == null ? "" : " -p " + port);
command.append(" -t ").append(deviceTelemetryTopic);
@ -68,7 +71,47 @@ public class DeviceConnectivityUtil {
default:
return null;
}
command.append(payload);
command.append(" -m " + JSON_EXAMPLE_PAYLOAD);
return command.toString();
}
public static String getDockerMosquittoClientsPublishCommand(String protocol, String host, String port, String deviceTelemetryTopic, DeviceCredentials deviceCredentials) {
StringBuilder command = new StringBuilder("docker run");
if (MQTTS.equals(protocol)) {
command.append(" --volume pathToFile/" + MQTT_SSL_PEM_FILE_NAME + ":/tmp/" + MQTT_SSL_PEM_FILE_NAME);
}
command.append(" -it --rm thingsboard/mosquitto-clients pub");
if (MQTTS.equals(protocol)) {
command.append(" --cafile tmp/" + MQTT_SSL_PEM_FILE_NAME);
}
command.append(" -h ").append(host).append(port == null ? "" : " -p " + port);
command.append(" -t ").append(deviceTelemetryTopic);
switch (deviceCredentials.getCredentialsType()) {
case ACCESS_TOKEN:
command.append(" -u ").append(deviceCredentials.getCredentialsId());
break;
case MQTT_BASIC:
BasicMqttCredentials credentials = JacksonUtil.fromString(deviceCredentials.getCredentialsValue(),
BasicMqttCredentials.class);
if (credentials != null) {
if (credentials.getClientId() != null) {
command.append(" -i ").append(credentials.getClientId());
}
if (credentials.getUserName() != null) {
command.append(" -u ").append(credentials.getUserName());
}
if (credentials.getPassword() != null) {
command.append(" -P ").append(credentials.getPassword());
}
} else {
return null;
}
break;
default:
return null;
}
command.append(" -m " + JSON_EXAMPLE_PAYLOAD);
return command.toString();
}

Loading…
Cancel
Save