|
|
@ -19,13 +19,16 @@ import com.fasterxml.jackson.databind.JsonNode; |
|
|
import com.fasterxml.jackson.databind.node.ArrayNode; |
|
|
import com.fasterxml.jackson.databind.node.ArrayNode; |
|
|
import com.fasterxml.jackson.databind.node.ObjectNode; |
|
|
import com.fasterxml.jackson.databind.node.ObjectNode; |
|
|
import com.google.common.util.concurrent.FutureCallback; |
|
|
import com.google.common.util.concurrent.FutureCallback; |
|
|
|
|
|
import com.google.common.util.concurrent.Futures; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import org.checkerframework.checker.nullness.qual.Nullable; |
|
|
import org.checkerframework.checker.nullness.qual.Nullable; |
|
|
import org.junit.After; |
|
|
import org.junit.After; |
|
|
import org.junit.Assert; |
|
|
import org.junit.Assert; |
|
|
import org.junit.Before; |
|
|
import org.junit.Before; |
|
|
import org.junit.Test; |
|
|
import org.junit.Test; |
|
|
|
|
|
import org.mockito.Mockito; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
|
|
import org.springframework.boot.test.mock.mockito.SpyBean; |
|
|
import org.springframework.test.context.TestPropertySource; |
|
|
import org.springframework.test.context.TestPropertySource; |
|
|
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; |
|
|
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; |
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
@ -60,7 +63,9 @@ import org.thingsboard.server.common.data.query.NumericFilterPredicate; |
|
|
import org.thingsboard.server.common.data.query.SingleEntityFilter; |
|
|
import org.thingsboard.server.common.data.query.SingleEntityFilter; |
|
|
import org.thingsboard.server.common.data.query.TsValue; |
|
|
import org.thingsboard.server.common.data.query.TsValue; |
|
|
import org.thingsboard.server.common.data.relation.EntityRelation; |
|
|
import org.thingsboard.server.common.data.relation.EntityRelation; |
|
|
|
|
|
import org.thingsboard.server.dao.nosql.ResultSetSizeLimitExceededException; |
|
|
import org.thingsboard.server.dao.service.DaoSqlTest; |
|
|
import org.thingsboard.server.dao.service.DaoSqlTest; |
|
|
|
|
|
import org.thingsboard.server.dao.timeseries.TimeseriesService; |
|
|
import org.thingsboard.server.service.subscription.SubscriptionErrorCode; |
|
|
import org.thingsboard.server.service.subscription.SubscriptionErrorCode; |
|
|
import org.thingsboard.server.service.subscription.TbAttributeSubscriptionScope; |
|
|
import org.thingsboard.server.service.subscription.TbAttributeSubscriptionScope; |
|
|
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; |
|
|
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; |
|
|
@ -95,6 +100,9 @@ public class WebsocketApiTest extends AbstractControllerTest { |
|
|
@Autowired |
|
|
@Autowired |
|
|
private TelemetrySubscriptionService tsService; |
|
|
private TelemetrySubscriptionService tsService; |
|
|
|
|
|
|
|
|
|
|
|
@SpyBean |
|
|
|
|
|
private TimeseriesService timeseriesService; |
|
|
|
|
|
|
|
|
Device device; |
|
|
Device device; |
|
|
DeviceTypeFilter dtf; |
|
|
DeviceTypeFilter dtf; |
|
|
|
|
|
|
|
|
@ -965,6 +973,44 @@ public class WebsocketApiTest extends AbstractControllerTest { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void testHistoryCmdSendsWsErrorOnResultSetSizeLimitExceeded() throws Exception { |
|
|
|
|
|
ResultSetSizeLimitExceededException exception = new ResultSetSizeLimitExceededException(100L, 200L); |
|
|
|
|
|
Mockito.doReturn(Futures.immediateFailedFuture(exception)) |
|
|
|
|
|
.when(timeseriesService).findAllByQueries(Mockito.any(), Mockito.any(), Mockito.any()); |
|
|
|
|
|
|
|
|
|
|
|
List<String> keys = List.of("temperature"); |
|
|
|
|
|
long now = System.currentTimeMillis(); |
|
|
|
|
|
|
|
|
|
|
|
// Register for 2 messages: initial entity page data + error
|
|
|
|
|
|
getWsClient().registerWaitForUpdate(2); |
|
|
|
|
|
getWsClient().sendHistoryCmd(keys, now, TimeUnit.HOURS.toMillis(1), dtf); |
|
|
|
|
|
getWsClient().waitForUpdate(); |
|
|
|
|
|
|
|
|
|
|
|
EntityDataUpdate errorUpdate = JacksonUtil.fromString(getWsClient().getLastMsg(), EntityDataUpdate.class); |
|
|
|
|
|
assertThat(errorUpdate.getErrorCode()).isEqualTo(SubscriptionErrorCode.INTERNAL_ERROR.getCode()); |
|
|
|
|
|
assertThat(errorUpdate.getErrorMsg()).isEqualTo(exception.getMessage()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void testTimeSeriesCmdSendsWsErrorOnResultSetSizeLimitExceeded() throws Exception { |
|
|
|
|
|
ResultSetSizeLimitExceededException exception = new ResultSetSizeLimitExceededException(100L, 200L); |
|
|
|
|
|
Mockito.doReturn(Futures.immediateFailedFuture(exception)) |
|
|
|
|
|
.when(timeseriesService).findAllByQueries(Mockito.any(), Mockito.any(), Mockito.any()); |
|
|
|
|
|
|
|
|
|
|
|
List<String> keys = List.of("temperature"); |
|
|
|
|
|
long now = System.currentTimeMillis(); |
|
|
|
|
|
|
|
|
|
|
|
// Register for 2 messages: initial entity page data + error
|
|
|
|
|
|
getWsClient().registerWaitForUpdate(2); |
|
|
|
|
|
getWsClient().subscribeTsUpdate(keys, now, TimeUnit.HOURS.toMillis(1), dtf); |
|
|
|
|
|
getWsClient().waitForUpdate(); |
|
|
|
|
|
|
|
|
|
|
|
EntityDataUpdate errorUpdate = JacksonUtil.fromString(getWsClient().getLastMsg(), EntityDataUpdate.class); |
|
|
|
|
|
assertThat(errorUpdate.getErrorCode()).isEqualTo(SubscriptionErrorCode.INTERNAL_ERROR.getCode()); |
|
|
|
|
|
assertThat(errorUpdate.getErrorMsg()).isEqualTo(exception.getMessage()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private void sendTelemetry(Device device, List<TsKvEntry> tsData) throws InterruptedException { |
|
|
private void sendTelemetry(Device device, List<TsKvEntry> tsData) throws InterruptedException { |
|
|
CountDownLatch latch = new CountDownLatch(1); |
|
|
CountDownLatch latch = new CountDownLatch(1); |
|
|
tsService.saveTimeseries(TimeseriesSaveRequest.builder() |
|
|
tsService.saveTimeseries(TimeseriesSaveRequest.builder() |
|
|
|