diff --git a/msa/black-box-tests/pom.xml b/msa/black-box-tests/pom.xml
index 054b4ee5a8..9cd38c0c05 100644
--- a/msa/black-box-tests/pom.xml
+++ b/msa/black-box-tests/pom.xml
@@ -70,25 +70,21 @@
org.testng
testng
- 7.6.1
test
org.assertj
assertj-core
- 3.23.1
test
io.rest-assured
rest-assured
- 5.2.0
test
org.hamcrest
hamcrest-all
- 1.3
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 df622a7752..df1fe4a522 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
@@ -55,7 +55,6 @@ public abstract class AbstractContainerTest {
@BeforeSuite
public void beforeSuite() {
- RestAssured.filters(new RequestLoggingFilter(), new ResponseLoggingFilter());
if ("false".equals(System.getProperty("runLocal", "false"))) {
containerTestSuite.start();
}
diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java
index f50caa1aee..6e3a024cda 100644
--- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java
+++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java
@@ -38,7 +38,7 @@ public class TestProperties {
if (instance.isActive()) {
return WSS_URL;
}
- return getProperty("tb.baseUrl");
+ return getProperty("tb.wsUrl");
}
private static String getProperty(String propertyName) {
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 eaf5332323..0b0c4b89bc 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
@@ -16,13 +16,21 @@
package org.thingsboard.server.msa;
import com.fasterxml.jackson.databind.JsonNode;
+import io.restassured.RestAssured;
+import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.common.mapper.TypeRef;
+import io.restassured.config.HeaderConfig;
+import io.restassured.config.HttpClientConfig;
+import io.restassured.config.RestAssuredConfig;
+import io.restassured.filter.log.RequestLoggingFilter;
+import io.restassured.filter.log.ResponseLoggingFilter;
import io.restassured.http.ContentType;
import io.restassured.path.json.JsonPath;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
+import io.restassured.specification.ResponseSpecification;
+import org.hamcrest.Matchers;
import org.springframework.http.HttpStatus;
-import org.thingsboard.rest.client.RestClient;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
@@ -40,24 +48,33 @@ import java.util.List;
import java.util.Map;
import static io.restassured.RestAssured.given;
+import static org.apache.http.params.CoreConnectionPNames.CONNECTION_TIMEOUT;
+import static org.apache.http.params.CoreConnectionPNames.SO_TIMEOUT;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.thingsboard.server.common.data.StringUtils.isEmpty;
-import static org.thingsboard.server.msa.AbstractContainerTest.getRequestFactoryForSelfSignedCert;
public class TestRestClient {
private static final String JWT_TOKEN_HEADER_PARAM = "X-Authorization";
private final String baseURL;
private String token;
private String refreshToken;
- private RequestSpecification spec;
+ private RequestSpecification requestSpec;
+ private ResponseSpecification responseSpec;
protected static final String ACTIVATE_TOKEN_REGEX = "/api/noauth/activate?activateToken=";
public TestRestClient(String url) {
+ RestAssured.filters(new RequestLoggingFilter(), new ResponseLoggingFilter());
+
baseURL = url;
- spec = given().baseUri(baseURL).contentType(ContentType.JSON);
+ requestSpec = given().baseUri(baseURL)
+ .contentType(ContentType.JSON)
+ .config(RestAssuredConfig.config()
+ .headerConfig(HeaderConfig.headerConfig()
+ .overwriteHeadersWithName(JWT_TOKEN_HEADER_PARAM)));
+
if (url.matches("^(https)://.*$")) {
- spec.relaxedHTTPSValidation();
+ requestSpec.relaxedHTTPSValidation();
}
}
@@ -70,12 +87,11 @@ public class TestRestClient {
.getBody().jsonPath();
token = jsonPath.get("token");
refreshToken = jsonPath.get("refreshToken");
- spec.header(JWT_TOKEN_HEADER_PARAM, "Bearer " + token)
- .contentType(ContentType.JSON);
+ requestSpec.header(JWT_TOKEN_HEADER_PARAM, "Bearer " + token);
}
public Device postDevice(String accessToken, Device device) {
- return given().spec(spec).body(device)
+ return given().spec(requestSpec).body(device)
.pathParams("accessToken", accessToken)
.post("/api/device?accessToken={accessToken}")
.then()
@@ -85,7 +101,7 @@ public class TestRestClient {
}
public ValidatableResponse getDeviceById(DeviceId deviceId, int statusCode) {
- return given().spec(spec)
+ return given().spec(requestSpec)
.pathParams("deviceId", deviceId.getId())
.get("/api/device/{deviceId}")
.then()
@@ -97,7 +113,7 @@ public class TestRestClient {
.as(Device.class);
}
public DeviceCredentials getDeviceCredentialsByDeviceId(DeviceId deviceId) {
- return given().spec(spec).get("/api/device/{deviceId}/credentials", deviceId.getId())
+ return given().spec(requestSpec).get("/api/device/{deviceId}/credentials", deviceId.getId())
.then()
.assertThat()
.statusCode(HttpStatus.OK.value())
@@ -106,41 +122,41 @@ public class TestRestClient {
}
public ValidatableResponse postTelemetry(String credentialsId, JsonNode telemetry) {
- return given().spec(spec).body(telemetry)
+ return given().spec(requestSpec).body(telemetry)
.post("/api/v1/{credentialsId}/telemetry", credentialsId)
.then()
.statusCode(HttpStatus.OK.value());
}
public ValidatableResponse deleteDevice(DeviceId deviceId) {
- return given().spec(spec)
+ return given().spec(requestSpec)
.delete("/api/device/{deviceId}", deviceId.getId())
.then()
.statusCode(HttpStatus.OK.value());
}
public ValidatableResponse deleteDeviceIfExists(DeviceId deviceId) {
- return given().spec(spec)
+ return given().spec(requestSpec)
.delete("/api/device/{deviceId}", deviceId.getId())
.then()
.statusCode(anyOf(is(HttpStatus.OK.value()),is(HttpStatus.NOT_FOUND.value())));
}
public ValidatableResponse postTelemetryAttribute(String entityType, DeviceId deviceId, String scope, JsonNode attribute) {
- return given().spec(spec).body(attribute)
+ return given().spec(requestSpec).body(attribute)
.post("/api/plugins/telemetry/{entityType}/{entityId}/attributes/{scope}", entityType, deviceId.getId(), scope)
.then()
.statusCode(HttpStatus.OK.value());
}
public ValidatableResponse postAttribute(String accessToken, JsonNode attribute) {
- return given().spec(spec).body(attribute)
+ return given().spec(requestSpec).body(attribute)
.post("/api/v1/{accessToken}/attributes/", accessToken)
.then()
.statusCode(HttpStatus.OK.value());
}
public JsonNode getAttributes(String accessToken, String clientKeys, String sharedKeys) {
- return given().spec(spec)
+ return given().spec(requestSpec)
.queryParam("clientKeys", clientKeys)
.queryParam("sharedKeys", sharedKeys)
.get("/api/v1/{accessToken}/attributes", accessToken)
@@ -153,7 +169,7 @@ public class TestRestClient {
public PageData getRuleChains(PageLink pageLink) {
Map params = new HashMap<>();
addPageLinkToParam(params, pageLink);
- return given().spec(spec).queryParams(params)
+ return given().spec(requestSpec).queryParams(params)
.get("/api/ruleChains")
.then()
.statusCode(HttpStatus.OK.value())
@@ -162,7 +178,7 @@ public class TestRestClient {
}
public RuleChain postRootRuleChain(RuleChain ruleChain) {
- return given().spec(spec)
+ return given().spec(requestSpec)
.body(ruleChain)
.post("/api/ruleChain")
.then()
@@ -172,7 +188,7 @@ public class TestRestClient {
}
public RuleChainMetaData postRuleChainMetadata(RuleChainMetaData ruleChainMetaData) {
- return given().spec(spec)
+ return given().spec(requestSpec)
.body(ruleChainMetaData)
.post("/api/ruleChain/metadata")
.then()
@@ -182,14 +198,14 @@ public class TestRestClient {
}
public void setRootRuleChain(RuleChainId ruleChainId) {
- given().spec(spec)
+ given().spec(requestSpec)
.post("/api/ruleChain/{ruleChainId}/root", ruleChainId.getId())
.then()
.statusCode(HttpStatus.OK.value());
}
public void deleteRuleChain(RuleChainId ruleChainId) {
- given().spec(spec)
+ given().spec(requestSpec)
.delete("/api/ruleChain/{ruleChainId}", ruleChainId.getId())
.then()
.statusCode(HttpStatus.OK.value());
@@ -224,7 +240,7 @@ public class TestRestClient {
params.put("fromType", fromId.getEntityType().name());
params.put("relationTypeGroup", relationTypeGroup.name());
- return given().spec(spec)
+ return given().spec(requestSpec)
.pathParams(params)
.get("/api/relations?fromId={fromId}&fromType={fromType}&relationTypeGroup={relationTypeGroup}")
.then()
@@ -234,7 +250,7 @@ public class TestRestClient {
}
public JsonNode postServerSideRpc(DeviceId deviceId, JsonNode serverRpcPayload) {
- return given().spec(spec)
+ return given().spec(requestSpec)
.body(serverRpcPayload)
.post("/api/rpc/twoway/{deviceId}", deviceId.getId())
.then()
diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java
index f844be8a27..54aec26421 100644
--- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java
+++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java
@@ -16,6 +16,9 @@
package org.thingsboard.server.msa.connectivity;
import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@@ -24,11 +27,15 @@ import io.netty.buffer.Unpooled;
import io.netty.handler.codec.mqtt.MqttQoS;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
+import org.junit.Assert;
import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.common.util.JacksonUtil;
+import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.mqtt.MqttClient;
import org.thingsboard.mqtt.MqttClientConfig;
import org.thingsboard.mqtt.MqttHandler;
@@ -44,12 +51,10 @@ import org.thingsboard.server.msa.AbstractContainerTest;
import org.thingsboard.server.msa.WsClient;
import org.thingsboard.server.msa.mapper.WsTelemetryResponse;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.thingsboard.server.common.data.DataConstants.DEVICE;
@@ -187,7 +192,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest {
event = listener.getEvents().poll(10 * timeoutMultiplier, TimeUnit.SECONDS);
responseData = jsonParser.parse(Objects.requireNonNull(event).getMessage()).getAsJsonObject();
- assertThat(responseData.has("value")).isTrue();
+ assertThat(responseData.has("values")).isTrue();
assertThat(responseData.get("values").getAsJsonObject().get("attr1").getAsString()).isEqualTo(sharedAttributes.get("attr1").getAsString());
assertThat(responseData.get("values").getAsJsonObject().get("attr2").getAsString()).isEqualTo(sharedAttributes.get("attr2").getAsString());
@@ -304,11 +309,19 @@ public class MqttGatewayClientTest extends AbstractContainerTest {
JsonObject serverRpcPayload = new JsonObject();
serverRpcPayload.addProperty("method", "getValue");
serverRpcPayload.addProperty("params", true);
-
- JsonNode response = testRestClient.postServerSideRpc(createdDevice.getId(), mapper.readTree(serverRpcPayload.toString()));
+ ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName(getClass().getSimpleName())));
+ ListenableFuture future = service.submit(() -> {
+ try {
+ return testRestClient.postServerSideRpc(createdDevice.getId(), mapper.readTree(serverRpcPayload.toString()));
+ } catch (IOException e) {
+ return null;
+ }
+ });
// Wait for RPC call from the server and send the response
MqttEvent requestFromServer = listener.getEvents().poll(10 * timeoutMultiplier, TimeUnit.SECONDS);
+ service.shutdownNow();
+
assertThat(requestFromServer).isNotNull();
assertThat(requestFromServer.getMessage()).isNotNull();
JsonNode requestFromServerJson = JacksonUtil.toJsonNode(requestFromServer.getMessage());
@@ -326,8 +339,9 @@ public class MqttGatewayClientTest extends AbstractContainerTest {
// Send a response to the server's RPC request
mqttClient.publish(gatewayRpcTopic, Unpooled.wrappedBuffer(gatewayResponse.toString().getBytes())).get();
+ JsonNode serverResponse = future.get(5 * timeoutMultiplier, TimeUnit.SECONDS);
- assertThat(response).isEqualTo(clientResponse.getAsJsonObject());
+ assertThat(serverResponse).isEqualTo(mapper.readTree(clientResponse.toString()));
}
@Test
@@ -366,7 +380,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest {
TimeUnit.SECONDS.sleep(30);
}
- String deviceName = "mqtt_device";
+ String deviceName = "mqtt_device" + RandomStringUtils.randomAlphabetic(5);
mqttClient.publish("v1/gateway/connect", Unpooled.wrappedBuffer(createGatewayConnectPayload(deviceName).toString().getBytes()), MqttQoS.AT_LEAST_ONCE).get();
if (timeoutMultiplier > 1) {
diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/prototypes/DevicePrototypes.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/prototypes/DevicePrototypes.java
index d7edcb6699..e8ed09df18 100644
--- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/prototypes/DevicePrototypes.java
+++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/prototypes/DevicePrototypes.java
@@ -17,6 +17,7 @@ package org.thingsboard.server.msa.prototypes;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Device;
@@ -33,7 +34,7 @@ public class DevicePrototypes {
String isGateway = "{\"gateway\":true}";
JsonNode additionalInfo = JacksonUtil.valueToTree(isGateway);
Device gatewayDeviceTemplate = new Device();
- gatewayDeviceTemplate.setName("mqtt_gateway " + RandomStringUtils.randomAlphabetic(5));
+ gatewayDeviceTemplate.setName("mqtt_gateway_" + RandomStringUtils.randomAlphabetic(5));
gatewayDeviceTemplate.setType("gateway");
gatewayDeviceTemplate.setAdditionalInfo(additionalInfo);
return gatewayDeviceTemplate;
diff --git a/pom.xml b/pom.xml
index 1c5dea9f5c..7d5540ef20 100755
--- a/pom.xml
+++ b/pom.xml
@@ -133,6 +133,10 @@
1.3.0
1.2.7
+ 7.6.1
+ 3.23.1
+ 5.2.0
+ 1.3
1.17.3
1.12
3.0.0
@@ -1618,6 +1622,30 @@
+
+ org.testng
+ testng
+ ${testng.version}
+ test
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+ io.rest-assured
+ rest-assured
+ ${rest-assured.version}
+ test
+
+
+ org.hamcrest
+ hamcrest-all
+ ${hamcrest}
+ test
+
org.awaitility
awaitility