|
|
|
@ -34,6 +34,7 @@ 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; |
|
|
|
@ -51,14 +52,16 @@ 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.DefaultDeviceProfileTransportConfiguration; |
|
|
|
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; |
|
|
|
@ -91,12 +94,19 @@ 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; |
|
|
|
|
|
|
|
@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"; |
|
|
|
|
|
|
|
ListeningExecutorService executor; |
|
|
|
|
|
|
|
List<ListenableFuture<Device>> futures; |
|
|
|
@ -104,6 +114,8 @@ public class DeviceControllerTest extends AbstractControllerTest { |
|
|
|
|
|
|
|
private Tenant savedTenant; |
|
|
|
private User tenantAdmin; |
|
|
|
private DeviceProfileId mqttDeviceProfileId; |
|
|
|
private DeviceProfileId coapDeviceProfileId; |
|
|
|
|
|
|
|
@SpyBean |
|
|
|
private GatewayNotificationsService gatewayNotificationsService; |
|
|
|
@ -138,6 +150,34 @@ 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 |
|
|
|
@ -655,51 +695,136 @@ public class DeviceControllerTest extends AbstractControllerTest { |
|
|
|
device.setName("My device"); |
|
|
|
device.setType("default"); |
|
|
|
Device savedDevice = doPost("/api/device", device, Device.class); |
|
|
|
List<String> commands = |
|
|
|
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(3); |
|
|
|
assertThat(commands).containsExactly(String.format("mosquitto_pub -d -q 1 -h localhost -t v1/devices/me/telemetry -u %s -m \"{temperature:25}\"", |
|
|
|
credentials.getCredentialsId()), |
|
|
|
String.format("curl -v -X POST http://localhost:80/api/v1/%s/telemetry --header Content-Type:application/json --data \"{temperature:25}\"", |
|
|
|
credentials.getCredentialsId()), |
|
|
|
String.format("echo -n \"{temperature:25}\" | coap-client -m post coap://localhost:5683/api/v1/%s/telemetry -f-", |
|
|
|
credentials.getCredentialsId())); |
|
|
|
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 --cafile tb-server-chain.pem -d -q 1 -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 -v 9 -m POST coaps://localhost:5684/api/v1/%s/telemetry -t json -e \"{temperature:25}\"", |
|
|
|
credentials.getCredentialsId())); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void testFetchPublishTelemetryCommandsForMqttDevice() throws Exception { |
|
|
|
DeviceProfile mqttProfile = new DeviceProfile(); |
|
|
|
mqttProfile.setName("Mqtt device profile"); |
|
|
|
mqttProfile.setType(DeviceProfileType.DEFAULT); |
|
|
|
mqttProfile.setTransportType(DeviceTransportType.MQTT); |
|
|
|
public void testFetchPublishTelemetryCommandsForMqttDeviceWithAccessToken() throws Exception { |
|
|
|
Device device = new Device(); |
|
|
|
device.setName("My device"); |
|
|
|
device.setDeviceProfileId(mqttDeviceProfileId); |
|
|
|
|
|
|
|
DeviceProfileData deviceProfileData = new DeviceProfileData(); |
|
|
|
deviceProfileData.setConfiguration(new DefaultDeviceProfileConfiguration()); |
|
|
|
deviceProfileData.setTransportConfiguration(new MqttDeviceProfileTransportConfiguration()); |
|
|
|
Device savedDevice = doPost("/api/device", device, Device.class); |
|
|
|
DeviceCredentials credentials = |
|
|
|
doGet("/api/device/" + savedDevice.getId().getId() + "/credentials", DeviceCredentials.class); |
|
|
|
|
|
|
|
mqttProfile.setProfileData(deviceProfileData); |
|
|
|
mqttProfile.setDefault(false); |
|
|
|
mqttProfile.setDefaultRuleChainId(null); |
|
|
|
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 --cafile tb-server-chain.pem -d -q 1 -h localhost -p 8883 -t %s -u %s -m \"{temperature:25}\"", |
|
|
|
DEVICE_TELEMETRY_TOPIC, credentials.getCredentialsId())); |
|
|
|
} |
|
|
|
|
|
|
|
mqttProfile = doPost("/api/deviceProfile", mqttProfile, DeviceProfile.class); |
|
|
|
@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 --cafile tb-server-chain.pem -d -q 1 -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(mqttProfile.getId()); |
|
|
|
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("Not supported"); |
|
|
|
} |
|
|
|
|
|
|
|
@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 -v 9 -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()); |
|
|
|
|
|
|
|
List<String> commands = |
|
|
|
Map<String, String> commands = |
|
|
|
doGetTyped("/api/device/" + savedDevice.getId().getId() + "/commands", new TypeReference<>() {}); |
|
|
|
assertThat(commands).hasSize(1); |
|
|
|
assertThat(commands.get(0)).isEqualTo("mosquitto_pub -d -q 1 -h localhost -t v1/devices/me/telemetry -u " |
|
|
|
+ credentials.getCredentialsId() + " -m \"{temperature:25}\""); |
|
|
|
assertThat(commands.get("coaps")).isEqualTo("Not supported"); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
|