Browse Source

added fixes after review

pull/9776/head
ShvaykaD 3 years ago
parent
commit
f7af8e298c
  1. 4
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  2. 24
      dao/src/main/java/org/thingsboard/server/dao/DaoUtil.java
  3. 6
      dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java
  4. 15
      dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java
  5. 6
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java
  6. 7
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
  7. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetProfileRepository.java
  8. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java
  9. 2
      dao/src/main/resources/sql/schema-entities-idx.sql
  10. 97
      dao/src/test/java/org/thingsboard/server/dao/service/AssetProfileServiceTest.java
  11. 94
      dao/src/test/java/org/thingsboard/server/dao/service/DeviceProfileServiceTest.java

4
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java

@ -766,6 +766,10 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
} catch (Exception e) {
log.warn("Failed to execute update script for save attributes rule nodes due to: ", e);
}
try {
connection.createStatement().execute("CREATE INDEX IF NOT EXISTS idx_asset_profile_id ON asset(tenant_id, asset_profile_id);");
} catch (Exception e) {
}
});
break;
default:

24
dao/src/main/java/org/thingsboard/server/dao/DaoUtil.java

@ -153,28 +153,24 @@ public abstract class DaoUtil {
}
}
public static List<EntitySubtype> convertTenantEntityTypesToDto(UUID tenantId, EntityType entityType, List<String> types) {
public static List<EntitySubtype> convertTenantEntityTypesToDto(UUID tenantUUID, EntityType entityType, List<String> types) {
if (CollectionUtils.isEmpty(types)) {
return Collections.emptyList();
}
List<EntitySubtype> list = new ArrayList<>(types.size());
for (String type : types) {
list.add(new EntitySubtype(TenantId.fromUUID(tenantId), entityType, type));
}
return list;
TenantId tenantId = TenantId.fromUUID(tenantUUID);
return types.stream()
.map(type -> new EntitySubtype(tenantId, entityType, type))
.collect(Collectors.toList());
}
public static List<EntitySubtype> convertTenantEntityInfosToDto(UUID tenantId, EntityType entityType, List<EntityInfo> entityInfos) {
public static List<EntitySubtype> convertTenantEntityInfosToDto(UUID tenantUUID, 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;
var tenantId = TenantId.fromUUID(tenantUUID);
return entityInfos.stream()
.map(info -> new EntitySubtype(tenantId, entityType, info.getName()))
.collect(Collectors.toList());
}
}

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

@ -43,11 +43,9 @@ 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;
@ -325,9 +323,7 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService<AssetPr
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());
return assetProfileDao.findTenantAssetProfileNames(tenantId.getId(), activeOnly);
}
private final PaginatedRemover<TenantId, AssetProfile> tenantAssetProfilesRemover =

15
dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java

@ -56,7 +56,6 @@ import org.thingsboard.server.dao.service.PaginatedRemover;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@ -363,7 +362,12 @@ public class BaseAssetService extends AbstractCachedEntityService<AssetCacheKey,
return Futures.successfulAsList(futures);
}, MoreExecutors.directExecutor());
assets = Futures.transform(assets, assetList ->
assetList == null ? Collections.emptyList() : assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList()), MoreExecutors.directExecutor()
assetList == null ?
Collections.emptyList() :
assetList.stream()
.filter(asset -> query.getAssetTypes().contains(asset.getType()))
.collect(Collectors.toList()),
MoreExecutors.directExecutor()
);
return assets;
}
@ -372,12 +376,7 @@ public class BaseAssetService extends AbstractCachedEntityService<AssetCacheKey,
public ListenableFuture<List<EntitySubtype>> findAssetTypesByTenantId(TenantId tenantId) {
log.trace("Executing findAssetTypesByTenantId, tenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
ListenableFuture<List<EntitySubtype>> tenantAssetTypes = assetDao.findTenantAssetTypesAsync(tenantId.getId());
return Futures.transform(tenantAssetTypes,
assetTypes -> {
assetTypes.sort(Comparator.comparing(EntitySubtype::getType));
return assetTypes;
}, MoreExecutors.directExecutor());
return assetDao.findTenantAssetTypesAsync(tenantId.getId());
}
@Override

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

@ -58,13 +58,11 @@ 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;
@ -380,9 +378,7 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
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());
return deviceProfileDao.findTenantDeviceProfileNames(tenantId.getId(), activeOnly);
}
private final PaginatedRemover<TenantId, DeviceProfile> tenantDeviceProfilesRemover =

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

@ -486,12 +486,7 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
public ListenableFuture<List<EntitySubtype>> findDeviceTypesByTenantId(TenantId tenantId) {
log.trace("Executing findDeviceTypesByTenantId, tenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
ListenableFuture<List<EntitySubtype>> tenantDeviceTypes = deviceDao.findTenantDeviceTypesAsync(tenantId.getId());
return Futures.transform(tenantDeviceTypes,
deviceTypes -> {
deviceTypes.sort(Comparator.comparing(EntitySubtype::getType));
return deviceTypes;
}, MoreExecutors.directExecutor());
return deviceDao.findTenantDeviceTypesAsync(tenantId.getId());
}
@Transactional

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

@ -73,11 +73,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)")
"FROM AssetProfileEntity ap WHERE ap.tenantId = :tenantId AND EXISTS " +
"(SELECT 1 FROM AssetEntity a WHERE a.tenantId = :tenantId AND a.assetProfileId = ap.id) ORDER BY ap.name ASC")
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")
"FROM AssetProfileEntity a WHERE a.tenantId = :tenantId ORDER BY a.name ASC")
List<EntityInfo> findAllTenantAssetProfileNames(@Param("tenantId") UUID tenantId);
}

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

@ -84,11 +84,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)")
"FROM DeviceProfileEntity dp WHERE dp.tenantId = :tenantId AND EXISTS " +
"(SELECT 1 FROM DeviceEntity dv WHERE dv.tenantId = :tenantId AND dv.deviceProfileId = dp.id) ORDER BY dp.name ASC")
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")
"FROM DeviceProfileEntity d WHERE d.tenantId = :tenantId ORDER BY d.name ASC")
List<EntityInfo> findAllTenantDeviceProfileNames(@Param("tenantId") UUID tenantId);
}

2
dao/src/main/resources/sql/schema-entities-idx.sql

@ -57,6 +57,8 @@ CREATE INDEX IF NOT EXISTS idx_asset_customer_id_and_type ON asset(tenant_id, cu
CREATE INDEX IF NOT EXISTS idx_asset_type ON asset(tenant_id, type);
CREATE INDEX IF NOT EXISTS idx_asset_profile_id ON asset(tenant_id, asset_profile_id);
CREATE INDEX IF NOT EXISTS idx_attribute_kv_by_key_and_last_update_ts ON attribute_kv(entity_id, attribute_key, last_update_ts desc);
CREATE INDEX IF NOT EXISTS idx_audit_log_tenant_id_and_created_time ON audit_log(tenant_id, created_time DESC);

97
dao/src/test/java/org/thingsboard/server/dao/service/AssetProfileServiceTest.java

@ -24,6 +24,7 @@ import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.asset.AssetProfileInfo;
@ -35,11 +36,14 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
@DaoSqlTest
public class AssetProfileServiceTest extends AbstractServiceTest {
@ -272,4 +276,97 @@ public class AssetProfileServiceTest extends AbstractServiceTest {
Assert.assertEquals(1, pageData.getTotalElements());
}
@Test
public void testFindAllassetProfilesByTenantId() {
int assetProfilesCount = 4; // 3 created + default
var assetProfiles = new ArrayList<AssetProfile>(4);
var profileC = assetProfileService.saveAssetProfile(
createAssetProfile(tenantId, "profile C"));
assetProfiles.add(assetProfileService.saveAssetProfile(profileC));
var profileA = assetProfileService.saveAssetProfile(
createAssetProfile(tenantId, "profile A"));
assetProfiles.add(assetProfileService.saveAssetProfile(profileA));
var profileB = assetProfileService.saveAssetProfile(
createAssetProfile(tenantId, "profile B"));
assetProfiles.add(assetProfileService.saveAssetProfile(profileB));
assetProfiles.add(assetProfileService.findDefaultAssetProfile(tenantId));
List<EntityInfo> sortedProfileInfos = assetProfiles.stream()
.map(profile -> new EntityInfo(profile.getId(), profile.getName()))
.sorted(Comparator.comparing(EntityInfo::getName))
.collect(Collectors.toList());
var assetProfileInfos = assetProfileService
.findAssetProfileNamesByTenantId(tenantId, false);
assertThat(assetProfileInfos).isNotNull();
assertThat(assetProfileInfos).hasSize(assetProfilesCount);
assertThat(assetProfileInfos).isEqualTo(sortedProfileInfos);
}
@Test
public void testFindActiveOnlyassetProfilesByTenantId() {
String profileCName = "profile C";
assetProfileService.saveAssetProfile(
createAssetProfile(tenantId, profileCName));
String profileAName = "profile A";
assetProfileService.saveAssetProfile(
createAssetProfile(tenantId, profileAName));
String profileBName = "profile B";
assetProfileService.saveAssetProfile(
createAssetProfile(tenantId, profileBName));
var assetProfileInfos = assetProfileService
.findAssetProfileNamesByTenantId(tenantId, true);
assertThat(assetProfileInfos).isNotNull();
assertThat(assetProfileInfos).isEmpty();
var assetC = new Asset();
assetC.setName("Test asset C");
assetC.setType(profileCName);
assetC.setTenantId(tenantId);
assetC = assetService.saveAsset(assetC);
var assetA = new Asset();
assetA.setName("Test asset A");
assetA.setType(profileAName);
assetA.setTenantId(tenantId);
assetA = assetService.saveAsset(assetA);
var assetB = new Asset();
assetB.setName("Test asset B");
assetB.setType(profileBName);
assetB.setTenantId(tenantId);
assetB = assetService.saveAsset(assetB);
assetProfileInfos = assetProfileService
.findAssetProfileNamesByTenantId(tenantId, true);
var expected = List.of(
new EntityInfo(assetA.getAssetProfileId(), profileAName),
new EntityInfo(assetB.getAssetProfileId(), profileBName),
new EntityInfo(assetC.getAssetProfileId(), profileCName)
);
assertThat(assetProfileInfos).isNotEmpty();
assertThat(assetProfileInfos).hasSize(3);
assertThat(assetProfileInfos).isEqualTo(expected);
}
}

94
dao/src/test/java/org/thingsboard/server/dao/service/DeviceProfileServiceTest.java

@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.Device;
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.OtaPackage;
import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
import org.thingsboard.server.common.data.page.PageData;
@ -41,6 +42,7 @@ import org.thingsboard.server.dao.ota.OtaPackageService;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
@ -372,4 +374,96 @@ public class DeviceProfileServiceTest extends AbstractServiceTest {
Assert.assertEquals(1, pageData.getTotalElements());
}
@Test
public void testFindAllDeviceProfilesByTenantId() {
int deviceProfilesCount = 4; // 3 created + default
var deviceProfiles = new ArrayList<DeviceProfile>(4);
var profileC = deviceProfileService.saveDeviceProfile(
createDeviceProfile(tenantId, "profile C"));
deviceProfiles.add(deviceProfileService.saveDeviceProfile(profileC));
var profileA = deviceProfileService.saveDeviceProfile(
createDeviceProfile(tenantId, "profile A"));
deviceProfiles.add(deviceProfileService.saveDeviceProfile(profileA));
var profileB = deviceProfileService.saveDeviceProfile(
createDeviceProfile(tenantId, "profile B"));
deviceProfiles.add(deviceProfileService.saveDeviceProfile(profileB));
deviceProfiles.add(deviceProfileService.findDefaultDeviceProfile(tenantId));
List<EntityInfo> sortedProfileInfos = deviceProfiles.stream()
.map(profile -> new EntityInfo(profile.getId(), profile.getName()))
.sorted(Comparator.comparing(EntityInfo::getName))
.collect(Collectors.toList());
var deviceProfileInfos = deviceProfileService
.findDeviceProfileNamesByTenantId(tenantId, false);
assertThat(deviceProfileInfos).isNotNull();
assertThat(deviceProfileInfos).hasSize(deviceProfilesCount);
assertThat(deviceProfileInfos).isEqualTo(sortedProfileInfos);
}
@Test
public void testFindActiveOnlyDeviceProfilesByTenantId() {
String profileCName = "profile C";
deviceProfileService.saveDeviceProfile(
createDeviceProfile(tenantId, profileCName));
String profileAName = "profile A";
deviceProfileService.saveDeviceProfile(
createDeviceProfile(tenantId, profileAName));
String profileBName = "profile B";
deviceProfileService.saveDeviceProfile(
createDeviceProfile(tenantId, profileBName));
var deviceProfileInfos = deviceProfileService
.findDeviceProfileNamesByTenantId(tenantId, true);
assertThat(deviceProfileInfos).isNotNull();
assertThat(deviceProfileInfos).isEmpty();
var deviceC = new Device();
deviceC.setName("Test Device C");
deviceC.setType(profileCName);
deviceC.setTenantId(tenantId);
deviceC = deviceService.saveDevice(deviceC);
var deviceA = new Device();
deviceA.setName("Test Device A");
deviceA.setType(profileAName);
deviceA.setTenantId(tenantId);
deviceA = deviceService.saveDevice(deviceA);
var deviceB = new Device();
deviceB.setName("Test Device B");
deviceB.setType(profileBName);
deviceB.setTenantId(tenantId);
deviceB = deviceService.saveDevice(deviceB);
deviceProfileInfos = deviceProfileService
.findDeviceProfileNamesByTenantId(tenantId, true);
var expected = List.of(
new EntityInfo(deviceA.getDeviceProfileId(), profileAName),
new EntityInfo(deviceB.getDeviceProfileId(), profileBName),
new EntityInfo(deviceC.getDeviceProfileId(), profileCName)
);
assertThat(deviceProfileInfos).isNotEmpty();
assertThat(deviceProfileInfos).hasSize(3);
assertThat(deviceProfileInfos).isEqualTo(expected);
}
}

Loading…
Cancel
Save