Browse Source

Merge pull request #14355 from artem-barysh-dev/new-entity-endpoints

Added more find-by-ids API endpoints
pull/14550/head
Viacheslav Klimov 10 months ago
committed by GitHub
parent
commit
98175f671d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 21
      application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java
  2. 23
      application/src/main/java/org/thingsboard/server/controller/CustomerController.java
  3. 37
      application/src/main/java/org/thingsboard/server/controller/DashboardController.java
  4. 20
      application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
  5. 48
      application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
  6. 19
      application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
  7. 20
      application/src/main/java/org/thingsboard/server/controller/TenantController.java
  8. 30
      application/src/main/java/org/thingsboard/server/controller/UserController.java
  9. 19
      application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
  10. 4
      application/src/main/java/org/thingsboard/server/service/security/permission/AccessControlService.java
  11. 14
      application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java
  12. 5
      application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java
  13. 36
      application/src/test/java/org/thingsboard/server/controller/AssetProfileControllerTest.java
  14. 39
      application/src/test/java/org/thingsboard/server/controller/CustomerControllerTest.java
  15. 39
      application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java
  16. 40
      application/src/test/java/org/thingsboard/server/controller/DeviceProfileControllerTest.java
  17. 33
      application/src/test/java/org/thingsboard/server/controller/EntityViewControllerTest.java
  18. 43
      application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java
  19. 38
      application/src/test/java/org/thingsboard/server/controller/TenantControllerTest.java
  20. 41
      application/src/test/java/org/thingsboard/server/controller/TenantProfileControllerTest.java
  21. 35
      application/src/test/java/org/thingsboard/server/controller/UserControllerTest.java
  22. 36
      application/src/test/java/org/thingsboard/server/controller/WidgetsBundleControllerTest.java
  23. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java
  24. 3
      common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java
  25. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java
  26. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java
  27. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java
  28. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java
  29. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java
  30. 3
      common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java
  31. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java
  32. 2
      dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileDao.java
  33. 7
      dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java
  34. 3
      dao/src/main/java/org/thingsboard/server/dao/customer/CustomerDao.java
  35. 7
      dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java
  36. 3
      dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardInfoDao.java
  37. 7
      dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java
  38. 2
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java
  39. 7
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java
  40. 2
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java
  41. 7
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
  42. 7
      dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java
  43. 4
      dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java
  44. 6
      dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetProfileRepository.java
  45. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetProfileDao.java
  46. 2
      dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java
  47. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java
  48. 3
      dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/DashboardInfoRepository.java
  49. 6
      dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java
  50. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java
  51. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java
  52. 2
      dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java
  53. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java
  54. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java
  55. 3
      dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java
  56. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDao.java
  57. 2
      dao/src/main/java/org/thingsboard/server/dao/sql/tenant/TenantRepository.java
  58. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java
  59. 2
      dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java
  60. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java
  61. 8
      dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetsBundleRepository.java
  62. 2
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantDao.java
  63. 8
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java
  64. 2
      dao/src/main/java/org/thingsboard/server/dao/user/UserDao.java
  65. 7
      dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java
  66. 3
      dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleDao.java
  67. 7
      dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java

21
application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java

@ -16,11 +16,13 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@ -45,7 +47,10 @@ import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID;
import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID_PARAM_DESCRIPTION;
@ -222,4 +227,20 @@ public class AssetProfileController extends BaseController {
return checkNotNull(assetProfileService.findAssetProfileNamesByTenantId(tenantId, activeOnly));
}
@ApiOperation(value = "Get Asset Profiles By Ids (getAssetProfilesByIds)",
notes = "Requested asset profiles must be owned by tenant which is performing the request. " +
NEW_LINE)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping(value = "/assetProfileInfos", params = {"assetProfileIds"})
public List<AssetProfileInfo> getAssetProfilesByIds(
@Parameter(description = "A list of asset profile ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("assetProfileIds") Set<UUID> assetProfileUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List<AssetProfileId> assetProfileIds = new ArrayList<>();
for (UUID assetProfileUUID : assetProfileUUIDs) {
assetProfileIds.add(new AssetProfileId(assetProfileUUID));
}
return assetProfileService.findAssetProfilesByIds(tenantId, assetProfileIds);
}
}

23
application/src/main/java/org/thingsboard/server/controller/CustomerController.java

@ -18,10 +18,12 @@ package org.thingsboard.server.controller;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@ -46,6 +48,11 @@ import org.thingsboard.server.service.entitiy.customer.TbCustomerService;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID;
import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_TEXT_SEARCH_DESCRIPTION;
@ -195,4 +202,20 @@ public class CustomerController extends BaseController {
return checkNotNull(customerService.findCustomerByTenantIdAndTitle(tenantId, customerTitle), "Customer with title [" + customerTitle + "] is not found");
}
@ApiOperation(value = "Get customers by Customer Ids (getCustomersByIds)",
notes = "Returns a list of Customer objects based on the provided ids." +
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@GetMapping(value = "/customers", params = {"customerIds"})
public List<Customer> getCustomersByIds(
@Parameter(description = "A list of customer ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("customerIds") Set<UUID> customerUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List<CustomerId> customerIds = new ArrayList<>();
for (UUID customerUUID : customerUUIDs) {
customerIds.add(new CustomerId(customerUUID));
}
return customerService.findCustomersByTenantIdAndIds(tenantId, customerIds);
}
}

37
application/src/main/java/org/thingsboard/server/controller/DashboardController.java

@ -18,6 +18,7 @@ package org.thingsboard.server.controller;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
@ -62,6 +63,7 @@ import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -592,14 +594,7 @@ public class DashboardController extends BaseController {
checkEdgeId(edgeId, Operation.READ);
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
PageData<DashboardInfo> nonFilteredResult = dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edgeId, pageLink);
List<DashboardInfo> filteredDashboards = nonFilteredResult.getData().stream().filter(dashboardInfo -> {
try {
accessControlService.checkPermission(getCurrentUser(), Resource.DASHBOARD, Operation.READ, dashboardInfo.getId(), dashboardInfo);
return true;
} catch (ThingsboardException e) {
return false;
}
}).collect(Collectors.toList());
List<DashboardInfo> filteredDashboards = filterDashboardsByReadPermission(nonFilteredResult.getData());
PageData<DashboardInfo> filteredResult = new PageData<>(filteredDashboards,
nonFilteredResult.getTotalPages(),
nonFilteredResult.getTotalElements(),
@ -607,6 +602,22 @@ public class DashboardController extends BaseController {
return checkNotNull(filteredResult);
}
@ApiOperation(value = "Get dashboards by Dashboard Ids (getDashboardsByIds)",
notes = "Returns a list of DashboardInfo objects based on the provided ids. " +
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/dashboards", params = {"dashboardIds"})
public List<DashboardInfo> getDashboardsByIds(@Parameter(description = "A list of dashboard ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("dashboardIds") Set<UUID> dashboardUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List<DashboardId> dashboardIds = new ArrayList<>();
for (UUID dashboardUUID : dashboardUUIDs) {
dashboardIds.add(new DashboardId(dashboardUUID));
}
List<DashboardInfo> dashboards = dashboardService.findDashboardInfoByIds(tenantId, dashboardIds);
return filterDashboardsByReadPermission(dashboards);
}
private Set<CustomerId> customerIdFromStr(String[] strCustomerIds) {
Set<CustomerId> customerIds = new HashSet<>();
if (strCustomerIds != null) {
@ -617,4 +628,14 @@ public class DashboardController extends BaseController {
return customerIds;
}
private List<DashboardInfo> filterDashboardsByReadPermission(List<DashboardInfo> dashboards) {
return dashboards.stream().filter(dashboard -> {
try {
return accessControlService.hasPermission(getCurrentUser(), Resource.DASHBOARD, Operation.READ, dashboard.getId(), dashboard);
} catch (ThingsboardException e) {
return false;
}
}).collect(Collectors.toList());
}
}

20
application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java

@ -16,12 +16,14 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@ -48,7 +50,9 @@ import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_DATA;
@ -278,4 +282,20 @@ public class DeviceProfileController extends BaseController {
return checkNotNull(deviceProfileService.findDeviceProfileNamesByTenantId(tenantId, activeOnly));
}
@ApiOperation(value = "Get Device Profile Infos By Ids (getDeviceProfilesByIds)",
notes = "Requested device profiles must be owned by tenant which is performing the request. " +
NEW_LINE)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping(value = "/deviceProfileInfos", params = {"deviceProfileIds"})
public List<DeviceProfileInfo> getDeviceProfileInfosByIds(
@Parameter(description = "A list of device profile ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("deviceProfileIds") Set<UUID> deviceProfileUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List<DeviceProfileId> deviceProfileIds = new ArrayList<>();
for (UUID deviceProfileUUID : deviceProfileUUIDs) {
deviceProfileIds.add(new DeviceProfileId(deviceProfileUUID));
}
return deviceProfileService.findDeviceProfilesByIds(tenantId, deviceProfileIds);
}
}

48
application/src/main/java/org/thingsboard/server/controller/EntityViewController.java

@ -17,11 +17,13 @@ package org.thingsboard.server.controller;
import com.google.common.util.concurrent.ListenableFuture;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@ -57,7 +59,10 @@ import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
@ -346,14 +351,7 @@ public class EntityViewController extends BaseController {
checkNotNull(query.getEntityViewTypes());
checkEntityId(query.getParameters().getEntityId(), Operation.READ);
List<EntityView> entityViews = checkNotNull(entityViewService.findEntityViewsByQuery(getTenantId(), query).get());
entityViews = entityViews.stream().filter(entityView -> {
try {
accessControlService.checkPermission(getCurrentUser(), Resource.ENTITY_VIEW, Operation.READ, entityView.getId(), entityView);
return true;
} catch (ThingsboardException e) {
return false;
}
}).collect(Collectors.toList());
entityViews = filterEntityViewsByReadPermission(entityViews);
return entityViews;
}
@ -453,14 +451,7 @@ public class EntityViewController extends BaseController {
} else {
nonFilteredResult = entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edgeId, pageLink);
}
List<EntityView> filteredEntityViews = nonFilteredResult.getData().stream().filter(entityView -> {
try {
accessControlService.checkPermission(getCurrentUser(), Resource.ENTITY_VIEW, Operation.READ, entityView.getId(), entityView);
return true;
} catch (ThingsboardException e) {
return false;
}
}).collect(Collectors.toList());
List<EntityView> filteredEntityViews = filterEntityViewsByReadPermission(nonFilteredResult.getData());
PageData<EntityView> filteredResult = new PageData<>(filteredEntityViews,
nonFilteredResult.getTotalPages(),
nonFilteredResult.getTotalElements(),
@ -468,4 +459,29 @@ public class EntityViewController extends BaseController {
return checkNotNull(filteredResult);
}
@ApiOperation(value = "Get Entity Views By Ids (getEntityViewsByIds)",
notes = "Requested entity views must be owned by tenant or assigned to customer which user is performing the request. ")
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/entityViews", params = {"entityViewIds"})
public List<EntityView> getEntityViewsByIds(@Parameter(description = "A list of entity view ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("entityViewIds") Set<UUID> entityViewUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List<EntityViewId> entityViewIds = new ArrayList<>();
for (UUID entityViewUUID : entityViewUUIDs) {
entityViewIds.add(new EntityViewId(entityViewUUID));
}
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndIds(tenantId, entityViewIds);
return filterEntityViewsByReadPermission(entityViews);
}
private List<EntityView> filterEntityViewsByReadPermission(List<EntityView> entityViews) {
return entityViews.stream().filter(entityView -> {
try {
return accessControlService.hasPermission(getCurrentUser(), Resource.ENTITY_VIEW, Operation.READ, entityView.getId(), entityView);
} catch (ThingsboardException e) {
return false;
}
}).collect(Collectors.toList());
}
}

19
application/src/main/java/org/thingsboard/server/controller/RuleChainController.java

@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
@ -79,6 +80,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
@ -90,6 +92,7 @@ import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIG
import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_END;
import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_START;
import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
@ -579,4 +582,20 @@ public class RuleChainController extends BaseController {
return checkNotNull(result);
}
@ApiOperation(value = "Get Rule Chains By Ids (getRuleChainsByIds)",
notes = "Requested rule chains must be owned by tenant which is performing the request. " +
NEW_LINE)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping(value = "/ruleChains", params = {"ruleChainIds"})
public List<RuleChain> getRuleChainsByIds(
@Parameter(description = "A list of rule chain ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("ruleChainIds") Set<UUID> ruleChainUUIDs) throws Exception {
TenantId tenantId = getCurrentUser().getTenantId();
List<RuleChainId> ruleChainIds = new ArrayList<>();
for (UUID ruleChainUUID : ruleChainUUIDs) {
ruleChainIds.add(new RuleChainId(ruleChainUUID));
}
return ruleChainService.findRuleChainsByIds(tenantId, ruleChainIds);
}
}

20
application/src/main/java/org/thingsboard/server/controller/TenantController.java

@ -16,11 +16,13 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@ -43,6 +45,11 @@ import org.thingsboard.server.service.entitiy.tenant.TbTenantService;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import static org.thingsboard.server.controller.ControllerConstants.HOME_DASHBOARD;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
@ -162,4 +169,17 @@ public class TenantController extends BaseController {
return checkNotNull(tenantService.findTenantInfos(pageLink));
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
@GetMapping(value = "/tenants", params = {"tenantIds"})
public List<Tenant> getTenantsByIds(
@Parameter(description = "A list of tenant ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")))
@RequestParam("tenantIds") Set<UUID> tenantUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List<TenantId> tenantIds = new ArrayList<>();
for (UUID tenantIdUUID : tenantUUIDs) {
tenantIds.add(TenantId.fromUUID(tenantIdUUID));
}
return tenantService.findTenantsByIds(tenantId, tenantIds);
}
}

30
application/src/main/java/org/thingsboard/server/controller/UserController.java

@ -17,6 +17,7 @@ package org.thingsboard.server.controller;
import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
@ -82,6 +83,9 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD;
import static org.thingsboard.server.controller.ControllerConstants.ALARM_ID_PARAM_DESCRIPTION;
@ -579,6 +583,32 @@ public class UserController extends BaseController {
userService.removeMobileSession(user.getTenantId(), mobileToken);
}
@ApiOperation(value = "Get Users By Ids (getUsersByIds)",
notes = "Requested users must be owned by tenant or assigned to customer which user is performing the request. ")
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/users", params = {"userIds"})
public List<User> getUsersByIds(
@Parameter(description = "A list of user ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("userIds") Set<UUID> userUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List<UserId> userIds = new ArrayList<>();
for (UUID userUUID : userUUIDs) {
userIds.add(new UserId(userUUID));
}
List<User> users = userService.findUsersByTenantIdAndIds(tenantId, userIds);
return filterUsersByReadPermission(users);
}
private List<User> filterUsersByReadPermission(List<User> users) {
return users.stream().filter(user -> {
try {
return accessControlService.hasPermission(getCurrentUser(), Resource.USER, Operation.READ, user.getId(), user);
} catch (ThingsboardException e) {
return false;
}
}).collect(Collectors.toList());
}
private void checkNotReserved(String strType, UserSettingsType type) throws ThingsboardException {
if (type.isReserved()) {
throw new ThingsboardException("Settings with type: " + strType + " are reserved for internal use!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);

19
application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java

@ -16,10 +16,12 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@ -49,10 +51,12 @@ import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import static org.thingsboard.server.controller.ControllerConstants.AVAILABLE_FOR_ANY_AUTHORIZED_USER;
import static org.thingsboard.server.controller.ControllerConstants.INLINE_IMAGES;
import static org.thingsboard.server.controller.ControllerConstants.INLINE_IMAGES_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
@ -231,4 +235,19 @@ public class WidgetsBundleController extends BaseController {
}
}
@ApiOperation(value = "Get Widgets Bundles By Ids (getWidgetsBundlesByIds)",
notes = "Requested widgets bundles must be system level or owned by tenant of the user which is performing the request. " +
NEW_LINE)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/widgetsBundles", params = {"widgetsBundleIds"})
public List<WidgetsBundle> getWidgetsBundlesByIds(
@Parameter(description = "A list of widgets bundle ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("widgetsBundleIds") Set<UUID> widgetsBundleUUIDs) throws ThingsboardException {
List<WidgetsBundleId> widgetsBundleIds = new ArrayList<>();
for (UUID widgetsBundleUUID : widgetsBundleUUIDs) {
widgetsBundleIds.add(new WidgetsBundleId(widgetsBundleUUID));
}
return widgetsBundleService.findSystemOrTenantWidgetsBundlesByIds(getTenantId(), widgetsBundleIds);
}
}

4
application/src/main/java/org/thingsboard/server/service/security/permission/AccessControlService.java

@ -24,6 +24,10 @@ public interface AccessControlService {
void checkPermission(SecurityUser user, Resource resource, Operation operation) throws ThingsboardException;
boolean hasPermission(SecurityUser user, Resource resource, Operation operation) throws ThingsboardException;
<I extends EntityId, T extends HasTenantId> void checkPermission(SecurityUser user, Resource resource, Operation operation, I entityId, T entity) throws ThingsboardException;
<I extends EntityId, T extends HasTenantId> boolean hasPermission(SecurityUser user, Resource resource, Operation operation, I entityId, T entity) throws ThingsboardException;
}

14
application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java

@ -54,6 +54,13 @@ public class DefaultAccessControlService implements AccessControlService {
}
}
@Override
@SuppressWarnings("unchecked")
public boolean hasPermission(SecurityUser user, Resource resource, Operation operation) throws ThingsboardException {
var permissionChecker = getPermissionChecker(user.getAuthority(), resource);
return permissionChecker.hasPermission(user, operation);
}
@Override
@SuppressWarnings("unchecked")
public <I extends EntityId, T extends HasTenantId> void checkPermission(SecurityUser user, Resource resource,
@ -64,6 +71,13 @@ public class DefaultAccessControlService implements AccessControlService {
}
}
@Override
@SuppressWarnings("unchecked")
public <I extends EntityId, T extends HasTenantId> boolean hasPermission(SecurityUser user, Resource resource, Operation operation, I entityId, T entity) throws ThingsboardException {
var permissionChecker = getPermissionChecker(user.getAuthority(), resource);
return permissionChecker.hasPermission(user, operation, entityId, entity);
}
private PermissionChecker getPermissionChecker(Authority authority, Resource resource) throws ThingsboardException {
Permissions permissions = authorityPermissions.get(authority);
if (permissions == null) {

5
application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java

@ -66,6 +66,11 @@ public class TenantAdminPermissions extends AbstractPermissions {
public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker() {
@Override
public boolean hasPermission(SecurityUser user, Operation operation) {
return true;
}
@Override
public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
if (!user.getTenantId().equals(entity.getTenantId())) {

36
application/src/test/java/org/thingsboard/server/controller/AssetProfileControllerTest.java

@ -46,9 +46,13 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.containsString;
@ -195,6 +199,38 @@ public class AssetProfileControllerTest extends AbstractControllerTest {
Assert.assertEquals(savedAssetProfile.getName(), foundAssetProfileInfo.getName());
}
@Test
public void testFindAssetProfileInfoByIds() throws Exception {
List<AssetProfileInfo> assetProfiles = new ArrayList<>();
for (int i = 0; i < 20; i++) {
AssetProfile assetProfile = this.createAssetProfile("Asset Profile" + i);
assetProfile.setTenantId(savedTenant.getId());
assetProfiles.add(doPost("/api/assetProfile", assetProfile, AssetProfileInfo.class));
}
List<AssetProfileInfo> expected = assetProfiles.subList(5, 15);
String idsParam = expected.stream()
.map(ap -> ap.getId().getId().toString())
.collect(Collectors.joining(","));
AssetProfileInfo[] foundAssetProfileInfos = doGet("/api/assetProfileInfos?assetProfileIds=" + idsParam, AssetProfileInfo[].class);
Assert.assertNotNull(foundAssetProfileInfos);
Assert.assertEquals(expected.size(), foundAssetProfileInfos.length);
Map<UUID, AssetProfileInfo> infoById = Arrays.stream(foundAssetProfileInfos)
.collect(Collectors.toMap(info -> info.getId().getId(), Function.identity()));
for (AssetProfileInfo assetProfileInfo : expected) {
UUID id = assetProfileInfo.getId().getId();
AssetProfileInfo info = infoById.get(id);
Assert.assertNotNull("AssetProfileInfo not found for id " + id, info);
Assert.assertEquals(assetProfileInfo.getId(), info.getId());
Assert.assertEquals(assetProfileInfo.getName(), info.getName());
}
}
@Test
public void whenGetAssetProfileInfoById_thenPermissionsAreChecked() throws Exception {
AssetProfile assetProfile = createAssetProfile("Asset profile 1");

39
application/src/test/java/org/thingsboard/server/controller/CustomerControllerTest.java

@ -48,8 +48,13 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
@ -261,6 +266,40 @@ public class CustomerControllerTest extends AbstractControllerTest {
.andExpect(status().isOk());
}
@Test
public void testFindCustomersByIds() throws Exception {
List<Customer> savedCustomers = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Customer customer = new Customer();
customer.setTitle("My customer " + i);
savedCustomers.add(doPost("/api/customer", customer, Customer.class));
}
String idsParam = savedCustomers.stream()
.map(c -> c.getId().getId().toString())
.collect(Collectors.joining(","));
Customer[] foundCustomers = doGet("/api/customers?customerIds=" + idsParam, Customer[].class);
Assert.assertNotNull(foundCustomers);
Assert.assertEquals(savedCustomers.size(), foundCustomers.length);
Map<UUID, Customer> foundById = Arrays.stream(foundCustomers)
.collect(Collectors.toMap(c -> c.getId().getId(), Function.identity()));
for (Customer savedCustomer : savedCustomers) {
UUID id = savedCustomer.getId().getId();
Customer foundCustomer = foundById.get(id);
Assert.assertNotNull("Customer not found for id " + id, foundCustomer);
Assert.assertEquals(savedCustomer, foundCustomer);
}
for (Customer savedCustomer : savedCustomers) {
doDelete("/api/customer/" + savedCustomer.getId().getId().toString())
.andExpect(status().isOk());
}
}
@Test
public void testDeleteCustomer() throws Exception {
Customer customer = new Customer();

39
application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java

@ -55,9 +55,12 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
@ -155,6 +158,42 @@ public class DashboardControllerTest extends AbstractControllerTest {
Assert.assertEquals(savedDashboard, foundDashboard);
}
@Test
public void testFindDashboardInfosByIds() throws Exception {
List<Dashboard> dashboards = new ArrayList<>();
for (int i = 0; i < 20; i++) {
Dashboard dashboard = new Dashboard();
dashboard.setTitle("My dashboard " + i);
dashboards.add(doPost("/api/dashboard", dashboard, Dashboard.class));
}
List<Dashboard> expected = dashboards.subList(5, 15);
String idsParam = expected.stream()
.map(d -> d.getId().getId().toString())
.collect(Collectors.joining(","));
DashboardInfo[] result = doGet(
"/api/dashboards?dashboardIds=" + idsParam,
DashboardInfo[].class
);
Assert.assertNotNull(result);
Assert.assertEquals(expected.size(), result.length);
Map<UUID, DashboardInfo> infoById = Arrays.stream(result)
.collect(Collectors.toMap(info -> info.getId().getId(), Function.identity()));
for (Dashboard dashboard : expected) {
UUID id = dashboard.getId().getId();
DashboardInfo info = infoById.get(id);
Assert.assertNotNull("DashboardInfo not found for id " + id, info);
Assert.assertEquals(dashboard.getId(), info.getId());
Assert.assertEquals(dashboard.getTitle(), info.getTitle());
}
}
@Test
public void testDeleteDashboard() throws Exception {
Dashboard dashboard = new Dashboard();

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

@ -56,9 +56,13 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
@ -214,6 +218,42 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
Assert.assertEquals(savedDeviceProfile.getType(), foundDeviceProfileInfo.getType());
}
@Test
public void testFindDeviceProfileInfosByIds() throws Exception {
List<DeviceProfile> deviceProfiles = new ArrayList<>();
for (int i = 0; i < 20; i++) {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile " + i);
deviceProfiles.add(saveDeviceProfile(deviceProfile));
}
List<DeviceProfile> expected = deviceProfiles.subList(5, 15);
String idsParam = expected.stream()
.map(dp -> dp.getId().getId().toString())
.collect(Collectors.joining(","));
DeviceProfileInfo[] result = doGet(
"/api/deviceProfileInfos?deviceProfileIds=" + idsParam,
DeviceProfileInfo[].class
);
Assert.assertNotNull(result);
Assert.assertEquals(expected.size(), result.length);
Map<UUID, DeviceProfileInfo> infoById = Arrays.stream(result)
.collect(Collectors.toMap(info -> info.getId().getId(), Function.identity()));
for (DeviceProfile dp : expected) {
UUID id = dp.getId().getId();
DeviceProfileInfo info = infoById.get(id);
Assert.assertNotNull("DeviceProfileInfo not found for id " + id, info);
Assert.assertEquals(dp.getId(), info.getId());
Assert.assertEquals(dp.getName(), info.getName());
Assert.assertEquals(dp.getType(), info.getType());
}
}
@Test
public void whenGetDeviceProfileInfoById_thenPermissionsAreChecked() throws Exception {
DeviceProfile deviceProfile = createDeviceProfile("Device profile 1", null);

33
application/src/test/java/org/thingsboard/server/controller/EntityViewControllerTest.java

@ -68,11 +68,14 @@ import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import static java.util.concurrent.TimeUnit.HOURS;
@ -148,6 +151,36 @@ public class EntityViewControllerTest extends AbstractControllerTest {
assertEquals(savedView, foundView);
}
@Test
public void testFindEntityViewByIds() throws Exception {
List<EntityView> assetProfiles = new ArrayList<>();
for (int i = 0; i < 20; i++) {
assetProfiles.add(getNewSavedEntityView("Test entity view " + i));
}
List<EntityView> expected = assetProfiles.subList(5, 15);
String idsParam = expected.stream()
.map(ap -> ap.getId().getId().toString())
.collect(Collectors.joining(","));
EntityView[] foundEntityViews = doGet("/api/entityViews?entityViewIds=" + idsParam, EntityView[].class);
Assert.assertNotNull(foundEntityViews);
Assert.assertEquals(expected.size(), foundEntityViews.length);
Map<UUID, EntityView> infoById = Arrays.stream(foundEntityViews)
.collect(Collectors.toMap(info -> info.getId().getId(), Function.identity()));
for (EntityView entityView : expected) {
UUID id = entityView.getId().getId();
EntityView view = infoById.get(id);
Assert.assertNotNull("Entity view not found for id " + id, view);
Assert.assertEquals(entityView.getId(), view.getId());
Assert.assertEquals(entityView.getName(), view.getName());
}
}
@Test
public void testSaveEntityView() throws Exception {
String name = "Test entity view";

43
application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java

@ -52,7 +52,12 @@ import org.thingsboard.server.dao.rule.RuleChainDao;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
@ -231,6 +236,44 @@ public class RuleChainControllerTest extends AbstractControllerTest {
Assert.assertEquals(savedRuleChain, foundRuleChain);
}
@Test
public void testFindRuleChainsByIds() throws Exception {
List<RuleChain> ruleChains = new ArrayList<>();
for (int i = 0; i < 20; i++) {
RuleChain ruleChain = new RuleChain();
ruleChain.setName("RuleChain " + i);
ruleChains.add(doPost("/api/ruleChain", ruleChain, RuleChain.class));
}
List<RuleChain> expected = ruleChains.subList(5, 15);
String idsParam = expected.stream()
.map(rc -> rc.getId().getId().toString())
.collect(Collectors.joining(","));
RuleChain[] result = doGet(
"/api/ruleChains?ruleChainIds=" + idsParam,
RuleChain[].class
);
Assert.assertNotNull(result);
Assert.assertEquals(expected.size(), result.length);
Map<UUID, RuleChain> rcById = Arrays.stream(result)
.collect(Collectors.toMap(rc -> rc.getId().getId(), Function.identity()));
for (RuleChain rc : expected) {
UUID id = rc.getId().getId();
RuleChain found = rcById.get(id);
Assert.assertNotNull("RuleChain not found for id " + id, found);
Assert.assertEquals(rc.getId(), found.getId());
Assert.assertEquals(rc.getName(), found.getName());
Assert.assertEquals(rc.getTenantId(), found.getTenantId());
}
}
@Test
public void testDeleteRuleChain() throws Exception {
RuleChain ruleChain = new RuleChain();

38
application/src/test/java/org/thingsboard/server/controller/TenantControllerTest.java

@ -68,6 +68,7 @@ import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.QueueKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@ -77,6 +78,7 @@ import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -187,6 +189,42 @@ public class TenantControllerTest extends AbstractControllerTest {
deleteTenant(savedTenant.getId());
}
@Test
public void testFindTenantsByIds() throws Exception {
loginSysAdmin();
List<Tenant> savedTenants = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Tenant tenant = new Tenant();
tenant.setTitle("My tenant " + i);
savedTenants.add(saveTenant(tenant));
}
String idsParam = savedTenants.stream()
.map(t -> t.getId().getId().toString())
.collect(Collectors.joining(","));
Tenant[] foundTenants = doGet("/api/tenants?tenantIds=" + idsParam, Tenant[].class);
Assert.assertNotNull(foundTenants);
Assert.assertEquals(savedTenants.size(), foundTenants.length);
Map<UUID, Tenant> foundById = Arrays.stream(foundTenants)
.collect(Collectors.toMap(t -> t.getId().getId(), Function.identity()));
for (Tenant savedTenant : savedTenants) {
UUID id = savedTenant.getId().getId();
Tenant foundTenant = foundById.get(id);
Assert.assertNotNull("Tenant not found for id " + id, foundTenant);
Assert.assertEquals(savedTenant, foundTenant);
}
for (Tenant savedTenant : savedTenants) {
deleteTenant(savedTenant.getId());
}
}
@Test
public void testFindTenantInfoById() throws Exception {
loginSysAdmin();

41
application/src/test/java/org/thingsboard/server/controller/TenantProfileControllerTest.java

@ -42,8 +42,12 @@ import org.thingsboard.server.queue.TbQueueCallback;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.containsString;
@ -120,6 +124,43 @@ public class TenantProfileControllerTest extends AbstractControllerTest {
Assert.assertEquals(savedTenantProfile.getName(), foundTenantProfileInfo.getName());
}
@Test
public void testFindTenantProfilesByIds() throws Exception {
loginSysAdmin();
List<TenantProfile> tenantProfiles = new ArrayList<>();
for (int i = 0; i < 10; i++) {
TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile " + i);
tenantProfiles.add(doPost("/api/tenantProfile", tenantProfile, TenantProfile.class));
}
List<TenantProfile> expected = tenantProfiles.subList(2, 7);
String idsParam = expected.stream()
.map(tp -> tp.getId().getId().toString())
.collect(Collectors.joining(","));
TenantProfile[] result = doGet(
"/api/tenantProfiles?ids=" + idsParam,
TenantProfile[].class
);
Assert.assertNotNull(result);
Assert.assertEquals(expected.size(), result.length);
Map<UUID, TenantProfile> tpById = Arrays.stream(result)
.collect(Collectors.toMap(tp -> tp.getId().getId(), Function.identity()));
for (TenantProfile tp : expected) {
UUID id = tp.getId().getId();
TenantProfile found = tpById.get(id);
Assert.assertNotNull("TenantProfile not found for id " + id, found);
Assert.assertEquals(tp.getId(), found.getId());
Assert.assertEquals(tp.getName(), found.getName());
}
}
@Test
public void testFindDefaultTenantProfileInfo() throws Exception {
loginSysAdmin();

35
application/src/test/java/org/thingsboard/server/controller/UserControllerTest.java

@ -55,8 +55,12 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.dao.user.UserDao;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
@ -263,6 +267,37 @@ public class UserControllerTest extends AbstractControllerTest {
Assert.assertEquals(savedUser, foundUser);
}
@Test
public void testFindUsersByIds() throws Exception {
loginTenantAdmin();
List<User> savedUsers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User user = createTenantAdminUser();
savedUsers.add(doPost("/api/user", user, User.class));
}
String idsParam = savedUsers.stream()
.map(u -> u.getId().getId().toString())
.collect(Collectors.joining(","));
User[] foundUsers = doGet("/api/users?userIds=" + idsParam, User[].class);
Assert.assertNotNull(foundUsers);
Assert.assertEquals(savedUsers.size(), foundUsers.length);
Map<UUID, User> foundById = Arrays.stream(foundUsers)
.collect(Collectors.toMap(u -> u.getId().getId(), Function.identity()));
for (User savedUser : savedUsers) {
User foundUser = foundById.get(savedUser.getId().getId());
Assert.assertNotNull("User not found for id " + savedUser.getId().getId(), foundUser);
foundUser.setAdditionalInfo(savedUser.getAdditionalInfo());
Assert.assertEquals(savedUser, foundUser);
}
}
@Test
public void testSaveUserWithSameEmail() throws Exception {
loginSysAdmin();

36
application/src/test/java/org/thingsboard/server/controller/WidgetsBundleControllerTest.java

@ -33,8 +33,13 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -150,6 +155,37 @@ public class WidgetsBundleControllerTest extends AbstractControllerTest {
Assert.assertEquals(savedWidgetsBundle, foundWidgetsBundle);
}
@Test
public void testFindWidgetsBundlesByIds() throws Exception {
List<WidgetsBundle> savedWidgetsBundles = new ArrayList<>();
for (int i = 0; i < 10; i++) {
WidgetsBundle widgetsBundle = new WidgetsBundle();
widgetsBundle.setTitle("My widgets bundle " + i);
savedWidgetsBundles.add(doPost("/api/widgetsBundle", widgetsBundle, WidgetsBundle.class));
}
String idsParam = savedWidgetsBundles.stream()
.map(wb -> wb.getId().getId().toString())
.collect(Collectors.joining(","));
WidgetsBundle[] foundWidgetsBundles =
doGet("/api/widgetsBundles?widgetsBundleIds=" + idsParam, WidgetsBundle[].class);
Assert.assertNotNull(foundWidgetsBundles);
Assert.assertEquals(savedWidgetsBundles.size(), foundWidgetsBundles.length);
Map<UUID, WidgetsBundle> foundById = Arrays.stream(foundWidgetsBundles)
.collect(Collectors.toMap(wb -> wb.getId().getId(), Function.identity()));
for (WidgetsBundle savedWidgetsBundle : savedWidgetsBundles) {
UUID id = savedWidgetsBundle.getId().getId();
WidgetsBundle foundWidgetsBundle = foundById.get(id);
Assert.assertNotNull("WidgetsBundle not found for id " + id, foundWidgetsBundle);
Assert.assertEquals(savedWidgetsBundle, foundWidgetsBundle);
}
}
@Test
public void testDeleteWidgetsBundle() throws Exception {
WidgetsBundle widgetsBundle = new WidgetsBundle();

2
common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java

@ -62,4 +62,6 @@ public interface AssetProfileService extends EntityDaoService {
List<EntityInfo> findAssetProfileNamesByTenantId(TenantId tenantId, boolean activeOnly);
List<AssetProfileInfo> findAssetProfilesByIds(TenantId tenantId, List<AssetProfileId> assetProfileIds);
}

3
common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java

@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.entity.EntityDaoService;
import java.util.List;
import java.util.Optional;
public interface CustomerService extends EntityDaoService {
@ -50,4 +51,6 @@ public interface CustomerService extends EntityDaoService {
void deleteCustomersByTenantId(TenantId tenantId);
List<Customer> findCustomersByTenantIdAndIds(TenantId tenantId, List<CustomerId> customerIds);
}

2
common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java

@ -80,4 +80,6 @@ public interface DashboardService extends EntityDaoService {
PageData<DashboardId> findAllDashboardsIds(PageLink pageLink);
List<DashboardInfo> findDashboardInfoByIds(TenantId tenantId, List<DashboardId> dashboardIds);
}

2
common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java

@ -64,4 +64,6 @@ public interface DeviceProfileService extends EntityDaoService {
List<EntityInfo> findDeviceProfileNamesByTenantId(TenantId tenantId, boolean activeOnly);
List<DeviceProfileInfo> findDeviceProfilesByIds(TenantId tenantId, List<DeviceProfileId> deviceProfileIds);
}

2
common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java

@ -68,6 +68,8 @@ public interface EntityViewService extends EntityDaoService {
PageData<EntityView> findEntityViewsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, PageLink pageLink);
List<EntityView> findEntityViewsByTenantIdAndIds(TenantId tenantId, List<EntityViewId> entityViewIds);
PageData<EntityViewInfo> findEntityViewInfosByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, PageLink pageLink);
PageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndType(TenantId tenantId, CustomerId customerId, PageLink pageLink, String type);

2
common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java

@ -117,4 +117,6 @@ public interface RuleChainService extends EntityDaoService {
void deleteRuleNodes(TenantId tenantId, RuleChainId ruleChainId);
List<RuleChain> findRuleChainsByIds(TenantId tenantId, List<RuleChainId> ruleChainIds);
}

2
common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java

@ -55,4 +55,6 @@ public interface TenantService extends EntityDaoService {
PageData<TenantId> findTenantsIds(PageLink pageLink);
List<Tenant> findTenantsByIds(TenantId callerId, List<TenantId> tenantIds);
}

3
common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java

@ -126,4 +126,7 @@ public interface UserService extends EntityDaoService {
UserAuthDetails findUserAuthDetailsByUserId(TenantId tenantId, UserId userId);
List<User> findUsersByTenantIdAndIds(TenantId tenantId, List<UserId> userIds);
}

2
common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java

@ -52,4 +52,6 @@ public interface WidgetsBundleService extends EntityDaoService {
void updateSystemWidgets(Stream<String> bundles, Stream<String> widgets);
List<WidgetsBundle> findSystemOrTenantWidgetsBundlesByIds(TenantId tenantId, List<WidgetsBundleId> widgetsBundleIds);
}

2
dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileDao.java

@ -51,4 +51,6 @@ public interface AssetProfileDao extends Dao<AssetProfile>, ExportableEntityDao<
List<EntityInfo> findTenantAssetProfileNames(UUID tenantId, boolean activeOnly);
List<AssetProfileInfo> findAssetProfilesByTenantIdAndIds(UUID tenantId, List<UUID> assetProfileIds);
}

7
dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java

@ -51,6 +51,7 @@ import java.util.Optional;
import java.util.stream.Collectors;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
import static org.thingsboard.server.dao.service.Validator.validateId;
@Service("AssetProfileDaoService")
@ -345,6 +346,12 @@ public class AssetProfileServiceImpl extends CachedVersionedEntityService<AssetP
.collect(Collectors.toList());
}
@Override
public List<AssetProfileInfo> findAssetProfilesByIds(TenantId tenantId, List<AssetProfileId> assetProfileIds) {
log.trace("Executing findAssetProfilesByIds, tenantId [{}], assetProfileIds [{}]", tenantId, assetProfileIds);
return assetProfileDao.findAssetProfilesByTenantIdAndIds(tenantId.getId(), toUUIDs(assetProfileIds));
}
private final PaginatedRemover<TenantId, AssetProfile> tenantAssetProfilesRemover =
new PaginatedRemover<>() {

3
dao/src/main/java/org/thingsboard/server/dao/customer/CustomerDao.java

@ -24,6 +24,7 @@ import org.thingsboard.server.dao.Dao;
import org.thingsboard.server.dao.ExportableEntityDao;
import org.thingsboard.server.dao.TenantEntityDao;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@ -78,4 +79,6 @@ public interface CustomerDao extends Dao<Customer>, TenantEntityDao<Customer>, E
*/
PageData<Customer> findCustomersWithTheSameTitle(PageLink pageLink);
List<Customer> findCustomersByTenantIdAndIds(UUID tenantId, List<UUID> customerIds);
}

7
dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java

@ -57,6 +57,7 @@ import org.thingsboard.server.dao.user.UserService;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.thingsboard.server.dao.service.Validator.validateId;
@ -280,6 +281,12 @@ public class CustomerServiceImpl extends AbstractCachedEntityService<CustomerCac
customersByTenantRemover.removeEntities(tenantId, tenantId);
}
@Override
public List<Customer> findCustomersByTenantIdAndIds(TenantId tenantId, List<CustomerId> customerIds) {
log.trace("Executing findCustomersByTenantIdAndIds, tenantId [{}], customerIds [{}]", tenantId, customerIds);
return customerDao.findCustomersByTenantIdAndIds(tenantId.getId(), customerIds.stream().map(CustomerId::getId).collect(Collectors.toList()));
}
@Override
public void deleteByTenantId(TenantId tenantId) {
deleteCustomersByTenantId(tenantId);

3
dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardInfoDao.java

@ -22,6 +22,7 @@ import org.thingsboard.server.dao.Dao;
import org.thingsboard.server.dao.ImageContainerDao;
import org.thingsboard.server.dao.ResourceContainerDao;
import java.util.List;
import java.util.UUID;
/**
@ -81,4 +82,6 @@ public interface DashboardInfoDao extends Dao<DashboardInfo>, ImageContainerDao<
String findTitleById(UUID tenantId, UUID dashboardId);
List<DashboardInfo> findDashboardsByIds(UUID tenantId, List<UUID> dashboardIds);
}

7
dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java

@ -63,6 +63,7 @@ import java.util.Map;
import java.util.Optional;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
import static org.thingsboard.server.dao.service.Validator.validateId;
@Service("DashboardDaoService")
@ -413,6 +414,12 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
return dashboardDao.findAllIds(pageLink);
}
@Override
public List<DashboardInfo> findDashboardInfoByIds(TenantId tenantId, List<DashboardId> dashboardIds) {
log.trace("Executing findDashboardInfoByIds, dashboardIds [{}]", dashboardIds);
return dashboardInfoDao.findDashboardsByIds(tenantId.getId(), toUUIDs(dashboardIds));
}
private final PaginatedRemover<TenantId, DashboardId> tenantDashboardsRemover = new PaginatedRemover<>() {
@Override

2
dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java

@ -53,4 +53,6 @@ public interface DeviceProfileDao extends Dao<DeviceProfile>, ExportableEntityDa
List<EntityInfo> findTenantDeviceProfileNames(UUID tenantId, boolean activeOnly);
List<DeviceProfileInfo> findDeviceProfilesByTenantIdAndIds(UUID tenantId, List<UUID> deviceProfileIds);
}

7
dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java

@ -66,6 +66,7 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.service.Validator.validateString;
@ -391,6 +392,12 @@ public class DeviceProfileServiceImpl extends CachedVersionedEntityService<Devic
.collect(Collectors.toList());
}
@Override
public List<DeviceProfileInfo> findDeviceProfilesByIds(TenantId tenantId, List<DeviceProfileId> deviceProfileIds) {
log.trace("Executing findDeviceProfilesByIds, tenantId [{}], deviceProfileIds [{}]", tenantId, deviceProfileIds);
return deviceProfileDao.findDeviceProfilesByTenantIdAndIds(tenantId.getId(), toUUIDs(deviceProfileIds));
}
private final PaginatedRemover<TenantId, DeviceProfile> tenantDeviceProfilesRemover =
new PaginatedRemover<>() {

2
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java

@ -169,6 +169,8 @@ public interface EntityViewDao extends Dao<EntityView>, ExportableEntityDao<Enti
UUID edgeId,
PageLink pageLink);
List<EntityView> findEntityViewsByTenantIdAndIds(UUID tenantId, List<UUID> entityViewIds);
/**
* Find entity views by tenantId, edgeId, type and page link.
*

7
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java

@ -64,6 +64,7 @@ import java.util.Optional;
import java.util.stream.Collectors;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.service.Validator.validatePageLink;
import static org.thingsboard.server.dao.service.Validator.validateString;
@ -267,6 +268,12 @@ public class EntityViewServiceImpl extends CachedVersionedEntityService<EntityVi
customerId.getId(), pageLink);
}
@Override
public List<EntityView> findEntityViewsByTenantIdAndIds(TenantId tenantId, List<EntityViewId> entityViewIds) {
log.trace("Executing findEntityViewsByTenantIdAndIds, tenantId [{}], entityViewIds [{}]", tenantId, entityViewIds);
return entityViewDao.findEntityViewsByTenantIdAndIds(tenantId.getId(), toUUIDs(entityViewIds));
}
@Override
public PageData<EntityViewInfo> findEntityViewInfosByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, PageLink pageLink) {
log.trace("Executing findEntityViewInfosByTenantIdAndCustomerId, tenantId [{}], customerId [{}]," +

7
dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java

@ -85,6 +85,7 @@ import java.util.stream.Collectors;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.thingsboard.server.common.data.DataConstants.TENANT;
import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.service.Validator.validateIds;
import static org.thingsboard.server.dao.service.Validator.validatePageLink;
@ -873,6 +874,12 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
}
}
@Override
public List<RuleChain> findRuleChainsByIds(TenantId tenantId, List<RuleChainId> ruleChainIds) {
log.trace("Executing findRuleChainsByIds, tenantId [{}], ruleChainIds [{}]", tenantId, ruleChainIds);
return ruleChainDao.findRuleChainsByTenantIdAndIds(tenantId.getId(), toUUIDs(ruleChainIds));
}
@Override
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {

4
dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java

@ -21,13 +21,13 @@ import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.dao.Dao;
import org.thingsboard.server.dao.ExportableEntityDao;
import org.thingsboard.server.dao.ResourceContainerDao;
import org.thingsboard.server.dao.TenantEntityDao;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
/**
@ -83,4 +83,6 @@ public interface RuleChainDao extends Dao<RuleChain>, TenantEntityDao<RuleChain>
Collection<RuleChain> findByTenantIdAndTypeAndName(TenantId tenantId, RuleChainType type, String name);
List<RuleChain> findRuleChainsByTenantIdAndIds(UUID tenantId, List<UUID> ruleChainIds);
}

6
dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetProfileRepository.java

@ -87,4 +87,10 @@ public interface AssetProfileRepository extends JpaRepository<AssetProfileEntity
"a.name, a.version, a.isDefault) FROM AssetProfileEntity a WHERE a.id > :id ORDER BY a.id")
List<AssetProfileFields> findNextBatch(@Param("id") UUID id, Limit limit);
@Query("SELECT new org.thingsboard.server.common.data.asset.AssetProfileInfo(a.id, a.tenantId, a.name, a.image, a.defaultDashboardId) " +
"FROM AssetProfileEntity a WHERE " +
"a.tenantId = :tenantId AND a.id IN :assetProfileIds")
List<AssetProfileInfo> findAssetProfileInfosByTenantIdAndIdIn(@Param("tenantId") UUID tenantId,
@Param("assetProfileIds") List<UUID> assetProfileIds);
}

5
dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetProfileDao.java

@ -105,6 +105,11 @@ public class JpaAssetProfileDao extends JpaAbstractDao<AssetProfileEntity, Asset
assetProfileRepository.findAllTenantAssetProfileNames(tenantId);
}
@Override
public List<AssetProfileInfo> findAssetProfilesByTenantIdAndIds(UUID tenantId, List<UUID> assetProfileIds) {
return assetProfileRepository.findAssetProfileInfosByTenantIdAndIdIn(tenantId, assetProfileIds);
}
@Override
public AssetProfile findByTenantIdAndExternalId(UUID tenantId, UUID externalId) {
return DaoUtil.getData(assetProfileRepository.findByTenantIdAndExternalId(tenantId, externalId));

2
dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java

@ -67,4 +67,6 @@ public interface CustomerRepository extends JpaRepository<CustomerEntity, UUID>,
"c.title, c.version, c.additionalInfo, c.country, c.state, c.city, c.address, c.address2, c.zip, c.phone, c.email) " +
"FROM CustomerEntity c WHERE c.id > :id ORDER BY c.id")
List<CustomerFields> findNextBatch(@Param("id") UUID id, Limit limit);
List<CustomerEntity> findCustomersByTenantIdAndIdIn(UUID tenantId, List<UUID> customerIds);
}

5
dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java

@ -108,6 +108,11 @@ public class JpaCustomerDao extends JpaAbstractDao<CustomerEntity, Customer> imp
);
}
@Override
public List<Customer> findCustomersByTenantIdAndIds(UUID tenantId, List<UUID> customerIds) {
return DaoUtil.convertDataList(customerRepository.findCustomersByTenantIdAndIdIn(tenantId, customerIds));
}
@Override
public PageData<Customer> findAllByTenantId(TenantId tenantId, PageLink pageLink) {
return findByTenantId(tenantId.getId(), pageLink);

3
dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/DashboardInfoRepository.java

@ -20,6 +20,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.dao.model.sql.DashboardInfoEntity;
@ -99,4 +100,6 @@ public interface DashboardInfoRepository extends JpaRepository<DashboardInfoEnti
List<EntityInfo> findDashboardInfosByResourceLink(@Param("link") String link,
Pageable pageable);
List<DashboardInfoEntity> findByIdIn(List<UUID> dashboardIds);
}

6
dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.dao.sql.dashboard;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
@ -126,6 +127,11 @@ public class JpaDashboardInfoDao extends JpaAbstractDao<DashboardInfoEntity, Das
return dashboardInfoRepository.findTitleByTenantIdAndId(tenantId, dashboardId);
}
@Override
public List<DashboardInfo> findDashboardsByIds(UUID tenantId, List<UUID> dashboardIds) {
return DaoUtil.convertDataList(dashboardInfoRepository.findByIdIn(dashboardIds));
}
@Override
public List<DashboardInfo> findByTenantAndImageLink(TenantId tenantId, String imageLink, int limit) {
return DaoUtil.convertDataList(dashboardInfoRepository.findByTenantAndImageLink(tenantId.getId(), imageLink, limit));

5
dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java

@ -59,6 +59,11 @@ public interface DeviceProfileRepository extends JpaRepository<DeviceProfileEnti
@Param("transportType") DeviceTransportType transportType,
Pageable pageable);
@Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.tenantId, d.name, d.image, d.defaultDashboardId, d.type, d.transportType) " +
"FROM DeviceProfileEntity d WHERE " +
"d.tenantId = :tenantId AND d.id IN :deviceProfileIds")
List<DeviceProfileInfo> findDeviceProfileInfosByTenantIdAndIdIn(@Param("tenantId") UUID tenantId, @Param("deviceProfileIds") List<UUID> deviceProfileIds);
@Query("SELECT d FROM DeviceProfileEntity d " +
"WHERE d.tenantId = :tenantId AND d.isDefault = true")
DeviceProfileEntity findByDefaultTrueAndTenantId(@Param("tenantId") UUID tenantId);

5
dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java

@ -123,6 +123,11 @@ public class JpaDeviceProfileDao extends JpaAbstractDao<DeviceProfileEntity, Dev
deviceProfileRepository.findAllTenantDeviceProfileNames(tenantId);
}
@Override
public List<DeviceProfileInfo> findDeviceProfilesByTenantIdAndIds(UUID tenantId, List<UUID> deviceProfileIds) {
return deviceProfileRepository.findDeviceProfileInfosByTenantIdAndIdIn(tenantId, deviceProfileIds);
}
@Override
public DeviceProfile findByTenantIdAndExternalId(UUID tenantId, UUID externalId) {
return DaoUtil.getData(deviceProfileRepository.findByTenantIdAndExternalId(tenantId, externalId));

2
dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java

@ -127,6 +127,8 @@ public interface EntityViewRepository extends JpaRepository<EntityViewEntity, UU
boolean existsByTenantIdAndEntityId(UUID tenantId, UUID entityId);
List<EntityViewEntity> findEntityViewsByTenantIdAndIdIn(UUID tenantId, List<UUID> entityViewIds);
@Query("SELECT DISTINCT ev.type FROM EntityViewEntity ev WHERE ev.tenantId = :tenantId")
List<String> findTenantEntityViewTypes(@Param("tenantId") UUID tenantId);

5
dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java

@ -188,6 +188,11 @@ public class JpaEntityViewDao extends JpaAbstractDao<EntityViewEntity, EntityVie
DaoUtil.toPageable(pageLink)));
}
@Override
public List<EntityView> findEntityViewsByTenantIdAndIds(UUID tenantId, List<UUID> entityViewIds) {
return DaoUtil.convertDataList(entityViewRepository.findEntityViewsByTenantIdAndIdIn(tenantId, entityViewIds));
}
@Override
public PageData<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, PageLink pageLink) {
log.debug("Try to find entity views by tenantId [{}], edgeId [{}], type [{}] and pageLink [{}]", tenantId, edgeId, type, pageLink);

5
dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java

@ -112,6 +112,11 @@ public class JpaRuleChainDao extends JpaAbstractDao<RuleChainEntity, RuleChain>
return DaoUtil.convertDataList(ruleChainRepository.findByTenantIdAndTypeAndName(tenantId.getId(), type, name));
}
@Override
public List<RuleChain> findRuleChainsByTenantIdAndIds(UUID tenantId, List<UUID> ruleChainIds) {
return DaoUtil.convertDataList(ruleChainRepository.findRuleChainsByTenantIdAndIdIn(tenantId, ruleChainIds));
}
@Override
public Long countByTenantId(TenantId tenantId) {
return ruleChainRepository.countByTenantId(tenantId.getId());

3
dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java

@ -90,4 +90,7 @@ public interface RuleChainRepository extends JpaRepository<RuleChainEntity, UUID
@Query("SELECT new org.thingsboard.server.common.data.edqs.fields.RuleChainFields(r.id, r.createdTime, r.tenantId," +
"r.name, r.version, r.additionalInfo) FROM RuleChainEntity r WHERE r.id > :id ORDER BY r.id")
List<RuleChainFields> findNextBatch(@Param("id") UUID id, Limit limit);
List<RuleChainEntity> findRuleChainsByTenantIdAndIdIn(UUID tenantId, List<UUID> ruleChainIds);
}

5
dao/src/main/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDao.java

@ -98,6 +98,11 @@ public class JpaTenantDao extends JpaAbstractDao<TenantEntity, Tenant> implement
return DaoUtil.getData(tenantRepository.findFirstByTitle(name));
}
@Override
public List<Tenant> findTenantsByIds(UUID tenantId, List<UUID> tenantIds) {
return DaoUtil.convertDataList(tenantRepository.findTenantsByIdIn(tenantIds));
}
@Override
public List<TenantFields> findNextBatch(UUID id, int batchSize) {
return tenantRepository.findNextBatch(id, Limit.of(batchSize));

2
dao/src/main/java/org/thingsboard/server/dao/sql/tenant/TenantRepository.java

@ -62,4 +62,6 @@ public interface TenantRepository extends JpaRepository<TenantEntity, UUID> {
TenantEntity findFirstByTitle(String name);
List<TenantEntity> findTenantsByIdIn(List<UUID> tenantIds);
}

5
dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java

@ -149,6 +149,11 @@ public class JpaUserDao extends JpaAbstractDao<UserEntity, User> implements User
return userRepository.countByTenantIdAndAuthority(tenantId, Authority.TENANT_ADMIN);
}
@Override
public List<User> findUsersByTenantIdAndIds(UUID tenantId, List<UUID> userIds) {
return DaoUtil.convertDataList(userRepository.findUsersByTenantIdAndIdIn(tenantId, userIds));
}
@Override
public Long countByTenantId(TenantId tenantId) {
return userRepository.countByTenantId(tenantId.getId());

2
dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java

@ -83,4 +83,6 @@ public interface UserRepository extends JpaRepository<UserEntity, UUID> {
"FROM UserEntity u JOIN UserCredentialsEntity uc ON u.id = uc.userId WHERE u.id = :userId ")
TbPair<UserEntity, Boolean> findUserAuthDetailsByUserId(@Param("userId") UUID userId);
List<UserEntity> findUsersByTenantIdAndIdIn(UUID tenantId, List<UUID> userIds);
}

5
dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java

@ -111,6 +111,11 @@ public class JpaWidgetsBundleDao extends JpaAbstractDao<WidgetsBundleEntity, Wid
return DaoUtil.toPageData(widgetsBundleRepository.findAll(DaoUtil.toPageable(pageLink)));
}
@Override
public List<WidgetsBundle> findSystemOrTenantWidgetBundlesByIds(UUID tenantId, List<UUID> widgetsBundleIds) {
return DaoUtil.convertDataList(widgetsBundleRepository.findSystemOrTenantWidgetsBundlesByIdIn(tenantId, TenantId.NULL_UUID, widgetsBundleIds));
}
private PageData<WidgetsBundle> findTenantWidgetsBundlesByTenantIds(List<UUID> tenantIds, WidgetsBundleFilter widgetsBundleFilter, PageLink pageLink) {
if (widgetsBundleFilter.isFullSearch()) {
return DaoUtil.toPageData(

8
dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetsBundleRepository.java

@ -21,7 +21,6 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.common.data.edqs.fields.WidgetTypeFields;
import org.thingsboard.server.common.data.edqs.fields.WidgetsBundleFields;
import org.thingsboard.server.dao.ExportableEntityRepository;
import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity;
@ -146,4 +145,11 @@ public interface WidgetsBundleRepository extends JpaRepository<WidgetsBundleEnti
@Query("SELECT new org.thingsboard.server.common.data.edqs.fields.WidgetsBundleFields(w.id, w.createdTime, w.tenantId," +
"w.alias, w.version) FROM WidgetsBundleEntity w WHERE w.id > :id ORDER BY w.id")
List<WidgetsBundleFields> findNextBatch(@Param("id") UUID id, Limit limit);
@Query("SELECT wb FROM WidgetsBundleEntity wb WHERE " +
"wb.id IN (:widgetsBundleIds) AND (wb.tenantId = :tenantId OR wb.tenantId = :systemTenantId)")
List<WidgetsBundleEntity> findSystemOrTenantWidgetsBundlesByIdIn(@Param("tenantId") UUID tenantId,
@Param("systemTenantId") UUID systemTenantId,
@Param("widgetsBundleIds") List<UUID> widgetsBundleIds);
}

2
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantDao.java

@ -42,4 +42,6 @@ public interface TenantDao extends Dao<Tenant> {
Tenant findTenantByName(TenantId tenantId, String name);
List<Tenant> findTenantsByIds(UUID tenantId, List<UUID> tenantIds);
}

8
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java

@ -53,7 +53,9 @@ import java.util.Optional;
import java.util.function.Consumer;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.service.Validator.validateIds;
@Service("TenantDaoService")
@Slf4j
@ -225,6 +227,12 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
return tenantDao.findTenantsIds(pageLink);
}
@Override
public List<Tenant> findTenantsByIds(TenantId callerId, List<TenantId> tenantIds) {
log.trace("Executing findTenantsByIds, callerId [{}], tenantIds [{}]", callerId, tenantIds);
return tenantDao.findTenantsByIds(callerId.getId(), toUUIDs(tenantIds));
}
@Override
public boolean tenantExists(TenantId tenantId) {
return existsTenantCache.getAndPutInTransaction(tenantId, () -> tenantDao.existsById(tenantId, tenantId.getId()), false);

2
dao/src/main/java/org/thingsboard/server/dao/user/UserDao.java

@ -106,4 +106,6 @@ public interface UserDao extends Dao<User>, TenantEntityDao<User> {
UserAuthDetails findUserAuthDetailsByUserId(UUID tenantId, UUID userId);
List<User> findUsersByTenantIdAndIds(UUID tenantId, List<UUID> userIds);
}

7
dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java

@ -85,6 +85,7 @@ import java.util.stream.Collectors;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
import static org.thingsboard.server.common.data.StringUtils.generateSafeToken;
import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.service.Validator.validatePageLink;
import static org.thingsboard.server.dao.service.Validator.validateString;
@ -544,6 +545,12 @@ public class UserServiceImpl extends AbstractCachedEntityService<UserCacheKey, U
return userDao.findUserAuthDetailsByUserId(tenantId.getId(), userId.getId());
}
@Override
public List<User> findUsersByTenantIdAndIds(TenantId tenantId, List<UserId> userIds) {
log.trace("Executing findUsersByTenantIdAndIds, tenantId [{}], userIds [{}]", tenantId, userIds);
return userDao.findUsersByTenantIdAndIds(tenantId.getId(), toUUIDs(userIds));
}
private Optional<UserMobileSessionInfo> findMobileSessionInfo(TenantId tenantId, UserId userId) {
return Optional.ofNullable(userSettingsService.findUserSettings(tenantId, userId, UserSettingsType.MOBILE))
.map(UserSettings::getSettings).map(settings -> JacksonUtil.treeToValue(settings, UserMobileSessionInfo.class));

3
dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleDao.java

@ -25,6 +25,7 @@ import org.thingsboard.server.dao.Dao;
import org.thingsboard.server.dao.ExportableEntityDao;
import org.thingsboard.server.dao.ImageContainerDao;
import java.util.List;
import java.util.UUID;
/**
@ -87,5 +88,7 @@ public interface WidgetsBundleDao extends Dao<WidgetsBundle>, ExportableEntityDa
PageData<WidgetsBundle> findAllWidgetsBundles(PageLink pageLink);
List<WidgetsBundle> findSystemOrTenantWidgetBundlesByIds(UUID tenantId, List<UUID> widgetsBundleIds);
}

7
dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java

@ -48,6 +48,7 @@ import java.util.Optional;
import java.util.stream.Stream;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
import static org.thingsboard.server.dao.entity.AbstractEntityService.checkConstraintViolation;
@Service("WidgetsBundleDaoService")
@ -252,6 +253,12 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService {
});
}
@Override
public List<WidgetsBundle> findSystemOrTenantWidgetsBundlesByIds(TenantId tenantId, List<WidgetsBundleId> widgetsBundleIds) {
log.trace("Executing findSystemOrTenantWidgetsBundlesByIds, tenantId [{}], widgetsBundleIds [{}]", tenantId, widgetsBundleIds);
return widgetsBundleDao.findSystemOrTenantWidgetBundlesByIds(tenantId.getId(), toUUIDs(widgetsBundleIds));
}
private WidgetTypeDetails updateSystemWidget(JsonNode widgetTypeJson) {
WidgetTypeDetails widgetTypeDetails = JacksonUtil.treeToValue(widgetTypeJson, WidgetTypeDetails.class);
WidgetType existingWidget = widgetTypeService.findWidgetTypeByTenantIdAndFqn(TenantId.SYS_TENANT_ID, widgetTypeDetails.getFqn());

Loading…
Cancel
Save