added new get entity profile names APIs for profile entities(AssetProfile & DeviceProfile)

This commit is contained in:
ShvaykaD 2023-12-05 18:52:52 +02:00
parent 35a9ec2714
commit 375ba46451
26 changed files with 298 additions and 29 deletions

View File

@ -397,10 +397,12 @@ public class AssetController extends BaseController {
}
@ApiOperation(value = "Get Asset Types (getAssetTypes)",
notes = "Returns a set of unique asset types based on assets that are either owned by the tenant or assigned to the customer which user is performing the request.", produces = MediaType.APPLICATION_JSON_VALUE)
notes = "Deprecated. See 'getAssetProfileNames' API from Asset Profile Controller instead." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
produces = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/asset/types", method = RequestMethod.GET)
@ResponseBody
@Deprecated(since = "3.6.2")
public List<EntitySubtype> getAssetTypes() throws ThingsboardException, ExecutionException, InterruptedException {
SecurityUser user = getCurrentUser();
TenantId tenantId = user.getTenantId();

View File

@ -29,18 +29,23 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.asset.AssetProfileInfo;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.AssetProfileId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.asset.profile.TbAssetProfileService;
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.List;
import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID;
import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_INFO_DESCRIPTION;
@ -212,4 +217,19 @@ public class AssetProfileController extends BaseController {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
return checkNotNull(assetProfileService.findAssetProfileInfos(getTenantId(), pageLink));
}
@ApiOperation(value = "Get Asset Profile names (getAssetProfileNames)",
notes = "Returns a set of unique asset profile names owned by the tenant."
+ TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/assetProfile/names", method = RequestMethod.GET)
@ResponseBody
public List<EntityInfo> getAssetProfileNames(
@ApiParam(value = "Flag indicating whether to retrieve exclusively the names of asset profiles that are referenced by tenant's assets.")
@RequestParam(value = "activeOnly", required = false, defaultValue = "false") boolean activeOnly) throws ThingsboardException {
SecurityUser user = getCurrentUser();
TenantId tenantId = user.getTenantId();
return checkNotNull(assetProfileService.findAssetProfileNamesByTenantId(tenantId, activeOnly));
}
}

View File

@ -534,11 +534,12 @@ public class DeviceController extends BaseController {
}
@ApiOperation(value = "Get Device Types (getDeviceTypes)",
notes = "Returns a set of unique device profile names based on devices that are either owned by the tenant or assigned to the customer which user is performing the request."
+ TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
notes = "Deprecated. See 'getDeviceProfileNames' API from Device Profile Controller instead." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
produces = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/device/types", method = RequestMethod.GET)
@ResponseBody
@Deprecated(since = "3.6.2")
public List<EntitySubtype> getDeviceTypes() throws ThingsboardException, ExecutionException, InterruptedException {
SecurityUser user = getCurrentUser();
TenantId tenantId = user.getTenantId();

View File

@ -32,15 +32,18 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.resource.ImageService;
import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.device.profile.TbDeviceProfileService;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
@ -273,4 +276,19 @@ public class DeviceProfileController extends BaseController {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
return checkNotNull(deviceProfileService.findDeviceProfileInfos(getTenantId(), pageLink, transportType));
}
@ApiOperation(value = "Get Device Profile names (getDeviceProfileNames)",
notes = "Returns a set of unique device profile names owned by the tenant."
+ TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/deviceProfile/names", method = RequestMethod.GET)
@ResponseBody
public List<EntityInfo> getDeviceProfileNames(
@ApiParam(value = "Flag indicating whether to retrieve exclusively the names of device profiles that are referenced by tenant's devices.")
@RequestParam(value = "activeOnly", required = false, defaultValue = "false") boolean activeOnly) throws ThingsboardException {
SecurityUser user = getCurrentUser();
TenantId tenantId = user.getTenantId();
return checkNotNull(deviceProfileService.findDeviceProfileNamesByTenantId(tenantId, activeOnly));
}
}

View File

@ -28,6 +28,7 @@ import org.springframework.context.annotation.Primary;
import org.springframework.test.context.ContextConfiguration;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
@ -46,11 +47,13 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.common.data.DataConstants.DEFAULT_DEVICE_TYPE;
@ContextConfiguration(classes = {AssetProfileControllerTest.Config.class})
@DaoSqlTest
@ -459,6 +462,62 @@ public class AssetProfileControllerTest extends AbstractControllerTest {
testEntityDaoWithRelationsTransactionalException(assetProfileDao, savedTenant.getId(), assetProfileId, "/api/assetProfile/" + assetProfileId);
}
@Test
public void testGetAssetProfileNames() throws Exception {
var pageLink = new PageLink(Integer.MAX_VALUE);
var assetProfileInfos = doGetTypedWithPageLink("/api/assetProfileInfos?",
new TypeReference<PageData<AssetProfileInfo>>() {
}, pageLink);
Assert.assertNotNull("Asset Profile Infos page data is null!", assetProfileInfos);
Assert.assertEquals("Asset Profile Infos Page data is empty! Expected to have default profile created!", 1, assetProfileInfos.getTotalElements());
List<EntityInfo> expectedAssetProfileNames = assetProfileInfos.getData().stream()
.map(info -> new EntityInfo(info.getId(), info.getName()))
.sorted(Comparator.comparing(EntityInfo::getName))
.collect(Collectors.toList());
var assetProfileNames = doGetTyped("/api/assetProfile/names", new TypeReference<List<EntityInfo>>() {
});
Assert.assertNotNull("Asset Profile Names list is null!", assetProfileNames);
Assert.assertFalse("Asset Profile Names list is empty!", assetProfileNames.isEmpty());
Assert.assertEquals(expectedAssetProfileNames, assetProfileNames);
Assert.assertEquals(1, assetProfileNames.size());
Assert.assertEquals(DEFAULT_DEVICE_TYPE, assetProfileNames.get(0).getName());
int count = 3;
for (int i = 0; i < count; i++) {
Asset asset = new Asset();
asset.setName("AssetName" + i);
asset.setType("AssetProfileName" + i);
Asset savedAsset = doPost("/api/asset", asset, Asset.class);
Assert.assertNotNull(savedAsset);
}
assetProfileInfos = doGetTypedWithPageLink("/api/assetProfileInfos?",
new TypeReference<>() {
}, pageLink);
Assert.assertNotNull("Asset Profile Infos page data is null!", assetProfileInfos);
Assert.assertEquals("Asset Profile Infos Page data is empty! Expected to have default profile created + count value!", 1 + count, assetProfileInfos.getTotalElements());
expectedAssetProfileNames = assetProfileInfos.getData().stream()
.map(info -> new EntityInfo(info.getId(), info.getName()))
.sorted(Comparator.comparing(EntityInfo::getName))
.collect(Collectors.toList());
assetProfileNames = doGetTyped("/api/assetProfile/names", new TypeReference<>() {
});
Assert.assertNotNull("Asset Profile Names list is null!", assetProfileNames);
Assert.assertFalse("Asset Profile Names list is empty!", assetProfileNames.isEmpty());
Assert.assertEquals(expectedAssetProfileNames, assetProfileNames);
Assert.assertEquals(1 + count, assetProfileNames.size());
assetProfileNames = doGetTyped("/api/assetProfile/names?activeOnly=true", new TypeReference<>() {
});
Assert.assertNotNull("Asset Profile Names list is null!", assetProfileNames);
Assert.assertFalse("Asset Profile Names list is empty!", assetProfileNames.isEmpty());
var expectedAssetProfileNamesWithoutDefault = expectedAssetProfileNames.stream()
.filter(entityInfo -> !entityInfo.getName().equals(DEFAULT_DEVICE_TYPE))
.collect(Collectors.toList());
Assert.assertEquals(expectedAssetProfileNamesWithoutDefault, assetProfileNames);
Assert.assertEquals(count, assetProfileNames.size());
}
private AssetProfile savedAssetProfile(String name) {
AssetProfile assetProfile = createAssetProfile(name);
return doPost("/api/assetProfile", assetProfile, AssetProfile.class);

View File

@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.DeviceProfileProvisionType;
import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest;
import org.thingsboard.server.common.data.StringUtils;
@ -55,11 +56,13 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.common.data.DataConstants.DEFAULT_DEVICE_TYPE;
import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE;
@ -1045,6 +1048,62 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
testEntityDaoWithRelationsTransactionalException(deviceProfileDao, savedTenant.getId(), deviceProfileId, "/api/deviceProfile/" + deviceProfileId);
}
@Test
public void testGetDeviceProfileNames() throws Exception {
var pageLink = new PageLink(Integer.MAX_VALUE);
var deviceProfileInfos = doGetTypedWithPageLink("/api/deviceProfileInfos?",
new TypeReference<PageData<DeviceProfileInfo>>() {
}, pageLink);
Assert.assertNotNull("Device Profile Infos page data is null!", deviceProfileInfos);
Assert.assertEquals("Device Profile Infos Page data is empty! Expected to have default profile created!", 1, deviceProfileInfos.getTotalElements());
List<EntityInfo> expectedDeviceProfileNames = deviceProfileInfos.getData().stream()
.map(info -> new EntityInfo(info.getId(), info.getName()))
.sorted(Comparator.comparing(EntityInfo::getName))
.collect(Collectors.toList());
var deviceProfileNames = doGetTyped("/api/deviceProfile/names", new TypeReference<List<EntityInfo>>() {
});
Assert.assertNotNull("Device Profile Names list is null!", deviceProfileNames);
Assert.assertFalse("Device Profile Names list is empty!", deviceProfileNames.isEmpty());
Assert.assertEquals(expectedDeviceProfileNames, deviceProfileNames);
Assert.assertEquals(1, deviceProfileNames.size());
Assert.assertEquals(DEFAULT_DEVICE_TYPE, deviceProfileNames.get(0).getName());
int count = 3;
for (int i = 0; i < count; i++) {
Device device = new Device();
device.setName("DeviceName" + i);
device.setType("DeviceProfileName" + i);
Device savedDevice = doPost("/api/device", device, Device.class);
Assert.assertNotNull(savedDevice);
}
deviceProfileInfos = doGetTypedWithPageLink("/api/deviceProfileInfos?",
new TypeReference<>() {
}, pageLink);
Assert.assertNotNull("Device Profile Infos page data is null!", deviceProfileInfos);
Assert.assertEquals("Device Profile Infos Page data is empty! Expected to have default profile created + count value!", 1 + count, deviceProfileInfos.getTotalElements());
expectedDeviceProfileNames = deviceProfileInfos.getData().stream()
.map(info -> new EntityInfo(info.getId(), info.getName()))
.sorted(Comparator.comparing(EntityInfo::getName))
.collect(Collectors.toList());
deviceProfileNames = doGetTyped("/api/deviceProfile/names", new TypeReference<>() {
});
Assert.assertNotNull("Device Profile Names list is null!", deviceProfileNames);
Assert.assertFalse("Device Profile Names list is empty!", deviceProfileNames.isEmpty());
Assert.assertEquals(expectedDeviceProfileNames, deviceProfileNames);
Assert.assertEquals(1 + count, deviceProfileNames.size());
deviceProfileNames = doGetTyped("/api/deviceProfile/names?activeOnly=true", new TypeReference<>() {
});
Assert.assertNotNull("Device Profile Names list is null!", deviceProfileNames);
Assert.assertFalse("Device Profile Names list is empty!", deviceProfileNames.isEmpty());
var expectedDeviceProfileNamesWithoutDefault = expectedDeviceProfileNames.stream()
.filter(entityInfo -> !entityInfo.getName().equals(DEFAULT_DEVICE_TYPE))
.collect(Collectors.toList());
Assert.assertEquals(expectedDeviceProfileNamesWithoutDefault, deviceProfileNames);
Assert.assertEquals(count, deviceProfileNames.size());
}
private DeviceProfile savedDeviceProfile(String name) {
DeviceProfile deviceProfile = createDeviceProfile(name);
return doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);

View File

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.dao.asset;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.asset.AssetProfileInfo;
import org.thingsboard.server.common.data.id.AssetProfileId;
@ -23,6 +24,8 @@ 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;
public interface AssetProfileService extends EntityDaoService {
AssetProfile findAssetProfileById(TenantId tenantId, AssetProfileId assetProfileId);
@ -57,4 +60,6 @@ public interface AssetProfileService extends EntityDaoService {
void deleteAssetProfilesByTenantId(TenantId tenantId);
List<EntityInfo> findAssetProfileNamesByTenantId(TenantId tenantId, boolean activeOnly);
}

View File

@ -81,6 +81,7 @@ public interface AssetService extends EntityDaoService {
ListenableFuture<List<Asset>> findAssetsByQuery(TenantId tenantId, AssetSearchQuery query);
@Deprecated(since = "3.6.2", forRemoval = true)
ListenableFuture<List<EntitySubtype>> findAssetTypesByTenantId(TenantId tenantId);
Asset assignAssetToEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId);

View File

@ -17,12 +17,15 @@ package org.thingsboard.server.dao.device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.entity.EntityDaoService;
import java.util.List;
public interface DeviceProfileService extends EntityDaoService {
DeviceProfile findDeviceProfileById(TenantId tenantId, DeviceProfileId deviceProfileId);
@ -59,4 +62,6 @@ public interface DeviceProfileService extends EntityDaoService {
void deleteDeviceProfilesByTenantId(TenantId tenantId);
List<EntityInfo> findDeviceProfileNamesByTenantId(TenantId tenantId, boolean activeOnly);
}

View File

@ -95,6 +95,7 @@ public interface DeviceService extends EntityDaoService {
ListenableFuture<List<Device>> findDevicesByQuery(TenantId tenantId, DeviceSearchQuery query);
@Deprecated(since = "3.6.2", forRemoval = true)
ListenableFuture<List<EntitySubtype>> findDeviceTypesByTenantId(TenantId tenantId);
Device assignDeviceToTenant(TenantId tenantId, Device device);

View File

@ -19,6 +19,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.util.CollectionUtils;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.TenantId;
@ -163,4 +164,17 @@ public abstract class DaoUtil {
}
return list;
}
public static List<EntitySubtype> convertTenantEntityInfosToDto(UUID tenantId, EntityType entityType, List<EntityInfo> entityInfos) {
if (CollectionUtils.isEmpty(entityInfos)) {
return Collections.emptyList();
}
List<EntitySubtype> list = new ArrayList<>(entityInfos.size());
for (var info : entityInfos) {
list.add(new EntitySubtype(TenantId.fromUUID(tenantId), entityType, info.getName()));
}
return list;
}
}

View File

@ -24,10 +24,8 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.util.TbPair;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.Dao;
import org.thingsboard.server.dao.ExportableEntityDao;
import org.thingsboard.server.dao.ImageContainerDao;
import org.thingsboard.server.dao.TenantEntityDao;
import java.util.List;
@ -191,6 +189,7 @@ public interface AssetDao extends Dao<Asset>, TenantEntityDao, ExportableEntityD
*
* @return the list of tenant asset type objects
*/
@Deprecated(since = "3.6.2", forRemoval = true)
ListenableFuture<List<EntitySubtype>> findTenantAssetTypesAsync(UUID tenantId);
Long countAssetsByAssetProfileId(TenantId tenantId, UUID assetProfileId);

View File

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.dao.asset;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.asset.AssetProfileInfo;
import org.thingsboard.server.common.data.id.AssetProfileId;
@ -25,6 +26,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;
public interface AssetProfileDao extends Dao<AssetProfile>, ExportableEntityDao<AssetProfileId, AssetProfile>, ImageContainerDao<AssetProfileInfo> {
@ -47,4 +49,6 @@ public interface AssetProfileDao extends Dao<AssetProfile>, ExportableEntityDao<
PageData<AssetProfile> findAllWithImages(PageLink pageLink);
List<EntityInfo> findTenantAssetProfileNames(UUID tenantId, boolean activeOnly);
}

View File

@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionalEventListener;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.asset.Asset;
@ -42,9 +43,11 @@ import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.service.Validator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import static org.thingsboard.server.dao.service.Validator.validateId;
@ -318,7 +321,16 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService<AssetPr
return EntityType.ASSET_PROFILE;
}
private PaginatedRemover<TenantId, AssetProfile> tenantAssetProfilesRemover =
@Override
public List<EntityInfo> findAssetProfileNamesByTenantId(TenantId tenantId, boolean activeOnly) {
log.trace("Executing findAssetProfileNamesByTenantId, tenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return assetProfileDao.findTenantAssetProfileNames(tenantId.getId(), activeOnly)
.stream().sorted(Comparator.comparing(EntityInfo::getName))
.collect(Collectors.toList());
}
private final PaginatedRemover<TenantId, AssetProfile> tenantAssetProfilesRemover =
new PaginatedRemover<>() {
@Override

View File

@ -162,6 +162,7 @@ public interface DeviceDao extends Dao<Device>, TenantEntityDao, ExportableEntit
*
* @return the list of tenant device type objects
*/
@Deprecated(since = "3.6.2", forRemoval = true)
ListenableFuture<List<EntitySubtype>> findTenantDeviceTypesAsync(UUID tenantId);
/**

View File

@ -17,6 +17,7 @@ package org.thingsboard.server.dao.device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
@ -25,6 +26,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;
public interface DeviceProfileDao extends Dao<DeviceProfile>, ExportableEntityDao<DeviceProfileId, DeviceProfile>, ImageContainerDao<DeviceProfileInfo> {
@ -49,4 +51,6 @@ public interface DeviceProfileDao extends Dao<DeviceProfile>, ExportableEntityDa
PageData<DeviceProfile> findAllWithImages(PageLink pageLink);
List<EntityInfo> findTenantDeviceProfileNames(UUID tenantId, boolean activeOnly);
}

View File

@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.DeviceProfileProvisionType;
import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
@ -57,11 +58,13 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.service.Validator.validateString;
@ -373,7 +376,16 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
return EntityType.DEVICE_PROFILE;
}
private PaginatedRemover<TenantId, DeviceProfile> tenantDeviceProfilesRemover =
@Override
public List<EntityInfo> findDeviceProfileNamesByTenantId(TenantId tenantId, boolean activeOnly) {
log.trace("Executing findDeviceProfileNamesByTenantId, tenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return deviceProfileDao.findTenantDeviceProfileNames(tenantId.getId(), activeOnly)
.stream().sorted(Comparator.comparing(EntityInfo::getName))
.collect(Collectors.toList());
}
private final PaginatedRemover<TenantId, DeviceProfile> tenantDeviceProfilesRemover =
new PaginatedRemover<>() {
@Override
@ -422,7 +434,8 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
if (certificates.length > 1) {
return EncryptionUtil.certTrimNewLinesForChainInDeviceProfile(certificateValue);
}
} catch (CertificateException ignored) {}
} catch (CertificateException ignored) {
}
return EncryptionUtil.certTrimNewLines(certificateValue);
}

View File

@ -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.EntityInfo;
import org.thingsboard.server.common.data.asset.AssetProfileInfo;
import org.thingsboard.server.dao.ExportableEntityRepository;
import org.thingsboard.server.dao.model.sql.AssetProfileEntity;
@ -71,4 +72,12 @@ public interface AssetProfileRepository extends JpaRepository<AssetProfileEntity
Page<AssetProfileEntity> findAllByImageNotNull(Pageable pageable);
@Query("SELECT new org.thingsboard.server.common.data.EntityInfo(ap.id, 'ASSET_PROFILE', ap.name) " +
"FROM AssetProfileEntity ap WHERE ap.tenantId = :tenantId AND EXISTS (SELECT 1 FROM AssetEntity a WHERE a.tenantId = :tenantId AND a.assetProfileId = ap.id)")
List<EntityInfo> findActiveTenantAssetProfileNames(@Param("tenantId") UUID tenantId);
@Query("SELECT new org.thingsboard.server.common.data.EntityInfo(a.id, 'ASSET_PROFILE', a.name) " +
"FROM AssetProfileEntity a WHERE a.tenantId = :tenantId")
List<EntityInfo> findAllTenantAssetProfileNames(@Param("tenantId") UUID tenantId);
}

View File

@ -167,9 +167,6 @@ public interface AssetRepository extends JpaRepository<AssetEntity, UUID>, Expor
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT DISTINCT a.type FROM AssetEntity a WHERE a.tenantId = :tenantId")
List<String> findTenantAssetTypes(@Param("tenantId") UUID tenantId);
Long countByAssetProfileId(UUID assetProfileId);
@Query("SELECT a FROM AssetEntity a, RelationEntity re WHERE a.tenantId = :tenantId " +

View File

@ -39,11 +39,10 @@ import org.thingsboard.server.dao.util.SqlDao;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import static org.thingsboard.server.dao.DaoUtil.convertTenantEntityTypesToDto;
import static org.thingsboard.server.dao.DaoUtil.convertTenantEntityInfosToDto;
import static org.thingsboard.server.dao.asset.BaseAssetService.TB_SERVICE_QUEUE;
/**
@ -57,6 +56,9 @@ public class JpaAssetDao extends JpaAbstractDao<AssetEntity, Asset> implements A
@Autowired
private AssetRepository assetRepository;
@Autowired
private AssetProfileRepository assetProfileRepository;
@Override
protected Class<AssetEntity> getEntityClass() {
return AssetEntity.class;
@ -193,7 +195,7 @@ public class JpaAssetDao extends JpaAbstractDao<AssetEntity, Asset> implements A
@Override
public ListenableFuture<List<EntitySubtype>> findTenantAssetTypesAsync(UUID tenantId) {
return service.submit(() -> convertTenantEntityTypesToDto(tenantId, EntityType.ASSET, assetRepository.findTenantAssetTypes(tenantId)));
return service.submit(() -> convertTenantEntityInfosToDto(tenantId, EntityType.ASSET, assetProfileRepository.findActiveTenantAssetProfileNames(tenantId)));
}
@Override

View File

@ -20,6 +20,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.asset.AssetProfileInfo;
@ -103,6 +104,13 @@ public class JpaAssetProfileDao extends JpaAbstractDao<AssetProfileEntity, Asset
return DaoUtil.toPageData(assetProfileRepository.findAllByImageNotNull(DaoUtil.toPageable(pageLink)));
}
@Override
public List<EntityInfo> findTenantAssetProfileNames(UUID tenantId, boolean activeOnly) {
return activeOnly ?
assetProfileRepository.findActiveTenantAssetProfileNames(tenantId) :
assetProfileRepository.findAllTenantAssetProfileNames(tenantId);
}
@Override
public AssetProfile findByTenantIdAndExternalId(UUID tenantId, UUID externalId) {
return DaoUtil.getData(assetProfileRepository.findByTenantIdAndExternalId(tenantId, externalId));

View File

@ -22,7 +22,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.asset.AssetProfileInfo;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.dao.ExportableEntityRepository;
import org.thingsboard.server.dao.model.sql.DeviceProfileEntity;
@ -83,4 +83,12 @@ public interface DeviceProfileRepository extends JpaRepository<DeviceProfileEnti
Page<DeviceProfileEntity> findAllByImageNotNull(Pageable pageable);
@Query("SELECT new org.thingsboard.server.common.data.EntityInfo(dp.id, 'DEVICE_PROFILE', dp.name) " +
"FROM DeviceProfileEntity dp WHERE dp.tenantId = :tenantId AND EXISTS (SELECT 1 FROM DeviceEntity dv WHERE dv.tenantId = :tenantId AND dv.deviceProfileId = dp.id)")
List<EntityInfo> findActiveTenantDeviceProfileNames(@Param("tenantId") UUID tenantId);
@Query("SELECT new org.thingsboard.server.common.data.EntityInfo(d.id, 'DEVICE_PROFILE', d.name) " +
"FROM DeviceProfileEntity d WHERE d.tenantId = :tenantId")
List<EntityInfo> findAllTenantDeviceProfileNames(@Param("tenantId") UUID tenantId);
}

View File

@ -145,9 +145,6 @@ public interface DeviceRepository extends JpaRepository<DeviceEntity, UUID>, Exp
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT DISTINCT d.type FROM DeviceEntity d WHERE d.tenantId = :tenantId")
List<String> findTenantDeviceTypes(@Param("tenantId") UUID tenantId);
DeviceEntity findByTenantIdAndName(UUID tenantId, String name);
List<DeviceEntity> findDevicesByTenantIdAndCustomerIdAndIdIn(UUID tenantId, UUID customerId, List<UUID> deviceIds);

View File

@ -44,11 +44,10 @@ import org.thingsboard.server.dao.sql.JpaAbstractDao;
import org.thingsboard.server.dao.util.SqlDao;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import static org.thingsboard.server.dao.DaoUtil.convertTenantEntityTypesToDto;
import static org.thingsboard.server.dao.DaoUtil.convertTenantEntityInfosToDto;
/**
* Created by Valerii Sosliuk on 5/6/2017.
@ -64,6 +63,9 @@ public class JpaDeviceDao extends JpaAbstractDao<DeviceEntity, Device> implement
@Autowired
private NativeDeviceRepository nativeDeviceRepository;
@Autowired
private DeviceProfileRepository deviceProfileRepository;
@Override
protected Class<DeviceEntity> getEntityClass() {
return DeviceEntity.class;
@ -217,7 +219,7 @@ public class JpaDeviceDao extends JpaAbstractDao<DeviceEntity, Device> implement
@Override
public ListenableFuture<List<EntitySubtype>> findTenantDeviceTypesAsync(UUID tenantId) {
return service.submit(() -> convertTenantEntityTypesToDto(tenantId, EntityType.DEVICE, deviceRepository.findTenantDeviceTypes(tenantId)));
return service.submit(() -> convertTenantEntityInfosToDto(tenantId, EntityType.DEVICE, deviceProfileRepository.findActiveTenantDeviceProfileNames(tenantId)));
}
@Override

View File

@ -23,6 +23,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.DeviceProfileId;
@ -121,6 +122,13 @@ public class JpaDeviceProfileDao extends JpaAbstractDao<DeviceProfileEntity, Dev
return DaoUtil.toPageData(deviceProfileRepository.findAllByImageNotNull(DaoUtil.toPageable(pageLink)));
}
@Override
public List<EntityInfo> findTenantDeviceProfileNames(UUID tenantId, boolean activeOnly) {
return activeOnly ?
deviceProfileRepository.findActiveTenantDeviceProfileNames(tenantId) :
deviceProfileRepository.findAllTenantDeviceProfileNames(tenantId);
}
@Override
public DeviceProfile findByTenantIdAndExternalId(UUID tenantId, UUID externalId) {
return DaoUtil.getData(deviceProfileRepository.findByTenantIdAndExternalId(tenantId, externalId));

View File

@ -703,6 +703,7 @@ public class RestClient implements Closeable {
}).getBody();
}
@Deprecated(since = "3.6.2")
public List<EntitySubtype> getAssetTypes() {
return restTemplate.exchange(URI.create(
baseURL + "/api/asset/types"),
@ -712,6 +713,15 @@ public class RestClient implements Closeable {
}).getBody();
}
public List<EntitySubtype> getAssetProfileNames(boolean activeOnly) {
return restTemplate.exchange(
baseURL + "/api/assetProfile/names?activeOnly={activeOnly}",
HttpMethod.GET,
HttpEntity.EMPTY,
new ParameterizedTypeReference<List<EntitySubtype>>() {
}, activeOnly).getBody();
}
public BulkImportResult<Asset> processAssetsBulkImport(BulkImportRequest request) {
return restTemplate.exchange(
baseURL + "/api/asset/bulk_import",
@ -1394,6 +1404,7 @@ public class RestClient implements Closeable {
}).getBody();
}
@Deprecated(since = "3.6.2")
public List<EntitySubtype> getDeviceTypes() {
return restTemplate.exchange(
baseURL + "/api/device/types",
@ -1403,6 +1414,15 @@ public class RestClient implements Closeable {
}).getBody();
}
public List<EntitySubtype> getDeviceProfileNames(boolean activeOnly) {
return restTemplate.exchange(
baseURL + "/api/deviceProfile/names?activeOnly={activeOnly}",
HttpMethod.GET,
HttpEntity.EMPTY,
new ParameterizedTypeReference<List<EntitySubtype>>() {
}, activeOnly).getBody();
}
public JsonNode claimDevice(String deviceName, ClaimRequest claimRequest) {
return restTemplate.exchange(
baseURL + "/api/customer/device/{deviceName}/claim",