|
|
@ -16,15 +16,19 @@ |
|
|
package org.thingsboard.server.controller; |
|
|
package org.thingsboard.server.controller; |
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.core.type.TypeReference; |
|
|
import com.fasterxml.jackson.core.type.TypeReference; |
|
|
|
|
|
import org.apache.commons.lang3.RandomStringUtils; |
|
|
import org.junit.Assert; |
|
|
import org.junit.Assert; |
|
|
import org.junit.Test; |
|
|
import org.junit.Test; |
|
|
import org.mockito.ArgumentCaptor; |
|
|
import org.mockito.ArgumentCaptor; |
|
|
import org.mockito.Mockito; |
|
|
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.boot.test.mock.mockito.SpyBean; |
|
|
|
|
|
import org.springframework.test.context.TestPropertySource; |
|
|
|
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
import org.thingsboard.server.common.data.asset.Asset; |
|
|
import org.thingsboard.server.common.data.asset.Asset; |
|
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
|
|
|
import org.thingsboard.server.common.data.kv.TsKvEntry; |
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
import org.thingsboard.server.common.data.page.PageLink; |
|
|
import org.thingsboard.server.common.data.page.PageLink; |
|
|
import org.thingsboard.server.common.data.queue.ProcessingStrategy; |
|
|
import org.thingsboard.server.common.data.queue.ProcessingStrategy; |
|
|
@ -48,10 +52,13 @@ import java.util.Map; |
|
|
import java.util.UUID; |
|
|
import java.util.UUID; |
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
import java.util.concurrent.TimeUnit; |
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
|
import java.util.concurrent.atomic.AtomicReference; |
|
|
import java.util.stream.Collectors; |
|
|
import java.util.stream.Collectors; |
|
|
import java.util.stream.Stream; |
|
|
import java.util.stream.Stream; |
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
|
|
import static org.mockito.ArgumentMatchers.any; |
|
|
|
|
|
import static org.mockito.ArgumentMatchers.anyLong; |
|
|
import static org.mockito.ArgumentMatchers.argThat; |
|
|
import static org.mockito.ArgumentMatchers.argThat; |
|
|
import static org.mockito.ArgumentMatchers.eq; |
|
|
import static org.mockito.ArgumentMatchers.eq; |
|
|
import static org.mockito.Mockito.verify; |
|
|
import static org.mockito.Mockito.verify; |
|
|
@ -60,6 +67,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. |
|
|
import static org.thingsboard.server.dao.asset.BaseAssetService.TB_SERVICE_QUEUE; |
|
|
import static org.thingsboard.server.dao.asset.BaseAssetService.TB_SERVICE_QUEUE; |
|
|
|
|
|
|
|
|
@DaoSqlTest |
|
|
@DaoSqlTest |
|
|
|
|
|
@TestPropertySource(properties = { |
|
|
|
|
|
"queue.rule-engine.stats.max-error-message-length=100" |
|
|
|
|
|
}) |
|
|
public class BaseQueueControllerTest extends AbstractControllerTest { |
|
|
public class BaseQueueControllerTest extends AbstractControllerTest { |
|
|
|
|
|
|
|
|
@Autowired |
|
|
@Autowired |
|
|
@ -183,9 +193,44 @@ public class BaseQueueControllerTest extends AbstractControllerTest { |
|
|
|
|
|
|
|
|
verify(timeseriesDao).save(eq(tenantId), eq(serviceAsset.getId()), argThat(tsKvEntry -> { |
|
|
verify(timeseriesDao).save(eq(tenantId), eq(serviceAsset.getId()), argThat(tsKvEntry -> { |
|
|
return tsKvEntry.getKey().equals(DefaultRuleEngineStatisticsService.RULE_ENGINE_EXCEPTION) && |
|
|
return tsKvEntry.getKey().equals(DefaultRuleEngineStatisticsService.RULE_ENGINE_EXCEPTION) && |
|
|
tsKvEntry.getJsonValue().get().equals(ruleEngineException.toJsonString()); |
|
|
tsKvEntry.getJsonValue().get().equals(ruleEngineException.toJsonString(0)); |
|
|
}), ttlCaptor.capture()); |
|
|
}), ttlCaptor.capture()); |
|
|
assertThat(ttlCaptor.getValue()).isEqualTo(TimeUnit.DAYS.toSeconds(ruleEngineExceptionsTtlDays)); |
|
|
assertThat(ttlCaptor.getValue()).isEqualTo(TimeUnit.DAYS.toSeconds(ruleEngineExceptionsTtlDays)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void testRuleEngineExceptionTruncation() { |
|
|
|
|
|
Queue queue = new Queue(); |
|
|
|
|
|
queue.setName("Test-2"); |
|
|
|
|
|
queue.setTenantId(TenantId.SYS_TENANT_ID); |
|
|
|
|
|
|
|
|
|
|
|
TbRuleEngineProcessingResult testProcessingResult = Mockito.mock(TbRuleEngineProcessingResult.class); |
|
|
|
|
|
when(testProcessingResult.getSuccessMap()).thenReturn(new ConcurrentHashMap<>()); |
|
|
|
|
|
when(testProcessingResult.getFailedMap()).thenReturn(new ConcurrentHashMap<>()); |
|
|
|
|
|
when(testProcessingResult.getPendingMap()).thenReturn(new ConcurrentHashMap<>()); |
|
|
|
|
|
|
|
|
|
|
|
String largeExceptionMessage = RandomStringUtils.randomAlphabetic(150); |
|
|
|
|
|
RuleEngineException ruleEngineException = new RuleEngineException(largeExceptionMessage); |
|
|
|
|
|
when(testProcessingResult.getExceptionsMap()).thenReturn(new ConcurrentHashMap<>(Map.of( |
|
|
|
|
|
tenantId, ruleEngineException |
|
|
|
|
|
))); |
|
|
|
|
|
|
|
|
|
|
|
TbRuleEngineConsumerStats testStats = new TbRuleEngineConsumerStats(queue, statsFactory); |
|
|
|
|
|
testStats.log(testProcessingResult, true); |
|
|
|
|
|
ruleEngineStatisticsService.reportQueueStats(System.currentTimeMillis(), testStats); |
|
|
|
|
|
|
|
|
|
|
|
AtomicReference<TsKvEntry> reExceptionTsKvEntryCaptor = new AtomicReference<>(); |
|
|
|
|
|
verify(timeseriesDao).save(eq(tenantId), any(), argThat(tsKvEntry -> { |
|
|
|
|
|
if (tsKvEntry.getKey().equals(DefaultRuleEngineStatisticsService.RULE_ENGINE_EXCEPTION)) { |
|
|
|
|
|
reExceptionTsKvEntryCaptor.set(tsKvEntry); |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
return false; |
|
|
|
|
|
}), anyLong()); |
|
|
|
|
|
TsKvEntry reExceptionTsKvEntry = reExceptionTsKvEntryCaptor.get(); |
|
|
|
|
|
|
|
|
|
|
|
String finalErrorMessage = JacksonUtil.toJsonNode(reExceptionTsKvEntry.getJsonValue().get()).get("message").asText(); |
|
|
|
|
|
assertThat(finalErrorMessage).isEqualTo(largeExceptionMessage.substring(0, 100) + "...[truncated 50 symbols]"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|