thingsboard-aplcache
Changes
application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java 47(+39 -8)
application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java 25(+17 -8)
application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java 37(+19 -18)
dao/src/main/resources/cassandra/schema.cql 19(+6 -13)
Details
diff --git a/application/src/main/data/upgrade/1.3.0/schema_update.cql b/application/src/main/data/upgrade/1.3.0/schema_update.cql
index 4070614..1e4302d 100644
--- a/application/src/main/data/upgrade/1.3.0/schema_update.cql
+++ b/application/src/main/data/upgrade/1.3.0/schema_update.cql
@@ -69,13 +69,6 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_customer_by_type_an
PRIMARY KEY ( customer_id, tenant_id, type, search_text, id )
WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC );
-CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_types_by_tenant AS
- SELECT *
- from thingsboard.device
- WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND id IS NOT NULL
- PRIMARY KEY ( (type, tenant_id), id, customer_id)
- WITH CLUSTERING ORDER BY ( id ASC, customer_id DESC);
-
DROP MATERIALIZED VIEW IF EXISTS thingsboard.asset_by_tenant_and_name;
DROP MATERIALIZED VIEW IF EXISTS thingsboard.asset_by_tenant_and_search_text;
DROP MATERIALIZED VIEW IF EXISTS thingsboard.asset_by_tenant_by_type_and_search_text;
@@ -131,12 +124,12 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.asset_by_customer_by_type_and
PRIMARY KEY ( customer_id, tenant_id, type, search_text, id )
WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC );
-CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.asset_types_by_tenant AS
- SELECT *
- from thingsboard.asset
- WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND id IS NOT NULL
- PRIMARY KEY ( (type, tenant_id), id, customer_id)
- WITH CLUSTERING ORDER BY ( id ASC, customer_id DESC);
+CREATE TABLE IF NOT EXISTS thingsboard.entity_subtype (
+ tenant_id timeuuid,
+ entity_type text, // (DEVICE, ASSET)
+ type text,
+ PRIMARY KEY (tenant_id, entity_type, type)
+);
CREATE TABLE IF NOT EXISTS thingsboard.alarm (
id timeuuid,
diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetController.java b/application/src/main/java/org/thingsboard/server/controller/AssetController.java
index dd43e1c..2857874 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java
@@ -20,8 +20,8 @@ import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.Customer;
+import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.asset.Asset;
-import org.thingsboard.server.common.data.asset.TenantAssetType;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
@@ -246,11 +246,11 @@ public class AssetController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/asset/types", method = RequestMethod.GET)
@ResponseBody
- public List<TenantAssetType> getAssetTypes() throws ThingsboardException {
+ public List<EntitySubtype> getAssetTypes() throws ThingsboardException {
try {
SecurityUser user = getCurrentUser();
TenantId tenantId = user.getTenantId();
- ListenableFuture<List<TenantAssetType>> assetTypes = assetService.findAssetTypesByTenantId(tenantId);
+ ListenableFuture<List<EntitySubtype>> assetTypes = assetService.findAssetTypesByTenantId(tenantId);
return checkNotNull(assetTypes.get());
} catch (Exception e) {
throw handleException(e);
diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
index f0cde33..68b29b8 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
@@ -21,7 +21,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
-import org.thingsboard.server.common.data.TenantDeviceType;
+import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
@@ -283,11 +283,11 @@ public class DeviceController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/device/types", method = RequestMethod.GET)
@ResponseBody
- public List<TenantDeviceType> getDeviceTypes() throws ThingsboardException {
+ public List<EntitySubtype> getDeviceTypes() throws ThingsboardException {
try {
SecurityUser user = getCurrentUser();
TenantId tenantId = user.getTenantId();
- ListenableFuture<List<TenantDeviceType>> deviceTypes = deviceService.findDeviceTypesByTenantId(tenantId);
+ ListenableFuture<List<EntitySubtype>> deviceTypes = deviceService.findDeviceTypesByTenantId(tenantId);
return checkNotNull(deviceTypes.get());
} catch (Exception e) {
throw handleException(e);
diff --git a/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java
index 4e769f7..83f1435 100644
--- a/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java
+++ b/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java
@@ -64,26 +64,23 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService {
log.info("Dumping devices ...");
Path devicesDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), "device",
- new String[]{"id", "tenant_id", "customer_id", "name", "search_text", "additional_info"},
+ new String[]{"id", "tenant_id", "customer_id", "name", "search_text", "additional_info", "type"},
+ new String[]{"", "", "", "", "", "", "default"},
"tb-devices");
- if (devicesDump != null) {
- CassandraDbHelper.appendToEndOfLine(devicesDump, "default");
- }
log.info("Devices dumped.");
log.info("Dumping assets ...");
Path assetsDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), "asset",
new String[]{"id", "tenant_id", "customer_id", "name", "search_text", "additional_info", "type"},
+ new String[]{"", "", "", "", "", "", "default"},
"tb-assets");
log.info("Assets dumped.");
log.info("Dumping relations ...");
Path relationsDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), "relation",
- new String[]{"from_id", "from_type", "to_id", "to_type", "relation_type", "additional_info"},
+ new String[]{"from_id", "from_type", "to_id", "to_type", "relation_type", "additional_info", "relation_type_group"},
+ new String[]{"", "", "", "", "", "", "COMMON"},
"tb-relations");
- if (relationsDump != null) {
- CassandraDbHelper.appendToEndOfLine(relationsDump, "COMMON");
- }
log.info("Relations dumped.");
log.info("Updating schema ...");
@@ -101,6 +98,23 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService {
}
log.info("Devices restored.");
+ log.info("Dumping device types ...");
+ Path deviceTypesDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), "device",
+ new String[]{"tenant_id", "type"},
+ new String[]{"", ""},
+ "tb-device-types");
+ if (deviceTypesDump != null) {
+ CassandraDbHelper.appendToEndOfLine(deviceTypesDump, "DEVICE");
+ }
+ log.info("Device types dumped.");
+ log.info("Loading device types ...");
+ if (deviceTypesDump != null) {
+ CassandraDbHelper.loadCf(ks, cluster.getSession(), "entity_subtype",
+ new String[]{"tenant_id", "type", "entity_type"}, deviceTypesDump);
+ Files.deleteIfExists(deviceTypesDump);
+ }
+ log.info("Device types loaded.");
+
log.info("Restoring assets ...");
if (assetsDump != null) {
CassandraDbHelper.loadCf(ks, cluster.getSession(), "asset",
@@ -109,6 +123,23 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService {
}
log.info("Assets restored.");
+ log.info("Dumping asset types ...");
+ Path assetTypesDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), "asset",
+ new String[]{"tenant_id", "type"},
+ new String[]{"", ""},
+ "tb-asset-types");
+ if (assetTypesDump != null) {
+ CassandraDbHelper.appendToEndOfLine(assetTypesDump, "ASSET");
+ }
+ log.info("Asset types dumped.");
+ log.info("Loading asset types ...");
+ if (assetTypesDump != null) {
+ CassandraDbHelper.loadCf(ks, cluster.getSession(), "entity_subtype",
+ new String[]{"tenant_id", "type", "entity_type"}, assetTypesDump);
+ Files.deleteIfExists(assetTypesDump);
+ }
+ log.info("Asset types loaded.");
+
log.info("Restoring relations ...");
if (relationsDump != null) {
CassandraDbHelper.loadCf(ks, cluster.getSession(), "relation",
diff --git a/application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java b/application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java
index 4a92db2..0a411f6 100644
--- a/application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java
+++ b/application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java
@@ -33,7 +33,7 @@ public class CassandraDbHelper {
private static final CSVFormat CSV_DUMP_FORMAT = CSVFormat.DEFAULT.withNullString("\\N");
public static Path dumpCfIfExists(KeyspaceMetadata ks, Session session, String cfName,
- String[] columns, String dumpPrefix) throws Exception {
+ String[] columns, String[] defaultValues, String dumpPrefix) throws Exception {
if (ks.getTable(cfName) != null) {
Path dumpFile = Files.createTempFile(dumpPrefix, null);
Files.deleteIfExists(dumpFile);
@@ -45,7 +45,7 @@ public class CassandraDbHelper {
while (iter.hasNext()) {
Row row = iter.next();
if (row != null) {
- dumpRow(row, columns, csvPrinter);
+ dumpRow(row, columns, defaultValues, csvPrinter);
}
}
}
@@ -89,18 +89,25 @@ public class CassandraDbHelper {
}
- private static void dumpRow(Row row, String[] columns, CSVPrinter csvPrinter) throws Exception {
+ private static void dumpRow(Row row, String[] columns, String[] defaultValues, CSVPrinter csvPrinter) throws Exception {
List<String> record = new ArrayList<>();
- for (String column : columns) {
- record.add(getColumnValue(column, row));
+ for (int i=0;i<columns.length;i++) {
+ String column = columns[i];
+ String defaultValue;
+ if (defaultValues != null && i < defaultValues.length) {
+ defaultValue = defaultValues[i];
+ } else {
+ defaultValue = "";
+ }
+ record.add(getColumnValue(column, defaultValue, row));
}
csvPrinter.printRecord(record);
}
- private static String getColumnValue(String column, Row row) {
- String str = "";
+ private static String getColumnValue(String column, String defaultValue, Row row) {
int index = row.getColumnDefinitions().getIndexOf(column);
if (index > -1) {
+ String str;
DataType type = row.getColumnDefinitions().getType(index);
try {
if (row.isNull(index)) {
@@ -123,8 +130,10 @@ public class CassandraDbHelper {
} catch (Exception e) {
str = "";
}
+ return str;
+ } else {
+ return defaultValue;
}
- return str;
}
private static String createInsertStatement(String cfName, String[] columns) {
diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java
index 1350aae..fb2e720 100644
--- a/application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java
+++ b/application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java
@@ -15,30 +15,31 @@
*/
package org.thingsboard.server.controller;
-import static org.hamcrest.Matchers.containsString;
-import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
+import com.datastax.driver.core.utils.UUIDs;
+import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
-import org.thingsboard.server.common.data.*;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.thingsboard.server.common.data.Customer;
+import org.thingsboard.server.common.data.EntitySubtype;
+import org.thingsboard.server.common.data.Tenant;
+import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.asset.Asset;
-import org.thingsboard.server.common.data.asset.TenantAssetType;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.model.ModelConstants;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import com.datastax.driver.core.utils.UUIDs;
-import com.fasterxml.jackson.core.type.TypeReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
public abstract class BaseAssetControllerTest extends AbstractControllerTest {
@@ -128,8 +129,8 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
asset.setType("typeA");
assets.add(doPost("/api/asset", asset, Asset.class));
}
- List<TenantAssetType> assetTypes = doGetTyped("/api/asset/types",
- new TypeReference<List<TenantAssetType>>(){});
+ List<EntitySubtype> assetTypes = doGetTyped("/api/asset/types",
+ new TypeReference<List<EntitySubtype>>(){});
Assert.assertNotNull(assetTypes);
Assert.assertEquals(3, assetTypes.size());
diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java
index 3713fc4..f8da8fc 100644
--- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java
+++ b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java
@@ -140,8 +140,8 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
device.setType("typeA");
devices.add(doPost("/api/device", device, Device.class));
}
- List<TenantDeviceType> deviceTypes = doGetTyped("/api/device/types",
- new TypeReference<List<TenantDeviceType>>(){});
+ List<EntitySubtype> deviceTypes = doGetTyped("/api/device/types",
+ new TypeReference<List<EntitySubtype>>(){});
Assert.assertNotNull(deviceTypes);
Assert.assertEquals(3, deviceTypes.size());
diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetDao.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetDao.java
index 73211fe..f953335 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetDao.java
@@ -16,8 +16,8 @@
package org.thingsboard.server.dao.asset;
import com.google.common.util.concurrent.ListenableFuture;
+import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.asset.Asset;
-import org.thingsboard.server.common.data.asset.TenantAssetType;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.Dao;
@@ -112,6 +112,6 @@ public interface AssetDao extends Dao<Asset> {
*
* @return the list of tenant asset type objects
*/
- ListenableFuture<List<TenantAssetType>> findTenantAssetTypesAsync();
+ ListenableFuture<List<EntitySubtype>> findTenantAssetTypesAsync(UUID tenantId);
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetService.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetService.java
index 25baeda..214ef15 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetService.java
@@ -16,8 +16,8 @@
package org.thingsboard.server.dao.asset;
import com.google.common.util.concurrent.ListenableFuture;
+import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.asset.Asset;
-import org.thingsboard.server.common.data.asset.TenantAssetType;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
@@ -61,5 +61,5 @@ public interface AssetService {
ListenableFuture<List<Asset>> findAssetsByQuery(AssetSearchQuery query);
- ListenableFuture<List<TenantAssetType>> findAssetTypesByTenantId(TenantId tenantId);
+ ListenableFuture<List<EntitySubtype>> findAssetTypesByTenantId(TenantId tenantId);
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java
index 3a2805c..615cdf8 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java
@@ -25,10 +25,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.Customer;
+import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.asset.Asset;
-import org.thingsboard.server.common.data.asset.TenantAssetType;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
@@ -217,22 +217,15 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
}
@Override
- public ListenableFuture<List<TenantAssetType>> findAssetTypesByTenantId(TenantId tenantId) {
+ public ListenableFuture<List<EntitySubtype>> findAssetTypesByTenantId(TenantId tenantId) {
log.trace("Executing findAssetTypesByTenantId, tenantId [{}]", tenantId);
validateId(tenantId, "Incorrect tenantId " + tenantId);
- ListenableFuture<List<TenantAssetType>> tenantAssetTypeEntities = assetDao.findTenantAssetTypesAsync();
- ListenableFuture<List<TenantAssetType>> tenantAssetTypes = Futures.transform(tenantAssetTypeEntities,
- (Function<List<TenantAssetType>, List<TenantAssetType>>) assetTypeEntities -> {
- List<TenantAssetType> assetTypes = new ArrayList<>();
- for (TenantAssetType assetType : assetTypeEntities) {
- if (assetType.getTenantId().equals(tenantId)) {
- assetTypes.add(assetType);
- }
- }
- assetTypes.sort(Comparator.comparing(TenantAssetType::getType));
+ ListenableFuture<List<EntitySubtype>> tenantAssetTypes = assetDao.findTenantAssetTypesAsync(tenantId.getId());
+ return Futures.transform(tenantAssetTypes,
+ (Function<List<EntitySubtype>, List<EntitySubtype>>) assetTypes -> {
+ assetTypes.sort(Comparator.comparing(EntitySubtype::getType));
return assetTypes;
});
- return tenantAssetTypes;
}
private DataValidator<Asset> assetValidator =
diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/CassandraAssetDao.java b/dao/src/main/java/org/thingsboard/server/dao/asset/CassandraAssetDao.java
index 339c9ea..d6c6ca4 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/asset/CassandraAssetDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/asset/CassandraAssetDao.java
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.asset;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.ResultSetFuture;
+import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.Select;
import com.datastax.driver.mapping.Result;
import com.google.common.base.Function;
@@ -24,11 +25,12 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
+import org.thingsboard.server.common.data.EntitySubtype;
+import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.asset.Asset;
-import org.thingsboard.server.common.data.asset.TenantAssetType;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.TenantAssetTypeEntity;
+import org.thingsboard.server.dao.model.EntitySubtypeEntity;
import org.thingsboard.server.dao.model.nosql.AssetEntity;
import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao;
import org.thingsboard.server.dao.util.NoSqlDao;
@@ -55,6 +57,16 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
}
@Override
+ public Asset save(Asset domain) {
+ Asset savedAsset = super.save(domain);
+ EntitySubtype entitySubtype = new EntitySubtype(savedAsset.getTenantId(), EntityType.ASSET, savedAsset.getType());
+ EntitySubtypeEntity entitySubtypeEntity = new EntitySubtypeEntity(entitySubtype);
+ Statement saveStatement = cluster.getMapper(EntitySubtypeEntity.class).saveQuery(entitySubtypeEntity);
+ executeWrite(saveStatement);
+ return savedAsset;
+ }
+
+ @Override
public List<Asset> findAssetsByTenantId(UUID tenantId, TextPageLink pageLink) {
log.debug("Try to find assets by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
List<AssetEntity> assetEntities = findPageWithTextSearch(ASSET_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
@@ -130,36 +142,29 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
}
@Override
- public ListenableFuture<List<TenantAssetType>> findTenantAssetTypesAsync() {
- Select statement = select().distinct().column(ASSET_TYPE_PROPERTY).column(ASSET_TENANT_ID_PROPERTY).from(ASSET_TYPES_BY_TENANT_VIEW_NAME);
- statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
- ResultSetFuture resultSetFuture = getSession().executeAsync(statement);
- ListenableFuture<List<TenantAssetTypeEntity>> result = Futures.transform(resultSetFuture, new Function<ResultSet, List<TenantAssetTypeEntity>>() {
+ public ListenableFuture<List<EntitySubtype>> findTenantAssetTypesAsync(UUID tenantId) {
+ Select select = select().from(ENTITY_SUBTYPE_COLUMN_FAMILY_NAME);
+ Select.Where query = select.where();
+ query.and(eq(ENTITY_SUBTYPE_TENANT_ID_PROPERTY, tenantId));
+ query.and(eq(ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY, EntityType.ASSET));
+ query.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
+ ResultSetFuture resultSetFuture = getSession().executeAsync(query);
+ return Futures.transform(resultSetFuture, new Function<ResultSet, List<EntitySubtype>>() {
@Nullable
@Override
- public List<TenantAssetTypeEntity> apply(@Nullable ResultSet resultSet) {
- Result<TenantAssetTypeEntity> result = cluster.getMapper(TenantAssetTypeEntity.class).map(resultSet);
+ public List<EntitySubtype> apply(@Nullable ResultSet resultSet) {
+ Result<EntitySubtypeEntity> result = cluster.getMapper(EntitySubtypeEntity.class).map(resultSet);
if (result != null) {
- return result.all();
+ List<EntitySubtype> entitySubtypes = new ArrayList<>();
+ result.all().forEach((entitySubtypeEntity) ->
+ entitySubtypes.add(entitySubtypeEntity.toEntitySubtype())
+ );
+ return entitySubtypes;
} else {
return Collections.emptyList();
}
}
});
- return Futures.transform(result, new Function<List<TenantAssetTypeEntity>, List<TenantAssetType>>() {
- @Nullable
- @Override
- public List<TenantAssetType> apply(@Nullable List<TenantAssetTypeEntity> entityList) {
- List<TenantAssetType> list = Collections.emptyList();
- if (entityList != null && !entityList.isEmpty()) {
- list = new ArrayList<>();
- for (TenantAssetTypeEntity object : entityList) {
- list.add(object.toTenantAssetType());
- }
- }
- return list;
- }
- });
}
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceDao.java b/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceDao.java
index a0d4fe1..9c3a4bb 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceDao.java
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.device;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.ResultSetFuture;
+import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.Select;
import com.datastax.driver.mapping.Result;
import com.google.common.base.Function;
@@ -25,10 +26,11 @@ import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Device;
-import org.thingsboard.server.common.data.TenantDeviceType;
+import org.thingsboard.server.common.data.EntitySubtype;
+import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.TenantDeviceTypeEntity;
+import org.thingsboard.server.dao.model.EntitySubtypeEntity;
import org.thingsboard.server.dao.model.nosql.DeviceEntity;
import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao;
import org.thingsboard.server.dao.util.NoSqlDao;
@@ -55,6 +57,16 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
}
@Override
+ public Device save(Device domain) {
+ Device savedDevice = super.save(domain);
+ EntitySubtype entitySubtype = new EntitySubtype(savedDevice.getTenantId(), EntityType.DEVICE, savedDevice.getType());
+ EntitySubtypeEntity entitySubtypeEntity = new EntitySubtypeEntity(entitySubtype);
+ Statement saveStatement = cluster.getMapper(EntitySubtypeEntity.class).saveQuery(entitySubtypeEntity);
+ executeWrite(saveStatement);
+ return savedDevice;
+ }
+
+ @Override
public List<Device> findDevicesByTenantId(UUID tenantId, TextPageLink pageLink) {
log.debug("Try to find devices by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
List<DeviceEntity> deviceEntities = findPageWithTextSearch(DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
@@ -130,36 +142,29 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
}
@Override
- public ListenableFuture<List<TenantDeviceType>> findTenantDeviceTypesAsync() {
- Select statement = select().distinct().column(DEVICE_TYPE_PROPERTY).column(DEVICE_TENANT_ID_PROPERTY).from(DEVICE_TYPES_BY_TENANT_VIEW_NAME);
- statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
- ResultSetFuture resultSetFuture = getSession().executeAsync(statement);
- ListenableFuture<List<TenantDeviceTypeEntity>> result = Futures.transform(resultSetFuture, new Function<ResultSet, List<TenantDeviceTypeEntity>>() {
+ public ListenableFuture<List<EntitySubtype>> findTenantDeviceTypesAsync(UUID tenantId) {
+ Select select = select().from(ENTITY_SUBTYPE_COLUMN_FAMILY_NAME);
+ Select.Where query = select.where();
+ query.and(eq(ENTITY_SUBTYPE_TENANT_ID_PROPERTY, tenantId));
+ query.and(eq(ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY, EntityType.DEVICE));
+ query.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
+ ResultSetFuture resultSetFuture = getSession().executeAsync(query);
+ return Futures.transform(resultSetFuture, new Function<ResultSet, List<EntitySubtype>>() {
@Nullable
@Override
- public List<TenantDeviceTypeEntity> apply(@Nullable ResultSet resultSet) {
- Result<TenantDeviceTypeEntity> result = cluster.getMapper(TenantDeviceTypeEntity.class).map(resultSet);
+ public List<EntitySubtype> apply(@Nullable ResultSet resultSet) {
+ Result<EntitySubtypeEntity> result = cluster.getMapper(EntitySubtypeEntity.class).map(resultSet);
if (result != null) {
- return result.all();
+ List<EntitySubtype> entitySubtypes = new ArrayList<>();
+ result.all().forEach((entitySubtypeEntity) ->
+ entitySubtypes.add(entitySubtypeEntity.toEntitySubtype())
+ );
+ return entitySubtypes;
} else {
return Collections.emptyList();
}
}
});
- return Futures.transform(result, new Function<List<TenantDeviceTypeEntity>, List<TenantDeviceType>>() {
- @Nullable
- @Override
- public List<TenantDeviceType> apply(@Nullable List<TenantDeviceTypeEntity> entityList) {
- List<TenantDeviceType> list = Collections.emptyList();
- if (entityList != null && !entityList.isEmpty()) {
- list = new ArrayList<>();
- for (TenantDeviceTypeEntity object : entityList) {
- list.add(object.toTenantDeviceType());
- }
- }
- return list;
- }
- });
}
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java
index a6d785e..c0c1744 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java
@@ -17,7 +17,7 @@ package org.thingsboard.server.dao.device;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.Device;
-import org.thingsboard.server.common.data.TenantDeviceType;
+import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.Dao;
@@ -113,5 +113,5 @@ public interface DeviceDao extends Dao<Device> {
*
* @return the list of tenant device type objects
*/
- ListenableFuture<List<TenantDeviceType>> findTenantDeviceTypesAsync();
+ ListenableFuture<List<EntitySubtype>> findTenantDeviceTypesAsync(UUID tenantId);
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceService.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
index 3e7b6af..cd56fef 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
@@ -17,7 +17,7 @@ package org.thingsboard.server.dao.device;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.Device;
-import org.thingsboard.server.common.data.TenantDeviceType;
+import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
@@ -61,6 +61,6 @@ public interface DeviceService {
ListenableFuture<List<Device>> findDevicesByQuery(DeviceSearchQuery query);
- ListenableFuture<List<TenantDeviceType>> findDeviceTypesByTenantId(TenantId tenantId);
+ ListenableFuture<List<EntitySubtype>> findDeviceTypesByTenantId(TenantId tenantId);
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
index 7535967..e1056f8 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
@@ -237,22 +237,15 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
}
@Override
- public ListenableFuture<List<TenantDeviceType>> findDeviceTypesByTenantId(TenantId tenantId) {
+ public ListenableFuture<List<EntitySubtype>> findDeviceTypesByTenantId(TenantId tenantId) {
log.trace("Executing findDeviceTypesByTenantId, tenantId [{}]", tenantId);
validateId(tenantId, "Incorrect tenantId " + tenantId);
- ListenableFuture<List<TenantDeviceType>> tenantDeviceTypeEntities = deviceDao.findTenantDeviceTypesAsync();
- ListenableFuture<List<TenantDeviceType>> tenantDeviceTypes = Futures.transform(tenantDeviceTypeEntities,
- (Function<List<TenantDeviceType>, List<TenantDeviceType>>) deviceTypeEntities -> {
- List<TenantDeviceType> deviceTypes = new ArrayList<>();
- for (TenantDeviceType deviceType : deviceTypeEntities) {
- if (deviceType.getTenantId().equals(tenantId)) {
- deviceTypes.add(deviceType);
- }
- }
- deviceTypes.sort(Comparator.comparing(TenantDeviceType::getType));
+ ListenableFuture<List<EntitySubtype>> tenantDeviceTypes = deviceDao.findTenantDeviceTypesAsync(tenantId.getId());
+ return Futures.transform(tenantDeviceTypes,
+ (Function<List<EntitySubtype>, List<EntitySubtype>>) deviceTypes -> {
+ deviceTypes.sort(Comparator.comparing(EntitySubtype::getType));
return deviceTypes;
- });
- return tenantDeviceTypes;
+ });
}
private DataValidator<Device> deviceValidator =
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
index 1bf88be..194a41c 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
@@ -151,6 +151,14 @@ public class ModelConstants {
public static final String ASSET_TYPES_BY_TENANT_VIEW_NAME = "asset_types_by_tenant";
/**
+ * Cassandra entity_subtype constants.
+ */
+ public static final String ENTITY_SUBTYPE_COLUMN_FAMILY_NAME = "entity_subtype";
+ public static final String ENTITY_SUBTYPE_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
+ public static final String ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY = "entity_type";
+ public static final String ENTITY_SUBTYPE_TYPE_PROPERTY = "type";
+
+ /**
* Cassandra alarm constants.
*/
public static final String ALARM_COLUMN_FAMILY_NAME = "alarm";
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetRepository.java
index 478c6ef..b0636f1 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetRepository.java
@@ -19,7 +19,8 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
-import org.thingsboard.server.common.data.asset.TenantAssetType;
+import org.thingsboard.server.common.data.EntitySubtype;
+import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.dao.model.sql.AssetEntity;
import org.thingsboard.server.dao.util.SqlDao;
@@ -76,6 +77,7 @@ public interface AssetRepository extends CrudRepository<AssetEntity, String> {
@Param("idOffset") String idOffset,
Pageable pageable);
- @Query("SELECT NEW org.thingsboard.server.common.data.asset.TenantAssetType(a.type, a.tenantId) FROM AssetEntity a GROUP BY a.tenantId, a.type")
- List<TenantAssetType> findTenantAssetTypes();
+ @Query("SELECT DISTINCT a.type FROM AssetEntity a WHERE a.tenantId = :tenantId")
+ List<String> findTenantAssetTypes(@Param("tenantId") String tenantId);
+
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetDao.java
index 81ce691..ea256e6 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetDao.java
@@ -20,8 +20,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
+import org.thingsboard.server.common.data.EntitySubtype;
+import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.asset.Asset;
-import org.thingsboard.server.common.data.asset.TenantAssetType;
+import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.asset.AssetDao;
@@ -29,10 +31,7 @@ import org.thingsboard.server.dao.model.sql.AssetEntity;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
import org.thingsboard.server.dao.util.SqlDao;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.UUID;
+import java.util.*;
import static org.thingsboard.server.common.data.UUIDConverter.fromTimeUUID;
import static org.thingsboard.server.common.data.UUIDConverter.fromTimeUUIDs;
@@ -121,7 +120,18 @@ public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> im
}
@Override
- public ListenableFuture<List<TenantAssetType>> findTenantAssetTypesAsync() {
- return service.submit(() -> assetRepository.findTenantAssetTypes());
+ public ListenableFuture<List<EntitySubtype>> findTenantAssetTypesAsync(UUID tenantId) {
+ return service.submit(() -> convertTenantAssetTypesToDto(tenantId, assetRepository.findTenantAssetTypes(fromTimeUUID(tenantId))));
+ }
+
+ private List<EntitySubtype> convertTenantAssetTypesToDto(UUID tenantId, List<String> types) {
+ List<EntitySubtype> list = Collections.emptyList();
+ if (types != null && !types.isEmpty()) {
+ list = new ArrayList<>();
+ for (String type : types) {
+ list.add(new EntitySubtype(new TenantId(tenantId), EntityType.ASSET, type));
+ }
+ }
+ return list;
}
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java
index 256f623..bcea4ce 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java
@@ -20,7 +20,6 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.dao.model.sql.DeviceEntity;
-import org.thingsboard.server.dao.model.sql.TenantDeviceTypeEntity;
import org.thingsboard.server.dao.util.SqlDao;
import java.util.List;
@@ -72,8 +71,8 @@ public interface DeviceRepository extends CrudRepository<DeviceEntity, String> {
@Param("idOffset") String idOffset,
Pageable pageable);
- @Query("SELECT DISTINCT NEW org.thingsboard.server.dao.model.sql.TenantDeviceTypeEntity(d.tenantId, d.type) FROM DeviceEntity d")
- List<TenantDeviceTypeEntity> findTenantDeviceTypes();
+ @Query("SELECT DISTINCT d.type FROM DeviceEntity d WHERE d.tenantId = :tenantId")
+ List<String> findTenantDeviceTypes(@Param("tenantId") String tenantId);
DeviceEntity findByTenantIdAndName(String tenantId, String name);
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java
index 4835c6c..a3f02f8 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java
@@ -21,14 +21,14 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Device;
-import org.thingsboard.server.common.data.TenantDeviceType;
+import org.thingsboard.server.common.data.EntitySubtype;
+import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.device.DeviceDao;
import org.thingsboard.server.dao.model.sql.DeviceEntity;
-import org.thingsboard.server.dao.model.sql.TenantDeviceTypeEntity;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
import org.thingsboard.server.dao.util.SqlDao;
@@ -120,16 +120,16 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device>
}
@Override
- public ListenableFuture<List<TenantDeviceType>> findTenantDeviceTypesAsync() {
- return service.submit(() -> convertTenantDeviceTypeEntityToDto(deviceRepository.findTenantDeviceTypes()));
+ public ListenableFuture<List<EntitySubtype>> findTenantDeviceTypesAsync(UUID tenantId) {
+ return service.submit(() -> convertTenantDeviceTypesToDto(tenantId, deviceRepository.findTenantDeviceTypes(fromTimeUUID(tenantId))));
}
- private List<TenantDeviceType> convertTenantDeviceTypeEntityToDto(List<TenantDeviceTypeEntity> entities) {
- List<TenantDeviceType> list = Collections.emptyList();
- if (entities != null && !entities.isEmpty()) {
+ private List<EntitySubtype> convertTenantDeviceTypesToDto(UUID tenantId, List<String> types) {
+ List<EntitySubtype> list = Collections.emptyList();
+ if (types != null && !types.isEmpty()) {
list = new ArrayList<>();
- for (TenantDeviceTypeEntity entity : entities) {
- list.add(new TenantDeviceType(entity.getType(), new TenantId(UUIDConverter.fromString(entity.getTenantId()))));
+ for (String type : types) {
+ list.add(new EntitySubtype(new TenantId(tenantId), EntityType.DEVICE, type));
}
}
return list;
dao/src/main/resources/cassandra/schema.cql 19(+6 -13)
diff --git a/dao/src/main/resources/cassandra/schema.cql b/dao/src/main/resources/cassandra/schema.cql
index 71de677..dda8067 100644
--- a/dao/src/main/resources/cassandra/schema.cql
+++ b/dao/src/main/resources/cassandra/schema.cql
@@ -197,13 +197,6 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_customer_by_type_an
PRIMARY KEY ( customer_id, tenant_id, type, search_text, id )
WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC );
-CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_types_by_tenant AS
- SELECT *
- from thingsboard.device
- WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND id IS NOT NULL
- PRIMARY KEY ( (type, tenant_id), id, customer_id)
- WITH CLUSTERING ORDER BY ( id ASC, customer_id DESC);
-
CREATE TABLE IF NOT EXISTS thingsboard.device_credentials (
id timeuuid PRIMARY KEY,
device_id timeuuid,
@@ -270,12 +263,12 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.asset_by_customer_by_type_and
PRIMARY KEY ( customer_id, tenant_id, type, search_text, id )
WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC );
-CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.asset_types_by_tenant AS
- SELECT *
- from thingsboard.asset
- WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND id IS NOT NULL
- PRIMARY KEY ( (type, tenant_id), id, customer_id)
- WITH CLUSTERING ORDER BY ( id ASC, customer_id DESC);
+CREATE TABLE IF NOT EXISTS thingsboard.entity_subtype (
+ tenant_id timeuuid,
+ entity_type text, // (DEVICE, ASSET)
+ type text,
+ PRIMARY KEY (tenant_id, entity_type, type)
+);
CREATE TABLE IF NOT EXISTS thingsboard.alarm (
id timeuuid,
diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseAssetServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseAssetServiceTest.java
index 2dbf739..6bcc74a 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseAssetServiceTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseAssetServiceTest.java
@@ -22,9 +22,9 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.common.data.Customer;
+import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.asset.Asset;
-import org.thingsboard.server.common.data.asset.TenantAssetType;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageData;
@@ -181,7 +181,7 @@ public abstract class BaseAssetServiceTest extends AbstractServiceTest {
asset.setType("typeA");
assets.add(assetService.saveAsset(asset));
}
- List<TenantAssetType> assetTypes = assetService.findAssetTypesByTenantId(tenantId).get();
+ List<EntitySubtype> assetTypes = assetService.findAssetTypesByTenantId(tenantId).get();
Assert.assertNotNull(assetTypes);
Assert.assertEquals(3, assetTypes.size());
Assert.assertEquals("typeA", assetTypes.get(0).getType());
diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java
index addaf8f..0c35798 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java
@@ -23,8 +23,8 @@ import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
+import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.Tenant;
-import org.thingsboard.server.common.data.TenantDeviceType;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageData;
@@ -191,7 +191,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest {
device.setType("typeA");
devices.add(deviceService.saveDevice(device));
}
- List<TenantDeviceType> deviceTypes = deviceService.findDeviceTypesByTenantId(tenantId).get();
+ List<EntitySubtype> deviceTypes = deviceService.findDeviceTypesByTenantId(tenantId).get();
Assert.assertNotNull(deviceTypes);
Assert.assertEquals(3, deviceTypes.size());
Assert.assertEquals("typeA", deviceTypes.get(0).getType());
diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/asset/JpaAssetDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/asset/JpaAssetDaoTest.java
index 4be102e..062f0e6 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/sql/asset/JpaAssetDaoTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/sql/asset/JpaAssetDaoTest.java
@@ -19,8 +19,8 @@ import com.datastax.driver.core.utils.UUIDs;
import com.google.common.util.concurrent.ListenableFuture;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.asset.Asset;
-import org.thingsboard.server.common.data.asset.TenantAssetType;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
@@ -33,12 +33,9 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
-import java.util.stream.Collectors;
import static junit.framework.TestCase.assertFalse;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
/**
* Created by Valerii Sosliuk on 5/21/2017.
@@ -192,11 +189,10 @@ public class JpaAssetDaoTest extends AbstractJpaDaoTest {
saveAsset(UUIDs.timeBased(), tenantId2, customerId2, "TEST_ASSET_8", "TYPE_1");
saveAsset(UUIDs.timeBased(), tenantId2, customerId2, "TEST_ASSET_9", "TYPE_1");
- ListenableFuture<List<TenantAssetType>> tenantAssetTypesFuture = assetDao.findTenantAssetTypesAsync();
- List<TenantAssetType> tenantAssetTypes = tenantAssetTypesFuture.get();
- assertNotNull(tenantAssetTypes);
- List<TenantAssetType> tenant1Types = tenantAssetTypes.stream().filter(t -> t.getTenantId().getId().equals(tenantId1)).collect(Collectors.toList());
- List<TenantAssetType> tenant2Types = tenantAssetTypes.stream().filter(t -> t.getTenantId().getId().equals(tenantId2)).collect(Collectors.toList());
+ List<EntitySubtype> tenant1Types = assetDao.findTenantAssetTypesAsync(tenantId1).get();
+ assertNotNull(tenant1Types);
+ List<EntitySubtype> tenant2Types = assetDao.findTenantAssetTypesAsync(tenantId2).get();
+ assertNotNull(tenant2Types);
assertEquals(3, tenant1Types.size());
assertTrue(tenant1Types.stream().anyMatch(t -> t.getType().equals("TYPE_1")));