Details
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/TenantAssetType.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/TenantAssetType.java
index bd23f2a..8e0eb0e 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/TenantAssetType.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/TenantAssetType.java
@@ -17,6 +17,8 @@ package org.thingsboard.server.common.data.asset;
import org.thingsboard.server.common.data.id.TenantId;
+import java.util.UUID;
+
public class TenantAssetType {
private static final long serialVersionUID = 8057290243855622101L;
@@ -33,6 +35,11 @@ public class TenantAssetType {
this.tenantId = tenantId;
}
+ public TenantAssetType(String type, UUID tenantId) {
+ this.type = type;
+ this.tenantId = new TenantId(tenantId);
+ }
+
public String getType() {
return type;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java
index f14a08f..e46c144 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java
@@ -27,7 +27,7 @@ import java.util.UUID;
* Created by Valerii Sosliuk on 5/21/2017.
*/
@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
-public interface AlarmRepository extends CrudRepository<AlarmEntity, Alarm> {
+public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
@Query(nativeQuery = true, value = "SELECT * FROM ALARM WHERE TENANT_ID = ?1 AND ORIGINATOR_ID = ?2 " +
"AND ?3 = ?3 AND TYPE = ?4 ORDER BY ID DESC LIMIT 1")
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java
index 86ad736..cd0df63 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java
@@ -15,23 +15,28 @@
*/
package org.thingsboard.server.dao.sql.alarm;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.*;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
+import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmQuery;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.relation.EntityRelation;
+import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.alarm.AlarmDao;
+import org.thingsboard.server.dao.alarm.BaseAlarmService;
import org.thingsboard.server.dao.model.sql.AlarmEntity;
+import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.sql.JpaAbstractDao;
+import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executors;
@@ -41,6 +46,7 @@ import static org.springframework.transaction.annotation.Propagation.REQUIRES_NE
/**
* Created by Valerii Sosliuk on 5/19/2017.
*/
+@Slf4j
@Component
@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements AlarmDao {
@@ -48,6 +54,9 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
@Autowired
private AlarmRepository alarmRepository;
+ @Autowired
+ private RelationDao relationDao;
+
@Override
protected Class getEntityClass() {
return AlarmEntity.class;
@@ -62,21 +71,28 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
@Transactional(propagation = REQUIRES_NEW)
public ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) {
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
- ListenableFuture<Alarm> listenableFuture = service.submit(() -> DaoUtil.getData(
+ return service.submit(() -> DaoUtil.getData(
alarmRepository.findLatestByOriginatorAndType(tenantId.getId(), originator.getId(),
originator.getEntityType().ordinal(), type)));
- return listenableFuture;
}
@Override
public ListenableFuture<Alarm> findAlarmByIdAsync(UUID key) {
- //TODO: Implement
- return null;
+ return findByIdAsync(key);
}
@Override
public ListenableFuture<List<Alarm>> findAlarms(AlarmQuery query) {
- //TODO: Implement
- return null;
+ log.trace("Try to find alarms by entity [{}], status [{}] and pageLink [{}]", query.getAffectedEntityId(), query.getStatus(), query.getPageLink());
+ EntityId affectedEntity = query.getAffectedEntityId();
+ String relationType = query.getStatus() == null ? BaseAlarmService.ALARM_RELATION : BaseAlarmService.ALARM_RELATION_PREFIX + query.getStatus().name();
+ ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(affectedEntity, relationType, RelationTypeGroup.ALARM, EntityType.ALARM, query.getPageLink());
+ return Futures.transform(relations, (AsyncFunction<List<EntityRelation>, List<Alarm>>) input -> {
+ List<ListenableFuture<Alarm>> alarmFutures = new ArrayList<>(input.size());
+ for (EntityRelation relation : input) {
+ alarmFutures.add(findAlarmByIdAsync(relation.getTo().getId()));
+ }
+ return Futures.successfulAsList(alarmFutures);
+ });
}
}
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 cf38c02..b6c9891 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,6 +19,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.thingsboard.server.common.data.asset.Asset;
+import org.thingsboard.server.common.data.asset.TenantAssetType;
import org.thingsboard.server.dao.model.sql.AssetEntity;
import java.util.List;
@@ -58,4 +59,19 @@ public interface AssetRepository extends CrudRepository<AssetEntity, UUID> {
List<AssetEntity> findByTenantIdAndCustomerIdAndIdIn(UUID tenantId, UUID customerId, List<UUID> assetIds);
AssetEntity findByTenantIdAndName(UUID tenantId, String name);
+
+ @Query(nativeQuery = true, value = "SELECT * FROM ASSET WHERE TENANT_ID = ?2 " +
+ "AND CUSTOMER_ID = ?3 AND TYPE = ?4 " +
+ "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?5, '%')) " +
+ "ORDER BY ID LIMIT ?1")
+ List<AssetEntity> findByTenantIdAndCustomerIdAndTypeFirstPage(int limit, UUID tenantId, UUID customerId, String type, String textSearch);
+
+ @Query(nativeQuery = true, value = "SELECT * FROM ASSET WHERE TENANT_ID = ?2 " +
+ "AND CUSTOMER_ID = ?3 AND TYPE = ?4 " +
+ "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?5, '%')) " +
+ "AND ID > ?6 ORDER BY ID LIMIT ?1")
+ List<AssetEntity> findByTenantIdAndCustomerIdAndTypeNextPage(int limit, UUID tenantId, UUID customerId, String type, String textSearch, UUID idOffset);
+
+ @Query(value = "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();
}
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 bc52aa0..49f8d44 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
@@ -104,11 +104,18 @@ public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> im
@Override
public List<Asset> findAssetsByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) {
- return null;
+ if (pageLink.getIdOffset() == null) {
+ return DaoUtil.convertDataList(assetRepository.findByTenantIdAndCustomerIdAndTypeFirstPage(pageLink.getLimit(), tenantId,
+ customerId, type, pageLink.getTextSearch()));
+ } else {
+ return DaoUtil.convertDataList(assetRepository.findByTenantIdAndCustomerIdAndTypeNextPage(pageLink.getLimit(), tenantId,
+ customerId, type, pageLink.getTextSearch(), pageLink.getIdOffset()));
+ }
}
@Override
public ListenableFuture<List<TenantAssetType>> findTenantAssetTypesAsync() {
- return null;
+ ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
+ return service.submit(() -> assetRepository.findTenantAssetTypes());
}
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
index 7073b49..a2b2bc9 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
@@ -76,7 +76,6 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D> implements Dao<
@Override
public ListenableFuture<D> findByIdAsync(UUID key) {
log.debug("Get entity by key async {}", key);
- // Should ListeningExecutorService be a field?
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<D> listenableFuture = service.submit(() -> DaoUtil.getData(getCrudRepository().findOne(key)));
return listenableFuture;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/JpaRelationDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/JpaRelationDao.java
new file mode 100644
index 0000000..beaa9c6
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/JpaRelationDao.java
@@ -0,0 +1,84 @@
+package org.thingsboard.server.dao.sql.relation;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+import org.thingsboard.server.common.data.EntityType;
+import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.page.TimePageLink;
+import org.thingsboard.server.common.data.relation.EntityRelation;
+import org.thingsboard.server.common.data.relation.RelationTypeGroup;
+import org.thingsboard.server.dao.relation.RelationDao;
+
+import java.util.List;
+
+/**
+ * Created by Valerii Sosliuk on 5/29/2017.
+ */
+@Slf4j
+@Component
+@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
+public class JpaRelationDao implements RelationDao {
+
+
+ @Override
+ public ListenableFuture<List<EntityRelation>> findAllByFrom(EntityId from, RelationTypeGroup typeGroup) {
+ // TODO: Implement
+ return null;
+ }
+
+ @Override
+ public ListenableFuture<List<EntityRelation>> findAllByFromAndType(EntityId from, String relationType, RelationTypeGroup typeGroup) {
+ // TODO: Implement
+ return null;
+ }
+
+ @Override
+ public ListenableFuture<List<EntityRelation>> findAllByTo(EntityId to, RelationTypeGroup typeGroup) {
+ // TODO: Implement
+ return null;
+ }
+
+ @Override
+ public ListenableFuture<List<EntityRelation>> findAllByToAndType(EntityId to, String relationType, RelationTypeGroup typeGroup) {
+ // TODO: Implement
+ return null;
+ }
+
+ @Override
+ public ListenableFuture<Boolean> checkRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
+ // TODO: Implement
+ return null;
+ }
+
+ @Override
+ public ListenableFuture<Boolean> saveRelation(EntityRelation relation) {
+ // TODO: Implement
+ return null;
+ }
+
+ @Override
+ public ListenableFuture<Boolean> deleteRelation(EntityRelation relation) {
+ // TODO: Implement
+ return null;
+ }
+
+ @Override
+ public ListenableFuture<Boolean> deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
+ // TODO: Implement
+ return null;
+ }
+
+ @Override
+ public ListenableFuture<Boolean> deleteOutboundRelations(EntityId entity) {
+ // TODO: Implement
+ return null;
+ }
+
+ @Override
+ public ListenableFuture<List<EntityRelation>> findRelations(EntityId from, String relationType, RelationTypeGroup typeGroup, EntityType toType, TimePageLink pageLink) {
+ // TODO: Implement
+ return null;
+ }
+}
diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDaoTest.java
index 94b6f51..b26db0b 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDaoTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDaoTest.java
@@ -71,6 +71,11 @@ public class JpaAlarmDaoTest extends AbstractJpaDaoTest {
assertEquals(alarm2Id, alarm.getId().getId());
}
+ @Test
+ public void testFindAlarmByIdAsync() {
+ // TODO: implement
+ }
+
private void saveAlarm(UUID id, UUID tenantId, UUID deviceId, String type) {
Alarm alarm = new Alarm();
alarm.setId(new AlarmId(id));
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 ebee17e..4be102e 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
@@ -20,6 +20,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
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;
@@ -32,6 +33,7 @@ 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;
@@ -56,7 +58,7 @@ public class JpaAssetDaoTest extends AbstractJpaDaoTest {
UUID assetId = UUIDs.timeBased();
UUID tenantId = i % 2 == 0 ? tenantId1 : tenantId2;
UUID customerId = i % 2 == 0 ? customerId1 : customerId2;
- saveAsset(assetId, tenantId, customerId, "ASSET_" + i);
+ saveAsset(assetId, tenantId, customerId, "ASSET_" + i, "TYPE_1");
}
assertEquals(60, assetDao.find().size());
@@ -83,7 +85,7 @@ public class JpaAssetDaoTest extends AbstractJpaDaoTest {
UUID assetId = UUIDs.timeBased();
UUID tenantId = i % 2 == 0 ? tenantId1 : tenantId2;
UUID customerId = i % 2 == 0 ? customerId1 : customerId2;
- saveAsset(assetId, tenantId, customerId, "ASSET_" + i);
+ saveAsset(assetId, tenantId, customerId, "ASSET_" + i, "TYPE_1");
}
TextPageLink pageLink1 = new TextPageLink(20, "ASSET_");
@@ -106,7 +108,7 @@ public class JpaAssetDaoTest extends AbstractJpaDaoTest {
List<UUID> searchIds = new ArrayList<>();
for (int i = 0; i < 30; i++) {
UUID assetId = UUIDs.timeBased();
- saveAsset(assetId, tenantId, customerId, "ASSET_" + i);
+ saveAsset(assetId, tenantId, customerId, "ASSET_" + i, "TYPE_1");
if (i % 3 == 0) {
searchIds.add(assetId);
}
@@ -128,7 +130,7 @@ public class JpaAssetDaoTest extends AbstractJpaDaoTest {
for (int i = 0; i < 30; i++) {
UUID assetId = UUIDs.timeBased();
UUID customerId = i%2 == 0 ? customerId1 : customerId2;
- saveAsset(assetId, tenantId, customerId, "ASSET_" + i);
+ saveAsset(assetId, tenantId, customerId, "ASSET_" + i, "TYPE_1");
if (i % 3 == 0) {
searchIds.add(assetId);
}
@@ -150,8 +152,8 @@ public class JpaAssetDaoTest extends AbstractJpaDaoTest {
UUID customerId1 = UUIDs.timeBased();
UUID customerId2 = UUIDs.timeBased();
String name = "TEST_ASSET";
- saveAsset(assetId1, tenantId1, customerId1, name);
- saveAsset(assetId2, tenantId2, customerId2, name);
+ saveAsset(assetId1, tenantId1, customerId1, name, "TYPE_1");
+ saveAsset(assetId2, tenantId2, customerId2, name, "TYPE_1");
Optional<Asset> assetOpt1 = assetDao.findAssetsByTenantIdAndName(tenantId2, name);
assertTrue("Optional expected to be non-empty", assetOpt1.isPresent());
@@ -161,13 +163,61 @@ public class JpaAssetDaoTest extends AbstractJpaDaoTest {
assertFalse("Optional expected to be empty", assetOpt2.isPresent());
}
- private void saveAsset(UUID id, UUID tenantId, UUID customerId, String name) {
+ @Test
+ public void testFindAssetsByTenantIdAndType() {
+ // TODO: implement
+ }
+
+ @Test
+ public void testFindAssetsByTenantIdAndCustomerIdAndType() {
+ // TODO: implement
+ }
+
+ @Test
+ public void testFindTenantAssetTypesAsync() throws ExecutionException, InterruptedException {
+ UUID assetId1 = UUIDs.timeBased();
+ UUID assetId2 = UUIDs.timeBased();
+ UUID tenantId1 = UUIDs.timeBased();
+ UUID tenantId2 = UUIDs.timeBased();
+ UUID customerId1 = UUIDs.timeBased();
+ UUID customerId2 = UUIDs.timeBased();
+ saveAsset(UUIDs.timeBased(), tenantId1, customerId1, "TEST_ASSET_1", "TYPE_1");
+ saveAsset(UUIDs.timeBased(), tenantId1, customerId1, "TEST_ASSET_2", "TYPE_1");
+ saveAsset(UUIDs.timeBased(), tenantId1, customerId1, "TEST_ASSET_3", "TYPE_2");
+ saveAsset(UUIDs.timeBased(), tenantId1, customerId1, "TEST_ASSET_4", "TYPE_3");
+ saveAsset(UUIDs.timeBased(), tenantId1, customerId1, "TEST_ASSET_5", "TYPE_3");
+ saveAsset(UUIDs.timeBased(), tenantId1, customerId1, "TEST_ASSET_6", "TYPE_3");
+
+ saveAsset(UUIDs.timeBased(), tenantId2, customerId2, "TEST_ASSET_7", "TYPE_4");
+ 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());
+
+ assertEquals(3, tenant1Types.size());
+ assertTrue(tenant1Types.stream().anyMatch(t -> t.getType().equals("TYPE_1")));
+ assertTrue(tenant1Types.stream().anyMatch(t -> t.getType().equals("TYPE_2")));
+ assertTrue(tenant1Types.stream().anyMatch(t -> t.getType().equals("TYPE_3")));
+ assertFalse(tenant1Types.stream().anyMatch(t -> t.getType().equals("TYPE_4")));
+
+ assertEquals(2, tenant2Types.size());
+ assertTrue(tenant2Types.stream().anyMatch(t -> t.getType().equals("TYPE_1")));
+ assertTrue(tenant2Types.stream().anyMatch(t -> t.getType().equals("TYPE_4")));
+ assertFalse(tenant2Types.stream().anyMatch(t -> t.getType().equals("TYPE_2")));
+ assertFalse(tenant2Types.stream().anyMatch(t -> t.getType().equals("TYPE_3")));
+ }
+
+ private void saveAsset(UUID id, UUID tenantId, UUID customerId, String name, String type) {
Asset asset = new Asset();
asset.setId(new AssetId(id));
asset.setTenantId(new TenantId(tenantId));
asset.setCustomerId(new CustomerId(customerId));
asset.setName(name);
-
+ asset.setType(type);
assetDao.save(asset);
}
}