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