Merge pull request #9213 from volodymyr-babak/edge/fix-errors-in-case-dashboard-not-assigned

Add Server-side Checks for Default Dashboard and Rule Chain on Edge Versions < 3.6.0
This commit is contained in:
Andrew Shvayka 2023-09-08 12:21:29 +03:00 committed by GitHub
commit d670267e39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 749 additions and 9 deletions

View File

@ -614,13 +614,13 @@ public final class EdgeGrpcSession implements Closeable {
case EDGE:
return ctx.getEdgeProcessor().convertEdgeEventToDownlink(edgeEvent);
case DEVICE:
return ctx.getDeviceProcessor().convertDeviceEventToDownlink(edgeEvent);
return ctx.getDeviceProcessor().convertDeviceEventToDownlink(edgeEvent, this.edge.getId(), this.edgeVersion);
case DEVICE_PROFILE:
return ctx.getDeviceProfileProcessor().convertDeviceProfileEventToDownlink(edgeEvent);
return ctx.getDeviceProfileProcessor().convertDeviceProfileEventToDownlink(edgeEvent, this.edge.getId(), this.edgeVersion);
case ASSET_PROFILE:
return ctx.getAssetProfileProcessor().convertAssetProfileEventToDownlink(edgeEvent);
return ctx.getAssetProfileProcessor().convertAssetProfileEventToDownlink(edgeEvent, this.edge.getId(), this.edgeVersion);
case ASSET:
return ctx.getAssetProcessor().convertAssetEventToDownlink(edgeEvent);
return ctx.getAssetProcessor().convertAssetEventToDownlink(edgeEvent, this.edge.getId(), this.edgeVersion);
case ENTITY_VIEW:
return ctx.getEntityViewProcessor().convertEntityViewEventToDownlink(edgeEvent);
case DASHBOARD:

View File

@ -79,6 +79,7 @@ import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.dao.widget.WidgetTypeService;
import org.thingsboard.server.dao.widget.WidgetsBundleService;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.TbQueueCallback;
@ -596,4 +597,57 @@ public abstract class BaseEdgeProcessor {
}
});
}
protected AssetProfile checkIfAssetProfileDefaultFieldsAssignedToEdge(TenantId tenantId, EdgeId edgeId, AssetProfile assetProfile, EdgeVersion edgeVersion) {
switch (edgeVersion) {
case V_3_3_3:
case V_3_3_0:
case V_3_4_0:
if (assetProfile.getDefaultDashboardId() != null
&& isEntityNotAssignedToEdge(tenantId, assetProfile.getDefaultDashboardId(), edgeId)) {
assetProfile.setDefaultDashboardId(null);
}
if (assetProfile.getDefaultEdgeRuleChainId() != null
&& isEntityNotAssignedToEdge(tenantId, assetProfile.getDefaultEdgeRuleChainId(), edgeId)) {
assetProfile.setDefaultEdgeRuleChainId(null);
}
break;
}
return assetProfile;
}
protected DeviceProfile checkIfDeviceProfileDefaultFieldsAssignedToEdge(TenantId tenantId, EdgeId edgeId, DeviceProfile deviceProfile, EdgeVersion edgeVersion) {
switch (edgeVersion) {
case V_3_3_3:
case V_3_3_0:
case V_3_4_0:
if (deviceProfile.getDefaultDashboardId() != null
&& isEntityNotAssignedToEdge(tenantId, deviceProfile.getDefaultDashboardId(), edgeId)) {
deviceProfile.setDefaultDashboardId(null);
}
if (deviceProfile.getDefaultEdgeRuleChainId() != null
&& isEntityNotAssignedToEdge(tenantId, deviceProfile.getDefaultEdgeRuleChainId(), edgeId)) {
deviceProfile.setDefaultEdgeRuleChainId(null);
}
break;
}
return deviceProfile;
}
private boolean isEntityNotAssignedToEdge(TenantId tenantId, EntityId entityId, EdgeId edgeId) {
PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE);
PageData<EdgeId> pageData;
do {
pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, pageLink);
if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
if (pageData.getData().contains(edgeId)) {
return false;
}
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
}
} while (pageData != null && pageData.hasNext());
return true;
}
}

View File

@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.AssetId;
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.msg.TbMsgType;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -37,6 +38,7 @@ import org.thingsboard.server.dao.asset.BaseAssetService;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.util.TbCoreComponent;
@ -106,7 +108,7 @@ public class AssetEdgeProcessor extends BaseAssetProcessor {
}
}
public DownlinkMsg convertAssetEventToDownlink(EdgeEvent edgeEvent) {
public DownlinkMsg convertAssetEventToDownlink(EdgeEvent edgeEvent, EdgeId edgeId, EdgeVersion edgeVersion) {
AssetId assetId = new AssetId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
@ -125,6 +127,7 @@ public class AssetEdgeProcessor extends BaseAssetProcessor {
.addAssetUpdateMsg(assetUpdateMsg);
if (UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE.equals(msgType)) {
AssetProfile assetProfile = assetProfileService.findAssetProfileById(edgeEvent.getTenantId(), asset.getAssetProfileId());
assetProfile = checkIfAssetProfileDefaultFieldsAssignedToEdge(edgeEvent.getTenantId(), edgeId, assetProfile, edgeVersion);
builder.addAssetProfileUpdateMsg(assetProfileMsgConstructor.constructAssetProfileUpdatedMsg(msgType, assetProfile));
}
downlinkMsg = builder.build();

View File

@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.AssetProfileId;
import org.thingsboard.server.common.data.id.DashboardId;
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.msg.TbMsgType;
@ -36,6 +37,7 @@ import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.gen.edge.v1.AssetProfileUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.util.TbCoreComponent;
@ -94,7 +96,7 @@ public class AssetProfileEdgeProcessor extends BaseAssetProfileProcessor {
}
}
public DownlinkMsg convertAssetProfileEventToDownlink(EdgeEvent edgeEvent) {
public DownlinkMsg convertAssetProfileEventToDownlink(EdgeEvent edgeEvent, EdgeId edgeId, EdgeVersion edgeVersion) {
AssetProfileId assetProfileId = new AssetProfileId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
@ -103,6 +105,7 @@ public class AssetProfileEdgeProcessor extends BaseAssetProfileProcessor {
AssetProfile assetProfile = assetProfileService.findAssetProfileById(edgeEvent.getTenantId(), assetProfileId);
if (assetProfile != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
assetProfile = checkIfAssetProfileDefaultFieldsAssignedToEdge(edgeEvent.getTenantId(), edgeId, assetProfile, edgeVersion);
AssetProfileUpdateMsg assetProfileUpdateMsg =
assetProfileMsgConstructor.constructAssetProfileUpdatedMsg(msgType, assetProfile);
downlinkMsg = DownlinkMsg.newBuilder()

View File

@ -35,6 +35,7 @@ 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.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.rpc.RpcError;
@ -49,6 +50,7 @@ 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.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.TbQueueCallback;
import org.thingsboard.server.queue.TbQueueMsgMetadata;
@ -202,7 +204,7 @@ public class DeviceEdgeProcessor extends BaseDeviceProcessor {
return Futures.immediateFuture(null);
}
public DownlinkMsg convertDeviceEventToDownlink(EdgeEvent edgeEvent) {
public DownlinkMsg convertDeviceEventToDownlink(EdgeEvent edgeEvent, EdgeId edgeId, EdgeVersion edgeVersion) {
DeviceId deviceId = new DeviceId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
@ -221,6 +223,7 @@ public class DeviceEdgeProcessor extends BaseDeviceProcessor {
.addDeviceUpdateMsg(deviceUpdateMsg);
if (UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE.equals(msgType)) {
DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(edgeEvent.getTenantId(), device.getDeviceProfileId());
deviceProfile = checkIfDeviceProfileDefaultFieldsAssignedToEdge(edgeEvent.getTenantId(), edgeId, deviceProfile, edgeVersion);
builder.addDeviceProfileUpdateMsg(deviceProfileMsgConstructor.constructDeviceProfileUpdatedMsg(msgType, deviceProfile));
}
downlinkMsg = builder.build();

View File

@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.DashboardId;
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.msg.TbMsgType;
@ -36,6 +37,7 @@ import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.util.TbCoreComponent;
@ -94,7 +96,7 @@ public class DeviceProfileEdgeProcessor extends BaseDeviceProfileProcessor {
}
}
public DownlinkMsg convertDeviceProfileEventToDownlink(EdgeEvent edgeEvent) {
public DownlinkMsg convertDeviceProfileEventToDownlink(EdgeEvent edgeEvent, EdgeId edgeId, EdgeVersion edgeVersion) {
DeviceProfileId deviceProfileId = new DeviceProfileId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
@ -103,6 +105,7 @@ public class DeviceProfileEdgeProcessor extends BaseDeviceProfileProcessor {
DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(edgeEvent.getTenantId(), deviceProfileId);
if (deviceProfile != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
deviceProfile = checkIfDeviceProfileDefaultFieldsAssignedToEdge(edgeEvent.getTenantId(), edgeId, deviceProfile, edgeVersion);
DeviceProfileUpdateMsg deviceProfileUpdateMsg =
deviceProfileMsgConstructor.constructDeviceProfileUpdatedMsg(msgType, deviceProfile);
downlinkMsg = DownlinkMsg.newBuilder()

View File

@ -0,0 +1,306 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.processor;
import org.junit.jupiter.params.provider.Arguments;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.context.annotation.Lazy;
import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.DashboardId;
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.dao.alarm.AlarmService;
import org.thingsboard.server.dao.asset.AssetProfileService;
import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.device.DeviceCredentialsService;
import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.edge.EdgeEventService;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.edge.EdgeSynchronizationManager;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.tenant.TenantProfileService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.dao.widget.WidgetTypeService;
import org.thingsboard.server.dao.widget.WidgetsBundleService;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.service.edge.rpc.constructor.AdminSettingsMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.AlarmMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.AssetMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.AssetProfileMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.CustomerMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.DashboardMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.DeviceMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.DeviceProfileMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.EdgeMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.EntityDataMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.EntityViewMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.OtaPackageMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.QueueMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.RelationMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.RuleChainMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.TenantMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.TenantProfileMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.UserMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.WidgetTypeMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.WidgetsBundleMsgConstructor;
import org.thingsboard.server.service.entitiy.TbNotificationEntityService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.profile.TbAssetProfileCache;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
import org.thingsboard.server.service.state.DeviceStateService;
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import java.util.UUID;
import java.util.stream.Stream;
public abstract class BaseEdgeProcessorTest {
@MockBean
protected TelemetrySubscriptionService tsSubService;
@MockBean
protected TbNotificationEntityService notificationEntityService;
@MockBean
protected RuleChainService ruleChainService;
@MockBean
protected AlarmService alarmService;
@MockBean
protected DeviceService deviceService;
@MockBean
protected TbDeviceProfileCache deviceProfileCache;
@MockBean
protected TbAssetProfileCache assetProfileCache;
@MockBean
protected DashboardService dashboardService;
@MockBean
protected AssetService assetService;
@MockBean
protected EntityViewService entityViewService;
@MockBean
protected TenantService tenantService;
@MockBean
protected TenantProfileService tenantProfileService;
@MockBean
protected EdgeService edgeService;
@MockBean
protected CustomerService customerService;
@MockBean
protected UserService userService;
@MockBean
protected DeviceProfileService deviceProfileService;
@MockBean
protected AssetProfileService assetProfileService;
@MockBean
protected RelationService relationService;
@MockBean
protected DeviceCredentialsService deviceCredentialsService;
@MockBean
protected AttributesService attributesService;
@MockBean
protected TbClusterService tbClusterService;
@MockBean
protected DeviceStateService deviceStateService;
@MockBean
protected EdgeEventService edgeEventService;
@MockBean
protected WidgetsBundleService widgetsBundleService;
@MockBean
protected WidgetTypeService widgetTypeService;
@MockBean
protected OtaPackageService otaPackageService;
@MockBean
protected QueueService queueService;
@MockBean
protected PartitionService partitionService;
@MockBean
@Lazy
protected TbQueueProducerProvider producerProvider;
@MockBean
protected DataValidator<Device> deviceValidator;
@MockBean
protected DataValidator<DeviceProfile> deviceProfileValidator;
@MockBean
protected DataValidator<Asset> assetValidator;
@MockBean
protected DataValidator<AssetProfile> assetProfileValidator;
@MockBean
protected DataValidator<Dashboard> dashboardValidator;
@MockBean
protected DataValidator<EntityView> entityViewValidator;
@MockBean
protected EdgeMsgConstructor edgeMsgConstructor;
@MockBean
protected EntityDataMsgConstructor entityDataMsgConstructor;
@MockBean
protected RuleChainMsgConstructor ruleChainMsgConstructor;
@MockBean
protected AlarmMsgConstructor alarmMsgConstructor;
@SpyBean
protected DeviceMsgConstructor deviceMsgConstructor;
@SpyBean
protected AssetMsgConstructor assetMsgConstructor;
@MockBean
protected EntityViewMsgConstructor entityViewMsgConstructor;
@MockBean
protected DashboardMsgConstructor dashboardMsgConstructor;
@MockBean
protected RelationMsgConstructor relationMsgConstructor;
@MockBean
protected UserMsgConstructor userMsgConstructor;
@MockBean
protected CustomerMsgConstructor customerMsgConstructor;
@SpyBean
protected DeviceProfileMsgConstructor deviceProfileMsgConstructor;
@SpyBean
protected AssetProfileMsgConstructor assetProfileMsgConstructor;
@MockBean
protected TenantMsgConstructor tenantMsgConstructor;
@MockBean
protected TenantProfileMsgConstructor tenantProfileMsgConstructor;
@MockBean
protected WidgetsBundleMsgConstructor widgetsBundleMsgConstructor;
@MockBean
protected WidgetTypeMsgConstructor widgetTypeMsgConstructor;
@MockBean
protected AdminSettingsMsgConstructor adminSettingsMsgConstructor;
@MockBean
protected OtaPackageMsgConstructor otaPackageMsgConstructor;
@MockBean
protected QueueMsgConstructor queueMsgConstructor;
@MockBean
protected EdgeSynchronizationManager edgeSynchronizationManager;
@MockBean
protected DbCallbackExecutorService dbCallbackExecutorService;
@MockBean
protected DataDecodingEncodingService dataDecodingEncodingService;
protected EdgeId edgeId;
protected TenantId tenantId;
protected EdgeEvent edgeEvent;
protected DashboardId getDashboardId(long expectedDashboardIdMSB, long expectedDashboardIdLSB) {
DashboardId dashboardId;
if (expectedDashboardIdMSB != 0 && expectedDashboardIdLSB != 0) {
dashboardId = new DashboardId(new UUID(expectedDashboardIdMSB, expectedDashboardIdLSB));
} else {
dashboardId = new DashboardId(UUID.randomUUID());
}
return dashboardId;
}
protected RuleChainId getRuleChainId(long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) {
RuleChainId ruleChainId;
if (expectedRuleChainIdMSB != 0 && expectedRuleChainIdLSB != 0) {
ruleChainId = new RuleChainId(new UUID(expectedRuleChainIdMSB, expectedRuleChainIdLSB));
} else {
ruleChainId = new RuleChainId(UUID.randomUUID());
}
return ruleChainId;
}
protected static Stream<Arguments> provideParameters() {
UUID dashoboardUUID = UUID.randomUUID();
UUID ruleChaindUUID = UUID.randomUUID();
return Stream.of(
Arguments.of(EdgeVersion.V_3_3_0, 0, 0, 0, 0),
Arguments.of(EdgeVersion.V_3_3_3, 0, 0, 0, 0),
Arguments.of(EdgeVersion.V_3_4_0, 0, 0, 0, 0),
Arguments.of(EdgeVersion.V_3_6_0,
dashoboardUUID.getMostSignificantBits(),
dashoboardUUID.getLeastSignificantBits(),
ruleChaindUUID.getMostSignificantBits(),
ruleChaindUUID.getLeastSignificantBits())
);
}
}

View File

@ -0,0 +1,92 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.processor.asset;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.AssetProfileId;
import org.thingsboard.server.common.data.id.DashboardId;
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.gen.edge.v1.AssetProfileUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessorTest;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.BDDMockito.willReturn;
public abstract class AbstractAssetProcessorTest extends BaseEdgeProcessorTest {
protected AssetId assetId;
protected AssetProfileId assetProfileId;
protected AssetProfile assetProfile;
@BeforeEach
public void setUp() {
edgeId = new EdgeId(UUID.randomUUID());
tenantId = new TenantId(UUID.randomUUID());
assetId = new AssetId(UUID.randomUUID());
assetProfileId = new AssetProfileId(UUID.randomUUID());
assetProfile = new AssetProfile();
assetProfile.setId(assetProfileId);
assetProfile.setName("AssetProfile");
assetProfile.setDefault(true);
Asset asset = new Asset();
asset.setAssetProfileId(assetProfileId);
asset.setId(assetId);
asset.setName("Asset");
asset.setType(assetProfile.getName());
edgeEvent = new EdgeEvent();
edgeEvent.setTenantId(tenantId);
edgeEvent.setAction(EdgeEventActionType.ADDED);
willReturn(asset).given(assetService).findAssetById(tenantId, assetId);
willReturn(assetProfile).given(assetProfileService).findAssetProfileById(tenantId, assetProfileId);
}
protected void updateAssetProfileDefaultFields(long expectedDashboardIdMSB, long expectedDashboardIdLSB,
long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) {
DashboardId dashboardId = getDashboardId(expectedDashboardIdMSB, expectedDashboardIdLSB);
RuleChainId ruleChainId = getRuleChainId(expectedRuleChainIdMSB, expectedRuleChainIdLSB);
assetProfile.setDefaultDashboardId(dashboardId);
assetProfile.setDefaultEdgeRuleChainId(ruleChainId);
}
protected void verify(DownlinkMsg downlinkMsg, long expectedDashboardIdMSB, long expectedDashboardIdLSB,
long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) {
AssetProfileUpdateMsg assetProfileUpdateMsg = downlinkMsg.getAssetProfileUpdateMsgList().get(0);
assertNotNull(assetProfileUpdateMsg);
Assertions.assertThat(assetProfileUpdateMsg.getDefaultDashboardIdMSB()).isEqualTo(expectedDashboardIdMSB);
Assertions.assertThat(assetProfileUpdateMsg.getDefaultDashboardIdLSB()).isEqualTo(expectedDashboardIdLSB);
Assertions.assertThat(assetProfileUpdateMsg.getDefaultRuleChainIdMSB()).isEqualTo(expectedRuleChainIdMSB);
Assertions.assertThat(assetProfileUpdateMsg.getDefaultRuleChainIdLSB()).isEqualTo(expectedRuleChainIdLSB);
}
}

View File

@ -0,0 +1,44 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.processor.asset;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
@SpringBootTest(classes = {AssetEdgeProcessor.class})
class AssetEdgeProcessorTest extends AbstractAssetProcessorTest {
@SpyBean
AssetEdgeProcessor assetEdgeProcessor;
@ParameterizedTest
@MethodSource("provideParameters")
public void testAssetProfileDefaultFields_notSendToEdgeOlder3_6_0IfNotAssigned(EdgeVersion edgeVersion, long expectedDashboardIdMSB, long expectedDashboardIdLSB,
long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) {
updateAssetProfileDefaultFields(expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
edgeEvent.setEntityId(assetId.getId());
DownlinkMsg downlinkMsg = assetEdgeProcessor.convertAssetEventToDownlink(edgeEvent, edgeId, edgeVersion);
verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
}
}

View File

@ -0,0 +1,43 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.processor.asset;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
@SpringBootTest(classes = {AssetProfileEdgeProcessor.class})
class AssetProfileEdgeProcessorTest extends AbstractAssetProcessorTest{
@SpyBean
AssetProfileEdgeProcessor assetProfileEdgeProcessor;
@ParameterizedTest
@MethodSource("provideParameters")
public void testAssetProfileDefaultFields_notSendToEdgeOlder3_6_0IfNotAssigned(EdgeVersion edgeVersion, long expectedDashboardIdMSB, long expectedDashboardIdLSB,
long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) {
updateAssetProfileDefaultFields(expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
edgeEvent.setEntityId(assetProfileId.getId());
DownlinkMsg downlinkMsg = assetProfileEdgeProcessor.convertAssetProfileEventToDownlink(edgeEvent, edgeId, edgeVersion);
verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
}
}

View File

@ -0,0 +1,100 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.processor.device;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.DeviceId;
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.gen.edge.v1.DeviceProfileUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessorTest;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.BDDMockito.willReturn;
public abstract class AbstractDeviceProcessorTest extends BaseEdgeProcessorTest {
protected DeviceId deviceId;
protected DeviceProfileId deviceProfileId;
protected DeviceProfile deviceProfile;
@BeforeEach
public void setUp() {
edgeId = new EdgeId(UUID.randomUUID());
tenantId = new TenantId(UUID.randomUUID());
deviceId = new DeviceId(UUID.randomUUID());
deviceProfileId = new DeviceProfileId(UUID.randomUUID());
deviceProfile = new DeviceProfile();
deviceProfile.setId(deviceProfileId);
deviceProfile.setName("DeviceProfile");
deviceProfile.setDefault(true);
deviceProfile.setType(DeviceProfileType.DEFAULT);
DeviceProfileData deviceProfileData = new DeviceProfileData();
deviceProfile.setProfileData(deviceProfileData);
deviceProfile.setTransportType(DeviceTransportType.DEFAULT);
Device device = new Device();
device.setDeviceProfileId(deviceProfileId);
device.setId(deviceId);
device.setName("Device");
device.setType(deviceProfile.getName());
edgeEvent = new EdgeEvent();
edgeEvent.setTenantId(tenantId);
edgeEvent.setAction(EdgeEventActionType.ADDED);
willReturn(device).given(deviceService).findDeviceById(tenantId, deviceId);
willReturn(deviceProfile).given(deviceProfileService).findDeviceProfileById(tenantId, deviceProfileId);
willReturn(new byte[]{0x00}).given(dataDecodingEncodingService).encode(deviceProfileData);
}
protected void updateDeviceProfileDefaultFields(long expectedDashboardIdMSB, long expectedDashboardIdLSB,
long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) {
DashboardId dashboardId = getDashboardId(expectedDashboardIdMSB, expectedDashboardIdLSB);
RuleChainId ruleChainId = getRuleChainId(expectedRuleChainIdMSB, expectedRuleChainIdLSB);
deviceProfile.setDefaultDashboardId(dashboardId);
deviceProfile.setDefaultEdgeRuleChainId(ruleChainId);
}
protected void verify(DownlinkMsg downlinkMsg, long expectedDashboardIdMSB, long expectedDashboardIdLSB,
long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) {
DeviceProfileUpdateMsg deviceProfileUpdateMsg = downlinkMsg.getDeviceProfileUpdateMsgList().get(0);
assertNotNull(deviceProfileUpdateMsg);
Assertions.assertThat(deviceProfileUpdateMsg.getDefaultDashboardIdMSB()).isEqualTo(expectedDashboardIdMSB);
Assertions.assertThat(deviceProfileUpdateMsg.getDefaultDashboardIdLSB()).isEqualTo(expectedDashboardIdLSB);
Assertions.assertThat(deviceProfileUpdateMsg.getDefaultRuleChainIdMSB()).isEqualTo(expectedRuleChainIdMSB);
Assertions.assertThat(deviceProfileUpdateMsg.getDefaultRuleChainIdLSB()).isEqualTo(expectedRuleChainIdLSB);
}
}

View File

@ -0,0 +1,43 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.processor.device;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
@SpringBootTest(classes = {DeviceEdgeProcessor.class})
class DeviceEdgeProcessorTest extends AbstractDeviceProcessorTest {
@SpyBean
DeviceEdgeProcessor deviceEdgeProcessor;
@ParameterizedTest
@MethodSource("provideParameters")
public void testDeviceProfileDefaultFields_notSendToEdgeOlder3_6_0IfNotAssigned(EdgeVersion edgeVersion, long expectedDashboardIdMSB, long expectedDashboardIdLSB,
long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) {
updateDeviceProfileDefaultFields(expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
edgeEvent.setEntityId(deviceId.getId());
DownlinkMsg downlinkMsg = deviceEdgeProcessor.convertDeviceEventToDownlink(edgeEvent, edgeId, edgeVersion);
verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
}
}

View File

@ -0,0 +1,45 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge.rpc.processor.device;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
@SpringBootTest(classes = {DeviceProfileEdgeProcessor.class})
class DeviceProfileEdgeProcessorTest extends AbstractDeviceProcessorTest {
@SpyBean
DeviceProfileEdgeProcessor deviceProfileEdgeProcessor;
@ParameterizedTest
@MethodSource("provideParameters")
public void testDeviceProfileDefaultFields_notSendToEdgeOlder3_6_0IfNotAssigned(EdgeVersion edgeVersion, long expectedDashboardIdMSB, long expectedDashboardIdLSB,
long expectedRuleChainIdMSB, long expectedRuleChainIdLSB) {
updateDeviceProfileDefaultFields(expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
edgeEvent.setEntityId(deviceProfileId.getId());
DownlinkMsg downlinkMsg = deviceProfileEdgeProcessor.convertDeviceProfileEventToDownlink(edgeEvent, edgeId, edgeVersion);
verify(downlinkMsg, expectedDashboardIdMSB, expectedDashboardIdLSB, expectedRuleChainIdMSB, expectedRuleChainIdLSB);
}
}

View File

@ -111,7 +111,7 @@ public class EdgeGrpcClient implements EdgeRpcClient {
.setConnectRequestMsg(ConnectRequestMsg.newBuilder()
.setEdgeRoutingKey(edgeKey)
.setEdgeSecret(edgeSecret)
.setEdgeVersion(EdgeVersion.V_3_4_0)
.setEdgeVersion(EdgeVersion.V_3_6_0)
.setMaxInboundMessageSize(maxInboundMessageSize)
.build())
.build());

View File

@ -34,6 +34,7 @@ enum EdgeVersion {
V_3_3_0 = 0;
V_3_3_3 = 1;
V_3_4_0 = 2;
V_3_6_0 = 3;
}
/**