Browse Source

Merge branch 'master' of github.com:thingsboard/thingsboard into edqs

pull/12818/head
ViacheslavKlimov 2 years ago
parent
commit
05567f4937
  1. 2
      application/src/main/data/upgrade/basic/schema_update.sql
  2. 7
      application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
  3. 3
      application/src/main/java/org/thingsboard/server/service/apiusage/BaseApiUsageState.java
  4. 3
      application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
  5. 3
      application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java
  6. 5
      application/src/main/resources/thingsboard.yml
  7. 134
      application/src/test/java/org/thingsboard/server/actors/rule/DefaultTbContextTest.java
  8. 28
      application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java
  9. 74
      application/src/test/java/org/thingsboard/server/controller/DeviceProfileControllerTest.java
  10. 33
      application/src/test/java/org/thingsboard/server/edge/AlarmEdgeTest.java
  11. 144
      application/src/test/java/org/thingsboard/server/service/apiusage/ApiUsageTest.java
  12. 123
      application/src/test/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateServiceTest.java
  13. 2
      application/src/test/java/org/thingsboard/server/transport/coap/AbstractCoapIntegrationTest.java
  14. 2
      application/src/test/java/org/thingsboard/server/transport/coap/security/AbstractCoapSecurityIntegrationTest.java
  15. 2
      application/src/test/resources/application-test.properties
  16. 2
      common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapServerComponent.java
  17. 2
      common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapTransportComponent.java
  18. 1
      common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java
  19. 9
      common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageState.java
  20. 5
      common/proto/src/main/java/org/thingsboard/server/common/util/ProtoUtils.java
  21. 1
      common/proto/src/main/proto/queue.proto
  22. 10
      dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java
  23. 20
      dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
  24. 1
      dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java
  25. 1
      dao/src/main/resources/sql/schema-entities.sql
  26. 47
      dao/src/test/java/org/thingsboard/server/dao/service/ApiUsageStateServiceTest.java
  27. 16
      rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java
  28. 9
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java

2
application/src/main/data/upgrade/basic/schema_update.sql

@ -61,3 +61,5 @@ DO $$
$$;
-- UPDATE SAVE TIME SERIES NODES END
ALTER TABLE api_usage_state ADD COLUMN IF NOT EXISTS version BIGINT DEFAULT 1;

7
application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java

@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import io.netty.channel.EventLoopGroup;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.util.Arrays;
import org.thingsboard.common.util.DebugModeUtil;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ListeningExecutor;
import org.thingsboard.rule.engine.api.MailService;
@ -64,7 +65,6 @@ import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.common.util.DebugModeUtil;
import org.thingsboard.server.common.data.rule.RuleNodeState;
import org.thingsboard.server.common.data.script.ScriptLanguage;
import org.thingsboard.server.common.msg.TbActorMsg;
@ -178,7 +178,7 @@ public class DefaultTbContext implements TbContext {
.resetRuleNodeId()
.build();
tbMsg.pushToStack(nodeCtx.getSelf().getRuleChainId(), nodeCtx.getSelf().getId());
TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getQueueName(), getTenantId(), tbMsg.getOriginator());
TopicPartitionInfo tpi = resolvePartition(msg);
doEnqueue(tpi, tbMsg, new SimpleTbQueueCallback(md -> ack(msg), t -> tellFailure(msg, t)));
}
@ -195,8 +195,7 @@ public class DefaultTbContext implements TbContext {
@Override
public void enqueue(TbMsg tbMsg, Runnable onSuccess, Consumer<Throwable> onFailure) {
TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getQueueName(), getTenantId(), tbMsg.getOriginator());
enqueue(tpi, tbMsg, onFailure, onSuccess);
enqueue(tbMsg, tbMsg.getQueueName(), onSuccess, onFailure);
}
@Override

3
application/src/main/java/org/thingsboard/server/service/apiusage/BaseApiUsageState.java

@ -40,7 +40,8 @@ public abstract class BaseApiUsageState {
private final Map<ApiUsageRecordKey, Long> gaugesReportCycles = new HashMap<>();
@Getter
private final ApiUsageState apiUsageState;
@Setter
private ApiUsageState apiUsageState;
@Getter
private volatile long currentCycleTs;
@Getter

3
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java

@ -355,7 +355,8 @@ public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService
private void persistAndNotify(BaseApiUsageState state, Map<ApiFeature, ApiUsageStateValue> result) {
log.info("[{}] Detected update of the API state for {}: {}", state.getEntityId(), state.getEntityType(), result);
apiUsageStateService.update(state.getApiUsageState());
ApiUsageState updatedState = apiUsageStateService.update(state.getApiUsageState());
state.setApiUsageState(updatedState);
long ts = System.currentTimeMillis();
List<TsKvEntry> stateTelemetry = new ArrayList<>();
result.forEach((apiFeature, aState) -> stateTelemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(apiFeature.getApiStateKey(), aState.name()))));

3
application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java

@ -140,6 +140,9 @@ public class EdgeEventSourcingListener {
if (EntityType.DEVICE.equals(event.getEntityId().getEntityType()) && ActionType.ASSIGNED_TO_TENANT.equals(event.getActionType())) {
return;
}
if (EntityType.ALARM.equals(event.getEntityId().getEntityType())) {
return;
}
try {
if (event.getEntityId().getEntityType().equals(EntityType.RULE_CHAIN) && event.getEdgeId() != null && event.getActionType().equals(ActionType.ASSIGNED_TO_EDGE)) {
try {

5
application/src/main/resources/thingsboard.yml

@ -1279,8 +1279,9 @@ transport:
# CoAP server parameters
coap:
# Enable/disable coap server.
enabled: "${COAP_SERVER_ENABLED:true}"
server:
# Enable/disable coap server.
enabled: "${COAP_SERVER_ENABLED:true}"
# CoAP bind address
bind_address: "${COAP_BIND_ADDRESS:0.0.0.0}"
# CoAP bind port

134
application/src/test/java/org/thingsboard/server/actors/rule/DefaultTbContextTest.java

@ -98,6 +98,132 @@ class DefaultTbContextTest {
defaultTbContext = new DefaultTbContext(mainCtxMock, "Test rule chain name", nodeCtxMock);
}
@MethodSource
@ParameterizedTest
public void givenMsgWithQueueName_whenInput_thenVerifyEnqueueWithCorrectTpi(String queueName) {
// GIVEN
var tpi = resolve(queueName);
given(mainCtxMock.resolve(eq(ServiceType.TB_RULE_ENGINE), eq(queueName), eq(TENANT_ID), eq(TENANT_ID))).willReturn(tpi);
var clusterService = mock(TbClusterService.class);
given(mainCtxMock.getClusterService()).willReturn(clusterService);
var callbackMock = mock(TbMsgCallback.class);
given(callbackMock.isMsgValid()).willReturn(true);
var ruleNode = new RuleNode(RULE_NODE_ID);
var msg = TbMsg.newMsg()
.type(TbMsgType.POST_TELEMETRY_REQUEST)
.originator(TENANT_ID)
.queueName(queueName)
.copyMetaData(TbMsgMetaData.EMPTY)
.data(TbMsg.EMPTY_STRING)
.callback(callbackMock)
.build();
var ruleChainId = new RuleChainId(UUID.randomUUID());
ruleNode.setRuleChainId(RULE_CHAIN_ID);
ruleNode.setDebugSettings(DebugSettings.failures());
given(nodeCtxMock.getTenantId()).willReturn(TENANT_ID);
given(nodeCtxMock.getSelf()).willReturn(ruleNode);
// WHEN
defaultTbContext.input(msg, ruleChainId);
// THEN
then(clusterService).should().pushMsgToRuleEngine(eq(tpi), eq(msg.getId()), any(), any());
}
@MethodSource
@ParameterizedTest
public void givenMsgWithQueueName_whenEnqueue_thenVerifyEnqueueWithCorrectTpi(String queueName) {
// GIVEN
var tpi = resolve(queueName);
given(mainCtxMock.resolve(eq(ServiceType.TB_RULE_ENGINE), eq(queueName), eq(TENANT_ID), eq(TENANT_ID))).willReturn(tpi);
var clusterService = mock(TbClusterService.class);
given(mainCtxMock.getClusterService()).willReturn(clusterService);
var callbackMock = mock(TbMsgCallback.class);
given(callbackMock.isMsgValid()).willReturn(true);
var ruleNode = new RuleNode(RULE_NODE_ID);
var msg = TbMsg.newMsg()
.type(TbMsgType.POST_TELEMETRY_REQUEST)
.originator(TENANT_ID)
.queueName(queueName)
.copyMetaData(TbMsgMetaData.EMPTY)
.data(TbMsg.EMPTY_STRING)
.callback(callbackMock)
.build();
ruleNode.setRuleChainId(RULE_CHAIN_ID);
ruleNode.setDebugSettings(DebugSettings.failures());
given(nodeCtxMock.getTenantId()).willReturn(TENANT_ID);
// WHEN
defaultTbContext.enqueue(msg, () -> {}, t -> {});
// THEN
then(clusterService).should().pushMsgToRuleEngine(eq(tpi), eq(msg.getId()), any(), any());
}
@MethodSource
@ParameterizedTest
public void givenMsgAndQueueName_whenEnqueue_thenVerifyEnqueueWithCorrectTpi(String queueName) {
// GIVEN
var tpi = resolve(queueName);
given(mainCtxMock.resolve(eq(ServiceType.TB_RULE_ENGINE), eq(queueName), eq(TENANT_ID), eq(TENANT_ID))).willReturn(tpi);
var clusterService = mock(TbClusterService.class);
given(mainCtxMock.getClusterService()).willReturn(clusterService);
var callbackMock = mock(TbMsgCallback.class);
given(callbackMock.isMsgValid()).willReturn(true);
var ruleNode = new RuleNode(RULE_NODE_ID);
var msg = TbMsg.newMsg()
.type(TbMsgType.POST_TELEMETRY_REQUEST)
.originator(TENANT_ID)
.copyMetaData(TbMsgMetaData.EMPTY)
.data(TbMsg.EMPTY_STRING)
.callback(callbackMock)
.build();
ruleNode.setRuleChainId(RULE_CHAIN_ID);
ruleNode.setDebugSettings(DebugSettings.failures());
given(nodeCtxMock.getTenantId()).willReturn(TENANT_ID);
// WHEN
defaultTbContext.enqueue(msg, queueName, () -> {}, t -> {});
// THEN
then(clusterService).should().pushMsgToRuleEngine(eq(tpi), eq(msg.getId()), any(), any());
}
private static Stream<String> givenMsgWithQueueName_whenInput_thenVerifyEnqueueWithCorrectTpi() {
return testQueueNames();
}
private static Stream<String> givenMsgWithQueueName_whenEnqueue_thenVerifyEnqueueWithCorrectTpi() {
return testQueueNames();
}
private static Stream<String> givenMsgAndQueueName_whenEnqueue_thenVerifyEnqueueWithCorrectTpi() {
return testQueueNames();
}
private static Stream<String> testQueueNames() {
return Stream.of("Main", "Test", null);
}
private TopicPartitionInfo resolve(String queueName) {
var tpiBuilder = TopicPartitionInfo.builder()
.topic(queueName == null ? "MainQueueTopic" : queueName + "QueueTopic")
.partition(1)
.myPartition(true);
return tpiBuilder.build();
}
@Test
public void givenDebugFailuresEvents_whenTellSuccess_thenVerifyDebugOutputNotPersisted() {
// GIVEN
@ -810,10 +936,10 @@ class DefaultTbContextTest {
@MethodSource
@ParameterizedTest
void givenDebugFailuresAndDebugAllAndConnectionAndPersistedResultOptions_whenTellNext_thenVerifyDebugOutputPersistence(boolean debugFailures,
long debugAllUntil,
String connection,
boolean shouldPersist,
boolean shouldPersistAfterDurationTime) {
long debugAllUntil,
String connection,
boolean shouldPersist,
boolean shouldPersistAfterDurationTime) {
// GIVEN
var callbackMock = mock(TbMsgCallback.class);
var msg = getTbMsgWithCallback(callbackMock);

28
application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java

@ -169,7 +169,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundAlarm, customerDevice, tenantId,
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ACK, 1, 1, 1);
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ACK, 1, 0, 1);
Mockito.reset(tbClusterService, auditLogService);
alarm = updatedAlarm;
@ -183,7 +183,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundAlarm, customerDevice, tenantId,
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_CLEAR, 1, 1, 1);
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_CLEAR, 1, 0, 1);
Mockito.reset(tbClusterService, auditLogService);
alarm = updatedAlarm;
@ -197,7 +197,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundAlarm, customerDevice, tenantId,
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ASSIGNED, 1, 1, 1);
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ASSIGNED, 1, 0, 1);
Mockito.reset(tbClusterService, auditLogService);
alarm = updatedAlarm;
@ -211,7 +211,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundAlarm, customerDevice, tenantId,
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_UNASSIGNED, 1, 1, 1);
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_UNASSIGNED, 1, 0, 1);
Mockito.reset(tbClusterService, auditLogService);
}
@ -321,7 +321,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertNotNull(foundAlarm);
Assert.assertEquals(AlarmStatus.CLEARED_UNACK, foundAlarm.getStatus());
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ALARM_CLEAR);
}
@ -337,7 +337,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertNotNull(foundAlarm);
Assert.assertEquals(AlarmStatus.CLEARED_UNACK, foundAlarm.getStatus());
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_CLEAR);
}
@ -354,7 +354,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertNotNull(foundAlarm);
Assert.assertEquals(AlarmStatus.ACTIVE_ACK, foundAlarm.getStatus());
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ALARM_ACK);
}
@ -434,7 +434,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertEquals(tenantAdminUserId, foundAlarm.getAssigneeId());
Assert.assertTrue(foundAlarm.getAssignTs() > beforeAssignmentTs && foundAlarm.getAssignTs() < System.currentTimeMillis());
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ASSIGNED);
}
@ -465,7 +465,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertEquals(tenantAdminUserId, foundAlarm.getAssigneeId());
Assert.assertTrue(foundAlarm.getAssignTs() > beforeAssignmentTs && foundAlarm.getAssignTs() < System.currentTimeMillis());
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ASSIGNED);
logout();
@ -482,7 +482,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertEquals(customerUserId, foundAlarm.getAssigneeId());
Assert.assertTrue(foundAlarm.getAssignTs() > beforeAssignmentTs && foundAlarm.getAssignTs() < System.currentTimeMillis());
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ALARM_ASSIGNED);
}
@ -500,7 +500,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertEquals(tenantAdminUserId, foundAlarm.getAssigneeId());
Assert.assertTrue(foundAlarm.getAssignTs() > beforeAssignmentTs && foundAlarm.getAssignTs() < System.currentTimeMillis());
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ASSIGNED);
beforeAssignmentTs = System.currentTimeMillis();
@ -511,7 +511,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertNull(foundAlarm.getAssigneeId());
Assert.assertTrue(foundAlarm.getAssignTs() > beforeAssignmentTs && foundAlarm.getAssignTs() < System.currentTimeMillis());
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_UNASSIGNED);
}
@ -529,7 +529,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertEquals(tenantAdminUserId, foundAlarm.getAssigneeId());
Assert.assertTrue(foundAlarm.getAssignTs() > beforeAssignmentTs && foundAlarm.getAssignTs() < System.currentTimeMillis());
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ASSIGNED);
logout();
@ -545,7 +545,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertNull(foundAlarm.getAssigneeId());
Assert.assertTrue(foundAlarm.getAssignTs() > beforeAssignmentTs && foundAlarm.getAssignTs() < System.currentTimeMillis());
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
testNotifyEntityOneTimeMsgToEdgeServiceNever(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ALARM_UNASSIGNED);
}

74
application/src/test/java/org/thingsboard/server/controller/DeviceProfileControllerTest.java

@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.test.context.ContextConfiguration;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.Device;
@ -60,6 +61,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.common.data.DataConstants.DEFAULT_DEVICE_TYPE;
@ -79,6 +81,8 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Autowired
private DeviceProfileDao deviceProfileDao;
static final String LWM2M_PROFILE_JSON = "{\"name\":\"lwm2m profile\",\"type\":\"DEFAULT\",\"image\":null,\"defaultQueueName\":null,\"transportType\":\"LWM2M\",\"provisionType\":\"DISABLED\",\"description\":\"\",\"profileData\":{\"configuration\":{\"type\":\"DEFAULT\"},\"transportConfiguration\":{\"observeAttr\":{\"observe\":[],\"attribute\":[],\"telemetry\":[\"/11_1.1/0/0\"],\"keyName\":{\"/11_1.1/0/0\":\"profileName\"},\"attributeLwm2m\":{}},\"bootstrap\":[{\"shortServerId\":123,\"bootstrapServerIs\":false,\"host\":\"0.0.0.0\",\"port\":5685,\"clientHoldOffTime\":1,\"serverPublicKey\":\"\",\"serverCertificate\":\"\",\"bootstrapServerAccountTimeout\":0,\"lifetime\":300,\"defaultMinPeriod\":1,\"notifIfDisabled\":true,\"binding\":\"U\",\"securityMode\":\"NO_SEC\"}],\"clientLwM2mSettings\":{\"clientOnlyObserveAfterConnect\":1,\"fwUpdateStrategy\":1,\"swUpdateStrategy\":1,\"powerMode\":\"DRX\",\"edrxCycle\":81000,\"psmActivityTimer\":10000,\"pagingTransmissionWindow\":10000,\"defaultObjectIDVer\":\"1.0\"},\"bootstrapServerUpdateEnable\":false,\"type\":\"LWM2M\"},\"alarms\":null,\"provisionConfiguration\":{\"type\":\"DISABLED\"}}}";
static class Config {
@Bean
@Primary
@ -119,7 +123,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
Mockito.reset(tbClusterService, auditLogService);
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
Assert.assertNotNull(savedDeviceProfile);
Assert.assertNotNull(savedDeviceProfile.getId());
Assert.assertTrue(savedDeviceProfile.getCreatedTime() > 0);
@ -135,7 +139,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
ActionType.ADDED);
savedDeviceProfile.setName("New device profile");
doPost("/api/deviceProfile", savedDeviceProfile, DeviceProfile.class);
saveDeviceProfile(savedDeviceProfile);
DeviceProfile foundDeviceProfile = doGet("/api/deviceProfile/" + savedDeviceProfile.getId().getId().toString(), DeviceProfile.class);
Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfile.getName());
@ -162,7 +166,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Test
public void testFindDeviceProfileById() throws Exception {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile");
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
DeviceProfile foundDeviceProfile = doGet("/api/deviceProfile/" + savedDeviceProfile.getId().getId().toString(), DeviceProfile.class);
Assert.assertNotNull(foundDeviceProfile);
Assert.assertEquals(savedDeviceProfile, foundDeviceProfile);
@ -171,7 +175,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Test
public void whenGetDeviceProfileById_thenPermissionsAreChecked() throws Exception {
DeviceProfile deviceProfile = createDeviceProfile("Device profile 1", null);
deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
deviceProfile = saveDeviceProfile(deviceProfile);
loginDifferentTenant();
@ -183,7 +187,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Test
public void testFindDeviceProfileInfoById() throws Exception {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile");
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
DeviceProfileInfo foundDeviceProfileInfo = doGet("/api/deviceProfileInfo/" + savedDeviceProfile.getId().getId().toString(), DeviceProfileInfo.class);
Assert.assertNotNull(foundDeviceProfileInfo);
Assert.assertEquals(savedDeviceProfile.getId(), foundDeviceProfileInfo.getId());
@ -213,7 +217,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Test
public void whenGetDeviceProfileInfoById_thenPermissionsAreChecked() throws Exception {
DeviceProfile deviceProfile = createDeviceProfile("Device profile 1", null);
deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
deviceProfile = saveDeviceProfile(deviceProfile);
loginDifferentTenant();
doGet("/api/deviceProfileInfo/" + deviceProfile.getId())
@ -235,7 +239,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Test
public void testSetDefaultDeviceProfile() throws Exception {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile 1");
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
Mockito.reset(tbClusterService, auditLogService);
@ -328,7 +332,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Test
public void testChangeDeviceProfileTypeNull() throws Exception {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile");
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
Mockito.reset(tbClusterService, auditLogService);
@ -345,7 +349,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Test
public void testChangeDeviceProfileTransportTypeWithExistingDevices() throws Exception {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile");
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
Device device = new Device();
device.setName("Test device");
device.setType("default");
@ -367,7 +371,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Test
public void testDeleteDeviceProfileWithExistingDevice() throws Exception {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile");
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
Device device = new Device();
device.setName("Test device");
@ -419,7 +423,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
public void testSaveDeviceProfileWithFirmwareFromDifferentTenant() throws Exception {
loginDifferentTenant();
DeviceProfile differentProfile = createDeviceProfile("Different profile");
differentProfile = doPost("/api/deviceProfile", differentProfile, DeviceProfile.class);
differentProfile = saveDeviceProfile(differentProfile);
SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
firmwareInfo.setDeviceProfileId(differentProfile.getId());
firmwareInfo.setType(FIRMWARE);
@ -441,7 +445,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
public void testSaveDeviceProfileWithSoftwareFromDifferentTenant() throws Exception {
loginDifferentTenant();
DeviceProfile differentProfile = createDeviceProfile("Different profile");
differentProfile = doPost("/api/deviceProfile", differentProfile, DeviceProfile.class);
differentProfile = saveDeviceProfile(differentProfile);
SaveOtaPackageInfoRequest softwareInfo = new SaveOtaPackageInfoRequest();
softwareInfo.setDeviceProfileId(differentProfile.getId());
softwareInfo.setType(SOFTWARE);
@ -462,7 +466,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Test
public void testDeleteDeviceProfile() throws Exception {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile");
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
Mockito.reset(tbClusterService, auditLogService);
@ -495,7 +499,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
int cntEntity = 28;
for (int i = 0; i < cntEntity; i++) {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile" + i);
deviceProfiles.add(doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class));
deviceProfiles.add(saveDeviceProfile(deviceProfile));
}
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new DeviceProfile(), new DeviceProfile(),
@ -552,7 +556,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
for (int i = 0; i < 28; i++) {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile" + i);
deviceProfiles.add(doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class));
deviceProfiles.add(saveDeviceProfile(deviceProfile));
}
List<DeviceProfileInfo> loadedDeviceProfileInfos = new ArrayList<>();
@ -961,7 +965,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
JsonTransportPayloadConfiguration jsonTransportPayloadConfiguration = new JsonTransportPayloadConfiguration();
MqttDeviceProfileTransportConfiguration mqttDeviceProfileTransportConfiguration = this.createMqttDeviceProfileTransportConfiguration(jsonTransportPayloadConfiguration, true);
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile", mqttDeviceProfileTransportConfiguration);
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
Assert.assertNotNull(savedDeviceProfile);
Assert.assertEquals(savedDeviceProfile.getTransportType(), DeviceTransportType.MQTT);
Assert.assertTrue(savedDeviceProfile.getProfileData().getTransportConfiguration() instanceof MqttDeviceProfileTransportConfiguration);
@ -979,7 +983,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
"v1/devices/me/telemetry", "v1/devices/me/attributes", "v1/devices/me/subscribeattributes");
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile",
mqttDeviceProfileTransportConfiguration);
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
Assert.assertNotNull(savedDeviceProfile);
Assert.assertEquals(savedDeviceProfile.getTransportType(), DeviceTransportType.MQTT);
Assert.assertTrue(savedDeviceProfile.getProfileData().getTransportConfiguration() instanceof MqttDeviceProfileTransportConfiguration);
@ -997,7 +1001,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = this.createProtoTransportPayloadConfiguration(schema, schema, null, null);
MqttDeviceProfileTransportConfiguration mqttDeviceProfileTransportConfiguration = this.createMqttDeviceProfileTransportConfiguration(protoTransportPayloadConfiguration, false);
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile", mqttDeviceProfileTransportConfiguration);
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile savedDeviceProfile = saveDeviceProfile(deviceProfile);
Assert.assertNotNull(savedDeviceProfile);
DeviceProfile foundDeviceProfile = doGet("/api/deviceProfile/" + savedDeviceProfile.getId().getId().toString(), DeviceProfile.class);
Assert.assertEquals(savedDeviceProfile, foundDeviceProfile);
@ -1036,14 +1040,14 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
@Test
public void testDeleteDeviceProfileWithDeleteRelationsOk() throws Exception {
DeviceProfileId deviceProfileId = savedDeviceProfile("DeviceProfile for Test WithRelationsOk").getId();
DeviceProfileId deviceProfileId = saveDeviceProfile("DeviceProfile for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(savedTenant.getId(), deviceProfileId, "/api/deviceProfile/" + deviceProfileId);
}
@Ignore
@Test
public void testDeleteDeviceProfileExceptionWithRelationsTransactional() throws Exception {
DeviceProfileId deviceProfileId = savedDeviceProfile("DeviceProfile for Test WithRelations Transactional Exception").getId();
DeviceProfileId deviceProfileId = saveDeviceProfile("DeviceProfile for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(deviceProfileDao, savedTenant.getId(), deviceProfileId, "/api/deviceProfile/" + deviceProfileId);
}
@ -1103,8 +1107,36 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
Assert.assertEquals(count, deviceProfileNames.size());
}
private DeviceProfile savedDeviceProfile(String name) {
@Test
public void testSaveDeviceProfileWithOutdatedVersion() throws Exception {
DeviceProfile deviceProfile = JacksonUtil.fromString(LWM2M_PROFILE_JSON, DeviceProfile.class);
deviceProfile.setName("Device profile v1.0");
deviceProfile = saveDeviceProfile(deviceProfile);
assertThat(deviceProfile.getVersion()).isOne();
deviceProfile.setName("Device profile v2.0");
deviceProfile = saveDeviceProfile(deviceProfile);
assertThat(deviceProfile.getVersion()).isEqualTo(2);
deviceProfile.setName("Device profile v1.1");
deviceProfile.setVersion(1L);
String response = doPost("/api/deviceProfile", deviceProfile).andExpect(status().isConflict())
.andReturn().getResponse().getContentAsString();
assertThat(JacksonUtil.toJsonNode(response).get("message").asText())
.containsIgnoringCase("already changed by someone else");
deviceProfile.setVersion(null); // overriding entity
deviceProfile = saveDeviceProfile(deviceProfile);
assertThat(deviceProfile.getName()).isEqualTo("Device profile v1.1");
assertThat(deviceProfile.getVersion()).isEqualTo(3);
}
private DeviceProfile saveDeviceProfile(String name) {
DeviceProfile deviceProfile = createDeviceProfile(name);
return saveDeviceProfile(deviceProfile);
}
private DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile) {
return doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
}

33
application/src/test/java/org/thingsboard/server/edge/AlarmEdgeTest.java

@ -94,44 +94,26 @@ public class AlarmEdgeTest extends AbstractEdgeTest {
Alarm savedAlarm = doPost("/api/alarm", alarm, Alarm.class);
edgeImitator.ignoreType(AlarmCommentUpdateMsg.class);
// ack alarm
// ack alarm - send only by using push to edge node
edgeImitator.expectMessageAmount(1);
doPost("/api/alarm/" + savedAlarm.getUuidId() + "/ack");
Assert.assertTrue(edgeImitator.waitForMessages());
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg);
AlarmUpdateMsg alarmUpdateMsg = (AlarmUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ALARM_ACK_RPC_MESSAGE, alarmUpdateMsg.getMsgType());
Alarm alarmMsg = JacksonUtil.fromString(alarmUpdateMsg.getEntity(), Alarm.class, true);
Assert.assertNotNull(alarmMsg);
Assert.assertEquals(savedAlarm.getType(), alarmMsg.getType());
Assert.assertEquals(savedAlarm.getName(), alarmMsg.getName());
Assert.assertEquals(AlarmStatus.ACTIVE_ACK, alarmMsg.getStatus());
Assert.assertFalse(edgeImitator.waitForMessages(5));
// clear alarm
// clear alarm - send only by using push to edge node
edgeImitator.expectMessageAmount(1);
doPost("/api/alarm/" + savedAlarm.getUuidId() + "/clear");
Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg);
alarmUpdateMsg = (AlarmUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ALARM_CLEAR_RPC_MESSAGE, alarmUpdateMsg.getMsgType());
alarmMsg = JacksonUtil.fromString(alarmUpdateMsg.getEntity(), Alarm.class, true);
Assert.assertNotNull(alarmMsg);
Assert.assertEquals(savedAlarm.getType(), alarmMsg.getType());
Assert.assertEquals(savedAlarm.getName(), alarmMsg.getName());
Assert.assertEquals(AlarmStatus.CLEARED_ACK, alarmMsg.getStatus());
Assert.assertFalse(edgeImitator.waitForMessages(5));
// delete alarm
edgeImitator.expectMessageAmount(1);
doDelete("/api/alarm/" + savedAlarm.getUuidId())
.andExpect(status().isOk());
Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg);
alarmUpdateMsg = (AlarmUpdateMsg) latestMessage;
AlarmUpdateMsg alarmUpdateMsg = (AlarmUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, alarmUpdateMsg.getMsgType());
alarmMsg = JacksonUtil.fromString(alarmUpdateMsg.getEntity(), Alarm.class, true);
Alarm alarmMsg = JacksonUtil.fromString(alarmUpdateMsg.getEntity(), Alarm.class, true);
Assert.assertNotNull(alarmMsg);
Assert.assertEquals(savedAlarm.getType(), alarmMsg.getType());
Assert.assertEquals(savedAlarm.getName(), alarmMsg.getName());
@ -252,4 +234,5 @@ public class AlarmEdgeTest extends AbstractEdgeTest {
alarmComment.setCreatedTime(Uuids.unixTimestamp(uuid));
return alarmComment;
}
}

144
application/src/test/java/org/thingsboard/server/service/apiusage/ApiUsageTest.java

@ -0,0 +1,144 @@
/**
* Copyright © 2016-2025 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.service.apiusage;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.TestPropertySource;
import org.thingsboard.server.common.data.ApiUsageStateValue;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
import org.thingsboard.server.controller.AbstractControllerTest;
import org.thingsboard.server.controller.TbUrlConstants;
import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
import java.util.concurrent.TimeUnit;
import static org.awaitility.Awaitility.await;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@DaoSqlTest
@TestPropertySource(properties = {
"usage.stats.report.enabled=true",
"usage.stats.report.interval=2",
"usage.stats.gauge_report_interval=1",
})
public class ApiUsageTest extends AbstractControllerTest {
private Tenant savedTenant;
private User tenantAdmin;
private static final int MAX_DP_ENABLE_VALUE = 12;
private static final double WARN_THRESHOLD_VALUE = 0.5;
@Autowired
private ApiUsageStateService apiUsageStateService;
@Before
public void beforeTest() throws Exception {
loginSysAdmin();
TenantProfile tenantProfile = createTenantProfile();
TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class);
assertNotNull(savedTenantProfile);
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
tenant.setTenantProfileId(savedTenantProfile.getId());
savedTenant = saveTenant(tenant);
tenantId = savedTenant.getId();
assertNotNull(savedTenant);
tenantAdmin = new User();
tenantAdmin.setAuthority(Authority.TENANT_ADMIN);
tenantAdmin.setTenantId(savedTenant.getId());
tenantAdmin.setEmail("tenant2@thingsboard.org");
tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1");
}
@Test
public void testTelemetryApiCall() throws Exception {
Device device = createDevice();
assertNotNull(device);
String telemetryPayload = "{\"temperature\":25, \"humidity\":60}";
String url = TbUrlConstants.TELEMETRY_URL_PREFIX + "/DEVICE/" + device.getId() + "/timeseries/ANY";
long VALUE_WARNING = (long) (MAX_DP_ENABLE_VALUE * WARN_THRESHOLD_VALUE) / 2;
for (int i = 0; i < VALUE_WARNING; i++) {
doPostAsync(url, telemetryPayload, String.class, status().isOk());
}
await().atMost(TIMEOUT, TimeUnit.SECONDS).untilAsserted(() -> assertEquals(ApiUsageStateValue.WARNING, apiUsageStateService.findTenantApiUsageState(tenantId).getDbStorageState()));
long VALUE_DISABLE = (long) (MAX_DP_ENABLE_VALUE - (MAX_DP_ENABLE_VALUE * WARN_THRESHOLD_VALUE)) / 2;
for (int i = 0; i < VALUE_DISABLE; i++) {
doPostAsync(url, telemetryPayload, String.class, status().isOk());
}
await().atMost(TIMEOUT, TimeUnit.SECONDS)
.untilAsserted(() -> {
assertEquals(ApiUsageStateValue.DISABLED, apiUsageStateService.findTenantApiUsageState(tenantId).getDbStorageState());
});
}
private TenantProfile createTenantProfile() {
TenantProfile tenantProfile = new TenantProfile();
tenantProfile.setName("Tenant Profile");
tenantProfile.setDescription("Tenant Profile" + " Test");
TenantProfileData tenantProfileData = new TenantProfileData();
DefaultTenantProfileConfiguration config = DefaultTenantProfileConfiguration.builder()
.maxDPStorageDays(MAX_DP_ENABLE_VALUE)
.warnThreshold(WARN_THRESHOLD_VALUE)
.build();
tenantProfileData.setConfiguration(config);
tenantProfile.setProfileData(tenantProfileData);
return tenantProfile;
}
private Device createDevice() throws Exception {
String testToken = "TEST_TOKEN";
Device device = new Device();
device.setName("My device");
device.setType("default");
device.setTenantId(tenantId);
DeviceCredentials deviceCredentials = new DeviceCredentials();
deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN);
deviceCredentials.setCredentialsId(testToken);
SaveDeviceWithCredentialsRequest saveRequest = new SaveDeviceWithCredentialsRequest(device, deviceCredentials);
return readResponse(doPost("/api/device-with-credentials", saveRequest).andExpect(status().isOk()), Device.class);
}
}

123
application/src/test/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateServiceTest.java

@ -15,45 +15,114 @@
*/
package org.thingsboard.server.service.apiusage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.thingsboard.server.common.data.ApiUsageState;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.ApiUsageStateValue;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.controller.AbstractControllerTest;
import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import java.util.UUID;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.never;
import static org.junit.Assert.assertEquals;
@ExtendWith(MockitoExtension.class)
public class DefaultTbApiUsageStateServiceTest {
@DaoSqlTest
public class DefaultTbApiUsageStateServiceTest extends AbstractControllerTest {
@Mock
TenantApiUsageState tenantUsageStateMock;
@Autowired
DefaultTbApiUsageStateService service;
TenantId tenantId = TenantId.fromUUID(UUID.fromString("00797a3b-7aeb-4b5b-b57a-c2a810d0f112"));
@Autowired
private ApiUsageStateService apiUsageStateService;
@Spy
@InjectMocks
DefaultTbApiUsageStateService service;
private TenantId tenantId;
private Tenant savedTenant;
private static final int MAX_ENABLE_VALUE = 5000;
private static final long VALUE_WARNING = 4500L;
private static final long VALUE_DISABLE = 5500L;
private static final double WARN_THRESHOLD_VALUE = 0.8;
@Before
public void init() throws Exception {
loginSysAdmin();
@BeforeEach
public void setUp() {
TenantProfile tenantProfile = createTenantProfile();
TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class);
Assert.assertNotNull(savedTenantProfile);
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
tenant.setTenantProfileId(savedTenantProfile.getId());
savedTenant = saveTenant(tenant);
tenantId = savedTenant.getId();
Assert.assertNotNull(savedTenant);
}
@Test
public void givenTenantIdFromEntityStatesMap_whenGetApiUsageState() {
service.myUsageStates.put(tenantId, tenantUsageStateMock);
ApiUsageState tenantUsageState = service.getApiUsageState(tenantId);
assertThat(tenantUsageState, is(tenantUsageStateMock.getApiUsageState()));
Mockito.verify(service, never()).getOrFetchState(tenantId, tenantId);
public void testProcess_transitionFromWarningToDisabled() {
TransportProtos.ToUsageStatsServiceMsg.Builder warningMsgBuilder = TransportProtos.ToUsageStatsServiceMsg.newBuilder()
.setTenantIdMSB(tenantId.getId().getMostSignificantBits())
.setTenantIdLSB(tenantId.getId().getLeastSignificantBits())
.setCustomerIdMSB(0)
.setCustomerIdLSB(0)
.setServiceId("testService");
warningMsgBuilder.addValues(TransportProtos.UsageStatsKVProto.newBuilder()
.setKey(ApiUsageRecordKey.STORAGE_DP_COUNT.name())
.setValue(VALUE_WARNING)
.build());
TransportProtos.ToUsageStatsServiceMsg warningStatsMsg = warningMsgBuilder.build();
TbProtoQueueMsg<TransportProtos.ToUsageStatsServiceMsg> warningMsg = new TbProtoQueueMsg<>(UUID.randomUUID(), warningStatsMsg);
service.process(warningMsg, TbCallback.EMPTY);
assertEquals(ApiUsageStateValue.WARNING, apiUsageStateService.findTenantApiUsageState(tenantId).getDbStorageState());
TransportProtos.ToUsageStatsServiceMsg.Builder disableMsgBuilder = TransportProtos.ToUsageStatsServiceMsg.newBuilder()
.setTenantIdMSB(tenantId.getId().getMostSignificantBits())
.setTenantIdLSB(tenantId.getId().getLeastSignificantBits())
.setCustomerIdMSB(0)
.setCustomerIdLSB(0)
.setServiceId("testService");
disableMsgBuilder.addValues(TransportProtos.UsageStatsKVProto.newBuilder()
.setKey(ApiUsageRecordKey.STORAGE_DP_COUNT.name())
.setValue(VALUE_DISABLE)
.build());
TransportProtos.ToUsageStatsServiceMsg disableStatsMsg = disableMsgBuilder.build();
TbProtoQueueMsg<TransportProtos.ToUsageStatsServiceMsg> disableMsg = new TbProtoQueueMsg<>(UUID.randomUUID(), disableStatsMsg);
service.process(disableMsg, TbCallback.EMPTY);
assertEquals(ApiUsageStateValue.DISABLED, apiUsageStateService.findTenantApiUsageState(tenantId).getDbStorageState());
}
private TenantProfile createTenantProfile() {
TenantProfile tenantProfile = new TenantProfile();
tenantProfile.setName("Tenant Profile");
tenantProfile.setDescription("Tenant Profile" + " Test");
TenantProfileData tenantProfileData = new TenantProfileData();
DefaultTenantProfileConfiguration config = DefaultTenantProfileConfiguration.builder()
.maxDPStorageDays(MAX_ENABLE_VALUE)
.warnThreshold(WARN_THRESHOLD_VALUE)
.build();
tenantProfileData.setConfiguration(config);
tenantProfile.setProfileData(tenantProfileData);
return tenantProfile;
}
}

2
application/src/test/java/org/thingsboard/server/transport/coap/AbstractCoapIntegrationTest.java

@ -45,7 +45,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@TestPropertySource(properties = {
"coap.enabled=true",
"coap.server.enabled=true",
"service.integrations.supported=ALL",
"transport.coap.enabled=true",
})

2
application/src/test/java/org/thingsboard/server/transport/coap/security/AbstractCoapSecurityIntegrationTest.java

@ -61,7 +61,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@Slf4j
@TestPropertySource(properties = {
"coap.enabled=true",
"coap.server.enabled=true",
"coap.dtls.enabled=true",
"coap.dtls.credentials.pem.cert_file=coap/credentials/server/cert.pem",
"device.connectivity.coaps.enabled=true",

2
application/src/test/resources/application-test.properties

@ -19,7 +19,7 @@ transport.mqtt.enabled=false
transport.coap.enabled=false
transport.lwm2m.enabled=false
transport.snmp.enabled=false
coap.enabled=false
coap.server.enabled=false
integrations.rpc.enabled=false
service.integrations.supported=NONE

2
common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapServerComponent.java

@ -21,6 +21,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${coap.enabled}'=='true')")
@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || ('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${coap.server.enabled}'=='true')")
public @interface TbCoapServerComponent {
}

2
common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapTransportComponent.java

@ -22,6 +22,6 @@ import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@ConditionalOnExpression("'${service.type:null}'=='tb-transport' || " +
"('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${coap.enabled}'=='true' && '${transport.coap.enabled}'=='true')")
"('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' && '${coap.server.enabled}'=='true' && '${transport.coap.enabled}'=='true')")
public @interface TbCoapTransportComponent {
}

1
common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java

@ -34,4 +34,5 @@ public interface ApiUsageStateService extends EntityDaoService {
void deleteApiUsageStateByEntityId(EntityId entityId);
ApiUsageState findApiUsageStateById(TenantId tenantId, ApiUsageStateId id);
}

9
common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageState.java

@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.id.TenantId;
@EqualsAndHashCode(callSuper = true)
@Getter
@Setter
public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenantId {
public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenantId, HasVersion {
private static final long serialVersionUID = 8250339805336035966L;
@ -41,6 +41,7 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
private ApiUsageStateValue emailExecState;
private ApiUsageStateValue smsExecState;
private ApiUsageStateValue alarmExecState;
private Long version;
public ApiUsageState() {
super();
@ -62,6 +63,7 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
this.emailExecState = ur.getEmailExecState();
this.smsExecState = ur.getSmsExecState();
this.alarmExecState = ur.getAlarmExecState();
this.version = ur.getVersion();
}
public boolean isTransportEnabled() {
@ -84,15 +86,16 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
return !ApiUsageStateValue.DISABLED.equals(tbelExecState);
}
public boolean isEmailSendEnabled(){
public boolean isEmailSendEnabled() {
return !ApiUsageStateValue.DISABLED.equals(emailExecState);
}
public boolean isSmsSendEnabled(){
public boolean isSmsSendEnabled() {
return !ApiUsageStateValue.DISABLED.equals(smsExecState);
}
public boolean isAlarmCreationEnabled() {
return alarmExecState != ApiUsageStateValue.DISABLED;
}
}

5
common/proto/src/main/java/org/thingsboard/server/common/util/ProtoUtils.java

@ -1019,7 +1019,9 @@ public class ProtoUtils {
.setTbelExecState(apiUsageState.getTbelExecState().name())
.setEmailExecState(apiUsageState.getEmailExecState().name())
.setSmsExecState(apiUsageState.getSmsExecState().name())
.setAlarmExecState(apiUsageState.getAlarmExecState().name()).build();
.setAlarmExecState(apiUsageState.getAlarmExecState().name())
.setVersion(apiUsageState.getVersion())
.build();
}
public static ApiUsageState fromProto(TransportProtos.ApiUsageStateProto proto) {
@ -1035,6 +1037,7 @@ public class ProtoUtils {
apiUsageState.setEmailExecState(ApiUsageStateValue.valueOf(proto.getEmailExecState()));
apiUsageState.setSmsExecState(ApiUsageStateValue.valueOf(proto.getSmsExecState()));
apiUsageState.setAlarmExecState(ApiUsageStateValue.valueOf(proto.getAlarmExecState()));
apiUsageState.setVersion(proto.getVersion());
return apiUsageState;
}

1
common/proto/src/main/proto/queue.proto

@ -356,6 +356,7 @@ message ApiUsageStateProto {
string emailExecState = 14;
string smsExecState = 15;
string alarmExecState = 16;
int64 version = 17;
}
message RepositorySettingsProto {

10
dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java

@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.id.ApiUsageStateId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import java.util.UUID;
@ -40,7 +40,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = ModelConstants.API_USAGE_STATE_TABLE_NAME)
public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements BaseEntity<ApiUsageState> {
public class ApiUsageStateEntity extends BaseVersionedEntity<ApiUsageState> implements BaseEntity<ApiUsageState> {
@Column(name = ModelConstants.API_USAGE_STATE_TENANT_ID_COLUMN)
private UUID tenantId;
@ -77,10 +77,7 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
}
public ApiUsageStateEntity(ApiUsageState ur) {
if (ur.getId() != null) {
this.setUuid(ur.getId().getId());
}
this.setCreatedTime(ur.getCreatedTime());
super(ur);
if (ur.getTenantId() != null) {
this.tenantId = ur.getTenantId().getId();
}
@ -116,6 +113,7 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
ur.setEmailExecState(emailExecState);
ur.setSmsExecState(smsExecState);
ur.setAlarmExecState(alarmExecState);
ur.setVersion(version);
return ur;
}

20
dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java

@ -88,10 +88,10 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D>
boolean flushed = false;
EntityManager entityManager = getEntityManager();
if (isNew) {
entityManager.persist(entity);
if (entity instanceof HasVersion versionedEntity) {
versionedEntity.setVersion(1L);
}
entityManager.persist(entity);
} else {
if (entity instanceof HasVersion versionedEntity) {
if (versionedEntity.getVersion() == null) {
@ -106,23 +106,25 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D>
}
}
versionedEntity = entityManager.merge(versionedEntity);
entity = (E) versionedEntity;
/*
* by default, Hibernate doesn't issue an update query and thus version increment
* if the entity was not modified. to bypass this and always increment the version, we do it manually
* */
versionedEntity.setVersion(versionedEntity.getVersion() + 1);
/*
* flushing and then removing the entity from the persistence context so that it is not affected
* by next flushes (e.g. when a transaction is committed) to avoid double version increment
* */
entityManager.flush();
entityManager.detach(versionedEntity);
flushed = true;
entity = (E) versionedEntity;
} else {
entity = entityManager.merge(entity);
}
}
if (entity instanceof HasVersion versionedEntity) {
/*
* flushing and then removing the entity from the persistence context so that it is not affected
* by next flushes (e.g. when a transaction is committed) to avoid double version increment
* */
entityManager.flush();
entityManager.detach(versionedEntity);
flushed = true;
}
if (flush && !flushed) {
entityManager.flush();
}

1
dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java

@ -162,6 +162,7 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
log.trace("Executing save [{}]", apiUsageState.getTenantId());
validateId(apiUsageState.getTenantId(), id -> INCORRECT_TENANT_ID + id);
validateId(apiUsageState.getId(), "Can't save new usage state. Only update is allowed!");
apiUsageState.setVersion(null);
ApiUsageState savedState = apiUsageStateDao.save(apiUsageState.getTenantId(), apiUsageState);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedState.getTenantId()).entityId(savedState.getId())
.entity(savedState).build());

1
dao/src/main/resources/sql/schema-entities.sql

@ -702,6 +702,7 @@ CREATE TABLE IF NOT EXISTS api_usage_state (
email_exec varchar(32),
sms_exec varchar(32),
alarm_exec varchar(32),
version BIGINT DEFAULT 1,
CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id)
);

47
dao/src/test/java/org/thingsboard/server/dao/service/ApiUsageStateServiceTest.java

@ -20,6 +20,7 @@ import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.ApiUsageStateValue;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
@ -30,22 +31,42 @@ public class ApiUsageStateServiceTest extends AbstractServiceTest {
ApiUsageStateService apiUsageStateService;
@Test
public void testFindApiUsageStateByTenantId() {
ApiUsageState apiUsageState = apiUsageStateService.findTenantApiUsageState(tenantId);
Assert.assertNotNull(apiUsageState);
public void testFindTenantApiUsageState() {
ApiUsageState state = apiUsageStateService.findTenantApiUsageState(tenantId);
Assert.assertNotNull(state);
}
@Test
public void testUpdateApiUsageState(){
ApiUsageState apiUsageState = apiUsageStateService.findTenantApiUsageState(tenantId);
Assert.assertNotNull(apiUsageState);
Assert.assertTrue(apiUsageState.isTransportEnabled());
apiUsageState.setTransportState(ApiUsageStateValue.DISABLED);
apiUsageState = apiUsageStateService.update(apiUsageState);
Assert.assertNotNull(apiUsageState);
apiUsageState = apiUsageStateService.findTenantApiUsageState(tenantId);
Assert.assertNotNull(apiUsageState);
Assert.assertFalse(apiUsageState.isTransportEnabled());
public void testUpdate() {
ApiUsageState state = apiUsageStateService.findTenantApiUsageState(tenantId);
state.setTransportState(ApiUsageStateValue.DISABLED);
ApiUsageState updated = apiUsageStateService.update(state);
Assert.assertEquals(ApiUsageStateValue.DISABLED, updated.getTransportState());
}
@Test
public void testUpdateWithNullId() {
ApiUsageState newState = new ApiUsageState();
newState.setTenantId(tenantId);
newState.setTransportState(ApiUsageStateValue.ENABLED);
Assert.assertThrows(IncorrectParameterException.class, () -> apiUsageStateService.update(newState));
}
@Test
public void testFindApiUsageStateByEntityId() {
ApiUsageState state = apiUsageStateService.findApiUsageStateByEntityId(tenantId);
Assert.assertNotNull(state);
}
@Test
public void testDeleteByTenantId() {
ApiUsageState state = apiUsageStateService.findTenantApiUsageState(tenantId);
Assert.assertNotNull(state);
apiUsageStateService.deleteByTenantId(tenantId);
state = apiUsageStateService.findTenantApiUsageState(tenantId);
Assert.assertNull(state);
}
}

16
rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java

@ -143,12 +143,19 @@ public interface TbContext {
void tellFailure(TbMsg msg, Throwable th);
/**
* Puts new message to queue for processing by the Root Rule Chain
* Puts new message to queue from TbMsg for processing by the Root Rule Chain
*
* @param msg - message
*/
void enqueue(TbMsg msg, Runnable onSuccess, Consumer<Throwable> onFailure);
/**
* Puts new message to custom queue for processing
*
* @param msg - message
*/
void enqueue(TbMsg msg, String queueName, Runnable onSuccess, Consumer<Throwable> onFailure);
/**
* Sends message to the nested rule chain.
* Fails processing of the message if the nested rule chain is not found.
@ -167,13 +174,6 @@ public interface TbContext {
*/
void output(TbMsg msg, String relationType);
/**
* Puts new message to custom queue for processing
*
* @param msg - message
*/
void enqueue(TbMsg msg, String queueName, Runnable onSuccess, Consumer<Throwable> onFailure);
void enqueueForTellFailure(TbMsg msg, String failureMessage);
void enqueueForTellFailure(TbMsg tbMsg, Throwable t);

9
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java

@ -39,6 +39,8 @@ import java.util.UUID;
import static org.thingsboard.server.common.data.msg.TbMsgType.ACTIVITY_EVENT;
import static org.thingsboard.server.common.data.msg.TbMsgType.ALARM;
import static org.thingsboard.server.common.data.msg.TbMsgType.ALARM_ACK;
import static org.thingsboard.server.common.data.msg.TbMsgType.ALARM_CLEAR;
import static org.thingsboard.server.common.data.msg.TbMsgType.ATTRIBUTES_DELETED;
import static org.thingsboard.server.common.data.msg.TbMsgType.ATTRIBUTES_UPDATED;
import static org.thingsboard.server.common.data.msg.TbMsgType.CONNECT_EVENT;
@ -79,6 +81,9 @@ public abstract class AbstractTbMsgPushNode<T extends BaseTbMsgPushNodeConfigura
if (msg.isTypeOf(ALARM)) {
EdgeEventActionType actionType = getAlarmActionType(msg);
return buildEvent(ctx.getTenantId(), actionType, getUUIDFromMsgData(msg), getAlarmEventType(), null);
} else if (msg.isTypeOneOf(ALARM_ACK, ALARM_CLEAR)) {
EdgeEventActionType actionType = EdgeEventActionType.valueOf(msg.getType());
return buildEvent(ctx.getTenantId(), actionType, getUUIDFromMsgData(msg), getAlarmEventType(), null);
} else {
Map<String, String> metadata = msg.getMetaData().getData();
EdgeEventActionType actionType = getEdgeEventActionTypeByMsgType(msg);
@ -165,6 +170,8 @@ public abstract class AbstractTbMsgPushNode<T extends BaseTbMsgPushNodeConfigura
String scope = msg.getMetaData().getValue(DataConstants.SCOPE);
actionType = StringUtils.isEmpty(scope) ?
EdgeEventActionType.TIMESERIES_UPDATED : EdgeEventActionType.ATTRIBUTES_UPDATED;
} else if (msg.isTypeOneOf(ALARM_ACK, ALARM_CLEAR)) {
actionType = EdgeEventActionType.valueOf(msg.getType());
} else {
String type = msg.getType();
log.warn("Unsupported msg type [{}]", type);
@ -175,7 +182,7 @@ public abstract class AbstractTbMsgPushNode<T extends BaseTbMsgPushNodeConfigura
protected boolean isSupportedMsgType(TbMsg msg) {
return msg.isTypeOneOf(POST_TELEMETRY_REQUEST, POST_ATTRIBUTES_REQUEST, ATTRIBUTES_UPDATED, ATTRIBUTES_DELETED, TIMESERIES_UPDATED,
ALARM, CONNECT_EVENT, DISCONNECT_EVENT, ACTIVITY_EVENT, INACTIVITY_EVENT, TO_SERVER_RPC_REQUEST);
ALARM, ALARM_ACK, ALARM_CLEAR, CONNECT_EVENT, DISCONNECT_EVENT, ACTIVITY_EVENT, INACTIVITY_EVENT, TO_SERVER_RPC_REQUEST);
}
}

Loading…
Cancel
Save