diff --git a/msa/black-box-tests/pom.xml b/msa/black-box-tests/pom.xml
index 49f4c959e9..1d0f585eb6 100644
--- a/msa/black-box-tests/pom.xml
+++ b/msa/black-box-tests/pom.xml
@@ -92,6 +92,10 @@
awaitility
test
+
+ org.eclipse.californium
+ californium-core
+
ch.qos.logback
logback-classic
@@ -160,6 +164,12 @@
snmp
docker-info
+
+ org.thingsboard.common
+ message
+ ${project.version}
+ test
+
diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java
index a148d7d138..d259d46b43 100644
--- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java
+++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java
@@ -26,7 +26,14 @@ import org.apache.http.ssl.SSLContexts;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Listeners;
+import org.thingsboard.server.common.data.DeviceProfile;
+import org.thingsboard.server.common.data.DeviceProfileProvisionType;
import org.thingsboard.server.common.data.EntityType;
+import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration;
+import org.thingsboard.server.common.data.device.profile.CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration;
+import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
+import org.thingsboard.server.common.data.device.profile.DeviceProfileProvisionConfiguration;
+import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfileProvisionConfiguration;
import org.thingsboard.server.common.data.id.DeviceId;
import java.net.URI;
@@ -37,6 +44,9 @@ import java.util.Random;
@Slf4j
@Listeners(TestListener.class)
public abstract class AbstractContainerTest {
+
+ protected final static String TEST_PROVISION_DEVICE_KEY = "test_provision_key";
+ protected final static String TEST_PROVISION_DEVICE_SECRET = "test_provision_secret";
protected static long timeoutMultiplier = 1;
protected ObjectMapper mapper = new ObjectMapper();
private static final ContainerTestSuite containerTestSuite = ContainerTestSuite.getInstance();
@@ -150,4 +160,28 @@ public abstract class AbstractContainerTest {
}
}
+ protected DeviceProfile updateDeviceProfileWithProvisioningStrategy(DeviceProfile deviceProfile, DeviceProfileProvisionType provisionType) {
+ DeviceProfileProvisionConfiguration provisionConfiguration;
+ String testProvisionDeviceKey = TEST_PROVISION_DEVICE_KEY;
+ deviceProfile.setProvisionType(provisionType);
+ switch(provisionType) {
+ case ALLOW_CREATE_NEW_DEVICES:
+ provisionConfiguration = new AllowCreateNewDevicesDeviceProfileProvisionConfiguration(TEST_PROVISION_DEVICE_SECRET);
+ break;
+ case CHECK_PRE_PROVISIONED_DEVICES:
+ provisionConfiguration = new CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration(TEST_PROVISION_DEVICE_SECRET);
+ break;
+ default:
+ case DISABLED:
+ testProvisionDeviceKey = null;
+ provisionConfiguration = new DisabledDeviceProfileProvisionConfiguration(null);
+ break;
+ }
+ DeviceProfileData deviceProfileData = deviceProfile.getProfileData();
+ deviceProfileData.setProvisionConfiguration(provisionConfiguration);
+ deviceProfile.setProfileData(deviceProfileData);
+ deviceProfile.setProvisionDeviceKey(testProvisionDeviceKey);
+ return testRestClient.postDeviceProfile(deviceProfile);
+ }
+
}
diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClient.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClient.java
new file mode 100644
index 0000000000..e00fdeebfd
--- /dev/null
+++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClient.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright © 2016-2022 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.msa;
+
+import java.io.IOException;
+import org.eclipse.californium.core.CoapClient;
+import org.eclipse.californium.core.CoapHandler;
+import org.eclipse.californium.core.CoapObserveRelation;
+import org.eclipse.californium.core.CoapResponse;
+import org.eclipse.californium.core.coap.CoAP;
+import org.eclipse.californium.core.coap.MediaTypeRegistry;
+import org.eclipse.californium.core.coap.Request;
+import org.eclipse.californium.elements.exception.ConnectorException;
+import org.thingsboard.server.common.msg.session.FeatureType;
+
+public class TestCoapClient {
+
+ private static final String COAP_BASE_URL = "coap://localhost:5683/api/v1/";
+ private static final long CLIENT_REQUEST_TIMEOUT = 60000L;
+
+ private final CoapClient client;
+
+ public TestCoapClient(){
+ this.client = createClient();
+ }
+
+ public TestCoapClient(String accessToken, FeatureType featureType) {
+ this.client = createClient(getFeatureTokenUrl(accessToken, featureType));
+ }
+
+ public TestCoapClient(String featureTokenUrl) {
+ this.client = createClient(featureTokenUrl);
+ }
+
+ public void connectToCoap(String accessToken) {
+ setURI(accessToken, null);
+ }
+
+ public void connectToCoap(String accessToken, FeatureType featureType) {
+ setURI(accessToken, featureType);
+ }
+
+ public void disconnect() {
+ if (client != null) {
+ client.shutdown();
+ }
+ }
+
+ public CoapResponse postMethod(String requestBody) throws ConnectorException, IOException {
+ return this.postMethod(requestBody.getBytes());
+ }
+
+ public CoapResponse postMethod(byte[] requestBodyBytes) throws ConnectorException, IOException {
+ return client.setTimeout(CLIENT_REQUEST_TIMEOUT).post(requestBodyBytes, MediaTypeRegistry.APPLICATION_JSON);
+ }
+
+ public void postMethod(CoapHandler handler, String payload, int format) {
+ client.post(handler, payload, format);
+ }
+
+ public void postMethod(CoapHandler handler, byte[] payload, int format) {
+ client.post(handler, payload, format);
+ }
+
+ public CoapResponse getMethod() throws ConnectorException, IOException {
+ return client.setTimeout(CLIENT_REQUEST_TIMEOUT).get();
+ }
+
+ public CoapObserveRelation getObserveRelation(TestCoapClientCallback callback){
+ Request request = Request.newGet().setObserve();
+ request.setType(CoAP.Type.CON);
+ return client.observe(request, callback);
+ }
+
+ public void setURI(String featureTokenUrl) {
+ if (client == null) {
+ throw new RuntimeException("Failed to connect! CoapClient is not initialized!");
+ }
+ client.setURI(featureTokenUrl);
+ }
+
+ public void setURI(String accessToken, FeatureType featureType) {
+ if (featureType == null){
+ featureType = FeatureType.ATTRIBUTES;
+ }
+ setURI(getFeatureTokenUrl(accessToken, featureType));
+ }
+
+ private CoapClient createClient() {
+ return new CoapClient();
+ }
+
+ private CoapClient createClient(String featureTokenUrl) {
+ return new CoapClient(featureTokenUrl);
+ }
+
+ public static String getFeatureTokenUrl(FeatureType featureType) {
+ return COAP_BASE_URL + featureType.name().toLowerCase();
+ }
+
+ public static String getFeatureTokenUrl(String token, FeatureType featureType) {
+ return COAP_BASE_URL + token + "/" + featureType.name().toLowerCase();
+ }
+
+ public static String getFeatureTokenUrl(String token, FeatureType featureType, int requestId) {
+ return COAP_BASE_URL + token + "/" + featureType.name().toLowerCase() + "/" + requestId;
+ }
+}
diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClientCallback.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClientCallback.java
new file mode 100644
index 0000000000..b31f9c2905
--- /dev/null
+++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClientCallback.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright © 2016-2022 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.msa;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.californium.core.CoapHandler;
+import org.eclipse.californium.core.CoapResponse;
+import org.eclipse.californium.core.coap.CoAP;
+
+import java.util.concurrent.CountDownLatch;
+
+@Slf4j
+@Data
+public class TestCoapClientCallback implements CoapHandler {
+
+ protected final CountDownLatch latch;
+ protected Integer observe;
+ protected byte[] payloadBytes;
+ protected CoAP.ResponseCode responseCode;
+
+ public TestCoapClientCallback() {
+ this.latch = new CountDownLatch(1);
+ }
+
+ public TestCoapClientCallback(int subscribeCount) {
+ this.latch = new CountDownLatch(subscribeCount);
+ }
+
+ public Integer getObserve() {
+ return observe;
+ }
+
+ public byte[] getPayloadBytes() {
+ return payloadBytes;
+ }
+
+ public CoAP.ResponseCode getResponseCode() {
+ return responseCode;
+ }
+
+ @Override
+ public void onLoad(CoapResponse response) {
+ observe = response.getOptions().getObserve();
+ payloadBytes = response.getPayload();
+ responseCode = response.getCode();
+ latch.countDown();
+ }
+
+ @Override
+ public void onError() {
+ log.warn("Command Response Ack Error, No connect");
+ }
+
+}
diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java
index 713205e228..138c74e9b6 100644
--- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java
+++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java
@@ -27,7 +27,9 @@ import io.restassured.path.json.JsonPath;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.thingsboard.server.common.data.Device;
+import org.thingsboard.server.common.data.DeviceProfile;
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.id.RuleChainId;
import org.thingsboard.server.common.data.page.PageData;
@@ -93,6 +95,15 @@ public class TestRestClient {
.as(Device.class);
}
+ public Device getDeviceByName(String deviceName) {
+ return given().spec(requestSpec).pathParam("deviceName", deviceName)
+ .get("/api/tenant/devices?deviceName={deviceName}")
+ .then()
+ .statusCode(HTTP_OK)
+ .extract()
+ .as(Device.class);
+ }
+
public ValidatableResponse getDeviceById(DeviceId deviceId, int statusCode) {
return given().spec(requestSpec)
.pathParams("deviceId", deviceId.getId())
@@ -159,6 +170,14 @@ public class TestRestClient {
.as(JsonNode.class);
}
+ public JsonPath postProvisionRequest(String provisionRequest) {
+ return given().spec(requestSpec)
+ .body(provisionRequest)
+ .post("/api/v1/provision")
+ .getBody()
+ .jsonPath();
+ }
+
public PageData getRuleChains(PageLink pageLink) {
Map params = new HashMap<>();
addPageLinkToParam(params, pageLink);
@@ -252,6 +271,24 @@ public class TestRestClient {
.as(JsonNode.class);
}
+ public DeviceProfile getDeviceProfileById(DeviceProfileId deviceProfileId) {
+ return given().spec(requestSpec).get("/api/deviceProfile/{deviceProfileId}", deviceProfileId.getId())
+ .then()
+ .assertThat()
+ .statusCode(HTTP_OK)
+ .extract()
+ .as(DeviceProfile.class);
+ }
+
+ public DeviceProfile postDeviceProfile(DeviceProfile deviceProfile) {
+ return given().spec(requestSpec).body(deviceProfile)
+ .post("/api/deviceProfile")
+ .then()
+ .statusCode(HTTP_OK)
+ .extract()
+ .as(DeviceProfile.class);
+ }
+
public String getToken() {
return token;
}
diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/CoapClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/CoapClientTest.java
new file mode 100644
index 0000000000..fe3443dd0e
--- /dev/null
+++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/CoapClientTest.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright © 2016-2022 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.msa.connectivity;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.gson.JsonObject;
+import io.restassured.path.json.JsonPath;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+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.DeviceProfileProvisionType;
+import org.thingsboard.server.common.data.security.DeviceCredentials;
+import org.thingsboard.server.common.msg.session.FeatureType;
+import org.thingsboard.server.msa.AbstractContainerTest;
+import org.thingsboard.server.msa.TestCoapClient;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.thingsboard.server.msa.prototypes.DevicePrototypes.defaultDevicePrototype;
+
+public class CoapClientTest extends AbstractContainerTest {
+ private TestCoapClient client;
+
+ private Device device;
+ @BeforeMethod
+ public void setUp() throws Exception {
+ testRestClient.login("tenant@thingsboard.org", "tenant");
+ device = testRestClient.postDevice("", defaultDevicePrototype("http_"));
+ }
+
+ @AfterMethod
+ public void tearDown() {
+ testRestClient.deleteDeviceIfExists(device.getId());
+ }
+
+ @Test
+ public void provisionRequestForDeviceWithPreProvisionedStrategy() throws Exception {
+
+ DeviceProfile deviceProfile = testRestClient.getDeviceProfileById(device.getDeviceProfileId());
+ deviceProfile = updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES);
+
+ DeviceCredentials expectedDeviceCredentials = testRestClient.getDeviceCredentialsByDeviceId(device.getId());
+
+ JsonNode provisionResponse = JacksonUtil.fromBytes(createCoapClientAndPublish(device.getName()));
+
+ assertThat(provisionResponse.get("credentialsType").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsType().name());
+ assertThat(provisionResponse.get("credentialsValue").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsId());
+ assertThat(provisionResponse.get("status").asText()).isEqualTo("SUCCESS");
+
+ updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.DISABLED);
+ }
+
+ @Test
+ public void provisionRequestForDeviceWithAllowToCreateNewDevicesStrategy() throws Exception {
+
+ String testDeviceName = "test_provision_device";
+
+ DeviceProfile deviceProfile = testRestClient.getDeviceProfileById(device.getDeviceProfileId());
+
+ deviceProfile = updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES);
+
+ JsonNode provisionResponse = JacksonUtil.fromBytes(createCoapClientAndPublish(testDeviceName));
+
+ testRestClient.deleteDeviceIfExists(device.getId());
+ device = testRestClient.getDeviceByName(testDeviceName);
+
+ DeviceCredentials expectedDeviceCredentials = testRestClient.getDeviceCredentialsByDeviceId(device.getId());
+
+ assertThat(provisionResponse.get("credentialsType").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsType().name());
+ assertThat(provisionResponse.get("credentialsValue").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsId());
+ assertThat(provisionResponse.get("status").asText()).isEqualTo("SUCCESS");
+
+ updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.DISABLED);
+ }
+
+ @Test
+ public void provisionRequestForDeviceWithDisabledProvisioningStrategy() throws Exception {
+
+ JsonObject provisionRequest = new JsonObject();
+ provisionRequest.addProperty("provisionDeviceKey", TEST_PROVISION_DEVICE_KEY);
+ provisionRequest.addProperty("provisionDeviceSecret", TEST_PROVISION_DEVICE_SECRET);
+
+ JsonNode response = JacksonUtil.fromBytes(createCoapClientAndPublish(null));
+
+ assertThat(response.get("status").asText()).isEqualTo("NOT_FOUND");
+ }
+
+ private byte[] createCoapClientAndPublish(String deviceName) throws Exception {
+ String provisionRequestMsg = createTestProvisionMessage(deviceName);
+ client = new TestCoapClient(TestCoapClient.getFeatureTokenUrl(FeatureType.PROVISION));
+ return client.postMethod(provisionRequestMsg.getBytes()).getPayload();
+ }
+
+ private String createTestProvisionMessage(String deviceName) {
+ ObjectNode provisionRequest = JacksonUtil.newObjectNode();
+ provisionRequest.put("provisionDeviceKey", TEST_PROVISION_DEVICE_KEY);
+ provisionRequest.put("provisionDeviceSecret", TEST_PROVISION_DEVICE_SECRET);
+ if (deviceName != null) {
+ provisionRequest.put("deviceName", deviceName);
+ }
+ return provisionRequest.toString();
+ }
+
+}
diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java
index 2eb4cdf076..adaefa887a 100644
--- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java
+++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java
@@ -16,10 +16,14 @@
package org.thingsboard.server.msa.connectivity;
import com.fasterxml.jackson.databind.JsonNode;
+import com.google.gson.JsonObject;
+import io.restassured.path.json.JsonPath;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.server.common.data.Device;
+import org.thingsboard.server.common.data.DeviceProfile;
+import org.thingsboard.server.common.data.DeviceProfileProvisionType;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.msa.AbstractContainerTest;
import org.thingsboard.server.msa.WsClient;
@@ -69,8 +73,8 @@ public class HttpClientTest extends AbstractContainerTest {
String accessToken = testRestClient.getDeviceCredentialsByDeviceId(device.getId()).getCredentialsId();
assertThat(accessToken).isNotNull();
- JsonNode sharedAattribute = mapper.readTree(createPayload().toString());
- testRestClient.postTelemetryAttribute(DEVICE, device.getId(), SHARED_SCOPE, sharedAattribute);
+ JsonNode sharedAttribute = mapper.readTree(createPayload().toString());
+ testRestClient.postTelemetryAttribute(DEVICE, device.getId(), SHARED_SCOPE, sharedAttribute);
JsonNode clientAttribute = mapper.readTree(createPayload().toString());
testRestClient.postAttribute(accessToken, clientAttribute);
@@ -78,11 +82,11 @@ public class HttpClientTest extends AbstractContainerTest {
TimeUnit.SECONDS.sleep(3 * timeoutMultiplier);
JsonNode attributes = testRestClient.getAttributes(accessToken, null, null);
- assertThat(attributes.get("shared")).isEqualTo(sharedAattribute);
+ assertThat(attributes.get("shared")).isEqualTo(sharedAttribute);
assertThat(attributes.get("client")).isEqualTo(clientAttribute);
JsonNode attributes2 = testRestClient.getAttributes(accessToken, null, "stringKey");
- assertThat(attributes2.get("shared").get("stringKey")).isEqualTo(sharedAattribute.get("stringKey"));
+ assertThat(attributes2.get("shared").get("stringKey")).isEqualTo(sharedAttribute.get("stringKey"));
assertThat(attributes2.has("client")).isFalse();
JsonNode attributes3 = testRestClient.getAttributes(accessToken, "longKey,stringKey", null);
@@ -91,4 +95,77 @@ public class HttpClientTest extends AbstractContainerTest {
assertThat(attributes3.get("client").get("longKey")).isEqualTo(clientAttribute.get("longKey"));
assertThat(attributes3.get("client").get("stringKey")).isEqualTo(clientAttribute.get("stringKey"));
}
+
+ @Test
+ public void provisionRequestForDeviceWithPreProvisionedStrategy() throws Exception {
+
+ DeviceProfile deviceProfile = testRestClient.getDeviceProfileById(device.getDeviceProfileId());
+ deviceProfile = updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES);
+
+ DeviceCredentials expectedDeviceCredentials = testRestClient.getDeviceCredentialsByDeviceId(device.getId());
+
+ JsonObject provisionRequest = new JsonObject();
+ provisionRequest.addProperty("provisionDeviceKey", TEST_PROVISION_DEVICE_KEY);
+ provisionRequest.addProperty("provisionDeviceSecret", TEST_PROVISION_DEVICE_SECRET);
+ provisionRequest.addProperty("deviceName", device.getName());
+
+ JsonPath provisionResponse = testRestClient.postProvisionRequest(provisionRequest.toString());
+
+ String credentialsType = provisionResponse.get("credentialsType");
+ String credentialsValue = provisionResponse.get("credentialsValue");
+ String status = provisionResponse.get("status");
+
+ assertThat(credentialsType).isEqualTo(expectedDeviceCredentials.getCredentialsType().name());
+ assertThat(credentialsValue).isEqualTo(expectedDeviceCredentials.getCredentialsId());
+ assertThat(status).isEqualTo("SUCCESS");
+
+ updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.DISABLED);
+ }
+
+ @Test
+ public void provisionRequestForDeviceWithAllowToCreateNewDevicesStrategy() throws Exception {
+
+ String testDeviceName = "test_provision_device";
+
+ DeviceProfile deviceProfile = testRestClient.getDeviceProfileById(device.getDeviceProfileId());
+
+ deviceProfile = updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES);
+
+ JsonObject provisionRequest = new JsonObject();
+ provisionRequest.addProperty("provisionDeviceKey", TEST_PROVISION_DEVICE_KEY);
+ provisionRequest.addProperty("provisionDeviceSecret", TEST_PROVISION_DEVICE_SECRET);
+ provisionRequest.addProperty("deviceName", testDeviceName);
+
+ JsonPath provisionResponse = testRestClient.postProvisionRequest(provisionRequest.toString());
+
+ String credentialsType = provisionResponse.get("credentialsType");
+ String credentialsValue = provisionResponse.get("credentialsValue");
+ String status = provisionResponse.get("status");
+
+ testRestClient.deleteDeviceIfExists(device.getId());
+ device = testRestClient.getDeviceByName(testDeviceName);
+
+ DeviceCredentials expectedDeviceCredentials = testRestClient.getDeviceCredentialsByDeviceId(device.getId());
+
+ assertThat(credentialsType).isEqualTo(expectedDeviceCredentials.getCredentialsType().name());
+ assertThat(credentialsValue).isEqualTo(expectedDeviceCredentials.getCredentialsId());
+ assertThat(status).isEqualTo("SUCCESS");
+
+ updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.DISABLED);
+ }
+
+ @Test
+ public void provisionRequestForDeviceWithDisabledProvisioningStrategy() throws Exception {
+
+ JsonObject provisionRequest = new JsonObject();
+ provisionRequest.addProperty("provisionDeviceKey", TEST_PROVISION_DEVICE_KEY);
+ provisionRequest.addProperty("provisionDeviceSecret", TEST_PROVISION_DEVICE_SECRET);
+
+ JsonPath provisionResponse = testRestClient.postProvisionRequest(provisionRequest.toString());
+
+ String status = provisionResponse.get("status");
+
+ assertThat(status).isEqualTo("NOT_FOUND");
+ }
+
}
diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java
index 55dd432644..347598a9e7 100644
--- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java
+++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java
@@ -34,6 +34,8 @@ import org.thingsboard.mqtt.MqttClientConfig;
import org.thingsboard.mqtt.MqttHandler;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
+import org.thingsboard.server.common.data.DeviceProfile;
+import org.thingsboard.server.common.data.DeviceProfileProvisionType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.page.PageData;
@@ -322,6 +324,104 @@ public class MqttClientTest extends AbstractContainerTest {
assertThat(mqttClient.isConnected()).isFalse();
}
+ @Test
+ public void provisionRequestForDeviceWithPreProvisionedStrategy() throws Exception {
+
+ DeviceProfile deviceProfile = testRestClient.getDeviceProfileById(device.getDeviceProfileId());
+ deviceProfile = updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES);
+
+ DeviceCredentials expectedDeviceCredentials = testRestClient.getDeviceCredentialsByDeviceId(device.getId());
+
+ MqttMessageListener listener = new MqttMessageListener();
+ MqttClient mqttClient = getMqttClient("provision", listener);
+
+ JsonObject provisionRequest = new JsonObject();
+ provisionRequest.addProperty("provisionDeviceKey", TEST_PROVISION_DEVICE_KEY);
+ provisionRequest.addProperty("provisionDeviceSecret", TEST_PROVISION_DEVICE_SECRET);
+ provisionRequest.addProperty("deviceName", device.getName());
+
+ mqttClient.publish("/provision/request", Unpooled.wrappedBuffer(provisionRequest.toString().getBytes())).get();
+
+ //Wait for response
+ TimeUnit.SECONDS.sleep(3 * timeoutMultiplier);
+
+ MqttEvent provisionResponseMsg = listener.getEvents().poll(timeoutMultiplier, TimeUnit.SECONDS);
+
+ assertThat(provisionResponseMsg).isNotNull();
+
+ JsonNode provisionResponse = mapper.readTree(provisionResponseMsg.getMessage());
+
+ assertThat(provisionResponse.get("credentialsType").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsType().name());
+ assertThat(provisionResponse.get("credentialsValue").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsId());
+ assertThat(provisionResponse.get("status").asText()).isEqualTo("SUCCESS");
+
+ updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.DISABLED);
+ }
+
+ @Test
+ public void provisionRequestForDeviceWithAllowToCreateNewDevicesStrategy() throws Exception {
+
+ String testDeviceName = "test_provision_device";
+
+ DeviceProfile deviceProfile = testRestClient.getDeviceProfileById(device.getDeviceProfileId());
+
+ deviceProfile = updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES);
+
+ MqttMessageListener listener = new MqttMessageListener();
+ MqttClient mqttClient = getMqttClient("provision", listener);
+
+ JsonObject provisionRequest = new JsonObject();
+ provisionRequest.addProperty("provisionDeviceKey", TEST_PROVISION_DEVICE_KEY);
+ provisionRequest.addProperty("provisionDeviceSecret", TEST_PROVISION_DEVICE_SECRET);
+ provisionRequest.addProperty("deviceName", testDeviceName);
+
+ mqttClient.publish("/provision/request", Unpooled.wrappedBuffer(provisionRequest.toString().getBytes())).get();
+
+ //Wait for response
+ TimeUnit.SECONDS.sleep(3 * timeoutMultiplier);
+
+ MqttEvent provisionResponseMsg = listener.getEvents().poll(timeoutMultiplier, TimeUnit.SECONDS);
+
+ assertThat(provisionResponseMsg).isNotNull();
+
+ JsonNode provisionResponse = mapper.readTree(provisionResponseMsg.getMessage());
+
+ testRestClient.deleteDeviceIfExists(device.getId());
+ device = testRestClient.getDeviceByName(testDeviceName);
+
+ DeviceCredentials expectedDeviceCredentials = testRestClient.getDeviceCredentialsByDeviceId(device.getId());
+
+ assertThat(provisionResponse.get("credentialsType").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsType().name());
+ assertThat(provisionResponse.get("credentialsValue").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsId());
+ assertThat(provisionResponse.get("status").asText()).isEqualTo("SUCCESS");
+
+ updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.DISABLED);
+ }
+
+ @Test
+ public void provisionRequestForDeviceWithDisabledProvisioningStrategy() throws Exception {
+
+ MqttMessageListener listener = new MqttMessageListener();
+ MqttClient mqttClient = getMqttClient("provision", listener);
+
+ JsonObject provisionRequest = new JsonObject();
+ provisionRequest.addProperty("provisionDeviceKey", TEST_PROVISION_DEVICE_KEY);
+ provisionRequest.addProperty("provisionDeviceSecret", TEST_PROVISION_DEVICE_SECRET);
+
+ mqttClient.publish("/provision/request", Unpooled.wrappedBuffer(provisionRequest.toString().getBytes())).get();
+
+ //Wait for response
+ TimeUnit.SECONDS.sleep(3 * timeoutMultiplier);
+
+ MqttEvent provisionResponseMsg = listener.getEvents().poll(timeoutMultiplier, TimeUnit.SECONDS);
+
+ assertThat(provisionResponseMsg).isNotNull();
+
+ JsonNode provisionResponse = mapper.readTree(provisionResponseMsg.getMessage());
+
+ assertThat(provisionResponse.get("status").asText()).isEqualTo("NOT_FOUND");
+ }
+
private RuleChainId createRootRuleChainForRpcResponse() throws Exception {
RuleChain newRuleChain = new RuleChain();
newRuleChain.setName("testRuleChain");
@@ -356,9 +456,13 @@ public class MqttClientTest extends AbstractContainerTest {
}
private MqttClient getMqttClient(DeviceCredentials deviceCredentials, MqttMessageListener listener) throws InterruptedException, ExecutionException {
+ return getMqttClient(deviceCredentials.getCredentialsId(), listener);
+ }
+
+ private MqttClient getMqttClient(String username, MqttMessageListener listener) throws InterruptedException, ExecutionException {
MqttClientConfig clientConfig = new MqttClientConfig();
clientConfig.setClientId("MQTT client from test");
- clientConfig.setUsername(deviceCredentials.getCredentialsId());
+ clientConfig.setUsername(username);
MqttClient mqttClient = MqttClient.create(clientConfig, listener);
mqttClient.connect("localhost", 1883).get();
return mqttClient;