From d915cf6485fe8498e65e38367497eef2f91587ef Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 14 Sep 2022 18:42:04 +0300 Subject: [PATCH] Base Edge test split into multiple tests. Push customer create/update/delete notification to edge --- .../edge/DefaultEdgeNotificationService.java | 12 +- .../service/edge/rpc/EdgeGrpcSession.java | 6 +- .../rpc/constructor/AssetMsgConstructor.java | 4 +- .../rpc/processor/CustomerEdgeProcessor.java | 44 - .../rpc/processor/EntityEdgeProcessor.java | 3 +- .../customer/DefaultTbCustomerService.java | 11 +- .../entitiy/user/DefaultUserService.java | 7 +- .../server/controller/AbstractWebTest.java | 4 +- .../server/edge/AbstractEdgeTest.java | 469 ++++ .../server/edge/BaseAlarmEdgeTest.java | 136 + .../server/edge/BaseAssetEdgeTest.java | 140 + .../server/edge/BaseCustomerEdgeTest.java | 72 + .../server/edge/BaseDashboardEdgeTest.java | 147 ++ .../server/edge/BaseDeviceEdgeTest.java | 554 ++++ .../edge/BaseDeviceProfileEdgeTest.java | 319 +++ .../thingsboard/server/edge/BaseEdgeTest.java | 2280 ----------------- .../server/edge/BaseEntityViewEdgeTest.java | 174 ++ .../server/edge/BaseOtaPackageEdgeTest.java | 151 ++ .../server/edge/BaseQueueEdgeTest.java | 107 + .../server/edge/BaseRelationEdgeTest.java | 174 ++ .../server/edge/BaseRuleChainEdgeTest.java | 174 ++ .../server/edge/BaseTelemetryEdgeTest.java | 195 ++ .../server/edge/BaseUserEdgeTest.java | 206 ++ .../server/edge/BaseWidgetEdgeTest.java | 99 + .../server/edge/sql/AlarmEdgeSqlTest.java | 24 + .../server/edge/sql/AssetEdgeSqlTest.java | 24 + .../server/edge/sql/CustomerEdgeSqlTest.java | 24 + .../server/edge/sql/DashboardEdgeSqlTest.java | 24 + .../server/edge/sql/DeviceEdgeSqlTest.java | 24 + .../edge/sql/DeviceProfileEdgeSqlTest.java | 24 + .../edge/sql/EntityViewEdgeSqlTest.java | 24 + .../edge/sql/OtaPackageEdgeSqlTest.java | 24 + .../server/edge/sql/QueueEdgeSqlTest.java | 24 + .../server/edge/sql/RelationEdgeSqlTest.java | 24 + .../server/edge/sql/RuleChainEdgeSqlTest.java | 24 + .../server/edge/sql/TelemetryEdgeSqlTest.java | 24 + ...{EdgeSqlTest.java => UserEdgeSqlTest.java} | 5 +- .../server/edge/sql/WidgetEdgeSqlTest.java | 24 + .../server/dao/edge/EdgeServiceImpl.java | 3 +- 39 files changed, 3450 insertions(+), 2358 deletions(-) create mode 100644 application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseAlarmEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseAssetEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseCustomerEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseDashboardEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseDeviceProfileEdgeTest.java delete mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseEntityViewEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseOtaPackageEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseQueueEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseRelationEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseRuleChainEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseTelemetryEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseUserEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/BaseWidgetEdgeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/AlarmEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/AssetEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/CustomerEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/DashboardEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/DeviceEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/DeviceProfileEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/EntityViewEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/OtaPackageEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/QueueEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/RelationEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/RuleChainEdgeSqlTest.java create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/TelemetryEdgeSqlTest.java rename application/src/test/java/org/thingsboard/server/edge/sql/{EdgeSqlTest.java => UserEdgeSqlTest.java} (86%) create mode 100644 application/src/test/java/org/thingsboard/server/edge/sql/WidgetEdgeSqlTest.java diff --git a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java index 5fa58a5bb5..4829e1cd98 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java @@ -40,7 +40,6 @@ import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.edge.rpc.processor.AlarmEdgeProcessor; -import org.thingsboard.server.service.edge.rpc.processor.CustomerEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.EdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.EntityEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.RelationEdgeProcessor; @@ -77,9 +76,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { @Autowired private RelationEdgeProcessor relationProcessor; - @Autowired - private CustomerEdgeProcessor customerProcessor; - private ExecutorService dbCallBackExecutor; @PostConstruct @@ -130,19 +126,17 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { case EDGE: future = edgeProcessor.processEdgeNotification(tenantId, edgeNotificationMsg); break; - case USER: case ASSET: case DEVICE: - case DEVICE_PROFILE: case ENTITY_VIEW: case DASHBOARD: case RULE_CHAIN: - case OTA_PACKAGE: future = entityProcessor.processEntityNotification(tenantId, edgeNotificationMsg); break; + case USER: case CUSTOMER: - future = customerProcessor.processCustomerNotification(tenantId, edgeNotificationMsg); - break; + case DEVICE_PROFILE: + case OTA_PACKAGE: case WIDGETS_BUNDLE: case WIDGET_TYPE: case QUEUE: diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 08770c7b43..53375ff1fc 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -385,9 +385,9 @@ public final class EdgeGrpcSession implements Closeable { private ListenableFuture sendDownlinkMsgsPack(List downlinkMsgsPack) { if (sessionState.getSendDownlinkMsgsFuture() != null && !sessionState.getSendDownlinkMsgsFuture().isDone()) { - String erroMsg = "[" + this.sessionId + "] Previous send downdlink future was not properly completed, stopping it now"; - log.error(erroMsg); - sessionState.getSendDownlinkMsgsFuture().setException(new RuntimeException(erroMsg)); + String errorMsg = "[" + this.sessionId + "] Previous send downlink future was not properly completed, stopping it now"; + log.error(errorMsg); + sessionState.getSendDownlinkMsgsFuture().setException(new RuntimeException(errorMsg)); } sessionState.setSendDownlinkMsgsFuture(SettableFuture.create()); sessionState.getPendingMsgsMap().clear(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java index 47e5bbf1b3..cd326796e6 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java @@ -30,8 +30,8 @@ public class AssetMsgConstructor { public AssetUpdateMsg constructAssetUpdatedMsg(UpdateMsgType msgType, Asset asset) { AssetUpdateMsg.Builder builder = AssetUpdateMsg.newBuilder() .setMsgType(msgType) - .setIdMSB(asset.getId().getId().getMostSignificantBits()) - .setIdLSB(asset.getId().getId().getLeastSignificantBits()) + .setIdMSB(asset.getUuidId().getMostSignificantBits()) + .setIdLSB(asset.getUuidId().getLeastSignificantBits()) .setName(asset.getName()) .setType(asset.getType()); if (asset.getLabel() != null) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java index 3554057482..85182fdaa2 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/CustomerEdgeProcessor.java @@ -15,32 +15,18 @@ */ package org.thingsboard.server.service.edge.rpc.processor; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EdgeUtils; -import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; -import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.EntityIdFactory; -import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.page.PageData; -import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.UpdateMsgType; -import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - @Component @Slf4j @TbCoreComponent @@ -74,34 +60,4 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor { return downlinkMsg; } - public ListenableFuture processCustomerNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { - EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); - EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); - UUID uuid = new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB()); - CustomerId customerId = new CustomerId(EntityIdFactory.getByEdgeEventTypeAndUuid(type, uuid).getId()); - switch (actionType) { - case UPDATED: - PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); - PageData pageData; - List> futures = new ArrayList<>(); - do { - pageData = edgeService.findEdgesByTenantIdAndCustomerId(tenantId, customerId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - for (Edge edge : pageData.getData()) { - futures.add(saveEdgeEvent(tenantId, edge.getId(), type, actionType, customerId, null)); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } - } while (pageData != null && pageData.hasNext()); - return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService); - case DELETED: - EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEdgeIdMSB(), edgeNotificationMsg.getEdgeIdLSB())); - return saveEdgeEvent(tenantId, edgeId, type, actionType, customerId, null); - default: - return Futures.immediateFuture(null); - } - } - } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java index c2b7a5cab5..5ebc8c5654 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/EntityEdgeProcessor.java @@ -95,7 +95,7 @@ public class EntityEdgeProcessor extends BaseEdgeProcessor { new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); EdgeId edgeId = safeGetEdgeId(edgeNotificationMsg); switch (actionType) { - case ADDED: // used only for USER entity + case ADDED: case UPDATED: case CREDENTIALS_UPDATED: case ASSIGNED_TO_CUSTOMER: @@ -189,6 +189,7 @@ public class EntityEdgeProcessor extends BaseEdgeProcessor { case ADDED: case UPDATED: case DELETED: + case CREDENTIALS_UPDATED: // used by USER entity return processActionForAllEdges(tenantId, type, actionType, entityId); default: return Futures.immediateFuture(null); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java index 07ef6a2eef..f46f7551cd 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java @@ -22,13 +22,10 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; -import java.util.List; - @Service @AllArgsConstructor public class DefaultTbCustomerService extends AbstractTbEntityService implements TbCustomerService { @@ -40,7 +37,8 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements try { Customer savedCustomer = checkNotNull(customerService.saveCustomer(customer)); autoCommit(user, savedCustomer.getId()); - notificationEntityService.notifyCreateOrUpdateEntity(tenantId, savedCustomer.getId(), savedCustomer, null, actionType, user); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedCustomer.getId(), + savedCustomer, user, actionType, true, null); return savedCustomer; } catch (Exception e) { notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.CUSTOMER), customer, actionType, user, e); @@ -53,10 +51,9 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements TenantId tenantId = customer.getTenantId(); CustomerId customerId = customer.getId(); try { - List relatedEdgeIds = findRelatedEdgeIds(tenantId, customer.getId()); customerService.deleteCustomer(tenantId, customerId); - notificationEntityService.notifyDeleteEntity(tenantId, customer.getId(), customer, customerId, - ActionType.DELETED, relatedEdgeIds, user, customerId.toString()); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, customerId, customer.getId(), customer, + user, ActionType.DELETED, true, null, customerId.toString()); tbClusterService.broadcastEntityStateChangeEvent(tenantId, customer.getId(), ComponentLifecycleEvent.DELETED); } catch (Exception e) { notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.CUSTOMER), ActionType.DELETED, diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java index a41bbb4385..a3df4b816b 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java @@ -24,7 +24,6 @@ import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.UserCredentials; @@ -34,7 +33,6 @@ import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.security.system.SystemSecurityService; import javax.servlet.http.HttpServletRequest; -import java.util.List; import static org.thingsboard.server.controller.UserController.ACTIVATE_URL_PATTERN; @@ -82,10 +80,9 @@ public class DefaultUserService extends AbstractTbEntityService implements TbUse UserId userId = tbUser.getId(); try { - List relatedEdgeIds = findRelatedEdgeIds(tenantId, userId); userService.deleteUser(tenantId, userId); - notificationEntityService.notifyDeleteEntity(tenantId, userId, tbUser, customerId, - ActionType.DELETED, relatedEdgeIds, user, userId.toString()); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, customerId, userId, tbUser, + user, ActionType.DELETED, true, null, customerId.toString()); } catch (Exception e) { notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.USER), ActionType.DELETED, user, e, userId.toString()); diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index 09c40f263c..c18ff48577 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -373,9 +373,7 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { } protected void login(String username, String password) throws Exception { - this.token = null; - this.refreshToken = null; - this.username = null; + logout(); JsonNode tokenInfo = readResponse(doPost("/api/auth/login", new LoginRequest(username, password)).andExpect(status().isOk()), JsonNode.class); validateAndSetJwtToken(tokenInfo, username); } diff --git a/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java new file mode 100644 index 0000000000..f6e14f6051 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java @@ -0,0 +1,469 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.MessageLite; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.TestPropertySource; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; +import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.alarm.AlarmSeverity; +import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration; +import org.thingsboard.server.common.data.device.data.DeviceData; +import org.thingsboard.server.common.data.device.data.MqttDeviceTransportConfiguration; +import org.thingsboard.server.common.data.device.profile.AlarmCondition; +import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter; +import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey; +import org.thingsboard.server.common.data.device.profile.AlarmConditionKeyType; +import org.thingsboard.server.common.data.device.profile.AlarmRule; +import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration; +import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; +import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; +import org.thingsboard.server.common.data.device.profile.SimpleAlarmConditionSpec; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.DeviceProfileId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.query.EntityKeyValueType; +import org.thingsboard.server.common.data.query.FilterPredicateValue; +import org.thingsboard.server.common.data.query.NumericFilterPredicate; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.controller.AbstractControllerTest; +import org.thingsboard.server.dao.edge.EdgeEventService; +import org.thingsboard.server.edge.imitator.EdgeImitator; +import org.thingsboard.server.gen.edge.v1.AdminSettingsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.v1.EdgeConfiguration; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; +import org.thingsboard.server.queue.util.DataDecodingEncodingService; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.TreeMap; +import java.util.UUID; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; + +@TestPropertySource(properties = { + "edges.enabled=true", +}) +abstract public class AbstractEdgeTest extends AbstractControllerTest { + + private static final String THERMOSTAT_DEVICE_PROFILE_NAME = "Thermostat"; + + protected Tenant savedTenant; + protected TenantId tenantId; + protected User tenantAdmin; + + protected DeviceProfile thermostatDeviceProfile; + + protected EdgeImitator edgeImitator; + protected Edge edge; + + @Autowired + protected EdgeEventService edgeEventService; + + @Autowired + protected DataDecodingEncodingService dataDecodingEncodingService; + + @Autowired + protected TbClusterService clusterService; + + @Before + public void beforeTest() throws Exception { + loginSysAdmin(); + + Tenant tenant = new Tenant(); + tenant.setTitle("My tenant"); + savedTenant = doPost("/api/tenant", tenant, Tenant.class); + tenantId = savedTenant.getId(); + Assert.assertNotNull(savedTenant); + + tenantAdmin = new User(); + tenantAdmin.setAuthority(Authority.TENANT_ADMIN); + tenantAdmin.setTenantId(savedTenant.getId()); + tenantAdmin.setEmail("tenant2@thingsboard.org"); + tenantAdmin.setFirstName("Joe"); + tenantAdmin.setLastName("Downs"); + + tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); + // sleep 0.5 second to avoid CREDENTIALS updated message for the user + // user credentials is going to be stored and updated event pushed to edge notification service + // while service will be processing this event edge could be already added and additional message will be pushed + Thread.sleep(500); + + installation(); + + edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret()); + edgeImitator.expectMessageAmount(15); + edgeImitator.connect(); + + requestEdgeRuleChainMetadata(); + + verifyEdgeConnectionAndInitialData(); + } + + private void requestEdgeRuleChainMetadata() throws Exception { + RuleChainId rootRuleChainId = getEdgeRootRuleChainId(); + RuleChainMetadataRequestMsg.Builder builder = RuleChainMetadataRequestMsg.newBuilder() + .setRuleChainIdMSB(rootRuleChainId.getId().getMostSignificantBits()) + .setRuleChainIdLSB(rootRuleChainId.getId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(builder); + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder() + .addRuleChainMetadataRequestMsg(builder.build()); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + } + + private RuleChainId getEdgeRootRuleChainId() throws Exception { + List edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/ruleChains?", + new TypeReference>() {}, new PageLink(100)).getData(); + for (RuleChain edgeRuleChain : edgeRuleChains) { + if (edgeRuleChain.isRoot()) { + return edgeRuleChain.getId(); + } + } + throw new RuntimeException("Root rule chain not found"); + } + + @After + public void afterTest() throws Exception { + try { + edgeImitator.disconnect(); + } catch (Exception ignored) {} + + loginSysAdmin(); + + doDelete("/api/tenant/" + savedTenant.getUuidId()) + .andExpect(status().isOk()); + } + + private void installation() throws Exception { + edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); + + thermostatDeviceProfile = this.createDeviceProfile(THERMOSTAT_DEVICE_PROFILE_NAME, + createMqttDeviceProfileTransportConfiguration(new JsonTransportPayloadConfiguration(), false)); + + extendDeviceProfileData(thermostatDeviceProfile); + thermostatDeviceProfile = doPost("/api/deviceProfile", thermostatDeviceProfile, DeviceProfile.class); + + Device savedDevice = saveDevice("Edge Device 1", THERMOSTAT_DEVICE_PROFILE_NAME); + doPost("/api/edge/" + edge.getUuidId() + + "/device/" + savedDevice.getUuidId(), Device.class); + + Asset savedAsset = saveAsset("Edge Asset 1"); + doPost("/api/edge/" + edge.getUuidId() + + "/asset/" + savedAsset.getUuidId(), Asset.class); + } + + protected void extendDeviceProfileData(DeviceProfile deviceProfile) { + DeviceProfileData profileData = deviceProfile.getProfileData(); + List alarms = new ArrayList<>(); + DeviceProfileAlarm deviceProfileAlarm = new DeviceProfileAlarm(); + deviceProfileAlarm.setAlarmType("High Temperature"); + AlarmRule alarmRule = new AlarmRule(); + alarmRule.setAlarmDetails("Alarm Details"); + AlarmCondition alarmCondition = new AlarmCondition(); + alarmCondition.setSpec(new SimpleAlarmConditionSpec()); + List condition = new ArrayList<>(); + AlarmConditionFilter alarmConditionFilter = new AlarmConditionFilter(); + alarmConditionFilter.setKey(new AlarmConditionFilterKey(AlarmConditionKeyType.ATTRIBUTE, "temperature")); + NumericFilterPredicate predicate = new NumericFilterPredicate(); + predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER); + predicate.setValue(new FilterPredicateValue<>(55.0)); + alarmConditionFilter.setPredicate(predicate); + alarmConditionFilter.setValueType(EntityKeyValueType.NUMERIC); + condition.add(alarmConditionFilter); + alarmCondition.setCondition(condition); + alarmRule.setCondition(alarmCondition); + deviceProfileAlarm.setClearRule(alarmRule); + TreeMap createRules = new TreeMap<>(); + createRules.put(AlarmSeverity.CRITICAL, alarmRule); + deviceProfileAlarm.setCreateRules(createRules); + alarms.add(deviceProfileAlarm); + profileData.setAlarms(alarms); + profileData.setProvisionConfiguration(new AllowCreateNewDevicesDeviceProfileProvisionConfiguration("123")); + } + + private void verifyEdgeConnectionAndInitialData() throws Exception { + Assert.assertTrue(edgeImitator.waitForMessages()); + + EdgeConfiguration configuration = edgeImitator.getConfiguration(); + Assert.assertNotNull(configuration); + + testAutoGeneratedCodeByProtobuf(configuration); + + Optional deviceUpdateMsgOpt = edgeImitator.findMessageByType(DeviceUpdateMsg.class); + Assert.assertTrue(deviceUpdateMsgOpt.isPresent()); + DeviceUpdateMsg deviceUpdateMsg = deviceUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + UUID deviceUUID = new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()); + Device device = doGet("/api/device/" + deviceUUID, Device.class); + Assert.assertNotNull(device); + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/devices?", + new TypeReference>() {}, new PageLink(100)).getData(); + Assert.assertTrue(edgeDevices.contains(device)); + + List deviceProfileUpdateMsgList = edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class); + Assert.assertEquals(3, deviceProfileUpdateMsgList.size()); + Optional deviceProfileUpdateMsgOpt = + deviceProfileUpdateMsgList.stream().filter(dfum -> THERMOSTAT_DEVICE_PROFILE_NAME.equals(dfum.getName())).findAny(); + Assert.assertTrue(deviceProfileUpdateMsgOpt.isPresent()); + DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); + UUID deviceProfileUUID = new UUID(deviceProfileUpdateMsg.getIdMSB(), deviceProfileUpdateMsg.getIdLSB()); + DeviceProfile deviceProfile = doGet("/api/deviceProfile/" + deviceProfileUUID, DeviceProfile.class); + Assert.assertNotNull(deviceProfile); + Assert.assertNotNull(deviceProfile.getProfileData()); + Assert.assertNotNull(deviceProfile.getProfileData().getAlarms()); + Assert.assertNotNull(deviceProfile.getProfileData().getAlarms().get(0).getClearRule()); + + testAutoGeneratedCodeByProtobuf(deviceProfileUpdateMsg); + + Optional assetUpdateMsgOpt = edgeImitator.findMessageByType(AssetUpdateMsg.class); + Assert.assertTrue(assetUpdateMsgOpt.isPresent()); + AssetUpdateMsg assetUpdateMsg = assetUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); + UUID assetUUID = new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB()); + Asset asset = doGet("/api/asset/" + assetUUID.toString(), Asset.class); + Assert.assertNotNull(asset); + List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/assets?", + new TypeReference>() {}, new PageLink(100)).getData(); + Assert.assertTrue(edgeAssets.contains(asset)); + + testAutoGeneratedCodeByProtobuf(assetUpdateMsg); + + Optional ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); + Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); + RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); + UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()); + RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID, RuleChain.class); + Assert.assertNotNull(ruleChain); + List edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/ruleChains?", + new TypeReference>() {}, new PageLink(100)).getData(); + Assert.assertTrue(edgeRuleChains.contains(ruleChain)); + + testAutoGeneratedCodeByProtobuf(ruleChainUpdateMsg); + + Optional ruleChainMetadataUpdateOpt = edgeImitator.findMessageByType(RuleChainMetadataUpdateMsg.class); + Assert.assertTrue(ruleChainMetadataUpdateOpt.isPresent()); + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = ruleChainMetadataUpdateOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainMetadataUpdateMsg.getMsgType()); + Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), ruleChainMetadataUpdateMsg.getRuleChainIdMSB()); + Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), ruleChainMetadataUpdateMsg.getRuleChainIdLSB()); + + validateAdminSettings(); + } + + private void validateAdminSettings() throws JsonProcessingException { + List adminSettingsUpdateMsgs = edgeImitator.findAllMessagesByType(AdminSettingsUpdateMsg.class); + Assert.assertEquals(4, adminSettingsUpdateMsgs.size()); + + for (AdminSettingsUpdateMsg adminSettingsUpdateMsg : adminSettingsUpdateMsgs) { + if (adminSettingsUpdateMsg.getKey().equals("mail")) { + validateMailAdminSettings(adminSettingsUpdateMsg); + } + if (adminSettingsUpdateMsg.getKey().equals("mailTemplates")) { + validateMailTemplatesAdminSettings(adminSettingsUpdateMsg); + } + } + } + + private void validateMailAdminSettings(AdminSettingsUpdateMsg adminSettingsUpdateMsg) throws JsonProcessingException { + JsonNode jsonNode = mapper.readTree(adminSettingsUpdateMsg.getJsonValue()); + Assert.assertNotNull(jsonNode.get("mailFrom")); + Assert.assertNotNull(jsonNode.get("smtpProtocol")); + Assert.assertNotNull(jsonNode.get("smtpHost")); + Assert.assertNotNull(jsonNode.get("smtpPort")); + Assert.assertNotNull(jsonNode.get("timeout")); + } + + private void validateMailTemplatesAdminSettings(AdminSettingsUpdateMsg adminSettingsUpdateMsg) throws JsonProcessingException { + JsonNode jsonNode = mapper.readTree(adminSettingsUpdateMsg.getJsonValue()); + Assert.assertNotNull(jsonNode.get("accountActivated")); + Assert.assertNotNull(jsonNode.get("accountLockout")); + Assert.assertNotNull(jsonNode.get("activation")); + Assert.assertNotNull(jsonNode.get("passwordWasReset")); + Assert.assertNotNull(jsonNode.get("resetPassword")); + Assert.assertNotNull(jsonNode.get("test")); + } + + protected Device saveDeviceOnCloudAndVerifyDeliveryToEdge() throws Exception { + // create ota package + edgeImitator.expectMessageAmount(1); + OtaPackageInfo firmwareOtaPackageInfo = saveOtaPackageInfo(thermostatDeviceProfile.getId()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + // create device and assign to edge + Device savedDevice = saveDevice(StringUtils.randomAlphanumeric(15), thermostatDeviceProfile.getName()); + edgeImitator.expectMessageAmount(1); + doPost("/api/edge/" + edge.getUuidId() + + "/device/" + savedDevice.getUuidId(), Device.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); + DeviceUpdateMsg deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB()); + + // update device + edgeImitator.expectMessageAmount(1); + savedDevice.setFirmwareId(firmwareOtaPackageInfo.getId()); + + DeviceData deviceData = new DeviceData(); + deviceData.setConfiguration(new DefaultDeviceConfiguration()); + MqttDeviceTransportConfiguration transportConfiguration = new MqttDeviceTransportConfiguration(); + transportConfiguration.getProperties().put("topic", "tb_rule_engine.thermostat"); + deviceData.setTransportConfiguration(transportConfiguration); + savedDevice.setDeviceData(deviceData); + + savedDevice = doPost("/api/device", savedDevice, Device.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); + deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB()); + Assert.assertEquals(savedDevice.getName(), deviceUpdateMsg.getName()); + Assert.assertEquals(savedDevice.getType(), deviceUpdateMsg.getType()); + Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getFirmwareIdMSB()); + Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getFirmwareIdLSB()); + Optional deviceDataOpt = + dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray()); + Assert.assertTrue(deviceDataOpt.isPresent()); + deviceData = deviceDataOpt.get(); + Assert.assertTrue(deviceData.getTransportConfiguration() instanceof MqttDeviceTransportConfiguration); + MqttDeviceTransportConfiguration mqttDeviceTransportConfiguration = + (MqttDeviceTransportConfiguration) deviceData.getTransportConfiguration(); + Assert.assertEquals("tb_rule_engine.thermostat", mqttDeviceTransportConfiguration.getProperties().get("topic")); + return savedDevice; + } + + protected Device findDeviceByName(String deviceName) throws Exception { + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/devices?", + new TypeReference>() { + }, new PageLink(100)).getData(); + Optional foundDevice = edgeDevices.stream().filter(d -> d.getName().equals(deviceName)).findAny(); + Assert.assertTrue(foundDevice.isPresent()); + Device device = foundDevice.get(); + Assert.assertEquals(deviceName, device.getName()); + return device; + } + + protected Asset findAssetByName(String assetName) throws Exception { + List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/assets?", + new TypeReference>() { + }, new PageLink(100)).getData(); + + Assert.assertEquals(1, edgeAssets.size()); + Asset asset = edgeAssets.get(0); + Assert.assertEquals(assetName, asset.getName()); + return asset; + } + + protected Device saveDevice(String deviceName, String type) { + Device device = new Device(); + device.setName(deviceName); + device.setType(type); + return doPost("/api/device", device, Device.class); + } + + protected Asset saveAsset(String assetName) throws Exception { + Asset asset = new Asset(); + asset.setName(assetName); + asset.setType("test"); + return doPost("/api/asset", asset, Asset.class); + } + + protected OtaPackageInfo saveOtaPackageInfo(DeviceProfileId deviceProfileId) { + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest(); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); + firmwareInfo.setTitle("Firmware Edge " + StringUtils.randomAlphanumeric(3)); + firmwareInfo.setVersion("v1.0"); + firmwareInfo.setTag("My firmware #1 v1.0"); + firmwareInfo.setUsesUrl(true); + firmwareInfo.setUrl("http://localhost:8080/v1/package"); + firmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode()); + firmwareInfo.setChecksumAlgorithm(ChecksumAlgorithm.SHA256); + return doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class); + } + + protected EdgeEvent constructEdgeEvent(TenantId tenantId, EdgeId edgeId, EdgeEventActionType edgeEventAction, + UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) { + EdgeEvent edgeEvent = new EdgeEvent(); + edgeEvent.setEdgeId(edgeId); + edgeEvent.setTenantId(tenantId); + edgeEvent.setAction(edgeEventAction); + edgeEvent.setEntityId(entityId); + edgeEvent.setType(edgeEventType); + edgeEvent.setBody(entityBody); + return edgeEvent; + } + + protected void testAutoGeneratedCodeByProtobuf(MessageLite.Builder builder) throws InvalidProtocolBufferException { + MessageLite source = builder.build(); + + testAutoGeneratedCodeByProtobuf(source); + + MessageLite target = source.getParserForType().parseFrom(source.toByteArray()); + builder.clear().mergeFrom(target); + } + + protected void testAutoGeneratedCodeByProtobuf(MessageLite source) throws InvalidProtocolBufferException { + MessageLite target = source.getParserForType().parseFrom(source.toByteArray()); + Assert.assertEquals(source, target); + Assert.assertEquals(source.hashCode(), target.hashCode()); + } + + + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseAlarmEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseAlarmEdgeTest.java new file mode 100644 index 0000000000..49784c3939 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseAlarmEdgeTest.java @@ -0,0 +1,136 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.alarm.AlarmInfo; +import org.thingsboard.server.common.data.alarm.AlarmSeverity; +import org.thingsboard.server.common.data.alarm.AlarmStatus; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; + +import java.util.List; +import java.util.Optional; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseAlarmEdgeTest extends AbstractEdgeTest { + + @Test + public void testSendAlarmToCloud() throws Exception { + Device device = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + AlarmUpdateMsg.Builder alarmUpdateMgBuilder = AlarmUpdateMsg.newBuilder(); + alarmUpdateMgBuilder.setName("alarm from edge"); + alarmUpdateMgBuilder.setStatus(AlarmStatus.ACTIVE_UNACK.name()); + alarmUpdateMgBuilder.setSeverity(AlarmSeverity.CRITICAL.name()); + alarmUpdateMgBuilder.setOriginatorName(device.getName()); + alarmUpdateMgBuilder.setOriginatorType(EntityType.DEVICE.name()); + testAutoGeneratedCodeByProtobuf(alarmUpdateMgBuilder); + uplinkMsgBuilder.addAlarmUpdateMsg(alarmUpdateMgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + + List alarms = doGetTypedWithPageLink("/api/alarm/{entityType}/{entityId}?", + new TypeReference>() {}, + new PageLink(100), device.getId().getEntityType().name(), device.getUuidId()) + .getData(); + Optional foundAlarm = alarms.stream().filter(alarm -> alarm.getType().equals("alarm from edge")).findAny(); + Assert.assertTrue(foundAlarm.isPresent()); + AlarmInfo alarmInfo = foundAlarm.get(); + Assert.assertEquals(device.getId(), alarmInfo.getOriginator()); + Assert.assertEquals(AlarmStatus.ACTIVE_UNACK, alarmInfo.getStatus()); + Assert.assertEquals(AlarmSeverity.CRITICAL, alarmInfo.getSeverity()); + } + + @Test + public void testAlarms() throws Exception { + // create alarm + edgeImitator.expectMessageAmount(1); + Device device = findDeviceByName("Edge Device 1"); + Alarm alarm = new Alarm(); + alarm.setOriginator(device.getId()); + alarm.setStatus(AlarmStatus.ACTIVE_UNACK); + alarm.setType("alarm"); + alarm.setSeverity(AlarmSeverity.CRITICAL); + Alarm savedAlarm = doPost("/api/alarm", alarm, Alarm.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); + AlarmUpdateMsg alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); + Assert.assertEquals(savedAlarm.getType(), alarmUpdateMsg.getType()); + Assert.assertEquals(savedAlarm.getName(), alarmUpdateMsg.getName()); + Assert.assertEquals(device.getName(), alarmUpdateMsg.getOriginatorName()); + Assert.assertEquals(savedAlarm.getStatus().name(), alarmUpdateMsg.getStatus()); + Assert.assertEquals(savedAlarm.getSeverity().name(), alarmUpdateMsg.getSeverity()); + + // ack alarm + edgeImitator.expectMessageAmount(1); + doPost("/api/alarm/" + savedAlarm.getUuidId() + "/ack"); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); + alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ALARM_ACK_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); + Assert.assertEquals(savedAlarm.getType(), alarmUpdateMsg.getType()); + Assert.assertEquals(savedAlarm.getName(), alarmUpdateMsg.getName()); + Assert.assertEquals(device.getName(), alarmUpdateMsg.getOriginatorName()); + Assert.assertEquals(AlarmStatus.ACTIVE_ACK.name(), alarmUpdateMsg.getStatus()); + + // clear alarm + 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()); + Assert.assertEquals(savedAlarm.getType(), alarmUpdateMsg.getType()); + Assert.assertEquals(savedAlarm.getName(), alarmUpdateMsg.getName()); + Assert.assertEquals(device.getName(), alarmUpdateMsg.getOriginatorName()); + Assert.assertEquals(AlarmStatus.CLEARED_ACK.name(), alarmUpdateMsg.getStatus()); + + // delete alarm + edgeImitator.expectMessageAmount(1); + doDelete("/api/alarm/" + savedAlarm.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); + alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); + Assert.assertEquals(savedAlarm.getType(), alarmUpdateMsg.getType()); + Assert.assertEquals(savedAlarm.getName(), alarmUpdateMsg.getName()); + Assert.assertEquals(device.getName(), alarmUpdateMsg.getOriginatorName()); + Assert.assertEquals(AlarmStatus.CLEARED_ACK.name(), alarmUpdateMsg.getStatus()); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseAssetEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseAssetEdgeTest.java new file mode 100644 index 0000000000..5bfd39cbd2 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseAssetEdgeTest.java @@ -0,0 +1,140 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; + +import java.util.UUID; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseAssetEdgeTest extends AbstractEdgeTest { + + @Test + public void testAssets() throws Exception { + // create asset and assign to edge + edgeImitator.expectMessageAmount(1); + Asset savedAsset = saveAsset("Edge Asset 2"); + doPost("/api/edge/" + edge.getUuidId() + + "/asset/" + savedAsset.getUuidId(), Asset.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); + AssetUpdateMsg assetUpdateMsg = (AssetUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); + Assert.assertEquals(savedAsset.getUuidId().getMostSignificantBits(), assetUpdateMsg.getIdMSB()); + Assert.assertEquals(savedAsset.getUuidId().getLeastSignificantBits(), assetUpdateMsg.getIdLSB()); + Assert.assertEquals(savedAsset.getName(), assetUpdateMsg.getName()); + Assert.assertEquals(savedAsset.getType(), assetUpdateMsg.getType()); + testAutoGeneratedCodeByProtobuf(assetUpdateMsg); + + // update asset + edgeImitator.expectMessageAmount(1); + savedAsset.setName("Edge Asset 2 Updated"); + savedAsset = doPost("/api/asset", savedAsset, Asset.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); + assetUpdateMsg = (AssetUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); + Assert.assertEquals(savedAsset.getName(), assetUpdateMsg.getName()); + + // unassign asset from edge + edgeImitator.expectMessageAmount(1); + doDelete("/api/edge/" + edge.getUuidId() + + "/asset/" + savedAsset.getUuidId(), Asset.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); + assetUpdateMsg = (AssetUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); + Assert.assertEquals(savedAsset.getUuidId().getMostSignificantBits(), assetUpdateMsg.getIdMSB()); + Assert.assertEquals(savedAsset.getUuidId().getLeastSignificantBits(), assetUpdateMsg.getIdLSB()); + + // delete asset - no messages expected + edgeImitator.expectMessageAmount(1); + doDelete("/api/asset/" + savedAsset.getUuidId()) + .andExpect(status().isOk()); + Assert.assertFalse(edgeImitator.waitForMessages(1)); + + // create asset #2 and assign to edge + edgeImitator.expectMessageAmount(1); + savedAsset = saveAsset("Edge Asset 3"); + doPost("/api/edge/" + edge.getUuidId() + + "/asset/" + savedAsset.getUuidId(), Asset.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); + assetUpdateMsg = (AssetUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); + Assert.assertEquals(savedAsset.getUuidId().getMostSignificantBits(), assetUpdateMsg.getIdMSB()); + Assert.assertEquals(savedAsset.getUuidId().getLeastSignificantBits(), assetUpdateMsg.getIdLSB()); + Assert.assertEquals(savedAsset.getName(), assetUpdateMsg.getName()); + Assert.assertEquals(savedAsset.getType(), assetUpdateMsg.getType()); + + // assign asset #2 to customer + edgeImitator.expectMessageAmount(1); + Customer customer = new Customer(); + customer.setTitle("Edge Customer"); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + + edgeImitator.expectMessageAmount(1); + doPost("/api/customer/" + savedCustomer.getUuidId() + + "/asset/" + savedAsset.getUuidId(), Asset.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); + assetUpdateMsg = (AssetUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); + Assert.assertEquals(savedCustomer.getUuidId().getMostSignificantBits(), assetUpdateMsg.getCustomerIdMSB()); + Assert.assertEquals(savedCustomer.getUuidId().getLeastSignificantBits(), assetUpdateMsg.getCustomerIdLSB()); + + // unassign asset #2 from customer + edgeImitator.expectMessageAmount(1); + doDelete("/api/customer/asset/" + savedAsset.getUuidId(), Asset.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); + assetUpdateMsg = (AssetUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); + Assert.assertEquals( + new CustomerId(EntityId.NULL_UUID), + new CustomerId(new UUID(assetUpdateMsg.getCustomerIdMSB(), assetUpdateMsg.getCustomerIdLSB()))); + + // delete asset #2 - messages expected + edgeImitator.expectMessageAmount(1); + doDelete("/api/asset/" + savedAsset.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); + assetUpdateMsg = (AssetUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); + Assert.assertEquals(savedAsset.getUuidId().getMostSignificantBits(), assetUpdateMsg.getIdMSB()); + Assert.assertEquals(savedAsset.getUuidId().getLeastSignificantBits(), assetUpdateMsg.getIdLSB()); + } + + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseCustomerEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseCustomerEdgeTest.java new file mode 100644 index 0000000000..33065894c1 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseCustomerEdgeTest.java @@ -0,0 +1,72 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseCustomerEdgeTest extends AbstractEdgeTest { + + @Test + public void testCreateUpdateDeleteCustomer() throws Exception { + // create customer + edgeImitator.expectMessageAmount(1); + Customer customer = new Customer(); + customer.setTitle("Edge Customer"); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); + CustomerUpdateMsg customerUpdateMsg = (CustomerUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, customerUpdateMsg.getMsgType()); + Assert.assertEquals(savedCustomer.getUuidId().getMostSignificantBits(), customerUpdateMsg.getIdMSB()); + Assert.assertEquals(savedCustomer.getUuidId().getLeastSignificantBits(), customerUpdateMsg.getIdLSB()); + Assert.assertEquals(savedCustomer.getTitle(), customerUpdateMsg.getTitle()); + testAutoGeneratedCodeByProtobuf(customerUpdateMsg); + + // update customer + edgeImitator.expectMessageAmount(1); + savedCustomer.setTitle("Edge Customer Updated"); + savedCustomer = doPost("/api/customer", savedCustomer, Customer.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); + customerUpdateMsg = (CustomerUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, customerUpdateMsg.getMsgType()); + Assert.assertEquals(savedCustomer.getUuidId().getMostSignificantBits(), customerUpdateMsg.getIdMSB()); + Assert.assertEquals(savedCustomer.getUuidId().getLeastSignificantBits(), customerUpdateMsg.getIdLSB()); + Assert.assertEquals(savedCustomer.getTitle(), customerUpdateMsg.getTitle()); + + // delete customer + edgeImitator.expectMessageAmount(1); + doDelete("/api/customer/" + savedCustomer.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); + customerUpdateMsg = (CustomerUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, customerUpdateMsg.getMsgType()); + Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits()); + Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseDashboardEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseDashboardEdgeTest.java new file mode 100644 index 0000000000..9553d22fdd --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseDashboardEdgeTest.java @@ -0,0 +1,147 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Test; +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.ShortCustomerInfo; +import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; + +import java.util.Set; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseDashboardEdgeTest extends AbstractEdgeTest { + + @Test + public void testDashboards() throws Exception { + // create dashboard and assign to edge + edgeImitator.expectMessageAmount(1); + Dashboard dashboard = new Dashboard(); + dashboard.setTitle("Edge Test Dashboard"); + Dashboard savedDashboard = doPost("/api/dashboard", dashboard, Dashboard.class); + doPost("/api/edge/" + edge.getUuidId() + + "/dashboard/" + savedDashboard.getUuidId(), Dashboard.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); + DashboardUpdateMsg dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); + Assert.assertEquals(savedDashboard.getUuidId().getMostSignificantBits(), dashboardUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDashboard.getUuidId().getLeastSignificantBits(), dashboardUpdateMsg.getIdLSB()); + Assert.assertEquals(savedDashboard.getTitle(), dashboardUpdateMsg.getTitle()); + testAutoGeneratedCodeByProtobuf(dashboardUpdateMsg); + + // update dashboard + edgeImitator.expectMessageAmount(1); + savedDashboard.setTitle("Updated Edge Test Dashboard"); + savedDashboard = doPost("/api/dashboard", savedDashboard, Dashboard.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); + dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); + Assert.assertEquals(savedDashboard.getTitle(), dashboardUpdateMsg.getTitle()); + + // unassign dashboard from edge + edgeImitator.expectMessageAmount(1); + doDelete("/api/edge/" + edge.getUuidId() + + "/dashboard/" + savedDashboard.getUuidId(), Dashboard.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); + dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); + Assert.assertEquals(savedDashboard.getUuidId().getMostSignificantBits(), dashboardUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDashboard.getUuidId().getLeastSignificantBits(), dashboardUpdateMsg.getIdLSB()); + + // delete dashboard - no messages expected + edgeImitator.expectMessageAmount(1); + doDelete("/api/dashboard/" + savedDashboard.getUuidId()) + .andExpect(status().isOk()); + Assert.assertFalse(edgeImitator.waitForMessages(1)); + + // create dashboard #2 and assign to edge + edgeImitator.expectMessageAmount(1); + dashboard = new Dashboard(); + dashboard.setTitle("Edge Test Dashboard #2"); + savedDashboard = doPost("/api/dashboard", dashboard, Dashboard.class); + doPost("/api/edge/" + edge.getUuidId() + + "/dashboard/" + savedDashboard.getUuidId(), Dashboard.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); + dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); + Assert.assertEquals(savedDashboard.getUuidId().getMostSignificantBits(), dashboardUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDashboard.getUuidId().getLeastSignificantBits(), dashboardUpdateMsg.getIdLSB()); + Assert.assertEquals(savedDashboard.getTitle(), dashboardUpdateMsg.getTitle()); + + // assign dashboard #2 to customer + edgeImitator.expectMessageAmount(1); + Customer customer = new Customer(); + customer.setTitle("Edge Customer"); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + + edgeImitator.expectMessageAmount(1); + doPost("/api/customer/" + savedCustomer.getUuidId() + + "/dashboard/" + savedDashboard.getUuidId(), Dashboard.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); + dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); + Set assignedCustomers = + JacksonUtil.fromString(dashboardUpdateMsg.getAssignedCustomers(), new TypeReference<>() {}); + Assert.assertNotNull(assignedCustomers); + Assert.assertFalse(assignedCustomers.isEmpty()); + Assert.assertTrue(assignedCustomers.contains(new ShortCustomerInfo(savedCustomer.getId(), customer.getTitle(), customer.isPublic()))); + + // unassign dashboard #2 from customer + edgeImitator.expectMessageAmount(1); + doDelete("/api/customer/" + savedCustomer.getUuidId() + + "/dashboard/" + savedDashboard.getUuidId(), Dashboard.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); + dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); + assignedCustomers = + JacksonUtil.fromString(dashboardUpdateMsg.getAssignedCustomers(), new TypeReference<>() {}); + Assert.assertNotNull(assignedCustomers); + Assert.assertTrue(assignedCustomers.isEmpty()); + + // delete dashboard #2 - messages expected + edgeImitator.expectMessageAmount(1); + doDelete("/api/dashboard/" + savedDashboard.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); + dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); + Assert.assertEquals(savedDashboard.getUuidId().getMostSignificantBits(), dashboardUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDashboard.getUuidId().getLeastSignificantBits(), dashboardUpdateMsg.getIdLSB()); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java new file mode 100644 index 0000000000..dafd3f31e6 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java @@ -0,0 +1,554 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.datastax.oss.driver.api.core.uuid.Uuids; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.gson.JsonObject; +import com.google.protobuf.AbstractMessage; +import org.awaitility.Awaitility; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.TenantProfile; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +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.transport.adaptor.JsonConverter; +import org.thingsboard.server.gen.edge.v1.AttributesRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg; +import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; +import org.thingsboard.server.gen.edge.v1.EntityDataProto; +import org.thingsboard.server.gen.edge.v1.RpcResponseMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; +import org.thingsboard.server.gen.edge.v1.UplinkResponseMsg; +import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; +import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.service.security.model.ChangePasswordRequest; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseDeviceEdgeTest extends AbstractEdgeTest { + + @Test + public void testDevices() throws Exception { + // create device and assign to edge; update device + Device savedDevice = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + + // unassign device from edge + edgeImitator.expectMessageAmount(1); + doDelete("/api/edge/" + edge.getUuidId() + + "/device/" + savedDevice.getUuidId(), Device.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); + DeviceUpdateMsg deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB()); + + // delete device - no messages expected + edgeImitator.expectMessageAmount(1); + doDelete("/api/device/" + savedDevice.getUuidId()) + .andExpect(status().isOk()); + Assert.assertFalse(edgeImitator.waitForMessages(1)); + + // create device #2 and assign to edge + edgeImitator.expectMessageAmount(1); + savedDevice = saveDevice("Edge Device 3", "Default"); + doPost("/api/edge/" + edge.getUuidId() + + "/device/" + savedDevice.getUuidId(), Device.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); + deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB()); + Assert.assertEquals(savedDevice.getName(), deviceUpdateMsg.getName()); + Assert.assertEquals(savedDevice.getType(), deviceUpdateMsg.getType()); + + // assign device #2 to customer + edgeImitator.expectMessageAmount(1); + Customer customer = new Customer(); + customer.setTitle("Edge Customer"); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + + edgeImitator.expectMessageAmount(1); + doPost("/api/customer/" + savedCustomer.getUuidId() + + "/device/" + savedDevice.getUuidId(), Device.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); + deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + Assert.assertEquals(savedCustomer.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getCustomerIdMSB()); + Assert.assertEquals(savedCustomer.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getCustomerIdLSB()); + + // unassign device #2 from customer + edgeImitator.expectMessageAmount(1); + doDelete("/api/customer/device/" + savedDevice.getUuidId(), Device.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); + deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + Assert.assertEquals( + new CustomerId(EntityId.NULL_UUID), + new CustomerId(new UUID(deviceUpdateMsg.getCustomerIdMSB(), deviceUpdateMsg.getCustomerIdLSB()))); + + // delete device #2 - messages expected + edgeImitator.expectMessageAmount(1); + doDelete("/api/device/" + savedDevice.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); + deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB()); + + } + + + @Test + public void testUpdateDeviceCredentials() throws Exception { + // create device and assign to edge; update device + Device savedDevice = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + + // @TODO: update device credentials +// edgeImitator.expectMessageAmount(1); +// Assert.assertTrue(edgeImitator.waitForMessages()); +// AbstractMessage latestMessage = edgeImitator.getLatestMessage(); +// Assert.assertTrue(latestMessage instanceof DeviceCredentialsUpdateMsg); +// DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = (DeviceCredentialsUpdateMsg) latestMessage; + } + + @Test + public void testDeviceReachedMaximumAllowedOnCloud() throws Exception { + // update tenant profile configuration + loginSysAdmin(); + TenantProfile tenantProfile = doGet("/api/tenantProfile/" + savedTenant.getTenantProfileId().getId(), TenantProfile.class); + DefaultTenantProfileConfiguration profileConfiguration = + (DefaultTenantProfileConfiguration) tenantProfile.getProfileData().getConfiguration(); + profileConfiguration.setMaxDevices(1); + tenantProfile.getProfileData().setConfiguration(profileConfiguration); + doPost("/api/tenantProfile/", tenantProfile, TenantProfile.class); + + loginTenantAdmin(); + + UUID uuid = Uuids.timeBased(); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceUpdateMsg.Builder deviceUpdateMsgBuilder = DeviceUpdateMsg.newBuilder(); + deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits()); + deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits()); + deviceUpdateMsgBuilder.setName("Edge Device"); + deviceUpdateMsgBuilder.setType("default"); + deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); + uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); + + edgeImitator.expectResponsesAmount(1); + + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + + Assert.assertTrue(edgeImitator.waitForResponses()); + + UplinkResponseMsg latestResponseMsg = edgeImitator.getLatestResponseMsg(); + Assert.assertTrue(latestResponseMsg.getSuccess()); + } + + @Test + public void testSendDeviceRpcResponseToCloud() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceRpcCallMsg.Builder deviceRpcCallResponseBuilder = DeviceRpcCallMsg.newBuilder(); + deviceRpcCallResponseBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); + deviceRpcCallResponseBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); + deviceRpcCallResponseBuilder.setOneway(true); + deviceRpcCallResponseBuilder.setRequestId(0); + deviceRpcCallResponseBuilder.setExpirationTime(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10)); + RpcResponseMsg.Builder responseBuilder = + RpcResponseMsg.newBuilder().setResponse("{}"); + testAutoGeneratedCodeByProtobuf(responseBuilder); + + deviceRpcCallResponseBuilder.setResponseMsg(responseBuilder.build()); + testAutoGeneratedCodeByProtobuf(deviceRpcCallResponseBuilder); + + uplinkMsgBuilder.addDeviceRpcCallMsg(deviceRpcCallResponseBuilder.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + } + + @Test + public void testSendDeviceCredentialsUpdateToCloud() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceCredentialsUpdateMsg.Builder deviceCredentialsUpdateMsgBuilder = DeviceCredentialsUpdateMsg.newBuilder(); + deviceCredentialsUpdateMsgBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); + deviceCredentialsUpdateMsgBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); + deviceCredentialsUpdateMsgBuilder.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN.name()); + deviceCredentialsUpdateMsgBuilder.setCredentialsId("NEW_TOKEN"); + testAutoGeneratedCodeByProtobuf(deviceCredentialsUpdateMsgBuilder); + uplinkMsgBuilder.addDeviceCredentialsUpdateMsg(deviceCredentialsUpdateMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + } + + + @Test + public void testSendDeviceCredentialsRequestToCloud() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + DeviceCredentials deviceCredentials = doGet("/api/device/" + device.getUuidId() + "/credentials", DeviceCredentials.class); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceCredentialsRequestMsg.Builder deviceCredentialsRequestMsgBuilder = DeviceCredentialsRequestMsg.newBuilder(); + deviceCredentialsRequestMsgBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); + deviceCredentialsRequestMsgBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(deviceCredentialsRequestMsgBuilder); + uplinkMsgBuilder.addDeviceCredentialsRequestMsg(deviceCredentialsRequestMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceCredentialsUpdateMsg); + DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = (DeviceCredentialsUpdateMsg) latestMessage; + Assert.assertEquals(deviceCredentialsUpdateMsg.getDeviceIdMSB(), device.getUuidId().getMostSignificantBits()); + Assert.assertEquals(deviceCredentialsUpdateMsg.getDeviceIdLSB(), device.getUuidId().getLeastSignificantBits()); + Assert.assertEquals(deviceCredentialsUpdateMsg.getCredentialsType(), deviceCredentials.getCredentialsType().name()); + Assert.assertEquals(deviceCredentialsUpdateMsg.getCredentialsId(), deviceCredentials.getCredentialsId()); + } + + @Test + public void testSendAttributesRequestToCloud() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + sendAttributesRequestAndVerify(device, DataConstants.SERVER_SCOPE, "{\"key1\":\"value1\"}", + "key1", "value1"); + sendAttributesRequestAndVerify(device, DataConstants.SHARED_SCOPE, "{\"key2\":\"value2\"}", + "key2", "value2"); + } + + + @Test + public void testSendDeleteDeviceOnEdgeToCloud() throws Exception { + Device device = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + UplinkMsg.Builder upLinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceUpdateMsg.Builder deviceDeleteMsgBuilder = DeviceUpdateMsg.newBuilder(); + deviceDeleteMsgBuilder.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE); + deviceDeleteMsgBuilder.setIdMSB(device.getId().getId().getMostSignificantBits()); + deviceDeleteMsgBuilder.setIdLSB(device.getId().getId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(deviceDeleteMsgBuilder); + + upLinkMsgBuilder.addDeviceUpdateMsg(deviceDeleteMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(upLinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(upLinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + device = doGet("/api/device/" + device.getUuidId(), Device.class); + Assert.assertNotNull(device); + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/devices?", + new TypeReference>() { + }, new PageLink(100)).getData(); + Assert.assertFalse(edgeDevices.contains(device)); + } + + @Test + public void testSendTelemetryToCloud() throws Exception { + Device device = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + + edgeImitator.expectResponsesAmount(2); + + JsonObject data = new JsonObject(); + String timeseriesKey = "key"; + String timeseriesValue = "25"; + data.addProperty(timeseriesKey, timeseriesValue); + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + EntityDataProto.Builder entityDataBuilder = EntityDataProto.newBuilder(); + entityDataBuilder.setPostTelemetryMsg(JsonConverter.convertToTelemetryProto(data, System.currentTimeMillis())); + entityDataBuilder.setEntityType(device.getId().getEntityType().name()); + entityDataBuilder.setEntityIdMSB(device.getUuidId().getMostSignificantBits()); + entityDataBuilder.setEntityIdLSB(device.getUuidId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(entityDataBuilder); + uplinkMsgBuilder.addEntityData(entityDataBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + + JsonObject attributesData = new JsonObject(); + String attributesKey = "test_attr"; + String attributesValue = "test_value"; + attributesData.addProperty(attributesKey, attributesValue); + UplinkMsg.Builder uplinkMsgBuilder2 = UplinkMsg.newBuilder(); + EntityDataProto.Builder entityDataBuilder2 = EntityDataProto.newBuilder(); + entityDataBuilder2.setEntityType(device.getId().getEntityType().name()); + entityDataBuilder2.setEntityIdMSB(device.getId().getId().getMostSignificantBits()); + entityDataBuilder2.setEntityIdLSB(device.getId().getId().getLeastSignificantBits()); + entityDataBuilder2.setAttributesUpdatedMsg(JsonConverter.convertToAttributesProto(attributesData)); + entityDataBuilder2.setPostAttributeScope(DataConstants.SERVER_SCOPE); + testAutoGeneratedCodeByProtobuf(entityDataBuilder2); + + uplinkMsgBuilder2.addEntityData(entityDataBuilder2.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder2); + + edgeImitator.sendUplinkMsg(uplinkMsgBuilder2.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + + Awaitility.await() + .atMost(2, TimeUnit.SECONDS) + .until(() -> loadDeviceTimeseries(device, timeseriesKey).containsKey(timeseriesKey)); + + Map>> timeseries = loadDeviceTimeseries(device, timeseriesKey); + Assert.assertTrue(timeseries.containsKey(timeseriesKey)); + Assert.assertEquals(1, timeseries.get(timeseriesKey).size()); + Assert.assertEquals(timeseriesValue, timeseries.get(timeseriesKey).get(0).get("value")); + + String attributeValuesUrl = "/api/plugins/telemetry/DEVICE/" + device.getId() + "/values/attributes/" + DataConstants.SERVER_SCOPE; + List> attributes = doGetAsyncTyped(attributeValuesUrl, new TypeReference<>() {}); + + Assert.assertEquals(3, attributes.size()); + + Optional> activeAttributeOpt = getAttributeByKey("active", attributes); + Assert.assertTrue(activeAttributeOpt.isPresent()); + Map activeAttribute = activeAttributeOpt.get(); + Assert.assertEquals("true", activeAttribute.get("value")); + + Optional> customAttributeOpt = getAttributeByKey(attributesKey, attributes); + Assert.assertTrue(customAttributeOpt.isPresent()); + Map customAttribute = customAttributeOpt.get(); + Assert.assertEquals(attributesValue, customAttribute.get("value")); + + doDelete("/api/plugins/telemetry/DEVICE/" + device.getId().getId() + "/SERVER_SCOPE?keys=" + attributesKey, String.class); + } + + @Test + public void testSendDeviceToCloudWithNameThatAlreadyExistsOnCloud() throws Exception { + String deviceOnCloudName = StringUtils.randomAlphanumeric(15); + Device deviceOnCloud = saveDevice(deviceOnCloudName, "Default"); + + UUID uuid = Uuids.timeBased(); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceUpdateMsg.Builder deviceUpdateMsgBuilder = DeviceUpdateMsg.newBuilder(); + deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits()); + deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits()); + deviceUpdateMsgBuilder.setName(deviceOnCloudName); + deviceUpdateMsgBuilder.setType("test"); + deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); + testAutoGeneratedCodeByProtobuf(deviceUpdateMsgBuilder); + uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(2); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getMessageFromTail(2); + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); + DeviceUpdateMsg latestDeviceUpdateMsg = (DeviceUpdateMsg) latestMessage; + Assert.assertNotEquals(deviceOnCloudName, latestDeviceUpdateMsg.getName()); + Assert.assertEquals(deviceOnCloudName, latestDeviceUpdateMsg.getConflictName()); + + UUID newDeviceId = new UUID(latestDeviceUpdateMsg.getIdMSB(), latestDeviceUpdateMsg.getIdLSB()); + + Assert.assertNotEquals(deviceOnCloud.getId().getId(), newDeviceId); + + Device device = doGet("/api/device/" + newDeviceId, Device.class); + Assert.assertNotNull(device); + Assert.assertNotEquals(deviceOnCloudName, device.getName()); + + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceCredentialsRequestMsg); + DeviceCredentialsRequestMsg latestDeviceCredentialsRequestMsg = (DeviceCredentialsRequestMsg) latestMessage; + Assert.assertEquals(uuid.getMostSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdMSB()); + Assert.assertEquals(uuid.getLeastSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); + + newDeviceId = new UUID(latestDeviceCredentialsRequestMsg.getDeviceIdMSB(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); + + device = doGet("/api/device/" + newDeviceId, Device.class); + Assert.assertNotNull(device); + Assert.assertNotEquals(deviceOnCloudName, device.getName()); + } + + @Test + public void testSendDeviceToCloud() throws Exception { + UUID uuid = Uuids.timeBased(); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceUpdateMsg.Builder deviceUpdateMsgBuilder = DeviceUpdateMsg.newBuilder(); + deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits()); + deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits()); + deviceUpdateMsgBuilder.setName("Edge Device 2"); + deviceUpdateMsgBuilder.setType("test"); + deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); + testAutoGeneratedCodeByProtobuf(deviceUpdateMsgBuilder); + uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceCredentialsRequestMsg); + DeviceCredentialsRequestMsg latestDeviceCredentialsRequestMsg = (DeviceCredentialsRequestMsg) latestMessage; + Assert.assertEquals(uuid.getMostSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdMSB()); + Assert.assertEquals(uuid.getLeastSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); + + UUID newDeviceId = new UUID(latestDeviceCredentialsRequestMsg.getDeviceIdMSB(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); + + Device device = doGet("/api/device/" + newDeviceId, Device.class); + Assert.assertNotNull(device); + Assert.assertEquals("Edge Device 2", device.getName()); + } + + + @Test + public void testRpcCall() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + ObjectNode body = mapper.createObjectNode(); + body.put("requestId", new Random().nextInt()); + body.put("requestUUID", Uuids.timeBased().toString()); + body.put("oneway", false); + body.put("expirationTime", System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10)); + body.put("method", "test_method"); + body.put("params", "{\"param1\":\"value1\"}"); + + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body); + edgeImitator.expectMessageAmount(1); + edgeEventService.saveAsync(edgeEvent).get(); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceRpcCallMsg); + DeviceRpcCallMsg latestDeviceRpcCallMsg = (DeviceRpcCallMsg) latestMessage; + Assert.assertEquals("test_method", latestDeviceRpcCallMsg.getRequestMsg().getMethod()); + } + + private void sendAttributesRequestAndVerify(Device device, String scope, String attributesDataStr, String expectedKey, + String expectedValue) throws Exception { + JsonNode attributesData = mapper.readTree(attributesDataStr); + + doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/attributes/" + scope, + attributesData); + + // Wait before device attributes saved to database before requesting them from edge + Awaitility.await() + .atMost(10, TimeUnit.SECONDS) + .until(() -> { + String urlTemplate = "/api/plugins/telemetry/DEVICE/" + device.getId() + "/keys/attributes/" + scope; + List actualKeys = doGetAsyncTyped(urlTemplate, new TypeReference<>() {}); + return actualKeys != null && !actualKeys.isEmpty() && actualKeys.contains(expectedKey); + }); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + AttributesRequestMsg.Builder attributesRequestMsgBuilder = AttributesRequestMsg.newBuilder(); + attributesRequestMsgBuilder.setEntityIdMSB(device.getUuidId().getMostSignificantBits()); + attributesRequestMsgBuilder.setEntityIdLSB(device.getUuidId().getLeastSignificantBits()); + attributesRequestMsgBuilder.setEntityType(EntityType.DEVICE.name()); + attributesRequestMsgBuilder.setScope(scope); + testAutoGeneratedCodeByProtobuf(attributesRequestMsgBuilder); + uplinkMsgBuilder.addAttributesRequestMsg(attributesRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityDataProto); + EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); + Assert.assertEquals(scope, latestEntityDataMsg.getPostAttributeScope()); + Assert.assertTrue(latestEntityDataMsg.hasAttributesUpdatedMsg()); + + TransportProtos.PostAttributeMsg attributesUpdatedMsg = latestEntityDataMsg.getAttributesUpdatedMsg(); + + boolean found = false; + for (TransportProtos.KeyValueProto keyValueProto : attributesUpdatedMsg.getKvList()) { + if (keyValueProto.getKey().equals(expectedKey)) { + Assert.assertEquals(expectedKey, keyValueProto.getKey()); + Assert.assertEquals(expectedValue, keyValueProto.getStringV()); + found = true; + } + } + Assert.assertTrue("Expected key and value must be found", found); + } + + private Optional> getAttributeByKey(String key, List> attributes) { + return attributes.stream().filter(kv -> kv.get("key").equals(key)).findFirst(); + } + + private Map>> loadDeviceTimeseries(Device device, String timeseriesKey) throws Exception { + return doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/values/timeseries?keys=" + timeseriesKey, + new TypeReference<>() {}); + } +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseDeviceProfileEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceProfileEdgeTest.java new file mode 100644 index 0000000000..d0f0f48477 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceProfileEdgeTest.java @@ -0,0 +1,319 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.DeviceTransportType; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.device.data.PowerMode; +import org.thingsboard.server.common.data.device.data.PowerSavingConfiguration; +import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration; +import org.thingsboard.server.common.data.device.profile.DefaultCoapDeviceTypeConfiguration; +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; +import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; +import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; +import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.OtherConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryMappingConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.AbstractLwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.NoSecLwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.kv.DataType; +import org.thingsboard.server.common.data.transport.snmp.SnmpMapping; +import org.thingsboard.server.common.data.transport.snmp.config.SnmpCommunicationConfig; +import org.thingsboard.server.common.data.transport.snmp.config.impl.TelemetryQueryingSnmpCommunicationConfig; +import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.transport.AbstractTransportIntegrationTest; +import org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseDeviceProfileEdgeTest extends AbstractEdgeTest { + + @Test + public void testDeviceProfiles() throws Exception { + // create device profile + DeviceProfile deviceProfile = this.createDeviceProfile("ONE_MORE_DEVICE_PROFILE", null); + extendDeviceProfileData(deviceProfile); + edgeImitator.expectMessageAmount(1); + deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); + DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); + Assert.assertEquals(deviceProfile.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getIdMSB()); + Assert.assertEquals(deviceProfile.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getIdLSB()); + + // update device profile + OtaPackageInfo firmwareOtaPackageInfo = saveOtaPackageInfo(deviceProfile.getId()); + edgeImitator.expectMessageAmount(1); + Assert.assertTrue(edgeImitator.waitForMessages()); + + deviceProfile.setFirmwareId(firmwareOtaPackageInfo.getId()); + edgeImitator.expectMessageAmount(1); + deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); + deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; + Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getFirmwareIdMSB()); + Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getFirmwareIdLSB()); + + // delete profile + edgeImitator.expectMessageAmount(1); + doDelete("/api/deviceProfile/" + deviceProfile.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); + deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); + Assert.assertEquals(deviceProfile.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getIdMSB()); + Assert.assertEquals(deviceProfile.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getIdLSB()); + } + + @Test + public void testDeviceProfiles_snmp() throws Exception { + DeviceProfile deviceProfile = createDeviceProfileAndDoBasicAssert("SNMP", createSnmpDeviceProfileTransportConfiguration()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); + DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); + Assert.assertEquals(deviceProfile.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getIdMSB()); + Assert.assertEquals(deviceProfile.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getIdLSB()); + Assert.assertEquals(DeviceTransportType.SNMP.name(), deviceProfileUpdateMsg.getTransportType()); + + Optional deviceProfileDataOpt = + dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray()); + + Assert.assertTrue(deviceProfileDataOpt.isPresent()); + DeviceProfileData deviceProfileData = deviceProfileDataOpt.get(); + + Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof SnmpDeviceProfileTransportConfiguration); + SnmpDeviceProfileTransportConfiguration transportConfiguration = + (SnmpDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration(); + Assert.assertEquals(Integer.valueOf(1000), transportConfiguration.getTimeoutMs()); + Assert.assertEquals(Integer.valueOf(3), transportConfiguration.getRetries()); + + Assert.assertFalse(transportConfiguration.getCommunicationConfigs().isEmpty()); + SnmpCommunicationConfig communicationConfig = transportConfiguration.getCommunicationConfigs().get(0); + Assert.assertTrue(communicationConfig instanceof TelemetryQueryingSnmpCommunicationConfig); + TelemetryQueryingSnmpCommunicationConfig snmpCommunicationConfig = + (TelemetryQueryingSnmpCommunicationConfig) communicationConfig; + + Assert.assertEquals(Long.valueOf(500L), snmpCommunicationConfig.getQueryingFrequencyMs()); + Assert.assertFalse(snmpCommunicationConfig.getMappings().isEmpty()); + + SnmpMapping snmpMapping = snmpCommunicationConfig.getMappings().get(0); + Assert.assertEquals("temperature", snmpMapping.getKey()); + Assert.assertEquals("1.3.3.5.6.7.8.9.1", snmpMapping.getOid()); + Assert.assertEquals(DataType.DOUBLE, snmpMapping.getDataType()); + + removeDeviceProfileAndDoBasicAssert(deviceProfile); + } + + @Test + public void testDeviceProfiles_lwm2m() throws Exception { + DeviceProfile deviceProfile = createDeviceProfileAndDoBasicAssert("LWM2M", createLwm2mDeviceProfileTransportConfiguration()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); + DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); + Assert.assertEquals(deviceProfile.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getIdMSB()); + Assert.assertEquals(deviceProfile.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getIdLSB()); + Assert.assertEquals(DeviceTransportType.LWM2M.name(), deviceProfileUpdateMsg.getTransportType()); + + Optional deviceProfileDataOpt = + dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray()); + + Assert.assertTrue(deviceProfileDataOpt.isPresent()); + DeviceProfileData deviceProfileData = deviceProfileDataOpt.get(); + + Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof Lwm2mDeviceProfileTransportConfiguration); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = + (Lwm2mDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration(); + + OtherConfiguration clientLwM2mSettings = transportConfiguration.getClientLwM2mSettings(); + Assert.assertEquals(PowerMode.DRX, clientLwM2mSettings.getPowerMode()); + Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getFwUpdateStrategy()); + Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getSwUpdateStrategy()); + Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getClientOnlyObserveAfterConnect()); + + Assert.assertTrue(transportConfiguration.isBootstrapServerUpdateEnable()); + + Assert.assertFalse(transportConfiguration.getBootstrap().isEmpty()); + LwM2MBootstrapServerCredential lwM2MBootstrapServerCredential = transportConfiguration.getBootstrap().get(0); + Assert.assertTrue(lwM2MBootstrapServerCredential instanceof NoSecLwM2MBootstrapServerCredential); + NoSecLwM2MBootstrapServerCredential noSecLwM2MBootstrapServerCredential = (NoSecLwM2MBootstrapServerCredential) lwM2MBootstrapServerCredential; + + Assert.assertEquals("PUBLIC_KEY", noSecLwM2MBootstrapServerCredential.getServerPublicKey()); + Assert.assertEquals(Integer.valueOf(123), noSecLwM2MBootstrapServerCredential.getShortServerId()); + Assert.assertTrue(noSecLwM2MBootstrapServerCredential.isBootstrapServerIs()); + Assert.assertEquals("localhost", noSecLwM2MBootstrapServerCredential.getHost()); + Assert.assertEquals(Integer.valueOf(5687), noSecLwM2MBootstrapServerCredential.getPort()); + + TelemetryMappingConfiguration observeAttr = transportConfiguration.getObserveAttr(); + Assert.assertEquals("batteryLevel", observeAttr.getKeyName().get("/3_1.0/0/9")); + Assert.assertTrue(observeAttr.getObserve().isEmpty()); + Assert.assertTrue(observeAttr.getAttribute().isEmpty()); + Assert.assertFalse(observeAttr.getTelemetry().isEmpty()); + Assert.assertTrue(observeAttr.getTelemetry().contains("/3_1.0/0/9")); + Assert.assertTrue(observeAttr.getAttributeLwm2m().isEmpty()); + + removeDeviceProfileAndDoBasicAssert(deviceProfile); + } + + @Test + public void testDeviceProfiles_coap() throws Exception { + DeviceProfile deviceProfile = createDeviceProfileAndDoBasicAssert("COAP", createCoapDeviceProfileTransportConfiguration()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); + DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); + Assert.assertEquals(deviceProfile.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getIdMSB()); + Assert.assertEquals(deviceProfile.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getIdLSB()); + Assert.assertEquals(DeviceTransportType.COAP.name(), deviceProfileUpdateMsg.getTransportType()); + + Optional deviceProfileDataOpt = + dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray()); + + Assert.assertTrue(deviceProfileDataOpt.isPresent()); + DeviceProfileData deviceProfileData = deviceProfileDataOpt.get(); + + Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof CoapDeviceProfileTransportConfiguration); + CoapDeviceProfileTransportConfiguration transportConfiguration = + (CoapDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration(); + + PowerSavingConfiguration clientSettings = transportConfiguration.getClientSettings(); + + Assert.assertEquals(PowerMode.DRX, clientSettings.getPowerMode()); + Assert.assertEquals(Long.valueOf(1L), clientSettings.getEdrxCycle()); + Assert.assertEquals(Long.valueOf(1L), clientSettings.getPsmActivityTimer()); + Assert.assertEquals(Long.valueOf(1L), clientSettings.getPagingTransmissionWindow()); + + Assert.assertTrue(transportConfiguration.getCoapDeviceTypeConfiguration() instanceof DefaultCoapDeviceTypeConfiguration); + DefaultCoapDeviceTypeConfiguration coapDeviceTypeConfiguration = + (DefaultCoapDeviceTypeConfiguration) transportConfiguration.getCoapDeviceTypeConfiguration(); + + Assert.assertTrue(coapDeviceTypeConfiguration.getTransportPayloadTypeConfiguration() instanceof ProtoTransportPayloadConfiguration); + + ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = + (ProtoTransportPayloadConfiguration) coapDeviceTypeConfiguration.getTransportPayloadTypeConfiguration(); + + Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_TELEMETRY_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceTelemetryProtoSchema()); + Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_ATTRIBUTES_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceAttributesProtoSchema()); + Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_RPC_RESPONSE_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceRpcResponseProtoSchema()); + Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_RPC_REQUEST_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceRpcRequestProtoSchema()); + + removeDeviceProfileAndDoBasicAssert(deviceProfile); + } + + + private DeviceProfile createDeviceProfileAndDoBasicAssert(String deviceProfileName, DeviceProfileTransportConfiguration deviceProfileTransportConfiguration) throws Exception { + DeviceProfile deviceProfile = this.createDeviceProfile(deviceProfileName, deviceProfileTransportConfiguration); + extendDeviceProfileData(deviceProfile); + edgeImitator.expectMessageAmount(1); + deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + return deviceProfile; + } + + private void removeDeviceProfileAndDoBasicAssert(DeviceProfile deviceProfile) throws Exception { + edgeImitator.expectMessageAmount(1); + doDelete("/api/deviceProfile/" + deviceProfile.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); + DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); + Assert.assertEquals(deviceProfile.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getIdMSB()); + Assert.assertEquals(deviceProfile.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getIdLSB()); + } + + private SnmpDeviceProfileTransportConfiguration createSnmpDeviceProfileTransportConfiguration() { + SnmpDeviceProfileTransportConfiguration transportConfiguration = new SnmpDeviceProfileTransportConfiguration(); + List communicationConfigs = new ArrayList<>(); + TelemetryQueryingSnmpCommunicationConfig communicationConfig = new TelemetryQueryingSnmpCommunicationConfig(); + communicationConfig.setQueryingFrequencyMs(500L); + List mappings = new ArrayList<>(); + mappings.add(new SnmpMapping("1.3.3.5.6.7.8.9.1", "temperature", DataType.DOUBLE)); + communicationConfig.setMappings(mappings); + communicationConfigs.add(communicationConfig); + transportConfiguration.setCommunicationConfigs(communicationConfigs); + transportConfiguration.setTimeoutMs(1000); + transportConfiguration.setRetries(3); + return transportConfiguration; + } + + private Lwm2mDeviceProfileTransportConfiguration createLwm2mDeviceProfileTransportConfiguration() { + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = new Lwm2mDeviceProfileTransportConfiguration(); + + OtherConfiguration clientLwM2mSettings = JacksonUtil.fromString(AbstractLwM2MIntegrationTest.CLIENT_LWM2M_SETTINGS, OtherConfiguration.class); + transportConfiguration.setClientLwM2mSettings(clientLwM2mSettings); + + transportConfiguration.setBootstrapServerUpdateEnable(true); + + TelemetryMappingConfiguration observeAttrConfiguration = + JacksonUtil.fromString(AbstractLwM2MIntegrationTest.OBSERVE_ATTRIBUTES_WITH_PARAMS, TelemetryMappingConfiguration.class); + transportConfiguration.setObserveAttr(observeAttrConfiguration); + + List bootstrap = new ArrayList<>(); + AbstractLwM2MBootstrapServerCredential bootstrapServerCredential = new NoSecLwM2MBootstrapServerCredential(); + bootstrapServerCredential.setServerPublicKey("PUBLIC_KEY"); + bootstrapServerCredential.setShortServerId(123); + bootstrapServerCredential.setBootstrapServerIs(true); + bootstrapServerCredential.setHost("localhost"); + bootstrapServerCredential.setPort(5687); + bootstrap.add(bootstrapServerCredential); + transportConfiguration.setBootstrap(bootstrap); + + return transportConfiguration; + } + + private CoapDeviceProfileTransportConfiguration createCoapDeviceProfileTransportConfiguration() { + CoapDeviceProfileTransportConfiguration transportConfiguration = new CoapDeviceProfileTransportConfiguration(); + PowerSavingConfiguration clientSettings = new PowerSavingConfiguration(); + clientSettings.setPowerMode(PowerMode.DRX); + clientSettings.setEdrxCycle(1L); + clientSettings.setPsmActivityTimer(1L); + clientSettings.setPagingTransmissionWindow(1L); + transportConfiguration.setClientSettings(clientSettings); + DefaultCoapDeviceTypeConfiguration coapDeviceTypeConfiguration = new DefaultCoapDeviceTypeConfiguration(); + ProtoTransportPayloadConfiguration transportPayloadTypeConfiguration = new ProtoTransportPayloadConfiguration(); + transportPayloadTypeConfiguration.setDeviceTelemetryProtoSchema(AbstractTransportIntegrationTest.DEVICE_TELEMETRY_PROTO_SCHEMA); + transportPayloadTypeConfiguration.setDeviceAttributesProtoSchema(AbstractTransportIntegrationTest.DEVICE_ATTRIBUTES_PROTO_SCHEMA); + transportPayloadTypeConfiguration.setDeviceRpcResponseProtoSchema(AbstractTransportIntegrationTest.DEVICE_RPC_RESPONSE_PROTO_SCHEMA); + transportPayloadTypeConfiguration.setDeviceRpcRequestProtoSchema(AbstractTransportIntegrationTest.DEVICE_RPC_REQUEST_PROTO_SCHEMA); + coapDeviceTypeConfiguration.setTransportPayloadTypeConfiguration(transportPayloadTypeConfiguration); + transportConfiguration.setCoapDeviceTypeConfiguration(coapDeviceTypeConfiguration); + return transportConfiguration; + } +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java deleted file mode 100644 index dcd354ace5..0000000000 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ /dev/null @@ -1,2280 +0,0 @@ -/** - * Copyright © 2016-2022 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.edge; - -import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.gson.JsonObject; -import com.google.protobuf.AbstractMessage; -import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.MessageLite; -import org.awaitility.Awaitility; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.cluster.TbClusterService; -import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.Dashboard; -import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.DeviceTransportType; -import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.EntityView; -import org.thingsboard.server.common.data.OtaPackageInfo; -import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; -import org.thingsboard.server.common.data.StringUtils; -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.alarm.Alarm; -import org.thingsboard.server.common.data.alarm.AlarmInfo; -import org.thingsboard.server.common.data.alarm.AlarmSeverity; -import org.thingsboard.server.common.data.alarm.AlarmStatus; -import org.thingsboard.server.common.data.asset.Asset; -import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration; -import org.thingsboard.server.common.data.device.data.DeviceData; -import org.thingsboard.server.common.data.device.data.MqttDeviceTransportConfiguration; -import org.thingsboard.server.common.data.device.data.PowerMode; -import org.thingsboard.server.common.data.device.data.PowerSavingConfiguration; -import org.thingsboard.server.common.data.device.profile.AlarmCondition; -import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter; -import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey; -import org.thingsboard.server.common.data.device.profile.AlarmConditionKeyType; -import org.thingsboard.server.common.data.device.profile.AlarmRule; -import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration; -import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration; -import org.thingsboard.server.common.data.device.profile.DefaultCoapDeviceTypeConfiguration; -import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; -import org.thingsboard.server.common.data.device.profile.DeviceProfileData; -import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; -import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; -import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; -import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; -import org.thingsboard.server.common.data.device.profile.SimpleAlarmConditionSpec; -import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration; -import org.thingsboard.server.common.data.device.profile.lwm2m.OtherConfiguration; -import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryMappingConfiguration; -import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.AbstractLwM2MBootstrapServerCredential; -import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential; -import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.NoSecLwM2MBootstrapServerCredential; -import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.common.data.edge.EdgeEvent; -import org.thingsboard.server.common.data.edge.EdgeEventActionType; -import org.thingsboard.server.common.data.edge.EdgeEventType; -import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.EntityIdFactory; -import org.thingsboard.server.common.data.id.RuleChainId; -import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.kv.DataType; -import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; -import org.thingsboard.server.common.data.ota.OtaPackageType; -import org.thingsboard.server.common.data.page.PageData; -import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.common.data.query.EntityKeyValueType; -import org.thingsboard.server.common.data.query.FilterPredicateValue; -import org.thingsboard.server.common.data.query.NumericFilterPredicate; -import org.thingsboard.server.common.data.queue.ProcessingStrategy; -import org.thingsboard.server.common.data.queue.ProcessingStrategyType; -import org.thingsboard.server.common.data.queue.Queue; -import org.thingsboard.server.common.data.queue.SubmitStrategy; -import org.thingsboard.server.common.data.queue.SubmitStrategyType; -import org.thingsboard.server.common.data.relation.EntityRelation; -import org.thingsboard.server.common.data.relation.RelationTypeGroup; -import org.thingsboard.server.common.data.rule.RuleChain; -import org.thingsboard.server.common.data.rule.RuleChainMetaData; -import org.thingsboard.server.common.data.rule.RuleChainType; -import org.thingsboard.server.common.data.rule.RuleNode; -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.transport.snmp.SnmpMapping; -import org.thingsboard.server.common.data.transport.snmp.config.SnmpCommunicationConfig; -import org.thingsboard.server.common.data.transport.snmp.config.impl.TelemetryQueryingSnmpCommunicationConfig; -import org.thingsboard.server.common.data.widget.WidgetType; -import org.thingsboard.server.common.data.widget.WidgetsBundle; -import org.thingsboard.server.common.msg.queue.ServiceType; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; -import org.thingsboard.server.controller.AbstractControllerTest; -import org.thingsboard.server.dao.edge.EdgeEventService; -import org.thingsboard.server.edge.imitator.EdgeImitator; -import org.thingsboard.server.gen.edge.v1.AdminSettingsUpdateMsg; -import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; -import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; -import org.thingsboard.server.gen.edge.v1.AttributeDeleteMsg; -import org.thingsboard.server.gen.edge.v1.AttributesRequestMsg; -import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg; -import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg; -import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg; -import org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg; -import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; -import org.thingsboard.server.gen.edge.v1.EdgeConfiguration; -import org.thingsboard.server.gen.edge.v1.EntityDataProto; -import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg; -import org.thingsboard.server.gen.edge.v1.EntityViewsRequestMsg; -import org.thingsboard.server.gen.edge.v1.OtaPackageUpdateMsg; -import org.thingsboard.server.gen.edge.v1.QueueUpdateMsg; -import org.thingsboard.server.gen.edge.v1.RelationRequestMsg; -import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg; -import org.thingsboard.server.gen.edge.v1.RpcResponseMsg; -import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg; -import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; -import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; -import org.thingsboard.server.gen.edge.v1.UpdateMsgType; -import org.thingsboard.server.gen.edge.v1.UplinkMsg; -import org.thingsboard.server.gen.edge.v1.UplinkResponseMsg; -import org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg; -import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; -import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; -import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; -import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; -import org.thingsboard.server.gen.transport.TransportProtos; -import org.thingsboard.server.queue.util.DataDecodingEncodingService; -import org.thingsboard.server.transport.AbstractTransportIntegrationTest; -import org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Random; -import java.util.TreeMap; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; - -@TestPropertySource(properties = { - "edges.enabled=true", -}) -abstract public class BaseEdgeTest extends AbstractControllerTest { - - private static final String THERMOSTAT_DEVICE_PROFILE_NAME = "Thermostat"; - - private Tenant savedTenant; - private TenantId tenantId; - private User tenantAdmin; - - private DeviceProfile thermostatDeviceProfile; - - private EdgeImitator edgeImitator; - private Edge edge; - - @Autowired - private EdgeEventService edgeEventService; - - @Autowired - private DataDecodingEncodingService dataDecodingEncodingService; - - @Autowired - private TbClusterService clusterService; - - @Before - public void beforeTest() throws Exception { - loginSysAdmin(); - - Tenant tenant = new Tenant(); - tenant.setTitle("My tenant"); - savedTenant = doPost("/api/tenant", tenant, Tenant.class); - tenantId = savedTenant.getId(); - Assert.assertNotNull(savedTenant); - - tenantAdmin = new User(); - tenantAdmin.setAuthority(Authority.TENANT_ADMIN); - tenantAdmin.setTenantId(savedTenant.getId()); - tenantAdmin.setEmail("tenant2@thingsboard.org"); - tenantAdmin.setFirstName("Joe"); - tenantAdmin.setLastName("Downs"); - - tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); - // sleep 0.5 second to avoid CREDENTIALS updated message for the user - // user credentials is going to be stored and updated event pushed to edge notification service - // while service will be processing this event edge could be already added and additional message will be pushed - Thread.sleep(500); - - installation(); - - edgeImitator = new EdgeImitator("localhost", 7070, edge.getRoutingKey(), edge.getSecret()); - edgeImitator.expectMessageAmount(15); - edgeImitator.connect(); - - requestEdgeRuleChainMetadata(); - - verifyEdgeConnectionAndInitialData(); - } - - private void requestEdgeRuleChainMetadata() throws Exception { - RuleChainId rootRuleChainId = getEdgeRootRuleChainId(); - RuleChainMetadataRequestMsg.Builder builder = RuleChainMetadataRequestMsg.newBuilder() - .setRuleChainIdMSB(rootRuleChainId.getId().getMostSignificantBits()) - .setRuleChainIdLSB(rootRuleChainId.getId().getLeastSignificantBits()); - testAutoGeneratedCodeByProtobuf(builder); - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder() - .addRuleChainMetadataRequestMsg(builder.build()); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - } - - private RuleChainId getEdgeRootRuleChainId() throws Exception { - List edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/ruleChains?", - new TypeReference>() {}, new PageLink(100)).getData(); - for (RuleChain edgeRuleChain : edgeRuleChains) { - if (edgeRuleChain.isRoot()) { - return edgeRuleChain.getId(); - } - } - throw new RuntimeException("Root rule chain not found"); - } - - @After - public void afterTest() throws Exception { - try { - edgeImitator.disconnect(); - } catch (Exception ignored) {} - - loginSysAdmin(); - - doDelete("/api/tenant/" + savedTenant.getUuidId()) - .andExpect(status().isOk()); - } - - private void installation() throws Exception { - edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); - - thermostatDeviceProfile = this.createDeviceProfile(THERMOSTAT_DEVICE_PROFILE_NAME, - createMqttDeviceProfileTransportConfiguration(new JsonTransportPayloadConfiguration(), false)); - - extendDeviceProfileData(thermostatDeviceProfile); - thermostatDeviceProfile = doPost("/api/deviceProfile", thermostatDeviceProfile, DeviceProfile.class); - - Device savedDevice = saveDevice("Edge Device 1", THERMOSTAT_DEVICE_PROFILE_NAME); - doPost("/api/edge/" + edge.getUuidId() - + "/device/" + savedDevice.getUuidId(), Device.class); - - Asset savedAsset = saveAsset("Edge Asset 1"); - doPost("/api/edge/" + edge.getUuidId() - + "/asset/" + savedAsset.getUuidId(), Asset.class); - } - - private void extendDeviceProfileData(DeviceProfile deviceProfile) { - DeviceProfileData profileData = deviceProfile.getProfileData(); - List alarms = new ArrayList<>(); - DeviceProfileAlarm deviceProfileAlarm = new DeviceProfileAlarm(); - deviceProfileAlarm.setAlarmType("High Temperature"); - AlarmRule alarmRule = new AlarmRule(); - alarmRule.setAlarmDetails("Alarm Details"); - AlarmCondition alarmCondition = new AlarmCondition(); - alarmCondition.setSpec(new SimpleAlarmConditionSpec()); - List condition = new ArrayList<>(); - AlarmConditionFilter alarmConditionFilter = new AlarmConditionFilter(); - alarmConditionFilter.setKey(new AlarmConditionFilterKey(AlarmConditionKeyType.ATTRIBUTE, "temperature")); - NumericFilterPredicate predicate = new NumericFilterPredicate(); - predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER); - predicate.setValue(new FilterPredicateValue<>(55.0)); - alarmConditionFilter.setPredicate(predicate); - alarmConditionFilter.setValueType(EntityKeyValueType.NUMERIC); - condition.add(alarmConditionFilter); - alarmCondition.setCondition(condition); - alarmRule.setCondition(alarmCondition); - deviceProfileAlarm.setClearRule(alarmRule); - TreeMap createRules = new TreeMap<>(); - createRules.put(AlarmSeverity.CRITICAL, alarmRule); - deviceProfileAlarm.setCreateRules(createRules); - alarms.add(deviceProfileAlarm); - profileData.setAlarms(alarms); - profileData.setProvisionConfiguration(new AllowCreateNewDevicesDeviceProfileProvisionConfiguration("123")); - } - - private void verifyEdgeConnectionAndInitialData() throws Exception { - Assert.assertTrue(edgeImitator.waitForMessages()); - - EdgeConfiguration configuration = edgeImitator.getConfiguration(); - Assert.assertNotNull(configuration); - - testAutoGeneratedCodeByProtobuf(configuration); - - Optional deviceUpdateMsgOpt = edgeImitator.findMessageByType(DeviceUpdateMsg.class); - Assert.assertTrue(deviceUpdateMsgOpt.isPresent()); - DeviceUpdateMsg deviceUpdateMsg = deviceUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); - UUID deviceUUID = new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()); - Device device = doGet("/api/device/" + deviceUUID, Device.class); - Assert.assertNotNull(device); - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertTrue(edgeDevices.contains(device)); - - List deviceProfileUpdateMsgList = edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class); - Assert.assertEquals(3, deviceProfileUpdateMsgList.size()); - Optional deviceProfileUpdateMsgOpt = - deviceProfileUpdateMsgList.stream().filter(dfum -> THERMOSTAT_DEVICE_PROFILE_NAME.equals(dfum.getName())).findAny(); - Assert.assertTrue(deviceProfileUpdateMsgOpt.isPresent()); - DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceProfileUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); - UUID deviceProfileUUID = new UUID(deviceProfileUpdateMsg.getIdMSB(), deviceProfileUpdateMsg.getIdLSB()); - DeviceProfile deviceProfile = doGet("/api/deviceProfile/" + deviceProfileUUID, DeviceProfile.class); - Assert.assertNotNull(deviceProfile); - Assert.assertNotNull(deviceProfile.getProfileData()); - Assert.assertNotNull(deviceProfile.getProfileData().getAlarms()); - Assert.assertNotNull(deviceProfile.getProfileData().getAlarms().get(0).getClearRule()); - - testAutoGeneratedCodeByProtobuf(deviceProfileUpdateMsg); - - Optional assetUpdateMsgOpt = edgeImitator.findMessageByType(AssetUpdateMsg.class); - Assert.assertTrue(assetUpdateMsgOpt.isPresent()); - AssetUpdateMsg assetUpdateMsg = assetUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); - UUID assetUUID = new UUID(assetUpdateMsg.getIdMSB(), assetUpdateMsg.getIdLSB()); - Asset asset = doGet("/api/asset/" + assetUUID.toString(), Asset.class); - Assert.assertNotNull(asset); - List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/assets?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertTrue(edgeAssets.contains(asset)); - - testAutoGeneratedCodeByProtobuf(assetUpdateMsg); - - Optional ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); - Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); - RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); - UUID ruleChainUUID = new UUID(ruleChainUpdateMsg.getIdMSB(), ruleChainUpdateMsg.getIdLSB()); - RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID, RuleChain.class); - Assert.assertNotNull(ruleChain); - List edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/ruleChains?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertTrue(edgeRuleChains.contains(ruleChain)); - - testAutoGeneratedCodeByProtobuf(ruleChainUpdateMsg); - - Optional ruleChainMetadataUpdateOpt = edgeImitator.findMessageByType(RuleChainMetadataUpdateMsg.class); - Assert.assertTrue(ruleChainMetadataUpdateOpt.isPresent()); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = ruleChainMetadataUpdateOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, ruleChainMetadataUpdateMsg.getMsgType()); - Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), ruleChainMetadataUpdateMsg.getRuleChainIdMSB()); - Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), ruleChainMetadataUpdateMsg.getRuleChainIdLSB()); - - validateAdminSettings(); - } - - private void validateAdminSettings() throws JsonProcessingException { - List adminSettingsUpdateMsgs = edgeImitator.findAllMessagesByType(AdminSettingsUpdateMsg.class); - Assert.assertEquals(4, adminSettingsUpdateMsgs.size()); - - for (AdminSettingsUpdateMsg adminSettingsUpdateMsg : adminSettingsUpdateMsgs) { - if (adminSettingsUpdateMsg.getKey().equals("mail")) { - validateMailAdminSettings(adminSettingsUpdateMsg); - } - if (adminSettingsUpdateMsg.getKey().equals("mailTemplates")) { - validateMailTemplatesAdminSettings(adminSettingsUpdateMsg); - } - } - } - - private void validateMailAdminSettings(AdminSettingsUpdateMsg adminSettingsUpdateMsg) throws JsonProcessingException { - JsonNode jsonNode = mapper.readTree(adminSettingsUpdateMsg.getJsonValue()); - Assert.assertNotNull(jsonNode.get("mailFrom")); - Assert.assertNotNull(jsonNode.get("smtpProtocol")); - Assert.assertNotNull(jsonNode.get("smtpHost")); - Assert.assertNotNull(jsonNode.get("smtpPort")); - Assert.assertNotNull(jsonNode.get("timeout")); - } - - private void validateMailTemplatesAdminSettings(AdminSettingsUpdateMsg adminSettingsUpdateMsg) throws JsonProcessingException { - JsonNode jsonNode = mapper.readTree(adminSettingsUpdateMsg.getJsonValue()); - Assert.assertNotNull(jsonNode.get("accountActivated")); - Assert.assertNotNull(jsonNode.get("accountLockout")); - Assert.assertNotNull(jsonNode.get("activation")); - Assert.assertNotNull(jsonNode.get("passwordWasReset")); - Assert.assertNotNull(jsonNode.get("resetPassword")); - Assert.assertNotNull(jsonNode.get("test")); - } - - @Test - public void testDeviceProfiles() throws Exception { - // 1 - DeviceProfile deviceProfile = this.createDeviceProfile("ONE_MORE_DEVICE_PROFILE", null); - extendDeviceProfileData(deviceProfile); - edgeImitator.expectMessageAmount(1); - deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); - DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdMSB(), deviceProfile.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits()); - - // 2 - OtaPackageInfo firmwareOtaPackageInfo = saveOtaPackageInfo(deviceProfile.getId()); - edgeImitator.expectMessageAmount(1); - Assert.assertTrue(edgeImitator.waitForMessages()); - - deviceProfile.setFirmwareId(firmwareOtaPackageInfo.getId()); - edgeImitator.expectMessageAmount(1); - deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); - deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; - Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getFirmwareIdMSB()); - Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getFirmwareIdLSB()); - - // 3 - edgeImitator.expectMessageAmount(1); - doDelete("/api/deviceProfile/" + deviceProfile.getUuidId()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); - deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdMSB(), deviceProfile.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits()); - } - - @Test - public void testDeviceProfiles_snmp() throws Exception { - DeviceProfile deviceProfile = createDeviceProfileAndDoBasicAssert("SNMP", createSnmpDeviceProfileTransportConfiguration()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); - DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdMSB(), deviceProfile.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(DeviceTransportType.SNMP.name(), deviceProfileUpdateMsg.getTransportType()); - - Optional deviceProfileDataOpt = - dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray()); - - Assert.assertTrue(deviceProfileDataOpt.isPresent()); - DeviceProfileData deviceProfileData = deviceProfileDataOpt.get(); - - Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof SnmpDeviceProfileTransportConfiguration); - SnmpDeviceProfileTransportConfiguration transportConfiguration = - (SnmpDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration(); - Assert.assertEquals(Integer.valueOf(1000), transportConfiguration.getTimeoutMs()); - Assert.assertEquals(Integer.valueOf(3), transportConfiguration.getRetries()); - - Assert.assertFalse(transportConfiguration.getCommunicationConfigs().isEmpty()); - SnmpCommunicationConfig communicationConfig = transportConfiguration.getCommunicationConfigs().get(0); - Assert.assertTrue(communicationConfig instanceof TelemetryQueryingSnmpCommunicationConfig); - TelemetryQueryingSnmpCommunicationConfig snmpCommunicationConfig = - (TelemetryQueryingSnmpCommunicationConfig) communicationConfig; - - Assert.assertEquals(Long.valueOf(500L), snmpCommunicationConfig.getQueryingFrequencyMs()); - Assert.assertFalse(snmpCommunicationConfig.getMappings().isEmpty()); - - SnmpMapping snmpMapping = snmpCommunicationConfig.getMappings().get(0); - Assert.assertEquals("temperature", snmpMapping.getKey()); - Assert.assertEquals("1.3.3.5.6.7.8.9.1", snmpMapping.getOid()); - Assert.assertEquals(DataType.DOUBLE, snmpMapping.getDataType()); - - removeDeviceProfileAndDoBasicAssert(deviceProfile); - } - - @Test - public void testDeviceProfiles_lwm2m() throws Exception { - DeviceProfile deviceProfile = createDeviceProfileAndDoBasicAssert("LWM2M", createLwm2mDeviceProfileTransportConfiguration()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); - DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdMSB(), deviceProfile.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(DeviceTransportType.LWM2M.name(), deviceProfileUpdateMsg.getTransportType()); - - Optional deviceProfileDataOpt = - dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray()); - - Assert.assertTrue(deviceProfileDataOpt.isPresent()); - DeviceProfileData deviceProfileData = deviceProfileDataOpt.get(); - - Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof Lwm2mDeviceProfileTransportConfiguration); - Lwm2mDeviceProfileTransportConfiguration transportConfiguration = - (Lwm2mDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration(); - - OtherConfiguration clientLwM2mSettings = transportConfiguration.getClientLwM2mSettings(); - Assert.assertEquals(PowerMode.DRX, clientLwM2mSettings.getPowerMode()); - Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getFwUpdateStrategy()); - Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getSwUpdateStrategy()); - Assert.assertEquals(Integer.valueOf(1), clientLwM2mSettings.getClientOnlyObserveAfterConnect()); - - Assert.assertTrue(transportConfiguration.isBootstrapServerUpdateEnable()); - - Assert.assertFalse(transportConfiguration.getBootstrap().isEmpty()); - LwM2MBootstrapServerCredential lwM2MBootstrapServerCredential = transportConfiguration.getBootstrap().get(0); - Assert.assertTrue(lwM2MBootstrapServerCredential instanceof NoSecLwM2MBootstrapServerCredential); - NoSecLwM2MBootstrapServerCredential noSecLwM2MBootstrapServerCredential = (NoSecLwM2MBootstrapServerCredential) lwM2MBootstrapServerCredential; - - Assert.assertEquals("PUBLIC_KEY", noSecLwM2MBootstrapServerCredential.getServerPublicKey()); - Assert.assertEquals(Integer.valueOf(123), noSecLwM2MBootstrapServerCredential.getShortServerId()); - Assert.assertTrue(noSecLwM2MBootstrapServerCredential.isBootstrapServerIs()); - Assert.assertEquals("localhost", noSecLwM2MBootstrapServerCredential.getHost()); - Assert.assertEquals(Integer.valueOf(5687), noSecLwM2MBootstrapServerCredential.getPort()); - - TelemetryMappingConfiguration observeAttr = transportConfiguration.getObserveAttr(); - Assert.assertEquals("batteryLevel", observeAttr.getKeyName().get("/3_1.0/0/9")); - Assert.assertTrue(observeAttr.getObserve().isEmpty()); - Assert.assertTrue(observeAttr.getAttribute().isEmpty()); - Assert.assertFalse(observeAttr.getTelemetry().isEmpty()); - Assert.assertTrue(observeAttr.getTelemetry().contains("/3_1.0/0/9")); - Assert.assertTrue(observeAttr.getAttributeLwm2m().isEmpty()); - - removeDeviceProfileAndDoBasicAssert(deviceProfile); - } - - @Test - public void testDeviceProfiles_coap() throws Exception { - DeviceProfile deviceProfile = createDeviceProfileAndDoBasicAssert("COAP", createCoapDeviceProfileTransportConfiguration()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); - DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdMSB(), deviceProfile.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(DeviceTransportType.COAP.name(), deviceProfileUpdateMsg.getTransportType()); - - Optional deviceProfileDataOpt = - dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray()); - - Assert.assertTrue(deviceProfileDataOpt.isPresent()); - DeviceProfileData deviceProfileData = deviceProfileDataOpt.get(); - - Assert.assertTrue(deviceProfileData.getTransportConfiguration() instanceof CoapDeviceProfileTransportConfiguration); - CoapDeviceProfileTransportConfiguration transportConfiguration = - (CoapDeviceProfileTransportConfiguration) deviceProfileData.getTransportConfiguration(); - - PowerSavingConfiguration clientSettings = transportConfiguration.getClientSettings(); - - Assert.assertEquals(PowerMode.DRX, clientSettings.getPowerMode()); - Assert.assertEquals(Long.valueOf(1L), clientSettings.getEdrxCycle()); - Assert.assertEquals(Long.valueOf(1L), clientSettings.getPsmActivityTimer()); - Assert.assertEquals(Long.valueOf(1L), clientSettings.getPagingTransmissionWindow()); - - Assert.assertTrue(transportConfiguration.getCoapDeviceTypeConfiguration() instanceof DefaultCoapDeviceTypeConfiguration); - DefaultCoapDeviceTypeConfiguration coapDeviceTypeConfiguration = - (DefaultCoapDeviceTypeConfiguration) transportConfiguration.getCoapDeviceTypeConfiguration(); - - Assert.assertTrue(coapDeviceTypeConfiguration.getTransportPayloadTypeConfiguration() instanceof ProtoTransportPayloadConfiguration); - - ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = - (ProtoTransportPayloadConfiguration) coapDeviceTypeConfiguration.getTransportPayloadTypeConfiguration(); - - Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_TELEMETRY_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceTelemetryProtoSchema()); - Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_ATTRIBUTES_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceAttributesProtoSchema()); - Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_RPC_RESPONSE_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceRpcResponseProtoSchema()); - Assert.assertEquals(AbstractTransportIntegrationTest.DEVICE_RPC_REQUEST_PROTO_SCHEMA, protoTransportPayloadConfiguration.getDeviceRpcRequestProtoSchema()); - - removeDeviceProfileAndDoBasicAssert(deviceProfile); - } - - private DeviceProfile createDeviceProfileAndDoBasicAssert(String deviceProfileName, DeviceProfileTransportConfiguration deviceProfileTransportConfiguration) throws Exception { - DeviceProfile deviceProfile = this.createDeviceProfile(deviceProfileName, deviceProfileTransportConfiguration); - extendDeviceProfileData(deviceProfile); - edgeImitator.expectMessageAmount(1); - deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - return deviceProfile; - } - - private void removeDeviceProfileAndDoBasicAssert(DeviceProfile deviceProfile) throws Exception { - edgeImitator.expectMessageAmount(1); - doDelete("/api/deviceProfile/" + deviceProfile.getUuidId()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg); - DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdMSB(), deviceProfile.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceProfileUpdateMsg.getIdLSB(), deviceProfile.getUuidId().getLeastSignificantBits()); - } - - private SnmpDeviceProfileTransportConfiguration createSnmpDeviceProfileTransportConfiguration() { - SnmpDeviceProfileTransportConfiguration transportConfiguration = new SnmpDeviceProfileTransportConfiguration(); - List communicationConfigs = new ArrayList<>(); - TelemetryQueryingSnmpCommunicationConfig communicationConfig = new TelemetryQueryingSnmpCommunicationConfig(); - communicationConfig.setQueryingFrequencyMs(500L); - List mappings = new ArrayList<>(); - mappings.add(new SnmpMapping("1.3.3.5.6.7.8.9.1", "temperature", DataType.DOUBLE)); - communicationConfig.setMappings(mappings); - communicationConfigs.add(communicationConfig); - transportConfiguration.setCommunicationConfigs(communicationConfigs); - transportConfiguration.setTimeoutMs(1000); - transportConfiguration.setRetries(3); - return transportConfiguration; - } - - private Lwm2mDeviceProfileTransportConfiguration createLwm2mDeviceProfileTransportConfiguration() { - Lwm2mDeviceProfileTransportConfiguration transportConfiguration = new Lwm2mDeviceProfileTransportConfiguration(); - - OtherConfiguration clientLwM2mSettings = JacksonUtil.fromString(AbstractLwM2MIntegrationTest.CLIENT_LWM2M_SETTINGS, OtherConfiguration.class); - transportConfiguration.setClientLwM2mSettings(clientLwM2mSettings); - - transportConfiguration.setBootstrapServerUpdateEnable(true); - - TelemetryMappingConfiguration observeAttrConfiguration = - JacksonUtil.fromString(AbstractLwM2MIntegrationTest.OBSERVE_ATTRIBUTES_WITH_PARAMS, TelemetryMappingConfiguration.class); - transportConfiguration.setObserveAttr(observeAttrConfiguration); - - List bootstrap = new ArrayList<>(); - AbstractLwM2MBootstrapServerCredential bootstrapServerCredential = new NoSecLwM2MBootstrapServerCredential(); - bootstrapServerCredential.setServerPublicKey("PUBLIC_KEY"); - bootstrapServerCredential.setShortServerId(123); - bootstrapServerCredential.setBootstrapServerIs(true); - bootstrapServerCredential.setHost("localhost"); - bootstrapServerCredential.setPort(5687); - bootstrap.add(bootstrapServerCredential); - transportConfiguration.setBootstrap(bootstrap); - - return transportConfiguration; - } - - private CoapDeviceProfileTransportConfiguration createCoapDeviceProfileTransportConfiguration() { - CoapDeviceProfileTransportConfiguration transportConfiguration = new CoapDeviceProfileTransportConfiguration(); - PowerSavingConfiguration clientSettings = new PowerSavingConfiguration(); - clientSettings.setPowerMode(PowerMode.DRX); - clientSettings.setEdrxCycle(1L); - clientSettings.setPsmActivityTimer(1L); - clientSettings.setPagingTransmissionWindow(1L); - transportConfiguration.setClientSettings(clientSettings); - DefaultCoapDeviceTypeConfiguration coapDeviceTypeConfiguration = new DefaultCoapDeviceTypeConfiguration(); - ProtoTransportPayloadConfiguration transportPayloadTypeConfiguration = new ProtoTransportPayloadConfiguration(); - transportPayloadTypeConfiguration.setDeviceTelemetryProtoSchema(AbstractTransportIntegrationTest.DEVICE_TELEMETRY_PROTO_SCHEMA); - transportPayloadTypeConfiguration.setDeviceAttributesProtoSchema(AbstractTransportIntegrationTest.DEVICE_ATTRIBUTES_PROTO_SCHEMA); - transportPayloadTypeConfiguration.setDeviceRpcResponseProtoSchema(AbstractTransportIntegrationTest.DEVICE_RPC_RESPONSE_PROTO_SCHEMA); - transportPayloadTypeConfiguration.setDeviceRpcRequestProtoSchema(AbstractTransportIntegrationTest.DEVICE_RPC_REQUEST_PROTO_SCHEMA); - coapDeviceTypeConfiguration.setTransportPayloadTypeConfiguration(transportPayloadTypeConfiguration); - transportConfiguration.setCoapDeviceTypeConfiguration(coapDeviceTypeConfiguration); - return transportConfiguration; - } - - @Test - public void testDevices() throws Exception { - // 1 - Device savedDevice = saveDeviceOnCloudAndVerifyDeliveryToEdge(); - - // 2 - edgeImitator.expectMessageAmount(1); - doDelete("/api/edge/" + edge.getUuidId() - + "/device/" + savedDevice.getUuidId(), Device.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); - DeviceUpdateMsg deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); - Assert.assertEquals(deviceUpdateMsg.getIdMSB(), savedDevice.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceUpdateMsg.getIdLSB(), savedDevice.getUuidId().getLeastSignificantBits()); - - // 3 - edgeImitator.expectMessageAmount(1); - doDelete("/api/device/" + savedDevice.getUuidId()) - .andExpect(status().isOk()); - // we should not get any message because device is not assigned to edge any more - Assert.assertFalse(edgeImitator.waitForMessages(1)); - - // 4 - edgeImitator.expectMessageAmount(1); - savedDevice = saveDevice("Edge Device 3", "Default"); - doPost("/api/edge/" + edge.getUuidId() - + "/device/" + savedDevice.getUuidId(), Device.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); - deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); - Assert.assertEquals(deviceUpdateMsg.getIdMSB(), savedDevice.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceUpdateMsg.getIdLSB(), savedDevice.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(deviceUpdateMsg.getName(), savedDevice.getName()); - Assert.assertEquals(deviceUpdateMsg.getType(), savedDevice.getType()); - - // 5 - edgeImitator.expectMessageAmount(1); - doDelete("/api/device/" + savedDevice.getUuidId()) - .andExpect(status().isOk()); - // in this case we should get messages because device was assigned to edge - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); - deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); - Assert.assertEquals(deviceUpdateMsg.getIdMSB(), savedDevice.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceUpdateMsg.getIdLSB(), savedDevice.getUuidId().getLeastSignificantBits()); - - } - - @Test - public void testDeviceReachedMaximumAllowedOnCloud() throws Exception { - // update tenant profile configuration - loginSysAdmin(); - TenantProfile tenantProfile = doGet("/api/tenantProfile/" + savedTenant.getTenantProfileId().getId(), TenantProfile.class); - DefaultTenantProfileConfiguration profileConfiguration = - (DefaultTenantProfileConfiguration) tenantProfile.getProfileData().getConfiguration(); - profileConfiguration.setMaxDevices(1); - tenantProfile.getProfileData().setConfiguration(profileConfiguration); - doPost("/api/tenantProfile/", tenantProfile, TenantProfile.class); - - loginTenantAdmin(); - - UUID uuid = Uuids.timeBased(); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - DeviceUpdateMsg.Builder deviceUpdateMsgBuilder = DeviceUpdateMsg.newBuilder(); - deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits()); - deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits()); - deviceUpdateMsgBuilder.setName("Edge Device"); - deviceUpdateMsgBuilder.setType("default"); - deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); - uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); - - edgeImitator.expectResponsesAmount(1); - - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - - Assert.assertTrue(edgeImitator.waitForResponses()); - - UplinkResponseMsg latestResponseMsg = edgeImitator.getLatestResponseMsg(); - Assert.assertTrue(latestResponseMsg.getSuccess()); - } - - @Test - public void testAssets() throws Exception { - // 1 - edgeImitator.expectMessageAmount(1); - Asset savedAsset = saveAsset("Edge Asset 2"); - doPost("/api/edge/" + edge.getUuidId() - + "/asset/" + savedAsset.getUuidId(), Asset.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); - AssetUpdateMsg assetUpdateMsg = (AssetUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); - Assert.assertEquals(assetUpdateMsg.getIdMSB(), savedAsset.getUuidId().getMostSignificantBits()); - Assert.assertEquals(assetUpdateMsg.getIdLSB(), savedAsset.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(assetUpdateMsg.getName(), savedAsset.getName()); - Assert.assertEquals(assetUpdateMsg.getType(), savedAsset.getType()); - - // 2 - edgeImitator.expectMessageAmount(1); - doDelete("/api/edge/" + edge.getUuidId() - + "/asset/" + savedAsset.getUuidId(), Asset.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); - assetUpdateMsg = (AssetUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); - Assert.assertEquals(assetUpdateMsg.getIdMSB(), savedAsset.getUuidId().getMostSignificantBits()); - Assert.assertEquals(assetUpdateMsg.getIdLSB(), savedAsset.getUuidId().getLeastSignificantBits()); - - // 3 - edgeImitator.expectMessageAmount(1); - doDelete("/api/asset/" + savedAsset.getUuidId()) - .andExpect(status().isOk()); - Assert.assertFalse(edgeImitator.waitForMessages(1)); - - // 4 - edgeImitator.expectMessageAmount(1); - savedAsset = saveAsset("Edge Asset 3"); - doPost("/api/edge/" + edge.getUuidId() - + "/asset/" + savedAsset.getUuidId(), Asset.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); - assetUpdateMsg = (AssetUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); - Assert.assertEquals(assetUpdateMsg.getIdMSB(), savedAsset.getUuidId().getMostSignificantBits()); - Assert.assertEquals(assetUpdateMsg.getIdLSB(), savedAsset.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(assetUpdateMsg.getName(), savedAsset.getName()); - Assert.assertEquals(assetUpdateMsg.getType(), savedAsset.getType()); - - // 5 - edgeImitator.expectMessageAmount(1); - doDelete("/api/asset/" + savedAsset.getUuidId()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AssetUpdateMsg); - assetUpdateMsg = (AssetUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, assetUpdateMsg.getMsgType()); - Assert.assertEquals(assetUpdateMsg.getIdMSB(), savedAsset.getUuidId().getMostSignificantBits()); - Assert.assertEquals(assetUpdateMsg.getIdLSB(), savedAsset.getUuidId().getLeastSignificantBits()); - } - - @Test - public void testRuleChains() throws Exception { - // 1 - edgeImitator.expectMessageAmount(2); - RuleChain ruleChain = new RuleChain(); - ruleChain.setName("Edge Test Rule Chain"); - ruleChain.setType(RuleChainType.EDGE); - RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); - doPost("/api/edge/" + edge.getUuidId() - + "/ruleChain/" + savedRuleChain.getUuidId(), RuleChain.class); - createRuleChainMetadata(savedRuleChain); - Assert.assertTrue(edgeImitator.waitForMessages()); - Optional ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); - Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); - RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); - Assert.assertTrue(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE.equals(ruleChainUpdateMsg.getMsgType()) || - UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE.equals(ruleChainUpdateMsg.getMsgType())); - Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), savedRuleChain.getUuidId().getMostSignificantBits()); - Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(ruleChainUpdateMsg.getName(), savedRuleChain.getName()); - - // 2 - testRuleChainMetadataRequestMsg(savedRuleChain.getId()); - - // 3 - edgeImitator.expectMessageAmount(1); - doDelete("/api/edge/" + edge.getUuidId() - + "/ruleChain/" + savedRuleChain.getUuidId(), RuleChain.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); - Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); - ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); - Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), savedRuleChain.getUuidId().getMostSignificantBits()); - Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); - - // 4 - edgeImitator.expectMessageAmount(1); - doDelete("/api/ruleChain/" + savedRuleChain.getUuidId()) - .andExpect(status().isOk()); - Assert.assertFalse(edgeImitator.waitForMessages(1)); - } - - private void testRuleChainMetadataRequestMsg(RuleChainId ruleChainId) throws Exception { - RuleChainMetadataRequestMsg.Builder ruleChainMetadataRequestMsgBuilder = RuleChainMetadataRequestMsg.newBuilder() - .setRuleChainIdMSB(ruleChainId.getId().getMostSignificantBits()) - .setRuleChainIdLSB(ruleChainId.getId().getLeastSignificantBits()); - testAutoGeneratedCodeByProtobuf(ruleChainMetadataRequestMsgBuilder); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder() - .addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = (RuleChainMetadataUpdateMsg) latestMessage; - RuleChainId receivedRuleChainId = - new RuleChainId(new UUID(ruleChainMetadataUpdateMsg.getRuleChainIdMSB(), ruleChainMetadataUpdateMsg.getRuleChainIdLSB())); - Assert.assertEquals(ruleChainId, receivedRuleChainId); - } - - private void createRuleChainMetadata(RuleChain ruleChain) throws Exception { - RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); - ruleChainMetaData.setRuleChainId(ruleChain.getId()); - - ObjectMapper mapper = new ObjectMapper(); - - RuleNode ruleNode1 = new RuleNode(); - ruleNode1.setName("name1"); - ruleNode1.setType("type1"); - ruleNode1.setConfiguration(mapper.readTree("\"key1\": \"val1\"")); - - RuleNode ruleNode2 = new RuleNode(); - ruleNode2.setName("name2"); - ruleNode2.setType("type2"); - ruleNode2.setConfiguration(mapper.readTree("\"key2\": \"val2\"")); - - RuleNode ruleNode3 = new RuleNode(); - ruleNode3.setName("name3"); - ruleNode3.setType("type3"); - ruleNode3.setConfiguration(mapper.readTree("\"key3\": \"val3\"")); - - List ruleNodes = new ArrayList<>(); - ruleNodes.add(ruleNode1); - ruleNodes.add(ruleNode2); - ruleNodes.add(ruleNode3); - ruleChainMetaData.setFirstNodeIndex(0); - ruleChainMetaData.setNodes(ruleNodes); - - ruleChainMetaData.addConnectionInfo(0, 1, "success"); - ruleChainMetaData.addConnectionInfo(0, 2, "fail"); - ruleChainMetaData.addConnectionInfo(1, 2, "success"); - - doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class); - } - - @Test - public void testDashboards() throws Exception { - // 1 - edgeImitator.expectMessageAmount(1); - Dashboard dashboard = new Dashboard(); - dashboard.setTitle("Edge Test Dashboard"); - Dashboard savedDashboard = doPost("/api/dashboard", dashboard, Dashboard.class); - doPost("/api/edge/" + edge.getUuidId() - + "/dashboard/" + savedDashboard.getUuidId(), Dashboard.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); - DashboardUpdateMsg dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); - Assert.assertEquals(dashboardUpdateMsg.getIdMSB(), savedDashboard.getUuidId().getMostSignificantBits()); - Assert.assertEquals(dashboardUpdateMsg.getIdLSB(), savedDashboard.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(dashboardUpdateMsg.getTitle(), savedDashboard.getName()); - testAutoGeneratedCodeByProtobuf(dashboardUpdateMsg); - - // 2 - edgeImitator.expectMessageAmount(1); - savedDashboard.setTitle("Updated Edge Test Dashboard"); - doPost("/api/dashboard", savedDashboard, Dashboard.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); - dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); - Assert.assertEquals(dashboardUpdateMsg.getTitle(), savedDashboard.getName()); - - // 3 - edgeImitator.expectMessageAmount(1); - doDelete("/api/edge/" + edge.getUuidId() - + "/dashboard/" + savedDashboard.getUuidId(), Dashboard.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DashboardUpdateMsg); - dashboardUpdateMsg = (DashboardUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, dashboardUpdateMsg.getMsgType()); - Assert.assertEquals(dashboardUpdateMsg.getIdMSB(), savedDashboard.getUuidId().getMostSignificantBits()); - Assert.assertEquals(dashboardUpdateMsg.getIdLSB(), savedDashboard.getUuidId().getLeastSignificantBits()); - - // 4 - edgeImitator.expectMessageAmount(1); - doDelete("/api/dashboard/" + savedDashboard.getUuidId()) - .andExpect(status().isOk()); - Assert.assertFalse(edgeImitator.waitForMessages(1)); - } - - @Test - public void testRelations() throws Exception { - // 1 - edgeImitator.expectMessageAmount(1); - Device device = findDeviceByName("Edge Device 1"); - Asset asset = findAssetByName("Edge Asset 1"); - EntityRelation relation = new EntityRelation(); - relation.setType("test"); - relation.setFrom(device.getId()); - relation.setTo(asset.getId()); - relation.setTypeGroup(RelationTypeGroup.COMMON); - doPost("/api/relation", relation); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); - RelationUpdateMsg relationUpdateMsg = (RelationUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, relationUpdateMsg.getMsgType()); - Assert.assertEquals(relationUpdateMsg.getType(), relation.getType()); - Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); - Assert.assertEquals(relationUpdateMsg.getFromIdLSB(), relation.getFrom().getId().getLeastSignificantBits()); - Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); - Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); - Assert.assertEquals(relationUpdateMsg.getToIdLSB(), relation.getTo().getId().getLeastSignificantBits()); - Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); - Assert.assertEquals(relationUpdateMsg.getTypeGroup(), relation.getTypeGroup().name()); - - // 2 - edgeImitator.expectMessageAmount(1); - doDelete("/api/relation?" + - "fromId=" + relation.getFrom().getId().toString() + - "&fromType=" + relation.getFrom().getEntityType().name() + - "&relationType=" + relation.getType() + - "&relationTypeGroup=" + relation.getTypeGroup().name() + - "&toId=" + relation.getTo().getId().toString() + - "&toType=" + relation.getTo().getEntityType().name()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); - relationUpdateMsg = (RelationUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, relationUpdateMsg.getMsgType()); - Assert.assertEquals(relationUpdateMsg.getType(), relation.getType()); - Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); - Assert.assertEquals(relationUpdateMsg.getFromIdLSB(), relation.getFrom().getId().getLeastSignificantBits()); - Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); - Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); - Assert.assertEquals(relationUpdateMsg.getToIdLSB(), relation.getTo().getId().getLeastSignificantBits()); - Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); - Assert.assertEquals(relationUpdateMsg.getTypeGroup(), relation.getTypeGroup().name()); - } - - @Test - public void testAlarms() throws Exception { - // 1 - edgeImitator.expectMessageAmount(1); - Device device = findDeviceByName("Edge Device 1"); - Alarm alarm = new Alarm(); - alarm.setOriginator(device.getId()); - alarm.setStatus(AlarmStatus.ACTIVE_UNACK); - alarm.setType("alarm"); - alarm.setSeverity(AlarmSeverity.CRITICAL); - Alarm savedAlarm = doPost("/api/alarm", alarm, Alarm.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); - AlarmUpdateMsg alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); - Assert.assertEquals(alarmUpdateMsg.getType(), savedAlarm.getType()); - Assert.assertEquals(alarmUpdateMsg.getName(), savedAlarm.getName()); - Assert.assertEquals(alarmUpdateMsg.getOriginatorName(), device.getName()); - Assert.assertEquals(alarmUpdateMsg.getStatus(), savedAlarm.getStatus().name()); - Assert.assertEquals(alarmUpdateMsg.getSeverity(), savedAlarm.getSeverity().name()); - - // 2 - edgeImitator.expectMessageAmount(1); - doPost("/api/alarm/" + savedAlarm.getUuidId() + "/ack"); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); - alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ALARM_ACK_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); - Assert.assertEquals(alarmUpdateMsg.getType(), savedAlarm.getType()); - Assert.assertEquals(alarmUpdateMsg.getName(), savedAlarm.getName()); - Assert.assertEquals(alarmUpdateMsg.getOriginatorName(), device.getName()); - Assert.assertEquals(alarmUpdateMsg.getStatus(), AlarmStatus.ACTIVE_ACK.name()); - - // 3 - 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()); - Assert.assertEquals(alarmUpdateMsg.getType(), savedAlarm.getType()); - Assert.assertEquals(alarmUpdateMsg.getName(), savedAlarm.getName()); - Assert.assertEquals(alarmUpdateMsg.getOriginatorName(), device.getName()); - Assert.assertEquals(alarmUpdateMsg.getStatus(), AlarmStatus.CLEARED_ACK.name()); - - // 4 - edgeImitator.expectMessageAmount(1); - doDelete("/api/alarm/" + savedAlarm.getUuidId()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); - alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); - Assert.assertEquals(alarmUpdateMsg.getType(), savedAlarm.getType()); - Assert.assertEquals(alarmUpdateMsg.getName(), savedAlarm.getName()); - Assert.assertEquals(alarmUpdateMsg.getOriginatorName(), device.getName()); - Assert.assertEquals(alarmUpdateMsg.getStatus(), AlarmStatus.CLEARED_ACK.name()); - } - - @Test - public void testEntityView() throws Exception { - // 1 - edgeImitator.expectMessageAmount(1); - Device device = findDeviceByName("Edge Device 1"); - EntityView entityView = new EntityView(); - entityView.setName("Edge EntityView 1"); - entityView.setType("test"); - entityView.setEntityId(device.getId()); - EntityView savedEntityView = doPost("/api/entityView", entityView, EntityView.class); - doPost("/api/edge/" + edge.getUuidId() - + "/entityView/" + savedEntityView.getUuidId(), EntityView.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - verifyEntityViewUpdateMsg(savedEntityView, device); - - - // 2 - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - EntityViewsRequestMsg.Builder entityViewsRequestBuilder = EntityViewsRequestMsg.newBuilder(); - entityViewsRequestBuilder.setEntityIdMSB(device.getUuidId().getMostSignificantBits()); - entityViewsRequestBuilder.setEntityIdLSB(device.getUuidId().getLeastSignificantBits()); - entityViewsRequestBuilder.setEntityType(device.getId().getEntityType().name()); - testAutoGeneratedCodeByProtobuf(entityViewsRequestBuilder); - uplinkMsgBuilder.addEntityViewsRequestMsg(entityViewsRequestBuilder.build()); - - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - Assert.assertTrue(edgeImitator.waitForMessages()); - verifyEntityViewUpdateMsg(savedEntityView, device); - - - // 3 - edgeImitator.expectMessageAmount(1); - doDelete("/api/edge/" + edge.getUuidId() - + "/entityView/" + savedEntityView.getUuidId(), EntityView.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); - EntityViewUpdateMsg entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); - Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), savedEntityView.getUuidId().getMostSignificantBits()); - Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), savedEntityView.getUuidId().getLeastSignificantBits()); - - - edgeImitator.expectMessageAmount(1); - doDelete("/api/entityView/" + savedEntityView.getUuidId()) - .andExpect(status().isOk()); - Assert.assertFalse(edgeImitator.waitForMessages(1)); - } - - private void verifyEntityViewUpdateMsg(EntityView entityView, Device device) { - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); - EntityViewUpdateMsg entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); - Assert.assertEquals(entityViewUpdateMsg.getType(), entityView.getType()); - Assert.assertEquals(entityViewUpdateMsg.getName(), entityView.getName()); - Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), entityView.getUuidId().getMostSignificantBits()); - Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), entityView.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(entityViewUpdateMsg.getEntityIdMSB(), device.getUuidId().getMostSignificantBits()); - Assert.assertEquals(entityViewUpdateMsg.getEntityIdLSB(), device.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(entityViewUpdateMsg.getEntityType().name(), device.getId().getEntityType().name()); - } - - @Test - public void testCustomerAndNewUser() throws Exception { - // 1 - edgeImitator.expectMessageAmount(1); - Customer customer = new Customer(); - customer.setTitle("Edge Customer 1"); - Customer savedCustomer = doPost("/api/customer", customer, Customer.class); - doPost("/api/customer/" + savedCustomer.getUuidId() - + "/edge/" + edge.getUuidId(), Edge.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); - CustomerUpdateMsg customerUpdateMsg = (CustomerUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, customerUpdateMsg.getMsgType()); - Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits()); - Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(customerUpdateMsg.getTitle(), savedCustomer.getTitle()); - testAutoGeneratedCodeByProtobuf(customerUpdateMsg); - - // 2 - edgeImitator.expectMessageAmount(1); - User customerUser = new User(); - customerUser.setAuthority(Authority.CUSTOMER_USER); - customerUser.setTenantId(savedTenant.getId()); - customerUser.setCustomerId(savedCustomer.getId()); - customerUser.setEmail("customerUser@thingsboard.org"); - customerUser.setFirstName("John"); - customerUser.setLastName("Edwards"); - User savedUser = doPost("/api/user", customerUser, User.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof UserUpdateMsg); - UserUpdateMsg userUpdateMsg = (UserUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, userUpdateMsg.getMsgType()); - Assert.assertEquals(userUpdateMsg.getIdMSB(), savedUser.getUuidId().getMostSignificantBits()); - Assert.assertEquals(userUpdateMsg.getIdLSB(), savedUser.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(userUpdateMsg.getEmail(), savedUser.getEmail()); - testAutoGeneratedCodeByProtobuf(userUpdateMsg); - - // 3 - edgeImitator.expectMessageAmount(1); - doDelete("/api/customer/edge/" + edge.getUuidId(), Edge.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); - customerUpdateMsg = (CustomerUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, customerUpdateMsg.getMsgType()); - Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits()); - Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); - - edgeImitator.expectMessageAmount(1); - doDelete("/api/customer/" + savedCustomer.getUuidId()) - .andExpect(status().isOk()); - Assert.assertFalse(edgeImitator.waitForMessages(1)); - } - - @Test - public void testWidgetsBundleAndWidgetType() throws Exception { - // 1 - edgeImitator.expectMessageAmount(1); - WidgetsBundle widgetsBundle = new WidgetsBundle(); - widgetsBundle.setTitle("Test Widget Bundle"); - WidgetsBundle savedWidgetsBundle = doPost("/api/widgetsBundle", widgetsBundle, WidgetsBundle.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof WidgetsBundleUpdateMsg); - WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = (WidgetsBundleUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, widgetsBundleUpdateMsg.getMsgType()); - Assert.assertEquals(widgetsBundleUpdateMsg.getIdMSB(), savedWidgetsBundle.getUuidId().getMostSignificantBits()); - Assert.assertEquals(widgetsBundleUpdateMsg.getIdLSB(), savedWidgetsBundle.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(widgetsBundleUpdateMsg.getAlias(), savedWidgetsBundle.getAlias()); - Assert.assertEquals(widgetsBundleUpdateMsg.getTitle(), savedWidgetsBundle.getTitle()); - testAutoGeneratedCodeByProtobuf(widgetsBundleUpdateMsg); - - // 2 - edgeImitator.expectMessageAmount(1); - WidgetType widgetType = new WidgetType(); - widgetType.setName("Test Widget Type"); - widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); - ObjectNode descriptor = mapper.createObjectNode(); - descriptor.put("key", "value"); - widgetType.setDescriptor(descriptor); - WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof WidgetTypeUpdateMsg); - WidgetTypeUpdateMsg widgetTypeUpdateMsg = (WidgetTypeUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, widgetTypeUpdateMsg.getMsgType()); - Assert.assertEquals(widgetTypeUpdateMsg.getIdMSB(), savedWidgetType.getUuidId().getMostSignificantBits()); - Assert.assertEquals(widgetTypeUpdateMsg.getIdLSB(), savedWidgetType.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(widgetTypeUpdateMsg.getAlias(), savedWidgetType.getAlias()); - Assert.assertEquals(widgetTypeUpdateMsg.getName(), savedWidgetType.getName()); - Assert.assertEquals(JacksonUtil.toJsonNode(widgetTypeUpdateMsg.getDescriptorJson()), savedWidgetType.getDescriptor()); - - // 3 - edgeImitator.expectMessageAmount(1); - doDelete("/api/widgetType/" + savedWidgetType.getUuidId()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof WidgetTypeUpdateMsg); - widgetTypeUpdateMsg = (WidgetTypeUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, widgetTypeUpdateMsg.getMsgType()); - Assert.assertEquals(widgetTypeUpdateMsg.getIdMSB(), savedWidgetType.getUuidId().getMostSignificantBits()); - Assert.assertEquals(widgetTypeUpdateMsg.getIdLSB(), savedWidgetType.getUuidId().getLeastSignificantBits()); - - // 4 - edgeImitator.expectMessageAmount(1); - doDelete("/api/widgetsBundle/" + savedWidgetsBundle.getUuidId()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof WidgetsBundleUpdateMsg); - widgetsBundleUpdateMsg = (WidgetsBundleUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, widgetsBundleUpdateMsg.getMsgType()); - Assert.assertEquals(widgetsBundleUpdateMsg.getIdMSB(), savedWidgetsBundle.getUuidId().getMostSignificantBits()); - Assert.assertEquals(widgetsBundleUpdateMsg.getIdLSB(), savedWidgetsBundle.getUuidId().getLeastSignificantBits()); - } - - @Test - public void testTimeseries() throws Exception { - edgeImitator.expectMessageAmount(1); - Device device = findDeviceByName("Edge Device 1"); - String timeseriesData = "{\"data\":{\"temperature\":25},\"ts\":" + System.currentTimeMillis() + "}"; - JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); - EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); - edgeEventService.saveAsync(edgeEvent).get(); - clusterService.onEdgeEventUpdate(tenantId, edge.getId()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof EntityDataProto); - EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; - Assert.assertEquals(latestEntityDataMsg.getEntityIdMSB(), device.getUuidId().getMostSignificantBits()); - Assert.assertEquals(latestEntityDataMsg.getEntityIdLSB(), device.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(latestEntityDataMsg.getEntityType(), device.getId().getEntityType().name()); - Assert.assertTrue(latestEntityDataMsg.hasPostTelemetryMsg()); - - TransportProtos.PostTelemetryMsg postTelemetryMsg = latestEntityDataMsg.getPostTelemetryMsg(); - Assert.assertEquals(1, postTelemetryMsg.getTsKvListCount()); - TransportProtos.TsKvListProto tsKvListProto = postTelemetryMsg.getTsKvList(0); - Assert.assertEquals(timeseriesEntityData.get("ts").asLong(), tsKvListProto.getTs()); - Assert.assertEquals(1, tsKvListProto.getKvCount()); - TransportProtos.KeyValueProto keyValueProto = tsKvListProto.getKv(0); - Assert.assertEquals("temperature", keyValueProto.getKey()); - Assert.assertEquals(25, keyValueProto.getLongV()); - } - - @Test - public void testAttributes() throws Exception { - Device device = findDeviceByName("Edge Device 1"); - - testAttributesUpdatedMsg(device); - testPostAttributesMsg(device); - testAttributesDeleteMsg(device); - } - - private void testAttributesUpdatedMsg(Device device) throws Exception { - String attributesData = "{\"scope\":\"SERVER_SCOPE\",\"kv\":{\"key1\":\"value1\"}}"; - JsonNode attributesEntityData = mapper.readTree(attributesData); - EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData); - edgeImitator.expectMessageAmount(1); - edgeEventService.saveAsync(edgeEvent1).get(); - clusterService.onEdgeEventUpdate(tenantId, edge.getId()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof EntityDataProto); - EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; - Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); - Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); - Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); - Assert.assertEquals("SERVER_SCOPE", latestEntityDataMsg.getPostAttributeScope()); - Assert.assertTrue(latestEntityDataMsg.hasAttributesUpdatedMsg()); - - TransportProtos.PostAttributeMsg attributesUpdatedMsg = latestEntityDataMsg.getAttributesUpdatedMsg(); - Assert.assertEquals(1, attributesUpdatedMsg.getKvCount()); - TransportProtos.KeyValueProto keyValueProto = attributesUpdatedMsg.getKv(0); - Assert.assertEquals("key1", keyValueProto.getKey()); - Assert.assertEquals("value1", keyValueProto.getStringV()); - } - - private void testPostAttributesMsg(Device device) throws Exception { - String postAttributesData = "{\"scope\":\"SERVER_SCOPE\",\"kv\":{\"key2\":\"value2\"}}"; - JsonNode postAttributesEntityData = mapper.readTree(postAttributesData); - EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.POST_ATTRIBUTES, device.getId().getId(), EdgeEventType.DEVICE, postAttributesEntityData); - edgeImitator.expectMessageAmount(1); - edgeEventService.saveAsync(edgeEvent).get(); - clusterService.onEdgeEventUpdate(tenantId, edge.getId()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof EntityDataProto); - EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; - Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); - Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); - Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); - Assert.assertEquals("SERVER_SCOPE", latestEntityDataMsg.getPostAttributeScope()); - Assert.assertTrue(latestEntityDataMsg.hasPostAttributesMsg()); - - TransportProtos.PostAttributeMsg postAttributesMsg = latestEntityDataMsg.getPostAttributesMsg(); - Assert.assertEquals(1, postAttributesMsg.getKvCount()); - TransportProtos.KeyValueProto keyValueProto = postAttributesMsg.getKv(0); - Assert.assertEquals("key2", keyValueProto.getKey()); - Assert.assertEquals("value2", keyValueProto.getStringV()); - } - - private void testAttributesDeleteMsg(Device device) throws Exception { - String deleteAttributesData = "{\"scope\":\"SERVER_SCOPE\",\"keys\":[\"key1\",\"key2\"]}"; - JsonNode deleteAttributesEntityData = mapper.readTree(deleteAttributesData); - EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData); - edgeImitator.expectMessageAmount(1); - edgeEventService.saveAsync(edgeEvent).get(); - clusterService.onEdgeEventUpdate(tenantId, edge.getId()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof EntityDataProto); - EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; - Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); - Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); - Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); - - Assert.assertTrue(latestEntityDataMsg.hasAttributeDeleteMsg()); - - AttributeDeleteMsg attributeDeleteMsg = latestEntityDataMsg.getAttributeDeleteMsg(); - Assert.assertEquals(attributeDeleteMsg.getScope(), deleteAttributesEntityData.get("scope").asText()); - - Assert.assertEquals(2, attributeDeleteMsg.getAttributeNamesCount()); - Assert.assertEquals("key1", attributeDeleteMsg.getAttributeNames(0)); - Assert.assertEquals("key2", attributeDeleteMsg.getAttributeNames(1)); - } - - @Test - public void testRpcCall() throws Exception { - Device device = findDeviceByName("Edge Device 1"); - - ObjectNode body = mapper.createObjectNode(); - body.put("requestId", new Random().nextInt()); - body.put("requestUUID", Uuids.timeBased().toString()); - body.put("oneway", false); - body.put("expirationTime", System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10)); - body.put("method", "test_method"); - body.put("params", "{\"param1\":\"value1\"}"); - - EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body); - edgeImitator.expectMessageAmount(1); - edgeEventService.saveAsync(edgeEvent).get(); - clusterService.onEdgeEventUpdate(tenantId, edge.getId()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceRpcCallMsg); - DeviceRpcCallMsg latestDeviceRpcCallMsg = (DeviceRpcCallMsg) latestMessage; - Assert.assertEquals("test_method", latestDeviceRpcCallMsg.getRequestMsg().getMethod()); - } - - @Test - public void testTimeseriesWithFailures() throws Exception { - int numberOfTimeseriesToSend = 1000; - - edgeImitator.setRandomFailuresOnTimeseriesDownlink(true); - // imitator will generate failure in 5% of cases - edgeImitator.setFailureProbability(5.0); - - edgeImitator.expectMessageAmount(numberOfTimeseriesToSend); - Device device = findDeviceByName("Edge Device 1"); - for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { - String timeseriesData = "{\"data\":{\"idx\":" + idx + "},\"ts\":" + System.currentTimeMillis() + "}"; - JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); - EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, - device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); - edgeEventService.saveAsync(edgeEvent).get(); - clusterService.onEdgeEventUpdate(tenantId, edge.getId()); - } - - Assert.assertTrue(edgeImitator.waitForMessages(120)); - - List allTelemetryMsgs = edgeImitator.findAllMessagesByType(EntityDataProto.class); - Assert.assertEquals(numberOfTimeseriesToSend, allTelemetryMsgs.size()); - - for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { - Assert.assertTrue(isIdxExistsInTheDownlinkList(idx, allTelemetryMsgs)); - } - - edgeImitator.setRandomFailuresOnTimeseriesDownlink(false); - } - - private boolean isIdxExistsInTheDownlinkList(int idx, List allTelemetryMsgs) { - for (EntityDataProto proto : allTelemetryMsgs) { - TransportProtos.PostTelemetryMsg postTelemetryMsg = proto.getPostTelemetryMsg(); - Assert.assertEquals(1, postTelemetryMsg.getTsKvListCount()); - TransportProtos.TsKvListProto tsKvListProto = postTelemetryMsg.getTsKvList(0); - Assert.assertEquals(1, tsKvListProto.getKvCount()); - TransportProtos.KeyValueProto keyValueProto = tsKvListProto.getKv(0); - Assert.assertEquals("idx", keyValueProto.getKey()); - if (keyValueProto.getLongV() == idx) { - return true; - } - } - return false; - } - - @Test - public void testSendDeviceToCloud() throws Exception { - UUID uuid = Uuids.timeBased(); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - DeviceUpdateMsg.Builder deviceUpdateMsgBuilder = DeviceUpdateMsg.newBuilder(); - deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits()); - deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits()); - deviceUpdateMsgBuilder.setName("Edge Device 2"); - deviceUpdateMsgBuilder.setType("test"); - deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); - testAutoGeneratedCodeByProtobuf(deviceUpdateMsgBuilder); - uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(1); - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - - Assert.assertTrue(edgeImitator.waitForResponses()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceCredentialsRequestMsg); - DeviceCredentialsRequestMsg latestDeviceCredentialsRequestMsg = (DeviceCredentialsRequestMsg) latestMessage; - Assert.assertEquals(uuid.getMostSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdMSB()); - Assert.assertEquals(uuid.getLeastSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); - - UUID newDeviceId = new UUID(latestDeviceCredentialsRequestMsg.getDeviceIdMSB(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); - - Device device = doGet("/api/device/" + newDeviceId, Device.class); - Assert.assertNotNull(device); - Assert.assertEquals("Edge Device 2", device.getName()); - } - - @Test - public void testSendDeviceToCloudWithNameThatAlreadyExistsOnCloud() throws Exception { - String deviceOnCloudName = StringUtils.randomAlphanumeric(15); - Device deviceOnCloud = saveDevice(deviceOnCloudName, "Default"); - - UUID uuid = Uuids.timeBased(); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - DeviceUpdateMsg.Builder deviceUpdateMsgBuilder = DeviceUpdateMsg.newBuilder(); - deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits()); - deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits()); - deviceUpdateMsgBuilder.setName(deviceOnCloudName); - deviceUpdateMsgBuilder.setType("test"); - deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); - testAutoGeneratedCodeByProtobuf(deviceUpdateMsgBuilder); - uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(2); - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - - Assert.assertTrue(edgeImitator.waitForResponses()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getMessageFromTail(2); - Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); - DeviceUpdateMsg latestDeviceUpdateMsg = (DeviceUpdateMsg) latestMessage; - Assert.assertNotEquals(deviceOnCloudName, latestDeviceUpdateMsg.getName()); - Assert.assertEquals(deviceOnCloudName, latestDeviceUpdateMsg.getConflictName()); - - UUID newDeviceId = new UUID(latestDeviceUpdateMsg.getIdMSB(), latestDeviceUpdateMsg.getIdLSB()); - - Assert.assertNotEquals(deviceOnCloud.getId().getId(), newDeviceId); - - Device device = doGet("/api/device/" + newDeviceId, Device.class); - Assert.assertNotNull(device); - Assert.assertNotEquals(deviceOnCloudName, device.getName()); - - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceCredentialsRequestMsg); - DeviceCredentialsRequestMsg latestDeviceCredentialsRequestMsg = (DeviceCredentialsRequestMsg) latestMessage; - Assert.assertEquals(uuid.getMostSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdMSB()); - Assert.assertEquals(uuid.getLeastSignificantBits(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); - - newDeviceId = new UUID(latestDeviceCredentialsRequestMsg.getDeviceIdMSB(), latestDeviceCredentialsRequestMsg.getDeviceIdLSB()); - - device = doGet("/api/device/" + newDeviceId, Device.class); - Assert.assertNotNull(device); - Assert.assertNotEquals(deviceOnCloudName, device.getName()); - } - - @Test - public void testSendRelationRequestToCloud() throws Exception { - Device device = findDeviceByName("Edge Device 1"); - Asset asset = findAssetByName("Edge Asset 1"); - - EntityRelation relation = new EntityRelation(); - relation.setType("test"); - relation.setFrom(device.getId()); - relation.setTo(asset.getId()); - relation.setTypeGroup(RelationTypeGroup.COMMON); - - edgeImitator.expectMessageAmount(1); - doPost("/api/relation", relation); - Assert.assertTrue(edgeImitator.waitForMessages()); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - RelationRequestMsg.Builder relationRequestMsgBuilder = RelationRequestMsg.newBuilder(); - relationRequestMsgBuilder.setEntityIdMSB(device.getId().getId().getMostSignificantBits()); - relationRequestMsgBuilder.setEntityIdLSB(device.getId().getId().getLeastSignificantBits()); - relationRequestMsgBuilder.setEntityType(device.getId().getEntityType().name()); - testAutoGeneratedCodeByProtobuf(relationRequestMsgBuilder); - - uplinkMsgBuilder.addRelationRequestMsg(relationRequestMsgBuilder.build()); - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); - RelationUpdateMsg relationUpdateMsg = (RelationUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, relationUpdateMsg.getMsgType()); - Assert.assertEquals(relation.getType(), relationUpdateMsg.getType()); - - UUID fromUUID = new UUID(relationUpdateMsg.getFromIdMSB(), relationUpdateMsg.getFromIdLSB()); - EntityId fromEntityId = EntityIdFactory.getByTypeAndUuid(relationUpdateMsg.getFromEntityType(), fromUUID); - Assert.assertEquals(relation.getFrom(), fromEntityId); - - UUID toUUID = new UUID(relationUpdateMsg.getToIdMSB(), relationUpdateMsg.getToIdLSB()); - EntityId toEntityId = EntityIdFactory.getByTypeAndUuid(relationUpdateMsg.getToEntityType(), toUUID); - Assert.assertEquals(relation.getTo(), toEntityId); - - Assert.assertEquals(relation.getTypeGroup().name(), relationUpdateMsg.getTypeGroup()); - } - - @Test - public void testSendAlarmToCloud() throws Exception { - Device device = saveDeviceOnCloudAndVerifyDeliveryToEdge(); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - AlarmUpdateMsg.Builder alarmUpdateMgBuilder = AlarmUpdateMsg.newBuilder(); - alarmUpdateMgBuilder.setName("alarm from edge"); - alarmUpdateMgBuilder.setStatus(AlarmStatus.ACTIVE_UNACK.name()); - alarmUpdateMgBuilder.setSeverity(AlarmSeverity.CRITICAL.name()); - alarmUpdateMgBuilder.setOriginatorName(device.getName()); - alarmUpdateMgBuilder.setOriginatorType(EntityType.DEVICE.name()); - testAutoGeneratedCodeByProtobuf(alarmUpdateMgBuilder); - uplinkMsgBuilder.addAlarmUpdateMsg(alarmUpdateMgBuilder.build()); - - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - - - List alarms = doGetTypedWithPageLink("/api/alarm/{entityType}/{entityId}?", - new TypeReference>() {}, - new PageLink(100), device.getId().getEntityType().name(), device.getUuidId()) - .getData(); - Optional foundAlarm = alarms.stream().filter(alarm -> alarm.getType().equals("alarm from edge")).findAny(); - Assert.assertTrue(foundAlarm.isPresent()); - AlarmInfo alarmInfo = foundAlarm.get(); - Assert.assertEquals(device.getId(), alarmInfo.getOriginator()); - Assert.assertEquals(AlarmStatus.ACTIVE_UNACK, alarmInfo.getStatus()); - Assert.assertEquals(AlarmSeverity.CRITICAL, alarmInfo.getSeverity()); - } - - @Test - public void testSendTelemetryToCloud() throws Exception { - Device device = saveDeviceOnCloudAndVerifyDeliveryToEdge(); - - edgeImitator.expectResponsesAmount(2); - - JsonObject data = new JsonObject(); - String timeseriesKey = "key"; - String timeseriesValue = "25"; - data.addProperty(timeseriesKey, timeseriesValue); - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - EntityDataProto.Builder entityDataBuilder = EntityDataProto.newBuilder(); - entityDataBuilder.setPostTelemetryMsg(JsonConverter.convertToTelemetryProto(data, System.currentTimeMillis())); - entityDataBuilder.setEntityType(device.getId().getEntityType().name()); - entityDataBuilder.setEntityIdMSB(device.getUuidId().getMostSignificantBits()); - entityDataBuilder.setEntityIdLSB(device.getUuidId().getLeastSignificantBits()); - testAutoGeneratedCodeByProtobuf(entityDataBuilder); - uplinkMsgBuilder.addEntityData(entityDataBuilder.build()); - - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - - JsonObject attributesData = new JsonObject(); - String attributesKey = "test_attr"; - String attributesValue = "test_value"; - attributesData.addProperty(attributesKey, attributesValue); - UplinkMsg.Builder uplinkMsgBuilder2 = UplinkMsg.newBuilder(); - EntityDataProto.Builder entityDataBuilder2 = EntityDataProto.newBuilder(); - entityDataBuilder2.setEntityType(device.getId().getEntityType().name()); - entityDataBuilder2.setEntityIdMSB(device.getId().getId().getMostSignificantBits()); - entityDataBuilder2.setEntityIdLSB(device.getId().getId().getLeastSignificantBits()); - entityDataBuilder2.setAttributesUpdatedMsg(JsonConverter.convertToAttributesProto(attributesData)); - entityDataBuilder2.setPostAttributeScope(DataConstants.SERVER_SCOPE); - testAutoGeneratedCodeByProtobuf(entityDataBuilder2); - - uplinkMsgBuilder2.addEntityData(entityDataBuilder2.build()); - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder2); - - edgeImitator.sendUplinkMsg(uplinkMsgBuilder2.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - - Awaitility.await() - .atMost(2, TimeUnit.SECONDS) - .until(() -> loadDeviceTimeseries(device, timeseriesKey).containsKey(timeseriesKey)); - - Map>> timeseries = loadDeviceTimeseries(device, timeseriesKey); - Assert.assertTrue(timeseries.containsKey(timeseriesKey)); - Assert.assertEquals(1, timeseries.get(timeseriesKey).size()); - Assert.assertEquals(timeseriesValue, timeseries.get(timeseriesKey).get(0).get("value")); - - String attributeValuesUrl = "/api/plugins/telemetry/DEVICE/" + device.getId() + "/values/attributes/" + DataConstants.SERVER_SCOPE; - List> attributes = doGetAsyncTyped(attributeValuesUrl, new TypeReference<>() {}); - - Assert.assertEquals(3, attributes.size()); - - Optional> activeAttributeOpt = getAttributeByKey("active", attributes); - Assert.assertTrue(activeAttributeOpt.isPresent()); - Map activeAttribute = activeAttributeOpt.get(); - Assert.assertEquals("true", activeAttribute.get("value")); - - Optional> customAttributeOpt = getAttributeByKey(attributesKey, attributes); - Assert.assertTrue(customAttributeOpt.isPresent()); - Map customAttribute = customAttributeOpt.get(); - Assert.assertEquals(attributesValue, customAttribute.get("value")); - - doDelete("/api/plugins/telemetry/DEVICE/" + device.getId().getId() + "/SERVER_SCOPE?keys=" + attributesKey, String.class); - } - - private Optional> getAttributeByKey(String key, List> attributes) { - return attributes.stream().filter(kv -> kv.get("key").equals(key)).findFirst(); - } - - private Map>> loadDeviceTimeseries(Device device, String timeseriesKey) throws Exception { - return doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/values/timeseries?keys=" + timeseriesKey, - new TypeReference<>() {}); - } - - @Test - public void testSendRelationToCloud() throws Exception { - Device device1 = saveDeviceOnCloudAndVerifyDeliveryToEdge(); - Device device2 = saveDeviceOnCloudAndVerifyDeliveryToEdge(); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - RelationUpdateMsg.Builder relationUpdateMsgBuilder = RelationUpdateMsg.newBuilder(); - relationUpdateMsgBuilder.setType("test"); - relationUpdateMsgBuilder.setTypeGroup(RelationTypeGroup.COMMON.name()); - relationUpdateMsgBuilder.setToIdMSB(device1.getId().getId().getMostSignificantBits()); - relationUpdateMsgBuilder.setToIdLSB(device1.getId().getId().getLeastSignificantBits()); - relationUpdateMsgBuilder.setToEntityType(device1.getId().getEntityType().name()); - relationUpdateMsgBuilder.setFromIdMSB(device2.getId().getId().getMostSignificantBits()); - relationUpdateMsgBuilder.setFromIdLSB(device2.getId().getId().getLeastSignificantBits()); - relationUpdateMsgBuilder.setFromEntityType(device2.getId().getEntityType().name()); - relationUpdateMsgBuilder.setAdditionalInfo("{}"); - testAutoGeneratedCodeByProtobuf(relationUpdateMsgBuilder); - uplinkMsgBuilder.addRelationUpdateMsg(relationUpdateMsgBuilder.build()); - - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - - EntityRelation relation = doGet("/api/relation?" + - "&fromId=" + device2.getUuidId() + - "&fromType=" + device2.getId().getEntityType().name() + - "&relationType=" + "test" + - "&relationTypeGroup=" + RelationTypeGroup.COMMON.name() + - "&toId=" + device1.getUuidId() + - "&toType=" + device1.getId().getEntityType().name(), EntityRelation.class); - Assert.assertNotNull(relation); - } - - @Test - public void testSendDeleteDeviceOnEdgeToCloud() throws Exception { - Device device = saveDeviceOnCloudAndVerifyDeliveryToEdge(); - UplinkMsg.Builder upLinkMsgBuilder = UplinkMsg.newBuilder(); - DeviceUpdateMsg.Builder deviceDeleteMsgBuilder = DeviceUpdateMsg.newBuilder(); - deviceDeleteMsgBuilder.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE); - deviceDeleteMsgBuilder.setIdMSB(device.getId().getId().getMostSignificantBits()); - deviceDeleteMsgBuilder.setIdLSB(device.getId().getId().getLeastSignificantBits()); - testAutoGeneratedCodeByProtobuf(deviceDeleteMsgBuilder); - - upLinkMsgBuilder.addDeviceUpdateMsg(deviceDeleteMsgBuilder.build()); - testAutoGeneratedCodeByProtobuf(upLinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(upLinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - device = doGet("/api/device/" + device.getUuidId(), Device.class); - Assert.assertNotNull(device); - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/devices?", - new TypeReference>() { - }, new PageLink(100)).getData(); - Assert.assertFalse(edgeDevices.contains(device)); - } - - @Test - public void testSendRuleChainMetadataRequestToCloud() throws Exception { - RuleChainId edgeRootRuleChainId = edge.getRootRuleChainId(); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - RuleChainMetadataRequestMsg.Builder ruleChainMetadataRequestMsgBuilder = RuleChainMetadataRequestMsg.newBuilder(); - ruleChainMetadataRequestMsgBuilder.setRuleChainIdMSB(edgeRootRuleChainId.getId().getMostSignificantBits()); - ruleChainMetadataRequestMsgBuilder.setRuleChainIdLSB(edgeRootRuleChainId.getId().getLeastSignificantBits()); - testAutoGeneratedCodeByProtobuf(ruleChainMetadataRequestMsgBuilder); - uplinkMsgBuilder.addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); - - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); - RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = (RuleChainMetadataUpdateMsg) latestMessage; - Assert.assertEquals(ruleChainMetadataUpdateMsg.getRuleChainIdMSB(), edgeRootRuleChainId.getId().getMostSignificantBits()); - Assert.assertEquals(ruleChainMetadataUpdateMsg.getRuleChainIdLSB(), edgeRootRuleChainId.getId().getLeastSignificantBits()); - - testAutoGeneratedCodeByProtobuf(ruleChainMetadataUpdateMsg); - } - - @Test - public void testSendUserCredentialsRequestToCloud() throws Exception { - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - UserCredentialsRequestMsg.Builder userCredentialsRequestMsgBuilder = UserCredentialsRequestMsg.newBuilder(); - userCredentialsRequestMsgBuilder.setUserIdMSB(tenantAdmin.getId().getId().getMostSignificantBits()); - userCredentialsRequestMsgBuilder.setUserIdLSB(tenantAdmin.getId().getId().getLeastSignificantBits()); - testAutoGeneratedCodeByProtobuf(userCredentialsRequestMsgBuilder); - uplinkMsgBuilder.addUserCredentialsRequestMsg(userCredentialsRequestMsgBuilder.build()); - - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof UserCredentialsUpdateMsg); - UserCredentialsUpdateMsg userCredentialsUpdateMsg = (UserCredentialsUpdateMsg) latestMessage; - Assert.assertEquals(userCredentialsUpdateMsg.getUserIdMSB(), tenantAdmin.getId().getId().getMostSignificantBits()); - Assert.assertEquals(userCredentialsUpdateMsg.getUserIdLSB(), tenantAdmin.getId().getId().getLeastSignificantBits()); - - testAutoGeneratedCodeByProtobuf(userCredentialsUpdateMsg); - } - - @Test - public void testSendDeviceCredentialsRequestToCloud() throws Exception { - Device device = findDeviceByName("Edge Device 1"); - - DeviceCredentials deviceCredentials = doGet("/api/device/" + device.getUuidId() + "/credentials", DeviceCredentials.class); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - DeviceCredentialsRequestMsg.Builder deviceCredentialsRequestMsgBuilder = DeviceCredentialsRequestMsg.newBuilder(); - deviceCredentialsRequestMsgBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); - deviceCredentialsRequestMsgBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); - testAutoGeneratedCodeByProtobuf(deviceCredentialsRequestMsgBuilder); - uplinkMsgBuilder.addDeviceCredentialsRequestMsg(deviceCredentialsRequestMsgBuilder.build()); - - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceCredentialsUpdateMsg); - DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg = (DeviceCredentialsUpdateMsg) latestMessage; - Assert.assertEquals(deviceCredentialsUpdateMsg.getDeviceIdMSB(), device.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceCredentialsUpdateMsg.getDeviceIdLSB(), device.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(deviceCredentialsUpdateMsg.getCredentialsType(), deviceCredentials.getCredentialsType().name()); - Assert.assertEquals(deviceCredentialsUpdateMsg.getCredentialsId(), deviceCredentials.getCredentialsId()); - } - - @Test - public void testSendDeviceRpcResponseToCloud() throws Exception { - Device device = findDeviceByName("Edge Device 1"); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - DeviceRpcCallMsg.Builder deviceRpcCallResponseBuilder = DeviceRpcCallMsg.newBuilder(); - deviceRpcCallResponseBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); - deviceRpcCallResponseBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); - deviceRpcCallResponseBuilder.setOneway(true); - deviceRpcCallResponseBuilder.setRequestId(0); - deviceRpcCallResponseBuilder.setExpirationTime(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10)); - RpcResponseMsg.Builder responseBuilder = - RpcResponseMsg.newBuilder().setResponse("{}"); - testAutoGeneratedCodeByProtobuf(responseBuilder); - - deviceRpcCallResponseBuilder.setResponseMsg(responseBuilder.build()); - testAutoGeneratedCodeByProtobuf(deviceRpcCallResponseBuilder); - - uplinkMsgBuilder.addDeviceRpcCallMsg(deviceRpcCallResponseBuilder.build()); - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - } - - @Test - public void testSendDeviceCredentialsUpdateToCloud() throws Exception { - Device device = findDeviceByName("Edge Device 1"); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - DeviceCredentialsUpdateMsg.Builder deviceCredentialsUpdateMsgBuilder = DeviceCredentialsUpdateMsg.newBuilder(); - deviceCredentialsUpdateMsgBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); - deviceCredentialsUpdateMsgBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); - deviceCredentialsUpdateMsgBuilder.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN.name()); - deviceCredentialsUpdateMsgBuilder.setCredentialsId("NEW_TOKEN"); - testAutoGeneratedCodeByProtobuf(deviceCredentialsUpdateMsgBuilder); - uplinkMsgBuilder.addDeviceCredentialsUpdateMsg(deviceCredentialsUpdateMsgBuilder.build()); - - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - } - - @Test - public void testSendAttributesRequestToCloud() throws Exception { - Device device = findDeviceByName("Edge Device 1"); - sendAttributesRequestAndVerify(device, DataConstants.SERVER_SCOPE, "{\"key1\":\"value1\"}", - "key1", "value1"); - sendAttributesRequestAndVerify(device, DataConstants.SHARED_SCOPE, "{\"key2\":\"value2\"}", - "key2", "value2"); - } - - private void sendAttributesRequestAndVerify(Device device, String scope, String attributesDataStr, String expectedKey, - String expectedValue) throws Exception { - JsonNode attributesData = mapper.readTree(attributesDataStr); - - doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/attributes/" + scope, - attributesData); - - // Wait before device attributes saved to database before requesting them from edge - Awaitility.await() - .atMost(10, TimeUnit.SECONDS) - .until(() -> { - String urlTemplate = "/api/plugins/telemetry/DEVICE/" + device.getId() + "/keys/attributes/" + scope; - List actualKeys = doGetAsyncTyped(urlTemplate, new TypeReference<>() {}); - return actualKeys != null && !actualKeys.isEmpty() && actualKeys.contains(expectedKey); - }); - - UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); - AttributesRequestMsg.Builder attributesRequestMsgBuilder = AttributesRequestMsg.newBuilder(); - attributesRequestMsgBuilder.setEntityIdMSB(device.getUuidId().getMostSignificantBits()); - attributesRequestMsgBuilder.setEntityIdLSB(device.getUuidId().getLeastSignificantBits()); - attributesRequestMsgBuilder.setEntityType(EntityType.DEVICE.name()); - attributesRequestMsgBuilder.setScope(scope); - testAutoGeneratedCodeByProtobuf(attributesRequestMsgBuilder); - uplinkMsgBuilder.addAttributesRequestMsg(attributesRequestMsgBuilder.build()); - testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); - - edgeImitator.expectResponsesAmount(1); - edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); - Assert.assertTrue(edgeImitator.waitForResponses()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof EntityDataProto); - EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; - Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); - Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); - Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); - Assert.assertEquals(scope, latestEntityDataMsg.getPostAttributeScope()); - Assert.assertTrue(latestEntityDataMsg.hasAttributesUpdatedMsg()); - - TransportProtos.PostAttributeMsg attributesUpdatedMsg = latestEntityDataMsg.getAttributesUpdatedMsg(); - - boolean found = false; - for (TransportProtos.KeyValueProto keyValueProto : attributesUpdatedMsg.getKvList()) { - if (keyValueProto.getKey().equals(expectedKey)) { - Assert.assertEquals(expectedKey, keyValueProto.getKey()); - Assert.assertEquals(expectedValue, keyValueProto.getStringV()); - found = true; - } - } - Assert.assertTrue("Expected key and value must be found", found); - } - - @Test - public void testOtaPackages_usesUrl() throws Exception { - // 1 - SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest(); - firmwareInfo.setDeviceProfileId(thermostatDeviceProfile.getId()); - firmwareInfo.setType(FIRMWARE); - firmwareInfo.setTitle("My firmware #1"); - firmwareInfo.setVersion("v1.0"); - firmwareInfo.setTag("My firmware #1 v1.0"); - firmwareInfo.setUsesUrl(true); - firmwareInfo.setUrl("http://localhost:8080/v1/package"); - firmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode()); - - edgeImitator.expectMessageAmount(1); - OtaPackageInfo savedFirmwareInfo = doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof OtaPackageUpdateMsg); - OtaPackageUpdateMsg otaPackageUpdateMsg = (OtaPackageUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, otaPackageUpdateMsg.getMsgType()); - Assert.assertEquals(savedFirmwareInfo.getUuidId().getMostSignificantBits(), otaPackageUpdateMsg.getIdMSB()); - Assert.assertEquals(savedFirmwareInfo.getUuidId().getLeastSignificantBits(), otaPackageUpdateMsg.getIdLSB()); - Assert.assertEquals(thermostatDeviceProfile.getUuidId().getMostSignificantBits(), otaPackageUpdateMsg.getDeviceProfileIdMSB()); - Assert.assertEquals(thermostatDeviceProfile.getUuidId().getLeastSignificantBits(), otaPackageUpdateMsg.getDeviceProfileIdLSB()); - Assert.assertEquals(FIRMWARE, OtaPackageType.valueOf(otaPackageUpdateMsg.getType())); - Assert.assertEquals("My firmware #1", otaPackageUpdateMsg.getTitle()); - Assert.assertEquals("v1.0", otaPackageUpdateMsg.getVersion()); - Assert.assertEquals("My firmware #1 v1.0", otaPackageUpdateMsg.getTag()); - Assert.assertEquals("http://localhost:8080/v1/package", otaPackageUpdateMsg.getUrl()); - Assert.assertFalse(otaPackageUpdateMsg.hasData()); - Assert.assertFalse(otaPackageUpdateMsg.hasFileName()); - Assert.assertFalse(otaPackageUpdateMsg.hasContentType()); - Assert.assertFalse(otaPackageUpdateMsg.hasChecksumAlgorithm()); - Assert.assertFalse(otaPackageUpdateMsg.hasChecksum()); - Assert.assertFalse(otaPackageUpdateMsg.hasDataSize()); - - // 2 - edgeImitator.expectMessageAmount(1); - doDelete("/api/otaPackage/" + savedFirmwareInfo.getUuidId()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof OtaPackageUpdateMsg); - otaPackageUpdateMsg = (OtaPackageUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, otaPackageUpdateMsg.getMsgType()); - Assert.assertEquals(otaPackageUpdateMsg.getIdMSB(), savedFirmwareInfo.getUuidId().getMostSignificantBits()); - Assert.assertEquals(otaPackageUpdateMsg.getIdLSB(), savedFirmwareInfo.getUuidId().getLeastSignificantBits()); - } - - @Test - public void testOtaPackages_hasData() throws Exception { - // 1 - SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest(); - firmwareInfo.setDeviceProfileId(thermostatDeviceProfile.getId()); - firmwareInfo.setType(FIRMWARE); - firmwareInfo.setTitle("My firmware #2"); - firmwareInfo.setVersion("v2.0"); - firmwareInfo.setTag("My firmware #2 v2.0"); - firmwareInfo.setUsesUrl(false); - firmwareInfo.setHasData(false); - firmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode()); - - edgeImitator.expectMessageAmount(1); - - OtaPackageInfo savedFirmwareInfo = doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class); - MockMultipartFile testData = new MockMultipartFile("file", "firmware.bin", "image/png", ByteBuffer.wrap(new byte[]{1, 3, 5}).array()); - savedFirmwareInfo = saveData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksumAlgorithm={checksumAlgorithm}", testData, ChecksumAlgorithm.SHA256.name()); - - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof OtaPackageUpdateMsg); - OtaPackageUpdateMsg otaPackageUpdateMsg = (OtaPackageUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, otaPackageUpdateMsg.getMsgType()); - Assert.assertEquals(savedFirmwareInfo.getUuidId().getMostSignificantBits(), otaPackageUpdateMsg.getIdMSB()); - Assert.assertEquals(savedFirmwareInfo.getUuidId().getLeastSignificantBits(), otaPackageUpdateMsg.getIdLSB()); - Assert.assertEquals(thermostatDeviceProfile.getUuidId().getMostSignificantBits(), otaPackageUpdateMsg.getDeviceProfileIdMSB()); - Assert.assertEquals(thermostatDeviceProfile.getUuidId().getLeastSignificantBits(), otaPackageUpdateMsg.getDeviceProfileIdLSB()); - Assert.assertEquals(FIRMWARE, OtaPackageType.valueOf(otaPackageUpdateMsg.getType())); - Assert.assertEquals("My firmware #2", otaPackageUpdateMsg.getTitle()); - Assert.assertEquals("v2.0", otaPackageUpdateMsg.getVersion()); - Assert.assertEquals("My firmware #2 v2.0", otaPackageUpdateMsg.getTag()); - Assert.assertFalse(otaPackageUpdateMsg.hasUrl()); - Assert.assertEquals("firmware.bin", otaPackageUpdateMsg.getFileName()); - Assert.assertEquals("image/png", otaPackageUpdateMsg.getContentType()); - Assert.assertEquals(ChecksumAlgorithm.SHA256.name(), otaPackageUpdateMsg.getChecksumAlgorithm()); - Assert.assertEquals("62467691cf583d4fa78b18fafaf9801f505e0ef03baf0603fd4b0cd004cd1e75", otaPackageUpdateMsg.getChecksum()); - Assert.assertEquals(3L, otaPackageUpdateMsg.getDataSize()); - Assert.assertEquals(ByteString.copyFrom(new byte[]{1, 3, 5}), otaPackageUpdateMsg.getData()); - - // 2 - edgeImitator.expectMessageAmount(1); - doDelete("/api/otaPackage/" + savedFirmwareInfo.getUuidId()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof OtaPackageUpdateMsg); - otaPackageUpdateMsg = (OtaPackageUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, otaPackageUpdateMsg.getMsgType()); - Assert.assertEquals(otaPackageUpdateMsg.getIdMSB(), savedFirmwareInfo.getUuidId().getMostSignificantBits()); - Assert.assertEquals(otaPackageUpdateMsg.getIdLSB(), savedFirmwareInfo.getUuidId().getLeastSignificantBits()); - } - - @Test - public void testQueues() throws Exception { - loginSysAdmin(); - - // 1 - Queue queue = new Queue(); - queue.setName("EdgeMain"); - queue.setTopic("tb_rule_engine.EdgeMain"); - queue.setPollInterval(25); - queue.setPartitions(10); - queue.setConsumerPerPartition(false); - queue.setPackProcessingTimeout(2000); - SubmitStrategy submitStrategy = new SubmitStrategy(); - submitStrategy.setType(SubmitStrategyType.SEQUENTIAL_BY_ORIGINATOR); - queue.setSubmitStrategy(submitStrategy); - ProcessingStrategy processingStrategy = new ProcessingStrategy(); - processingStrategy.setType(ProcessingStrategyType.RETRY_ALL); - processingStrategy.setRetries(3); - processingStrategy.setFailurePercentage(0.7); - processingStrategy.setPauseBetweenRetries(3); - processingStrategy.setMaxPauseBetweenRetries(5); - queue.setProcessingStrategy(processingStrategy); - - edgeImitator.expectMessageAmount(1); - Queue savedQueue = doPost("/api/queues?serviceType=" + ServiceType.TB_RULE_ENGINE.name(), queue, Queue.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof QueueUpdateMsg); - QueueUpdateMsg queueUpdateMsg = (QueueUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, queueUpdateMsg.getMsgType()); - Assert.assertEquals(savedQueue.getUuidId().getMostSignificantBits(), queueUpdateMsg.getIdMSB()); - Assert.assertEquals(savedQueue.getUuidId().getLeastSignificantBits(), queueUpdateMsg.getIdLSB()); - Assert.assertEquals(savedQueue.getTenantId().getId().getMostSignificantBits(), queueUpdateMsg.getTenantIdMSB()); - Assert.assertEquals(savedQueue.getTenantId().getId().getLeastSignificantBits(), queueUpdateMsg.getTenantIdLSB()); - Assert.assertEquals("EdgeMain", queueUpdateMsg.getName()); - Assert.assertEquals("tb_rule_engine.EdgeMain", queueUpdateMsg.getTopic()); - Assert.assertEquals(25, queueUpdateMsg.getPollInterval()); - Assert.assertEquals(10, queueUpdateMsg.getPartitions()); - Assert.assertFalse(queueUpdateMsg.getConsumerPerPartition()); - Assert.assertEquals(2000, queueUpdateMsg.getPackProcessingTimeout()); - Assert.assertEquals(SubmitStrategyType.SEQUENTIAL_BY_ORIGINATOR.name(), queueUpdateMsg.getSubmitStrategy().getType()); - Assert.assertEquals(0, queueUpdateMsg.getSubmitStrategy().getBatchSize()); - Assert.assertEquals(ProcessingStrategyType.RETRY_ALL.name(), queueUpdateMsg.getProcessingStrategy().getType()); - Assert.assertEquals(3, queueUpdateMsg.getProcessingStrategy().getRetries()); - Assert.assertEquals(0.7, queueUpdateMsg.getProcessingStrategy().getFailurePercentage(), 1); - Assert.assertEquals(3, queueUpdateMsg.getProcessingStrategy().getPauseBetweenRetries()); - Assert.assertEquals(5, queueUpdateMsg.getProcessingStrategy().getMaxPauseBetweenRetries()); - - // 2 - edgeImitator.expectMessageAmount(1); - savedQueue.setPollInterval(50); - savedQueue = doPost("/api/queues?serviceType=" + ServiceType.TB_RULE_ENGINE.name(), savedQueue, Queue.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof QueueUpdateMsg); - queueUpdateMsg = (QueueUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, queueUpdateMsg.getMsgType()); - Assert.assertEquals(50, queueUpdateMsg.getPollInterval()); - - // 3 - edgeImitator.expectMessageAmount(1); - doDelete("/api/queues/" + savedQueue.getUuidId()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof QueueUpdateMsg); - queueUpdateMsg = (QueueUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, queueUpdateMsg.getMsgType()); - Assert.assertEquals(queueUpdateMsg.getIdMSB(), savedQueue.getUuidId().getMostSignificantBits()); - Assert.assertEquals(queueUpdateMsg.getIdLSB(), savedQueue.getUuidId().getLeastSignificantBits()); - } - - // Utility methods - - private Device saveDeviceOnCloudAndVerifyDeliveryToEdge() throws Exception { - edgeImitator.expectMessageAmount(1); - OtaPackageInfo firmwareOtaPackageInfo = saveOtaPackageInfo(thermostatDeviceProfile.getId()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - Device savedDevice = saveDevice(StringUtils.randomAlphanumeric(15), thermostatDeviceProfile.getName()); - savedDevice.setFirmwareId(firmwareOtaPackageInfo.getId()); - - DeviceData deviceData = new DeviceData(); - deviceData.setConfiguration(new DefaultDeviceConfiguration()); - MqttDeviceTransportConfiguration transportConfiguration = new MqttDeviceTransportConfiguration(); - transportConfiguration.getProperties().put("topic", "tb_rule_engine.thermostat"); - deviceData.setTransportConfiguration(transportConfiguration); - savedDevice.setDeviceData(deviceData); - - savedDevice = doPost("/api/device", savedDevice, Device.class); - - // wait until device UPDATED event is sent to edge notification service - // to avoid edge notification service to send device UPDATED event before ASSIGNED_TO_EDGE - Thread.sleep(500); - - edgeImitator.expectMessageAmount(1); - doPost("/api/edge/" + edge.getUuidId() - + "/device/" + savedDevice.getUuidId(), Device.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); - DeviceUpdateMsg deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; - Assert.assertEquals(deviceUpdateMsg.getIdMSB(), savedDevice.getUuidId().getMostSignificantBits()); - Assert.assertEquals(deviceUpdateMsg.getIdLSB(), savedDevice.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(deviceUpdateMsg.getName(), savedDevice.getName()); - Assert.assertEquals(deviceUpdateMsg.getType(), savedDevice.getType()); - Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getFirmwareIdMSB()); - Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getFirmwareIdLSB()); - Optional deviceDataOpt = - dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray()); - Assert.assertTrue(deviceDataOpt.isPresent()); - deviceData = deviceDataOpt.get(); - Assert.assertTrue(deviceData.getTransportConfiguration() instanceof MqttDeviceTransportConfiguration); - MqttDeviceTransportConfiguration mqttDeviceTransportConfiguration = - (MqttDeviceTransportConfiguration) deviceData.getTransportConfiguration(); - Assert.assertEquals("tb_rule_engine.thermostat", mqttDeviceTransportConfiguration.getProperties().get("topic")); - return savedDevice; - } - - private Device findDeviceByName(String deviceName) throws Exception { - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/devices?", - new TypeReference>() { - }, new PageLink(100)).getData(); - Optional foundDevice = edgeDevices.stream().filter(d -> d.getName().equals(deviceName)).findAny(); - Assert.assertTrue(foundDevice.isPresent()); - Device device = foundDevice.get(); - Assert.assertEquals(deviceName, device.getName()); - return device; - } - - private Asset findAssetByName(String assetName) throws Exception { - List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/assets?", - new TypeReference>() { - }, new PageLink(100)).getData(); - - Assert.assertEquals(1, edgeAssets.size()); - Asset asset = edgeAssets.get(0); - Assert.assertEquals(assetName, asset.getName()); - return asset; - } - - private Device saveDevice(String deviceName, String type) { - Device device = new Device(); - device.setName(deviceName); - device.setType(type); - return doPost("/api/device", device, Device.class); - } - - private Asset saveAsset(String assetName) throws Exception { - Asset asset = new Asset(); - asset.setName(assetName); - asset.setType("test"); - return doPost("/api/asset", asset, Asset.class); - } - - private OtaPackageInfo saveOtaPackageInfo(DeviceProfileId deviceProfileId) { - SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest(); - firmwareInfo.setDeviceProfileId(deviceProfileId); - firmwareInfo.setType(FIRMWARE); - firmwareInfo.setTitle("Firmware Edge " + StringUtils.randomAlphanumeric(3)); - firmwareInfo.setVersion("v1.0"); - firmwareInfo.setTag("My firmware #1 v1.0"); - firmwareInfo.setUsesUrl(true); - firmwareInfo.setUrl("http://localhost:8080/v1/package"); - firmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode()); - firmwareInfo.setChecksumAlgorithm(ChecksumAlgorithm.SHA256); - return doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class); - } - - private EdgeEvent constructEdgeEvent(TenantId tenantId, EdgeId edgeId, EdgeEventActionType edgeEventAction, UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) { - EdgeEvent edgeEvent = new EdgeEvent(); - edgeEvent.setEdgeId(edgeId); - edgeEvent.setTenantId(tenantId); - edgeEvent.setAction(edgeEventAction); - edgeEvent.setEntityId(entityId); - edgeEvent.setType(edgeEventType); - edgeEvent.setBody(entityBody); - return edgeEvent; - } - - private void testAutoGeneratedCodeByProtobuf(MessageLite.Builder builder) throws InvalidProtocolBufferException { - MessageLite source = builder.build(); - - testAutoGeneratedCodeByProtobuf(source); - - MessageLite target = source.getParserForType().parseFrom(source.toByteArray()); - builder.clear().mergeFrom(target); - } - - private void testAutoGeneratedCodeByProtobuf(MessageLite source) throws InvalidProtocolBufferException { - MessageLite target = source.getParserForType().parseFrom(source.toByteArray()); - Assert.assertEquals(source, target); - Assert.assertEquals(source.hashCode(), target.hashCode()); - } - - private OtaPackageInfo saveData(String urlTemplate, MockMultipartFile content, String... params) throws Exception { - MockMultipartHttpServletRequestBuilder postRequest = MockMvcRequestBuilders.multipart(urlTemplate, params); - postRequest.file(content); - setJwtToken(postRequest); - return readResponse(mockMvc.perform(postRequest).andExpect(status().isOk()), OtaPackageInfo.class); - } - -} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEntityViewEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEntityViewEdgeTest.java new file mode 100644 index 0000000000..d3749236ca --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEntityViewEdgeTest.java @@ -0,0 +1,174 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.InvalidProtocolBufferException; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg; +import org.thingsboard.server.gen.edge.v1.EntityViewsRequestMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; + +import java.util.UUID; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseEntityViewEdgeTest extends AbstractEdgeTest { + + @Test + public void testEntityView() throws Exception { + // create entity view and assign to edge + edgeImitator.expectMessageAmount(1); + Device device = findDeviceByName("Edge Device 1"); + EntityView entityView = new EntityView(); + entityView.setName("Edge EntityView 1"); + entityView.setType("test"); + entityView.setEntityId(device.getId()); + EntityView savedEntityView = doPost("/api/entityView", entityView, EntityView.class); + doPost("/api/edge/" + edge.getUuidId() + + "/entityView/" + savedEntityView.getUuidId(), EntityView.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + verifyEntityViewUpdateMsg(savedEntityView, device); + + // update entity view + edgeImitator.expectMessageAmount(1); + savedEntityView.setName("Edge EntityView 1 Updated"); + savedEntityView = doPost("/api/entityView", savedEntityView, EntityView.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); + EntityViewUpdateMsg entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); + Assert.assertEquals(savedEntityView.getName(), entityViewUpdateMsg.getName()); + + + // request entity view(s) for device + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + EntityViewsRequestMsg.Builder entityViewsRequestBuilder = EntityViewsRequestMsg.newBuilder(); + entityViewsRequestBuilder.setEntityIdMSB(device.getUuidId().getMostSignificantBits()); + entityViewsRequestBuilder.setEntityIdLSB(device.getUuidId().getLeastSignificantBits()); + entityViewsRequestBuilder.setEntityType(device.getId().getEntityType().name()); + testAutoGeneratedCodeByProtobuf(entityViewsRequestBuilder); + uplinkMsgBuilder.addEntityViewsRequestMsg(entityViewsRequestBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + verifyEntityViewUpdateMsg(savedEntityView, device); + + // unassign entity view from edge + edgeImitator.expectMessageAmount(1); + doDelete("/api/edge/" + edge.getUuidId() + + "/entityView/" + savedEntityView.getUuidId(), EntityView.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); + entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); + Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), savedEntityView.getUuidId().getMostSignificantBits()); + Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), savedEntityView.getUuidId().getLeastSignificantBits()); + + // delete entity view - no messages expected + edgeImitator.expectMessageAmount(1); + doDelete("/api/entityView/" + savedEntityView.getUuidId()) + .andExpect(status().isOk()); + Assert.assertFalse(edgeImitator.waitForMessages(1)); + + // create entity view #2 and assign to edge + edgeImitator.expectMessageAmount(1); + entityView = new EntityView(); + entityView.setName("Edge EntityView 2"); + entityView.setType("test"); + entityView.setEntityId(device.getId()); + savedEntityView = doPost("/api/entityView", entityView, EntityView.class); + doPost("/api/edge/" + edge.getUuidId() + + "/entityView/" + savedEntityView.getUuidId(), EntityView.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + verifyEntityViewUpdateMsg(savedEntityView, device); + + // assign entity view #2 to customer + edgeImitator.expectMessageAmount(1); + Customer customer = new Customer(); + customer.setTitle("Edge Customer"); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + + edgeImitator.expectMessageAmount(1); + doPost("/api/customer/" + savedCustomer.getUuidId() + + "/entityView/" + savedEntityView.getUuidId(), EntityView.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); + entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); + Assert.assertEquals(savedCustomer.getUuidId().getMostSignificantBits(), entityViewUpdateMsg.getCustomerIdMSB()); + Assert.assertEquals(savedCustomer.getUuidId().getLeastSignificantBits(), entityViewUpdateMsg.getCustomerIdLSB()); + + // unassign entity view #2 from customer + edgeImitator.expectMessageAmount(1); + doDelete("/api/customer/entityView/" + savedEntityView.getUuidId(), EntityView.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); + entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); + Assert.assertEquals( + new CustomerId(EntityId.NULL_UUID), + new CustomerId(new UUID(entityViewUpdateMsg.getCustomerIdMSB(), entityViewUpdateMsg.getCustomerIdLSB()))); + + // delete entity view #2 - messages expected + edgeImitator.expectMessageAmount(1); + doDelete("/api/entityView/" + savedEntityView.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); + entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); + Assert.assertEquals(savedEntityView.getUuidId().getMostSignificantBits(), entityViewUpdateMsg.getIdMSB()); + Assert.assertEquals(savedEntityView.getUuidId().getLeastSignificantBits(), entityViewUpdateMsg.getIdLSB()); + + } + + private void verifyEntityViewUpdateMsg(EntityView entityView, Device device) throws InvalidProtocolBufferException { + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityViewUpdateMsg); + EntityViewUpdateMsg entityViewUpdateMsg = (EntityViewUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, entityViewUpdateMsg.getMsgType()); + Assert.assertEquals(entityView.getType(), entityViewUpdateMsg.getType()); + Assert.assertEquals(entityView.getName(), entityViewUpdateMsg.getName()); + Assert.assertEquals(entityView.getUuidId().getMostSignificantBits(), entityViewUpdateMsg.getIdMSB()); + Assert.assertEquals(entityView.getUuidId().getLeastSignificantBits(), entityViewUpdateMsg.getIdLSB()); + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), entityViewUpdateMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), entityViewUpdateMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), entityViewUpdateMsg.getEntityType().name()); + testAutoGeneratedCodeByProtobuf(entityViewUpdateMsg); + } + + + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseOtaPackageEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseOtaPackageEdgeTest.java new file mode 100644 index 0000000000..90a6a3afcd --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseOtaPackageEdgeTest.java @@ -0,0 +1,151 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.google.protobuf.AbstractMessage; +import com.google.protobuf.ByteString; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.gen.edge.v1.OtaPackageUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; + +import java.nio.ByteBuffer; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; + +abstract public class BaseOtaPackageEdgeTest extends AbstractEdgeTest { + + @Test + public void testOtaPackages_usesUrl() throws Exception { + // create ota package + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest(); + firmwareInfo.setDeviceProfileId(thermostatDeviceProfile.getId()); + firmwareInfo.setType(FIRMWARE); + firmwareInfo.setTitle("My firmware #1"); + firmwareInfo.setVersion("v1.0"); + firmwareInfo.setTag("My firmware #1 v1.0"); + firmwareInfo.setUsesUrl(true); + firmwareInfo.setUrl("http://localhost:8080/v1/package"); + firmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode()); + + edgeImitator.expectMessageAmount(1); + OtaPackageInfo savedFirmwareInfo = doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof OtaPackageUpdateMsg); + OtaPackageUpdateMsg otaPackageUpdateMsg = (OtaPackageUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, otaPackageUpdateMsg.getMsgType()); + Assert.assertEquals(savedFirmwareInfo.getUuidId().getMostSignificantBits(), otaPackageUpdateMsg.getIdMSB()); + Assert.assertEquals(savedFirmwareInfo.getUuidId().getLeastSignificantBits(), otaPackageUpdateMsg.getIdLSB()); + Assert.assertEquals(thermostatDeviceProfile.getUuidId().getMostSignificantBits(), otaPackageUpdateMsg.getDeviceProfileIdMSB()); + Assert.assertEquals(thermostatDeviceProfile.getUuidId().getLeastSignificantBits(), otaPackageUpdateMsg.getDeviceProfileIdLSB()); + Assert.assertEquals(FIRMWARE, OtaPackageType.valueOf(otaPackageUpdateMsg.getType())); + Assert.assertEquals("My firmware #1", otaPackageUpdateMsg.getTitle()); + Assert.assertEquals("v1.0", otaPackageUpdateMsg.getVersion()); + Assert.assertEquals("My firmware #1 v1.0", otaPackageUpdateMsg.getTag()); + Assert.assertEquals("http://localhost:8080/v1/package", otaPackageUpdateMsg.getUrl()); + Assert.assertFalse(otaPackageUpdateMsg.hasData()); + Assert.assertFalse(otaPackageUpdateMsg.hasFileName()); + Assert.assertFalse(otaPackageUpdateMsg.hasContentType()); + Assert.assertFalse(otaPackageUpdateMsg.hasChecksumAlgorithm()); + Assert.assertFalse(otaPackageUpdateMsg.hasChecksum()); + Assert.assertFalse(otaPackageUpdateMsg.hasDataSize()); + + // delete ota package + edgeImitator.expectMessageAmount(1); + doDelete("/api/otaPackage/" + savedFirmwareInfo.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof OtaPackageUpdateMsg); + otaPackageUpdateMsg = (OtaPackageUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, otaPackageUpdateMsg.getMsgType()); + Assert.assertEquals(savedFirmwareInfo.getUuidId().getMostSignificantBits(), otaPackageUpdateMsg.getIdMSB()); + Assert.assertEquals(savedFirmwareInfo.getUuidId().getLeastSignificantBits(), otaPackageUpdateMsg.getIdLSB()); + } + + @Test + public void testOtaPackages_hasData() throws Exception { + // create ota package + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest(); + firmwareInfo.setDeviceProfileId(thermostatDeviceProfile.getId()); + firmwareInfo.setType(FIRMWARE); + firmwareInfo.setTitle("My firmware #2"); + firmwareInfo.setVersion("v2.0"); + firmwareInfo.setTag("My firmware #2 v2.0"); + firmwareInfo.setUsesUrl(false); + firmwareInfo.setHasData(false); + firmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode()); + + edgeImitator.expectMessageAmount(1); + + OtaPackageInfo savedFirmwareInfo = doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class); + MockMultipartFile testData = new MockMultipartFile("file", "firmware.bin", "image/png", ByteBuffer.wrap(new byte[]{1, 3, 5}).array()); + savedFirmwareInfo = saveData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksumAlgorithm={checksumAlgorithm}", testData, ChecksumAlgorithm.SHA256.name()); + + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof OtaPackageUpdateMsg); + OtaPackageUpdateMsg otaPackageUpdateMsg = (OtaPackageUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, otaPackageUpdateMsg.getMsgType()); + Assert.assertEquals(savedFirmwareInfo.getUuidId().getMostSignificantBits(), otaPackageUpdateMsg.getIdMSB()); + Assert.assertEquals(savedFirmwareInfo.getUuidId().getLeastSignificantBits(), otaPackageUpdateMsg.getIdLSB()); + Assert.assertEquals(thermostatDeviceProfile.getUuidId().getMostSignificantBits(), otaPackageUpdateMsg.getDeviceProfileIdMSB()); + Assert.assertEquals(thermostatDeviceProfile.getUuidId().getLeastSignificantBits(), otaPackageUpdateMsg.getDeviceProfileIdLSB()); + Assert.assertEquals(FIRMWARE, OtaPackageType.valueOf(otaPackageUpdateMsg.getType())); + Assert.assertEquals("My firmware #2", otaPackageUpdateMsg.getTitle()); + Assert.assertEquals("v2.0", otaPackageUpdateMsg.getVersion()); + Assert.assertEquals("My firmware #2 v2.0", otaPackageUpdateMsg.getTag()); + Assert.assertFalse(otaPackageUpdateMsg.hasUrl()); + Assert.assertEquals("firmware.bin", otaPackageUpdateMsg.getFileName()); + Assert.assertEquals("image/png", otaPackageUpdateMsg.getContentType()); + Assert.assertEquals(ChecksumAlgorithm.SHA256.name(), otaPackageUpdateMsg.getChecksumAlgorithm()); + Assert.assertEquals("62467691cf583d4fa78b18fafaf9801f505e0ef03baf0603fd4b0cd004cd1e75", otaPackageUpdateMsg.getChecksum()); + Assert.assertEquals(3L, otaPackageUpdateMsg.getDataSize()); + Assert.assertEquals(ByteString.copyFrom(new byte[]{1, 3, 5}), otaPackageUpdateMsg.getData()); + + // delete ota package + edgeImitator.expectMessageAmount(1); + doDelete("/api/otaPackage/" + savedFirmwareInfo.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof OtaPackageUpdateMsg); + otaPackageUpdateMsg = (OtaPackageUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, otaPackageUpdateMsg.getMsgType()); + Assert.assertEquals(savedFirmwareInfo.getUuidId().getMostSignificantBits(), otaPackageUpdateMsg.getIdMSB()); + Assert.assertEquals(savedFirmwareInfo.getUuidId().getLeastSignificantBits(), otaPackageUpdateMsg.getIdLSB()); + } + + private OtaPackageInfo saveData(String urlTemplate, MockMultipartFile content, String... params) throws Exception { + MockMultipartHttpServletRequestBuilder postRequest = MockMvcRequestBuilders.multipart(urlTemplate, params); + postRequest.file(content); + setJwtToken(postRequest); + return readResponse(mockMvc.perform(postRequest).andExpect(status().isOk()), OtaPackageInfo.class); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseQueueEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseQueueEdgeTest.java new file mode 100644 index 0000000000..daa55b8fe7 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseQueueEdgeTest.java @@ -0,0 +1,107 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.server.common.data.queue.ProcessingStrategy; +import org.thingsboard.server.common.data.queue.ProcessingStrategyType; +import org.thingsboard.server.common.data.queue.Queue; +import org.thingsboard.server.common.data.queue.SubmitStrategy; +import org.thingsboard.server.common.data.queue.SubmitStrategyType; +import org.thingsboard.server.common.msg.queue.ServiceType; +import org.thingsboard.server.gen.edge.v1.QueueUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseQueueEdgeTest extends AbstractEdgeTest { + + @Test + public void testQueues() throws Exception { + loginSysAdmin(); + + // create queue + Queue queue = new Queue(); + queue.setName("EdgeMain"); + queue.setTopic("tb_rule_engine.EdgeMain"); + queue.setPollInterval(25); + queue.setPartitions(10); + queue.setConsumerPerPartition(false); + queue.setPackProcessingTimeout(2000); + SubmitStrategy submitStrategy = new SubmitStrategy(); + submitStrategy.setType(SubmitStrategyType.SEQUENTIAL_BY_ORIGINATOR); + queue.setSubmitStrategy(submitStrategy); + ProcessingStrategy processingStrategy = new ProcessingStrategy(); + processingStrategy.setType(ProcessingStrategyType.RETRY_ALL); + processingStrategy.setRetries(3); + processingStrategy.setFailurePercentage(0.7); + processingStrategy.setPauseBetweenRetries(3); + processingStrategy.setMaxPauseBetweenRetries(5); + queue.setProcessingStrategy(processingStrategy); + + edgeImitator.expectMessageAmount(1); + Queue savedQueue = doPost("/api/queues?serviceType=" + ServiceType.TB_RULE_ENGINE.name(), queue, Queue.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof QueueUpdateMsg); + QueueUpdateMsg queueUpdateMsg = (QueueUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, queueUpdateMsg.getMsgType()); + Assert.assertEquals(savedQueue.getUuidId().getMostSignificantBits(), queueUpdateMsg.getIdMSB()); + Assert.assertEquals(savedQueue.getUuidId().getLeastSignificantBits(), queueUpdateMsg.getIdLSB()); + Assert.assertEquals(savedQueue.getTenantId().getId().getMostSignificantBits(), queueUpdateMsg.getTenantIdMSB()); + Assert.assertEquals(savedQueue.getTenantId().getId().getLeastSignificantBits(), queueUpdateMsg.getTenantIdLSB()); + Assert.assertEquals("EdgeMain", queueUpdateMsg.getName()); + Assert.assertEquals("tb_rule_engine.EdgeMain", queueUpdateMsg.getTopic()); + Assert.assertEquals(25, queueUpdateMsg.getPollInterval()); + Assert.assertEquals(10, queueUpdateMsg.getPartitions()); + Assert.assertFalse(queueUpdateMsg.getConsumerPerPartition()); + Assert.assertEquals(2000, queueUpdateMsg.getPackProcessingTimeout()); + Assert.assertEquals(SubmitStrategyType.SEQUENTIAL_BY_ORIGINATOR.name(), queueUpdateMsg.getSubmitStrategy().getType()); + Assert.assertEquals(0, queueUpdateMsg.getSubmitStrategy().getBatchSize()); + Assert.assertEquals(ProcessingStrategyType.RETRY_ALL.name(), queueUpdateMsg.getProcessingStrategy().getType()); + Assert.assertEquals(3, queueUpdateMsg.getProcessingStrategy().getRetries()); + Assert.assertEquals(0.7, queueUpdateMsg.getProcessingStrategy().getFailurePercentage(), 1); + Assert.assertEquals(3, queueUpdateMsg.getProcessingStrategy().getPauseBetweenRetries()); + Assert.assertEquals(5, queueUpdateMsg.getProcessingStrategy().getMaxPauseBetweenRetries()); + + // update queue + edgeImitator.expectMessageAmount(1); + savedQueue.setPollInterval(50); + savedQueue = doPost("/api/queues?serviceType=" + ServiceType.TB_RULE_ENGINE.name(), savedQueue, Queue.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof QueueUpdateMsg); + queueUpdateMsg = (QueueUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, queueUpdateMsg.getMsgType()); + Assert.assertEquals(50, queueUpdateMsg.getPollInterval()); + + // delete queue + edgeImitator.expectMessageAmount(1); + doDelete("/api/queues/" + savedQueue.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof QueueUpdateMsg); + queueUpdateMsg = (QueueUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, queueUpdateMsg.getMsgType()); + Assert.assertEquals(savedQueue.getUuidId().getMostSignificantBits(), queueUpdateMsg.getIdMSB()); + Assert.assertEquals(savedQueue.getUuidId().getLeastSignificantBits(), queueUpdateMsg.getIdLSB()); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseRelationEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseRelationEdgeTest.java new file mode 100644 index 0000000000..39f6c25f85 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseRelationEdgeTest.java @@ -0,0 +1,174 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.EntityIdFactory; +import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.relation.RelationTypeGroup; +import org.thingsboard.server.gen.edge.v1.RelationRequestMsg; +import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; + +import java.util.UUID; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseRelationEdgeTest extends AbstractEdgeTest { + + + @Test + public void testRelations() throws Exception { + // create relation + edgeImitator.expectMessageAmount(1); + Device device = findDeviceByName("Edge Device 1"); + Asset asset = findAssetByName("Edge Asset 1"); + EntityRelation relation = new EntityRelation(); + relation.setType("test"); + relation.setFrom(device.getId()); + relation.setTo(asset.getId()); + relation.setTypeGroup(RelationTypeGroup.COMMON); + doPost("/api/relation", relation); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); + RelationUpdateMsg relationUpdateMsg = (RelationUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, relationUpdateMsg.getMsgType()); + Assert.assertEquals(relationUpdateMsg.getType(), relation.getType()); + Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); + Assert.assertEquals(relationUpdateMsg.getFromIdLSB(), relation.getFrom().getId().getLeastSignificantBits()); + Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); + Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); + Assert.assertEquals(relationUpdateMsg.getToIdLSB(), relation.getTo().getId().getLeastSignificantBits()); + Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); + Assert.assertEquals(relationUpdateMsg.getTypeGroup(), relation.getTypeGroup().name()); + + // delete relation + edgeImitator.expectMessageAmount(1); + doDelete("/api/relation?" + + "fromId=" + relation.getFrom().getId().toString() + + "&fromType=" + relation.getFrom().getEntityType().name() + + "&relationType=" + relation.getType() + + "&relationTypeGroup=" + relation.getTypeGroup().name() + + "&toId=" + relation.getTo().getId().toString() + + "&toType=" + relation.getTo().getEntityType().name()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); + relationUpdateMsg = (RelationUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, relationUpdateMsg.getMsgType()); + Assert.assertEquals(relationUpdateMsg.getType(), relation.getType()); + Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); + Assert.assertEquals(relationUpdateMsg.getFromIdLSB(), relation.getFrom().getId().getLeastSignificantBits()); + Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); + Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); + Assert.assertEquals(relationUpdateMsg.getToIdLSB(), relation.getTo().getId().getLeastSignificantBits()); + Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); + Assert.assertEquals(relationUpdateMsg.getTypeGroup(), relation.getTypeGroup().name()); + } + + + + @Test + public void testSendRelationToCloud() throws Exception { + Device device1 = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + Device device2 = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + RelationUpdateMsg.Builder relationUpdateMsgBuilder = RelationUpdateMsg.newBuilder(); + relationUpdateMsgBuilder.setType("test"); + relationUpdateMsgBuilder.setTypeGroup(RelationTypeGroup.COMMON.name()); + relationUpdateMsgBuilder.setToIdMSB(device1.getId().getId().getMostSignificantBits()); + relationUpdateMsgBuilder.setToIdLSB(device1.getId().getId().getLeastSignificantBits()); + relationUpdateMsgBuilder.setToEntityType(device1.getId().getEntityType().name()); + relationUpdateMsgBuilder.setFromIdMSB(device2.getId().getId().getMostSignificantBits()); + relationUpdateMsgBuilder.setFromIdLSB(device2.getId().getId().getLeastSignificantBits()); + relationUpdateMsgBuilder.setFromEntityType(device2.getId().getEntityType().name()); + relationUpdateMsgBuilder.setAdditionalInfo("{}"); + testAutoGeneratedCodeByProtobuf(relationUpdateMsgBuilder); + uplinkMsgBuilder.addRelationUpdateMsg(relationUpdateMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + + EntityRelation relation = doGet("/api/relation?" + + "&fromId=" + device2.getUuidId() + + "&fromType=" + device2.getId().getEntityType().name() + + "&relationType=" + "test" + + "&relationTypeGroup=" + RelationTypeGroup.COMMON.name() + + "&toId=" + device1.getUuidId() + + "&toType=" + device1.getId().getEntityType().name(), EntityRelation.class); + Assert.assertNotNull(relation); + } + + @Test + public void testSendRelationRequestToCloud() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + Asset asset = findAssetByName("Edge Asset 1"); + + EntityRelation relation = new EntityRelation(); + relation.setType("test"); + relation.setFrom(device.getId()); + relation.setTo(asset.getId()); + relation.setTypeGroup(RelationTypeGroup.COMMON); + + edgeImitator.expectMessageAmount(1); + doPost("/api/relation", relation); + Assert.assertTrue(edgeImitator.waitForMessages()); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + RelationRequestMsg.Builder relationRequestMsgBuilder = RelationRequestMsg.newBuilder(); + relationRequestMsgBuilder.setEntityIdMSB(device.getId().getId().getMostSignificantBits()); + relationRequestMsgBuilder.setEntityIdLSB(device.getId().getId().getLeastSignificantBits()); + relationRequestMsgBuilder.setEntityType(device.getId().getEntityType().name()); + testAutoGeneratedCodeByProtobuf(relationRequestMsgBuilder); + + uplinkMsgBuilder.addRelationRequestMsg(relationRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); + RelationUpdateMsg relationUpdateMsg = (RelationUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, relationUpdateMsg.getMsgType()); + Assert.assertEquals(relation.getType(), relationUpdateMsg.getType()); + + UUID fromUUID = new UUID(relationUpdateMsg.getFromIdMSB(), relationUpdateMsg.getFromIdLSB()); + EntityId fromEntityId = EntityIdFactory.getByTypeAndUuid(relationUpdateMsg.getFromEntityType(), fromUUID); + Assert.assertEquals(relation.getFrom(), fromEntityId); + + UUID toUUID = new UUID(relationUpdateMsg.getToIdMSB(), relationUpdateMsg.getToIdLSB()); + EntityId toEntityId = EntityIdFactory.getByTypeAndUuid(relationUpdateMsg.getToEntityType(), toUUID); + Assert.assertEquals(relation.getTo(), toEntityId); + + Assert.assertEquals(relation.getTypeGroup().name(), relationUpdateMsg.getTypeGroup()); + } +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseRuleChainEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseRuleChainEdgeTest.java new file mode 100644 index 0000000000..c5c05cf6d0 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseRuleChainEdgeTest.java @@ -0,0 +1,174 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainMetaData; +import org.thingsboard.server.common.data.rule.RuleChainType; +import org.thingsboard.server.common.data.rule.RuleNode; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; +import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseRuleChainEdgeTest extends AbstractEdgeTest { + + @Test + public void testRuleChains() throws Exception { + // create rule chain + edgeImitator.expectMessageAmount(2); + RuleChain ruleChain = new RuleChain(); + ruleChain.setName("Edge Test Rule Chain"); + ruleChain.setType(RuleChainType.EDGE); + RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); + doPost("/api/edge/" + edge.getUuidId() + + "/ruleChain/" + savedRuleChain.getUuidId(), RuleChain.class); + createRuleChainMetadata(savedRuleChain); + Assert.assertTrue(edgeImitator.waitForMessages()); + Optional ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); + Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); + RuleChainUpdateMsg ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); + Assert.assertTrue(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE.equals(ruleChainUpdateMsg.getMsgType()) || + UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE.equals(ruleChainUpdateMsg.getMsgType())); + Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), savedRuleChain.getUuidId().getMostSignificantBits()); + Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); + Assert.assertEquals(ruleChainUpdateMsg.getName(), savedRuleChain.getName()); + + testRuleChainMetadataRequestMsg(savedRuleChain.getId()); + + // unassign rule chain from edge + edgeImitator.expectMessageAmount(1); + doDelete("/api/edge/" + edge.getUuidId() + + "/ruleChain/" + savedRuleChain.getUuidId(), RuleChain.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); + Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent()); + ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, ruleChainUpdateMsg.getMsgType()); + Assert.assertEquals(ruleChainUpdateMsg.getIdMSB(), savedRuleChain.getUuidId().getMostSignificantBits()); + Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); + + // delete rule chain + edgeImitator.expectMessageAmount(1); + doDelete("/api/ruleChain/" + savedRuleChain.getUuidId()) + .andExpect(status().isOk()); + Assert.assertFalse(edgeImitator.waitForMessages(1)); + } + + + @Test + public void testSendRuleChainMetadataRequestToCloud() throws Exception { + RuleChainId edgeRootRuleChainId = edge.getRootRuleChainId(); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + RuleChainMetadataRequestMsg.Builder ruleChainMetadataRequestMsgBuilder = RuleChainMetadataRequestMsg.newBuilder(); + ruleChainMetadataRequestMsgBuilder.setRuleChainIdMSB(edgeRootRuleChainId.getId().getMostSignificantBits()); + ruleChainMetadataRequestMsgBuilder.setRuleChainIdLSB(edgeRootRuleChainId.getId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(ruleChainMetadataRequestMsgBuilder); + uplinkMsgBuilder.addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = (RuleChainMetadataUpdateMsg) latestMessage; + Assert.assertEquals(ruleChainMetadataUpdateMsg.getRuleChainIdMSB(), edgeRootRuleChainId.getId().getMostSignificantBits()); + Assert.assertEquals(ruleChainMetadataUpdateMsg.getRuleChainIdLSB(), edgeRootRuleChainId.getId().getLeastSignificantBits()); + + testAutoGeneratedCodeByProtobuf(ruleChainMetadataUpdateMsg); + } + + + private void testRuleChainMetadataRequestMsg(RuleChainId ruleChainId) throws Exception { + RuleChainMetadataRequestMsg.Builder ruleChainMetadataRequestMsgBuilder = RuleChainMetadataRequestMsg.newBuilder() + .setRuleChainIdMSB(ruleChainId.getId().getMostSignificantBits()) + .setRuleChainIdLSB(ruleChainId.getId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(ruleChainMetadataRequestMsgBuilder); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder() + .addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = (RuleChainMetadataUpdateMsg) latestMessage; + RuleChainId receivedRuleChainId = + new RuleChainId(new UUID(ruleChainMetadataUpdateMsg.getRuleChainIdMSB(), ruleChainMetadataUpdateMsg.getRuleChainIdLSB())); + Assert.assertEquals(ruleChainId, receivedRuleChainId); + } + + private void createRuleChainMetadata(RuleChain ruleChain) throws Exception { + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); + ruleChainMetaData.setRuleChainId(ruleChain.getId()); + + ObjectMapper mapper = new ObjectMapper(); + + RuleNode ruleNode1 = new RuleNode(); + ruleNode1.setName("name1"); + ruleNode1.setType("type1"); + ruleNode1.setConfiguration(mapper.readTree("\"key1\": \"val1\"")); + + RuleNode ruleNode2 = new RuleNode(); + ruleNode2.setName("name2"); + ruleNode2.setType("type2"); + ruleNode2.setConfiguration(mapper.readTree("\"key2\": \"val2\"")); + + RuleNode ruleNode3 = new RuleNode(); + ruleNode3.setName("name3"); + ruleNode3.setType("type3"); + ruleNode3.setConfiguration(mapper.readTree("\"key3\": \"val3\"")); + + List ruleNodes = new ArrayList<>(); + ruleNodes.add(ruleNode1); + ruleNodes.add(ruleNode2); + ruleNodes.add(ruleNode3); + ruleChainMetaData.setFirstNodeIndex(0); + ruleChainMetaData.setNodes(ruleNodes); + + ruleChainMetaData.addConnectionInfo(0, 1, "success"); + ruleChainMetaData.addConnectionInfo(0, 2, "fail"); + ruleChainMetaData.addConnectionInfo(1, 2, "success"); + + doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class); + } + + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseTelemetryEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseTelemetryEdgeTest.java new file mode 100644 index 0000000000..d1450c2225 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseTelemetryEdgeTest.java @@ -0,0 +1,195 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.fasterxml.jackson.databind.JsonNode; +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.gen.edge.v1.AttributeDeleteMsg; +import org.thingsboard.server.gen.edge.v1.EntityDataProto; +import org.thingsboard.server.gen.transport.TransportProtos; + +import java.util.List; + +abstract public class BaseTelemetryEdgeTest extends AbstractEdgeTest { + + @Test + public void testTimeseriesWithFailures() throws Exception { + int numberOfTimeseriesToSend = 1000; + + edgeImitator.setRandomFailuresOnTimeseriesDownlink(true); + // imitator will generate failure in 5% of cases + edgeImitator.setFailureProbability(5.0); + + edgeImitator.expectMessageAmount(numberOfTimeseriesToSend); + Device device = findDeviceByName("Edge Device 1"); + for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { + String timeseriesData = "{\"data\":{\"idx\":" + idx + "},\"ts\":" + System.currentTimeMillis() + "}"; + JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, + device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); + edgeEventService.saveAsync(edgeEvent).get(); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); + } + + Assert.assertTrue(edgeImitator.waitForMessages(120)); + + List allTelemetryMsgs = edgeImitator.findAllMessagesByType(EntityDataProto.class); + Assert.assertEquals(numberOfTimeseriesToSend, allTelemetryMsgs.size()); + + for (int idx = 1; idx <= numberOfTimeseriesToSend; idx++) { + Assert.assertTrue(isIdxExistsInTheDownlinkList(idx, allTelemetryMsgs)); + } + + edgeImitator.setRandomFailuresOnTimeseriesDownlink(false); + } + + @Test + public void testAttributes() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + testAttributesUpdatedMsg(device); + testPostAttributesMsg(device); + testAttributesDeleteMsg(device); + } + + private void testAttributesUpdatedMsg(Device device) throws Exception { + String attributesData = "{\"scope\":\"SERVER_SCOPE\",\"kv\":{\"key1\":\"value1\"}}"; + JsonNode attributesEntityData = mapper.readTree(attributesData); + EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData); + edgeImitator.expectMessageAmount(1); + edgeEventService.saveAsync(edgeEvent1).get(); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityDataProto); + EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); + Assert.assertEquals("SERVER_SCOPE", latestEntityDataMsg.getPostAttributeScope()); + Assert.assertTrue(latestEntityDataMsg.hasAttributesUpdatedMsg()); + + TransportProtos.PostAttributeMsg attributesUpdatedMsg = latestEntityDataMsg.getAttributesUpdatedMsg(); + Assert.assertEquals(1, attributesUpdatedMsg.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = attributesUpdatedMsg.getKv(0); + Assert.assertEquals("key1", keyValueProto.getKey()); + Assert.assertEquals("value1", keyValueProto.getStringV()); + } + + private void testPostAttributesMsg(Device device) throws Exception { + String postAttributesData = "{\"scope\":\"SERVER_SCOPE\",\"kv\":{\"key2\":\"value2\"}}"; + JsonNode postAttributesEntityData = mapper.readTree(postAttributesData); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.POST_ATTRIBUTES, device.getId().getId(), EdgeEventType.DEVICE, postAttributesEntityData); + edgeImitator.expectMessageAmount(1); + edgeEventService.saveAsync(edgeEvent).get(); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityDataProto); + EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); + Assert.assertEquals("SERVER_SCOPE", latestEntityDataMsg.getPostAttributeScope()); + Assert.assertTrue(latestEntityDataMsg.hasPostAttributesMsg()); + + TransportProtos.PostAttributeMsg postAttributesMsg = latestEntityDataMsg.getPostAttributesMsg(); + Assert.assertEquals(1, postAttributesMsg.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = postAttributesMsg.getKv(0); + Assert.assertEquals("key2", keyValueProto.getKey()); + Assert.assertEquals("value2", keyValueProto.getStringV()); + } + + private void testAttributesDeleteMsg(Device device) throws Exception { + String deleteAttributesData = "{\"scope\":\"SERVER_SCOPE\",\"keys\":[\"key1\",\"key2\"]}"; + JsonNode deleteAttributesEntityData = mapper.readTree(deleteAttributesData); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData); + edgeImitator.expectMessageAmount(1); + edgeEventService.saveAsync(edgeEvent).get(); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityDataProto); + EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); + + Assert.assertTrue(latestEntityDataMsg.hasAttributeDeleteMsg()); + + AttributeDeleteMsg attributeDeleteMsg = latestEntityDataMsg.getAttributeDeleteMsg(); + Assert.assertEquals(attributeDeleteMsg.getScope(), deleteAttributesEntityData.get("scope").asText()); + + Assert.assertEquals(2, attributeDeleteMsg.getAttributeNamesCount()); + Assert.assertEquals("key1", attributeDeleteMsg.getAttributeNames(0)); + Assert.assertEquals("key2", attributeDeleteMsg.getAttributeNames(1)); + } + + @Test + public void testTimeseries() throws Exception { + edgeImitator.expectMessageAmount(1); + Device device = findDeviceByName("Edge Device 1"); + String timeseriesData = "{\"data\":{\"temperature\":25},\"ts\":" + System.currentTimeMillis() + "}"; + JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); + edgeEventService.saveAsync(edgeEvent).get(); + clusterService.onEdgeEventUpdate(tenantId, edge.getId()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityDataProto); + EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; + Assert.assertEquals(latestEntityDataMsg.getEntityIdMSB(), device.getUuidId().getMostSignificantBits()); + Assert.assertEquals(latestEntityDataMsg.getEntityIdLSB(), device.getUuidId().getLeastSignificantBits()); + Assert.assertEquals(latestEntityDataMsg.getEntityType(), device.getId().getEntityType().name()); + Assert.assertTrue(latestEntityDataMsg.hasPostTelemetryMsg()); + + TransportProtos.PostTelemetryMsg postTelemetryMsg = latestEntityDataMsg.getPostTelemetryMsg(); + Assert.assertEquals(1, postTelemetryMsg.getTsKvListCount()); + TransportProtos.TsKvListProto tsKvListProto = postTelemetryMsg.getTsKvList(0); + Assert.assertEquals(timeseriesEntityData.get("ts").asLong(), tsKvListProto.getTs()); + Assert.assertEquals(1, tsKvListProto.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = tsKvListProto.getKv(0); + Assert.assertEquals("temperature", keyValueProto.getKey()); + Assert.assertEquals(25, keyValueProto.getLongV()); + } + + private boolean isIdxExistsInTheDownlinkList(int idx, List allTelemetryMsgs) { + for (EntityDataProto proto : allTelemetryMsgs) { + TransportProtos.PostTelemetryMsg postTelemetryMsg = proto.getPostTelemetryMsg(); + Assert.assertEquals(1, postTelemetryMsg.getTsKvListCount()); + TransportProtos.TsKvListProto tsKvListProto = postTelemetryMsg.getTsKvList(0); + Assert.assertEquals(1, tsKvListProto.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = tsKvListProto.getKv(0); + Assert.assertEquals("idx", keyValueProto.getKey()); + if (keyValueProto.getLongV() == idx) { + return true; + } + } + return false; + } + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseUserEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseUserEdgeTest.java new file mode 100644 index 0000000000..0e694e034b --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseUserEdgeTest.java @@ -0,0 +1,206 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.UplinkMsg; +import org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg; +import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; +import org.thingsboard.server.service.security.model.ChangePasswordRequest; + +import java.util.Optional; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseUserEdgeTest extends AbstractEdgeTest { + + @Autowired + private BCryptPasswordEncoder passwordEncoder; + + @Test + public void testCreateUpdateDeleteTenantUser() throws Exception { + // create user + edgeImitator.expectMessageAmount(2); + User newTenantAdmin = new User(); + newTenantAdmin.setAuthority(Authority.TENANT_ADMIN); + newTenantAdmin.setTenantId(savedTenant.getId()); + newTenantAdmin.setEmail("tenantAdmin@thingsboard.org"); + newTenantAdmin.setFirstName("Boris"); + newTenantAdmin.setLastName("Johnson"); + User savedTenantAdmin = createUser(newTenantAdmin, "tenant"); + Assert.assertTrue(edgeImitator.waitForMessages()); // wait 2 messages - user update msg and user credentials update msg + Optional latestMessageOpt = edgeImitator.findMessageByType(UserUpdateMsg.class); + Assert.assertTrue(latestMessageOpt.isPresent()); + UserUpdateMsg userUpdateMsg = latestMessageOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, userUpdateMsg.getMsgType()); + Assert.assertEquals(savedTenantAdmin.getUuidId().getMostSignificantBits(), userUpdateMsg.getIdMSB()); + Assert.assertEquals(savedTenantAdmin.getUuidId().getLeastSignificantBits(), userUpdateMsg.getIdLSB()); + Assert.assertEquals(savedTenantAdmin.getAuthority().name(), userUpdateMsg.getAuthority()); + Assert.assertEquals(savedTenantAdmin.getEmail(), userUpdateMsg.getEmail()); + Assert.assertEquals(savedTenantAdmin.getFirstName(), userUpdateMsg.getFirstName()); + Assert.assertEquals(savedTenantAdmin.getLastName(), userUpdateMsg.getLastName()); + testAutoGeneratedCodeByProtobuf(userUpdateMsg); + + // update user + edgeImitator.expectMessageAmount(1); + savedTenantAdmin.setLastName("Borisov"); + savedTenantAdmin = doPost("/api/user", savedTenantAdmin, User.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof UserUpdateMsg); + userUpdateMsg = (UserUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, userUpdateMsg.getMsgType()); + Assert.assertEquals(savedTenantAdmin.getLastName(), userUpdateMsg.getLastName()); + + // update user credentials + edgeImitator.expectMessageAmount(1); + login(savedTenantAdmin.getEmail(), "tenant"); + ChangePasswordRequest changePasswordRequest = new ChangePasswordRequest(); + changePasswordRequest.setCurrentPassword("tenant"); + changePasswordRequest.setNewPassword("newTenant"); + doPost("/api/auth/changePassword", changePasswordRequest); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof UserCredentialsUpdateMsg); + UserCredentialsUpdateMsg userCredentialsUpdateMsg = (UserCredentialsUpdateMsg) latestMessage; + Assert.assertEquals(savedTenantAdmin.getUuidId().getMostSignificantBits(), userCredentialsUpdateMsg.getUserIdMSB()); + Assert.assertEquals(savedTenantAdmin.getUuidId().getLeastSignificantBits(), userCredentialsUpdateMsg.getUserIdLSB()); + Assert.assertTrue(passwordEncoder.matches(changePasswordRequest.getNewPassword(), userCredentialsUpdateMsg.getPassword())); + + // delete user + edgeImitator.expectMessageAmount(1); + login(tenantAdmin.getEmail(), "testPassword1"); + doDelete("/api/user/" + savedTenantAdmin.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof UserUpdateMsg); + userUpdateMsg = (UserUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, userUpdateMsg.getMsgType()); + Assert.assertEquals(savedTenantAdmin.getUuidId().getMostSignificantBits(), userUpdateMsg.getIdMSB()); + Assert.assertEquals(savedTenantAdmin.getUuidId().getLeastSignificantBits(), userUpdateMsg.getIdLSB()); + } + + @Test + public void testCreateUpdateDeleteCustomerUser() throws Exception { + // create customer + edgeImitator.expectMessageAmount(1); + Customer customer = new Customer(); + customer.setTitle("Edge Customer"); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + + // create user + edgeImitator.expectMessageAmount(2); + User customerUser = new User(); + customerUser.setAuthority(Authority.CUSTOMER_USER); + customerUser.setTenantId(savedTenant.getId()); + customerUser.setCustomerId(savedCustomer.getId()); + customerUser.setEmail("customerUser@thingsboard.org"); + customerUser.setFirstName("John"); + customerUser.setLastName("Edwards"); + User savedCustomerUser = createUser(customerUser, "customer"); + Assert.assertTrue(edgeImitator.waitForMessages()); // wait 2 messages - user update msg and user credentials update msg + Optional latestMessageOpt = edgeImitator.findMessageByType(UserUpdateMsg.class); + Assert.assertTrue(latestMessageOpt.isPresent()); + UserUpdateMsg userUpdateMsg = latestMessageOpt.get(); + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, userUpdateMsg.getMsgType()); + Assert.assertEquals(savedCustomerUser.getUuidId().getMostSignificantBits(), userUpdateMsg.getIdMSB()); + Assert.assertEquals(savedCustomerUser.getUuidId().getLeastSignificantBits(), userUpdateMsg.getIdLSB()); + Assert.assertEquals(savedCustomerUser.getCustomerId().getId().getMostSignificantBits(), userUpdateMsg.getCustomerIdMSB()); + Assert.assertEquals(savedCustomerUser.getCustomerId().getId().getLeastSignificantBits(), userUpdateMsg.getCustomerIdLSB()); + Assert.assertEquals(savedCustomerUser.getAuthority().name(), userUpdateMsg.getAuthority()); + Assert.assertEquals(savedCustomerUser.getEmail(), userUpdateMsg.getEmail()); + Assert.assertEquals(savedCustomerUser.getFirstName(), userUpdateMsg.getFirstName()); + Assert.assertEquals(savedCustomerUser.getLastName(), userUpdateMsg.getLastName()); + + // update user + edgeImitator.expectMessageAmount(1); + savedCustomerUser.setLastName("Addams"); + savedCustomerUser = doPost("/api/user", savedCustomerUser, User.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof UserUpdateMsg); + userUpdateMsg = (UserUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, userUpdateMsg.getMsgType()); + Assert.assertEquals(savedCustomerUser.getLastName(), userUpdateMsg.getLastName()); + + // update user credentials + edgeImitator.expectMessageAmount(1); + login(savedCustomerUser.getEmail(), "customer"); + ChangePasswordRequest changePasswordRequest = new ChangePasswordRequest(); + changePasswordRequest.setCurrentPassword("customer"); + changePasswordRequest.setNewPassword("newCustomer"); + doPost("/api/auth/changePassword", changePasswordRequest); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof UserCredentialsUpdateMsg); + UserCredentialsUpdateMsg userCredentialsUpdateMsg = (UserCredentialsUpdateMsg) latestMessage; + Assert.assertEquals(savedCustomerUser.getUuidId().getMostSignificantBits(), userCredentialsUpdateMsg.getUserIdMSB()); + Assert.assertEquals(savedCustomerUser.getUuidId().getLeastSignificantBits(), userCredentialsUpdateMsg.getUserIdLSB()); + Assert.assertTrue(passwordEncoder.matches(changePasswordRequest.getNewPassword(), userCredentialsUpdateMsg.getPassword())); + + // delete user + edgeImitator.expectMessageAmount(1); + login(tenantAdmin.getEmail(), "testPassword1"); + doDelete("/api/user/" + savedCustomerUser.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof UserUpdateMsg); + userUpdateMsg = (UserUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, userUpdateMsg.getMsgType()); + Assert.assertEquals(savedCustomerUser.getUuidId().getMostSignificantBits(), userUpdateMsg.getIdMSB()); + Assert.assertEquals(savedCustomerUser.getUuidId().getLeastSignificantBits(), userUpdateMsg.getIdLSB()); + + } + + @Test + public void testSendUserCredentialsRequestToCloud() throws Exception { + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + UserCredentialsRequestMsg.Builder userCredentialsRequestMsgBuilder = UserCredentialsRequestMsg.newBuilder(); + userCredentialsRequestMsgBuilder.setUserIdMSB(tenantAdmin.getId().getId().getMostSignificantBits()); + userCredentialsRequestMsgBuilder.setUserIdLSB(tenantAdmin.getId().getId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(userCredentialsRequestMsgBuilder); + uplinkMsgBuilder.addUserCredentialsRequestMsg(userCredentialsRequestMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof UserCredentialsUpdateMsg); + UserCredentialsUpdateMsg userCredentialsUpdateMsg = (UserCredentialsUpdateMsg) latestMessage; + Assert.assertEquals(tenantAdmin.getId().getId().getMostSignificantBits(), userCredentialsUpdateMsg.getUserIdMSB()); + Assert.assertEquals(tenantAdmin.getId().getId().getLeastSignificantBits(), userCredentialsUpdateMsg.getUserIdLSB()); + + testAutoGeneratedCodeByProtobuf(userCredentialsUpdateMsg); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseWidgetEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseWidgetEdgeTest.java new file mode 100644 index 0000000000..6dc4d50ed2 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/BaseWidgetEdgeTest.java @@ -0,0 +1,99 @@ +/** + * Copyright © 2016-2022 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.edge; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.protobuf.AbstractMessage; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.widget.WidgetType; +import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; +import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +abstract public class BaseWidgetEdgeTest extends AbstractEdgeTest { + + @Test + public void testWidgetsBundleAndWidgetType() throws Exception { + // create widget bundle + edgeImitator.expectMessageAmount(1); + WidgetsBundle widgetsBundle = new WidgetsBundle(); + widgetsBundle.setTitle("Test Widget Bundle"); + WidgetsBundle savedWidgetsBundle = doPost("/api/widgetsBundle", widgetsBundle, WidgetsBundle.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof WidgetsBundleUpdateMsg); + WidgetsBundleUpdateMsg widgetsBundleUpdateMsg = (WidgetsBundleUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, widgetsBundleUpdateMsg.getMsgType()); + Assert.assertEquals(widgetsBundleUpdateMsg.getIdMSB(), savedWidgetsBundle.getUuidId().getMostSignificantBits()); + Assert.assertEquals(widgetsBundleUpdateMsg.getIdLSB(), savedWidgetsBundle.getUuidId().getLeastSignificantBits()); + Assert.assertEquals(widgetsBundleUpdateMsg.getAlias(), savedWidgetsBundle.getAlias()); + Assert.assertEquals(widgetsBundleUpdateMsg.getTitle(), savedWidgetsBundle.getTitle()); + testAutoGeneratedCodeByProtobuf(widgetsBundleUpdateMsg); + + // create widget type + edgeImitator.expectMessageAmount(1); + WidgetType widgetType = new WidgetType(); + widgetType.setName("Test Widget Type"); + widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); + ObjectNode descriptor = mapper.createObjectNode(); + descriptor.put("key", "value"); + widgetType.setDescriptor(descriptor); + WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof WidgetTypeUpdateMsg); + WidgetTypeUpdateMsg widgetTypeUpdateMsg = (WidgetTypeUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, widgetTypeUpdateMsg.getMsgType()); + Assert.assertEquals(widgetTypeUpdateMsg.getIdMSB(), savedWidgetType.getUuidId().getMostSignificantBits()); + Assert.assertEquals(widgetTypeUpdateMsg.getIdLSB(), savedWidgetType.getUuidId().getLeastSignificantBits()); + Assert.assertEquals(widgetTypeUpdateMsg.getAlias(), savedWidgetType.getAlias()); + Assert.assertEquals(widgetTypeUpdateMsg.getName(), savedWidgetType.getName()); + Assert.assertEquals(JacksonUtil.toJsonNode(widgetTypeUpdateMsg.getDescriptorJson()), savedWidgetType.getDescriptor()); + + // @TODO: update widget bundle + // @TODO: update widget type + + // delete widget type + edgeImitator.expectMessageAmount(1); + doDelete("/api/widgetType/" + savedWidgetType.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof WidgetTypeUpdateMsg); + widgetTypeUpdateMsg = (WidgetTypeUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, widgetTypeUpdateMsg.getMsgType()); + Assert.assertEquals(widgetTypeUpdateMsg.getIdMSB(), savedWidgetType.getUuidId().getMostSignificantBits()); + Assert.assertEquals(widgetTypeUpdateMsg.getIdLSB(), savedWidgetType.getUuidId().getLeastSignificantBits()); + + // delete widget bundle + edgeImitator.expectMessageAmount(1); + doDelete("/api/widgetsBundle/" + savedWidgetsBundle.getUuidId()) + .andExpect(status().isOk()); + Assert.assertTrue(edgeImitator.waitForMessages()); + latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof WidgetsBundleUpdateMsg); + widgetsBundleUpdateMsg = (WidgetsBundleUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, widgetsBundleUpdateMsg.getMsgType()); + Assert.assertEquals(widgetsBundleUpdateMsg.getIdMSB(), savedWidgetsBundle.getUuidId().getMostSignificantBits()); + Assert.assertEquals(widgetsBundleUpdateMsg.getIdLSB(), savedWidgetsBundle.getUuidId().getLeastSignificantBits()); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/AlarmEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/AlarmEdgeSqlTest.java new file mode 100644 index 0000000000..e7c6e1e84a --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/AlarmEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseAlarmEdgeTest; + +@DaoSqlTest +public class AlarmEdgeSqlTest extends BaseAlarmEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/AssetEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/AssetEdgeSqlTest.java new file mode 100644 index 0000000000..bbf2449a03 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/AssetEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseAssetEdgeTest; + +@DaoSqlTest +public class AssetEdgeSqlTest extends BaseAssetEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/CustomerEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/CustomerEdgeSqlTest.java new file mode 100644 index 0000000000..73bb27f976 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/CustomerEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseCustomerEdgeTest; + +@DaoSqlTest +public class CustomerEdgeSqlTest extends BaseCustomerEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/DashboardEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/DashboardEdgeSqlTest.java new file mode 100644 index 0000000000..fe6915b355 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/DashboardEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseDashboardEdgeTest; + +@DaoSqlTest +public class DashboardEdgeSqlTest extends BaseDashboardEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/DeviceEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/DeviceEdgeSqlTest.java new file mode 100644 index 0000000000..a82e5d5fe6 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/DeviceEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseDeviceEdgeTest; + +@DaoSqlTest +public class DeviceEdgeSqlTest extends BaseDeviceEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/DeviceProfileEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/DeviceProfileEdgeSqlTest.java new file mode 100644 index 0000000000..a870660413 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/DeviceProfileEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseDeviceProfileEdgeTest; + +@DaoSqlTest +public class DeviceProfileEdgeSqlTest extends BaseDeviceProfileEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/EntityViewEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/EntityViewEdgeSqlTest.java new file mode 100644 index 0000000000..a77aed7c37 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/EntityViewEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseEntityViewEdgeTest; + +@DaoSqlTest +public class EntityViewEdgeSqlTest extends BaseEntityViewEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/OtaPackageEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/OtaPackageEdgeSqlTest.java new file mode 100644 index 0000000000..17dcd444f7 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/OtaPackageEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseOtaPackageEdgeTest; + +@DaoSqlTest +public class OtaPackageEdgeSqlTest extends BaseOtaPackageEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/QueueEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/QueueEdgeSqlTest.java new file mode 100644 index 0000000000..28a7f51458 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/QueueEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseQueueEdgeTest; + +@DaoSqlTest +public class QueueEdgeSqlTest extends BaseQueueEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/RelationEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/RelationEdgeSqlTest.java new file mode 100644 index 0000000000..75fceacd45 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/RelationEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseRelationEdgeTest; + +@DaoSqlTest +public class RelationEdgeSqlTest extends BaseRelationEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/RuleChainEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/RuleChainEdgeSqlTest.java new file mode 100644 index 0000000000..34921eb806 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/RuleChainEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseRuleChainEdgeTest; + +@DaoSqlTest +public class RuleChainEdgeSqlTest extends BaseRuleChainEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/TelemetryEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/TelemetryEdgeSqlTest.java new file mode 100644 index 0000000000..e88df0b8bf --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/TelemetryEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseTelemetryEdgeTest; + +@DaoSqlTest +public class TelemetryEdgeSqlTest extends BaseTelemetryEdgeTest { + +} diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/EdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/UserEdgeSqlTest.java similarity index 86% rename from application/src/test/java/org/thingsboard/server/edge/sql/EdgeSqlTest.java rename to application/src/test/java/org/thingsboard/server/edge/sql/UserEdgeSqlTest.java index 8f6c26271b..0b84f76aba 100644 --- a/application/src/test/java/org/thingsboard/server/edge/sql/EdgeSqlTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/sql/UserEdgeSqlTest.java @@ -16,8 +16,9 @@ package org.thingsboard.server.edge.sql; import org.thingsboard.server.dao.service.DaoSqlTest; -import org.thingsboard.server.edge.BaseEdgeTest; +import org.thingsboard.server.edge.BaseUserEdgeTest; @DaoSqlTest -public class EdgeSqlTest extends BaseEdgeTest { +public class UserEdgeSqlTest extends BaseUserEdgeTest { + } diff --git a/application/src/test/java/org/thingsboard/server/edge/sql/WidgetEdgeSqlTest.java b/application/src/test/java/org/thingsboard/server/edge/sql/WidgetEdgeSqlTest.java new file mode 100644 index 0000000000..6714d19438 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/edge/sql/WidgetEdgeSqlTest.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 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.edge.sql; + +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.edge.BaseWidgetEdgeTest; + +@DaoSqlTest +public class WidgetEdgeSqlTest extends BaseWidgetEdgeTest { + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 3a1520aa4f..8d1dbc5c8d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -403,9 +403,8 @@ public class EdgeServiceImpl extends AbstractCachedEntityService edgeIds = Collections.singletonList(new EdgeId(entityId.getId())); return new PageData<>(edgeIds, 1, 1, false);