12 changed files with 553 additions and 24 deletions
@ -0,0 +1,26 @@ |
|||
/** |
|||
* 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.rule.engine.api; |
|||
|
|||
import org.thingsboard.server.common.data.ApiUsageState; |
|||
import org.thingsboard.server.common.data.id.ApiUsageStateId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
|
|||
public interface RuleEngineApiUsageStateService { |
|||
|
|||
ApiUsageState findApiUsageStateById(TenantId tenantId, ApiUsageStateId id); |
|||
|
|||
} |
|||
@ -0,0 +1,347 @@ |
|||
/** |
|||
* 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.rule.engine.util; |
|||
|
|||
import com.google.common.util.concurrent.Futures; |
|||
import org.junit.After; |
|||
import org.junit.Assert; |
|||
import org.junit.Before; |
|||
import org.junit.Test; |
|||
import org.junit.runner.RunWith; |
|||
import org.mockito.Mock; |
|||
import org.mockito.junit.MockitoJUnitRunner; |
|||
import org.thingsboard.common.util.AbstractListeningExecutor; |
|||
import org.thingsboard.rule.engine.api.RuleEngineAlarmService; |
|||
import org.thingsboard.rule.engine.api.RuleEngineApiUsageStateService; |
|||
import org.thingsboard.rule.engine.api.RuleEngineAssetProfileCache; |
|||
import org.thingsboard.rule.engine.api.RuleEngineDeviceProfileCache; |
|||
import org.thingsboard.rule.engine.api.RuleEngineRpcService; |
|||
import org.thingsboard.rule.engine.api.TbContext; |
|||
import org.thingsboard.server.common.data.ApiUsageState; |
|||
import org.thingsboard.server.common.data.Customer; |
|||
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.EntityType; |
|||
import org.thingsboard.server.common.data.EntityView; |
|||
import org.thingsboard.server.common.data.OtaPackage; |
|||
import org.thingsboard.server.common.data.TbResource; |
|||
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.asset.Asset; |
|||
import org.thingsboard.server.common.data.asset.AssetProfile; |
|||
import org.thingsboard.server.common.data.edge.Edge; |
|||
import org.thingsboard.server.common.data.id.AssetProfileId; |
|||
import org.thingsboard.server.common.data.id.DeviceProfileId; |
|||
import org.thingsboard.server.common.data.id.EntityId; |
|||
import org.thingsboard.server.common.data.id.EntityIdFactory; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.queue.Queue; |
|||
import org.thingsboard.server.common.data.rpc.Rpc; |
|||
import org.thingsboard.server.common.data.rule.RuleChain; |
|||
import org.thingsboard.server.common.data.rule.RuleNode; |
|||
import org.thingsboard.server.common.data.widget.WidgetType; |
|||
import org.thingsboard.server.common.data.widget.WidgetsBundle; |
|||
import org.thingsboard.server.dao.asset.AssetService; |
|||
import org.thingsboard.server.dao.customer.CustomerService; |
|||
import org.thingsboard.server.dao.dashboard.DashboardService; |
|||
import org.thingsboard.server.dao.device.DeviceService; |
|||
import org.thingsboard.server.dao.edge.EdgeService; |
|||
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.resource.ResourceService; |
|||
import org.thingsboard.server.dao.rule.RuleChainService; |
|||
import org.thingsboard.server.dao.user.UserService; |
|||
import org.thingsboard.server.dao.widget.WidgetTypeService; |
|||
import org.thingsboard.server.dao.widget.WidgetsBundleService; |
|||
|
|||
import java.util.UUID; |
|||
import java.util.concurrent.ExecutionException; |
|||
|
|||
import static org.mockito.ArgumentMatchers.any; |
|||
import static org.mockito.ArgumentMatchers.eq; |
|||
import static org.mockito.Mockito.doReturn; |
|||
import static org.mockito.Mockito.when; |
|||
|
|||
@RunWith(MockitoJUnitRunner.class) |
|||
public class EntitiesTenantIdAsyncLoaderTest { |
|||
|
|||
@Mock |
|||
private TbContext ctx; |
|||
@Mock |
|||
private CustomerService customerService; |
|||
@Mock |
|||
private UserService userService; |
|||
@Mock |
|||
private AssetService assetService; |
|||
@Mock |
|||
private DeviceService deviceService; |
|||
@Mock |
|||
private RuleEngineAlarmService alarmService; |
|||
@Mock |
|||
private RuleChainService ruleChainService; |
|||
@Mock |
|||
private EntityViewService entityViewService; |
|||
@Mock |
|||
private DashboardService dashboardService; |
|||
@Mock |
|||
private EdgeService edgeService; |
|||
@Mock |
|||
private OtaPackageService otaPackageService; |
|||
@Mock |
|||
private RuleEngineAssetProfileCache assetProfileCache; |
|||
@Mock |
|||
private RuleEngineDeviceProfileCache deviceProfileCache; |
|||
@Mock |
|||
private WidgetTypeService widgetTypeService; |
|||
@Mock |
|||
private WidgetsBundleService widgetsBundleService; |
|||
@Mock |
|||
private QueueService queueService; |
|||
@Mock |
|||
private ResourceService resourceService; |
|||
@Mock |
|||
private RuleEngineRpcService rpcService; |
|||
@Mock |
|||
private RuleEngineApiUsageStateService ruleEngineApiUsageStateService; |
|||
|
|||
private TenantId tenantId; |
|||
private AbstractListeningExecutor dbExecutor; |
|||
|
|||
@Before |
|||
public void before() { |
|||
dbExecutor = new AbstractListeningExecutor() { |
|||
@Override |
|||
protected int getThreadPollSize() { |
|||
return 3; |
|||
} |
|||
}; |
|||
dbExecutor.init(); |
|||
this.tenantId = new TenantId(UUID.randomUUID()); |
|||
|
|||
when(ctx.getTenantId()).thenReturn(tenantId); |
|||
when(ctx.getDbCallbackExecutor()).thenReturn(dbExecutor); |
|||
|
|||
for (EntityType entityType : EntityType.values()) { |
|||
initMocks(entityType, tenantId); |
|||
} |
|||
} |
|||
|
|||
@After |
|||
public void after() { |
|||
dbExecutor.destroy(); |
|||
} |
|||
|
|||
private void initMocks(EntityType entityType, TenantId tenantId) { |
|||
switch (entityType) { |
|||
case TENANT: |
|||
break; |
|||
case CUSTOMER: |
|||
Customer customer = new Customer(); |
|||
customer.setTenantId(tenantId); |
|||
|
|||
when(ctx.getCustomerService()).thenReturn(customerService); |
|||
doReturn(Futures.immediateFuture(customer)).when(customerService).findCustomerByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case USER: |
|||
User user = new User(); |
|||
user.setTenantId(tenantId); |
|||
|
|||
when(ctx.getUserService()).thenReturn(userService); |
|||
doReturn(Futures.immediateFuture(user)).when(userService).findUserByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case ASSET: |
|||
Asset asset = new Asset(); |
|||
asset.setTenantId(tenantId); |
|||
|
|||
when(ctx.getAssetService()).thenReturn(assetService); |
|||
doReturn(Futures.immediateFuture(asset)).when(assetService).findAssetByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case DEVICE: |
|||
Device device = new Device(); |
|||
device.setTenantId(tenantId); |
|||
|
|||
when(ctx.getDeviceService()).thenReturn(deviceService); |
|||
doReturn(Futures.immediateFuture(device)).when(deviceService).findDeviceByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case ALARM: |
|||
Alarm alarm = new Alarm(); |
|||
alarm.setTenantId(tenantId); |
|||
|
|||
when(ctx.getAlarmService()).thenReturn(alarmService); |
|||
doReturn(Futures.immediateFuture(alarm)).when(alarmService).findAlarmByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case RULE_CHAIN: |
|||
RuleChain ruleChain = new RuleChain(); |
|||
ruleChain.setTenantId(tenantId); |
|||
|
|||
when(ctx.getRuleChainService()).thenReturn(ruleChainService); |
|||
doReturn(Futures.immediateFuture(ruleChain)).when(ruleChainService).findRuleChainByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case ENTITY_VIEW: |
|||
EntityView entityView = new EntityView(); |
|||
entityView.setTenantId(tenantId); |
|||
|
|||
when(ctx.getEntityViewService()).thenReturn(entityViewService); |
|||
doReturn(Futures.immediateFuture(entityView)).when(entityViewService).findEntityViewByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case DASHBOARD: |
|||
Dashboard dashboard = new Dashboard(); |
|||
dashboard.setTenantId(tenantId); |
|||
|
|||
when(ctx.getDashboardService()).thenReturn(dashboardService); |
|||
doReturn(Futures.immediateFuture(dashboard)).when(dashboardService).findDashboardByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case EDGE: |
|||
Edge edge = new Edge(); |
|||
edge.setTenantId(tenantId); |
|||
|
|||
when(ctx.getEdgeService()).thenReturn(edgeService); |
|||
doReturn(Futures.immediateFuture(edge)).when(edgeService).findEdgeByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case OTA_PACKAGE: |
|||
OtaPackage otaPackage = new OtaPackage(); |
|||
otaPackage.setTenantId(tenantId); |
|||
|
|||
when(ctx.getOtaPackageService()).thenReturn(otaPackageService); |
|||
doReturn(Futures.immediateFuture(otaPackage)).when(otaPackageService).findOtaPackageInfoByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case ASSET_PROFILE: |
|||
AssetProfile assetProfile = new AssetProfile(); |
|||
assetProfile.setTenantId(tenantId); |
|||
|
|||
when(ctx.getAssetProfileCache()).thenReturn(assetProfileCache); |
|||
doReturn(assetProfile).when(assetProfileCache).get(eq(tenantId), any(AssetProfileId.class)); |
|||
|
|||
break; |
|||
case DEVICE_PROFILE: |
|||
DeviceProfile deviceProfile = new DeviceProfile(); |
|||
deviceProfile.setTenantId(tenantId); |
|||
|
|||
when(ctx.getDeviceProfileCache()).thenReturn(deviceProfileCache); |
|||
doReturn(deviceProfile).when(deviceProfileCache).get(eq(tenantId), any(DeviceProfileId.class)); |
|||
|
|||
break; |
|||
case WIDGET_TYPE: |
|||
WidgetType widgetType = new WidgetType(); |
|||
widgetType.setTenantId(tenantId); |
|||
|
|||
when(ctx.getWidgetTypeService()).thenReturn(widgetTypeService); |
|||
doReturn(widgetType).when(widgetTypeService).findWidgetTypeById(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case WIDGETS_BUNDLE: |
|||
WidgetsBundle widgetsBundle = new WidgetsBundle(); |
|||
widgetsBundle.setTenantId(tenantId); |
|||
|
|||
when(ctx.getWidgetBundleService()).thenReturn(widgetsBundleService); |
|||
doReturn(widgetsBundle).when(widgetsBundleService).findWidgetsBundleById(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case RPC: |
|||
Rpc rps = new Rpc(); |
|||
rps.setTenantId(tenantId); |
|||
|
|||
when(ctx.getRpcService()).thenReturn(rpcService); |
|||
doReturn(Futures.immediateFuture(rps)).when(rpcService).findRpcByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case QUEUE: |
|||
Queue queue = new Queue(); |
|||
queue.setTenantId(tenantId); |
|||
|
|||
when(ctx.getQueueService()).thenReturn(queueService); |
|||
doReturn(queue).when(queueService).findQueueById(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case API_USAGE_STATE: |
|||
ApiUsageState apiUsageState = new ApiUsageState(); |
|||
apiUsageState.setTenantId(tenantId); |
|||
|
|||
when(ctx.getRuleEngineApiUsageStateService()).thenReturn(ruleEngineApiUsageStateService); |
|||
doReturn(apiUsageState).when(ruleEngineApiUsageStateService).findApiUsageStateById(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case TB_RESOURCE: |
|||
TbResource tbResource = new TbResource(); |
|||
tbResource.setTenantId(tenantId); |
|||
|
|||
when(ctx.getResourceService()).thenReturn(resourceService); |
|||
doReturn(Futures.immediateFuture(tbResource)).when(resourceService).findResourceInfoByIdAsync(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case RULE_NODE: |
|||
RuleNode ruleNode = new RuleNode(); |
|||
|
|||
when(ctx.getRuleChainService()).thenReturn(ruleChainService); |
|||
doReturn(ruleNode).when(ruleChainService).findRuleNodeById(eq(tenantId), any()); |
|||
|
|||
break; |
|||
case TENANT_PROFILE: |
|||
TenantProfile tenantProfile = new TenantProfile(); |
|||
|
|||
when(ctx.getTenantProfile()).thenReturn(tenantProfile); |
|||
when(ctx.getTenantProfile(any(TenantId.class))).thenReturn(tenantProfile); |
|||
|
|||
break; |
|||
default: |
|||
throw new RuntimeException("Unexpected original EntityType " + entityType); |
|||
} |
|||
|
|||
} |
|||
|
|||
private EntityId getEntityId(EntityType entityType) { |
|||
return EntityIdFactory.getByTypeAndUuid(entityType, UUID.randomUUID()); |
|||
} |
|||
|
|||
private void checkTenant(TenantId checkTenantId, boolean equals) throws ExecutionException, InterruptedException { |
|||
for (EntityType entityType : EntityType.values()) { |
|||
EntityId entityId = EntityType.TENANT.equals(entityType) ? tenantId : getEntityId(entityType); |
|||
TenantId targetTenantId = EntitiesTenantIdAsyncLoader.findEntityIdAsync(ctx, entityId).get(); |
|||
|
|||
Assert.assertNotNull(targetTenantId); |
|||
String msg = "Check entity type <" + entityType.name() + ">:"; |
|||
if (equals) { |
|||
Assert.assertEquals(msg, targetTenantId, checkTenantId); |
|||
} else { |
|||
Assert.assertNotEquals(msg, targetTenantId, checkTenantId); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@Test |
|||
public void test_findEntityIdAsync_current_tenant() throws ExecutionException, InterruptedException { |
|||
checkTenant(tenantId, true); |
|||
} |
|||
|
|||
@Test |
|||
public void test_findEntityIdAsync_other_tenant() throws ExecutionException, InterruptedException { |
|||
checkTenant(new TenantId(UUID.randomUUID()), false); |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue