thingsboard-memoizeit

Details

dao/pom.xml 1(+1 -0)

diff --git a/dao/pom.xml b/dao/pom.xml
index 9ab0b62..4cddf8b 100644
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -172,6 +172,7 @@
         <dependency>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
+            <scope>test</scope>
         </dependency>
     </dependencies>
     <build>
diff --git a/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java b/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java
index 0fba69c..5d372b1 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java
@@ -47,8 +47,8 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte
 
     protected abstract String getColumnFamilyName();
 
-    protected boolean isSearchTextDao() {
-        return false;
+    protected E updateSearchTextIfPresent(E entity) {
+        return entity;
     }
 
     protected Mapper<E> getMapper() {
@@ -153,9 +153,7 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte
             log.error("Can't create entity for domain object {}", domain, e);
             throw new IllegalArgumentException("Can't create entity for domain object {" + domain + "}", e);
         }
-        if (isSearchTextDao()) {
-            ((SearchTextEntity) entity).setSearchText(((SearchTextEntity) entity).getSearchTextSource().toLowerCase());
-        }
+        entity = updateSearchTextIfPresent(entity);
         log.debug("Saving entity {}", entity);
         entity = saveWithResult(entity).getEntity();
         return DaoUtil.getData(entity);
diff --git a/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractSearchTextDao.java b/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractSearchTextDao.java
index 735dd30..89c3583 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractSearchTextDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractSearchTextDao.java
@@ -34,8 +34,13 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
 public abstract class CassandraAbstractSearchTextDao<E extends SearchTextEntity<D>, D> extends CassandraAbstractModelDao<E, D> {
 
     @Override
-    protected boolean isSearchTextDao() {
-        return true;
+    protected E updateSearchTextIfPresent(E entity) {
+        if (entity.getSearchTextSource() != null) {
+            entity.setSearchText(entity.getSearchTextSource().toLowerCase());
+        } else {
+            log.trace("Entity [{}] has null SearchTextSource", entity);
+        }
+        return entity;
     }
 
     protected List<E> findPageWithTextSearch(String searchView, List<Clause> clauses, TextPageLink pageLink) {
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java
index 9cde87e..649a201 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java
@@ -100,7 +100,7 @@ public class JpaBaseEventDao extends JpaAbstractSearchTimeDao<EventEntity, Event
     }
     @Override
     public List<Event> findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink) {
-        Specification<EventEntity> timeSearchSpec = getTimeSearchPageSpec(pageLink);
+        Specification<EventEntity> timeSearchSpec = JpaAbstractSearchTimeDao.<EventEntity>getTimeSearchPageSpec(pageLink, ID_PROPERTY);
         Specification<EventEntity> fieldsSpec = getEntityFieldsSpec(tenantId, entityId, eventType);
         Sort.Direction sortDirection = pageLink.isAscOrder() ? Sort.Direction.ASC : Sort.Direction.DESC;
         Pageable pageable = new PageRequest(0, pageLink.getLimit(), sortDirection, ID_PROPERTY);
@@ -136,15 +136,15 @@ public class JpaBaseEventDao extends JpaAbstractSearchTimeDao<EventEntity, Event
                 }
                 if (entityId != null) {
                     Predicate entityTypePredicate = criteriaBuilder.equal(root.get("entityType"), entityId.getEntityType());
-                    Predicate entityIdPredicate = criteriaBuilder.equal(root.get("entityId"), entityId.getId());
                     predicates.add(entityTypePredicate);
+                    Predicate entityIdPredicate = criteriaBuilder.equal(root.get("entityId"), entityId.getId());
                     predicates.add(entityIdPredicate);
                 }
                 if (eventType != null) {
                     Predicate eventTypePredicate = criteriaBuilder.equal(root.get("eventType"), eventType);
                     predicates.add(eventTypePredicate);
                 }
-                return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
+                return criteriaBuilder.and(predicates.toArray(new Predicate[]{}));
             }
         };
     }
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java
index 594de17..b86fab0 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java
@@ -34,43 +34,41 @@ import java.util.UUID;
  */
 public abstract class JpaAbstractSearchTimeDao<E extends BaseEntity<D>, D> extends JpaAbstractDao<E, D> {
 
-    protected Specification<E> getTimeSearchPageSpec(TimePageLink pageLink) {
-        return new Specification<E>() {
+    public static <T> Specification<T> getTimeSearchPageSpec(TimePageLink pageLink, String idColumn) {
+        return new Specification<T>() {
             @Override
-            public Predicate toPredicate(Root<E> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
-                Predicate lowerBound = null;
-                Predicate upperBound = null;
+            public Predicate toPredicate(Root<T> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                 List<Predicate> predicates = new ArrayList<>();
                 if (pageLink.isAscOrder()) {
                     if (pageLink.getIdOffset() != null) {
-                        lowerBound = criteriaBuilder.greaterThan(root.get(ID_PROPERTY), pageLink.getIdOffset());
+                        Predicate lowerBound = criteriaBuilder.greaterThan(root.get(idColumn), pageLink.getIdOffset());
                         predicates.add(lowerBound);
                     } else if (pageLink.getStartTime() != null) {
                         UUID startOf = UUIDs.startOf(pageLink.getStartTime());
-                        lowerBound = criteriaBuilder.greaterThanOrEqualTo(root.get(ID_PROPERTY), startOf);
+                        Predicate lowerBound = criteriaBuilder.greaterThanOrEqualTo(root.get(idColumn), startOf);
                         predicates.add(lowerBound);
                     }
                     if (pageLink.getEndTime() != null) {
                         UUID endOf = UUIDs.endOf(pageLink.getEndTime());
-                        upperBound = criteriaBuilder.lessThanOrEqualTo(root.get(ID_PROPERTY), endOf);
+                        Predicate upperBound = criteriaBuilder.lessThanOrEqualTo(root.get(idColumn), endOf);
                         predicates.add(upperBound);
                     }
                 } else {
                     if (pageLink.getIdOffset() != null) {
-                        lowerBound = criteriaBuilder.lessThan(root.get(ID_PROPERTY), pageLink.getIdOffset());
+                        Predicate lowerBound = criteriaBuilder.lessThan(root.get(idColumn), pageLink.getIdOffset());
                         predicates.add(lowerBound);
                     } else if (pageLink.getEndTime() != null) {
                         UUID endOf = UUIDs.endOf(pageLink.getEndTime());
-                        lowerBound = criteriaBuilder.lessThanOrEqualTo(root.get(ID_PROPERTY), endOf);
+                        Predicate lowerBound = criteriaBuilder.lessThanOrEqualTo(root.get(idColumn), endOf);
                         predicates.add(lowerBound);
                     }
                     if (pageLink.getStartTime() != null) {
                         UUID startOf = UUIDs.startOf(pageLink.getStartTime());
-                        upperBound = criteriaBuilder.greaterThanOrEqualTo(root.get(ID_PROPERTY), startOf);
+                        Predicate upperBound = criteriaBuilder.greaterThanOrEqualTo(root.get(idColumn), startOf);
                         predicates.add(upperBound);
                     }
                 }
-                return  criteriaBuilder.and(predicates.toArray(new Predicate[0]));
+                return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
             }
         };
     }
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
index 169612c..3dadbf0 100644
--- 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
@@ -21,6 +21,11 @@ import com.google.common.util.concurrent.MoreExecutors;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Order;
+import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Component;
 import org.thingsboard.server.common.data.EntityType;
 import org.thingsboard.server.common.data.id.EntityId;
@@ -31,10 +36,20 @@ import org.thingsboard.server.dao.DaoUtil;
 import org.thingsboard.server.dao.model.sql.RelationCompositeKey;
 import org.thingsboard.server.dao.model.sql.RelationEntity;
 import org.thingsboard.server.dao.relation.RelationDao;
+import org.thingsboard.server.dao.sql.JpaAbstractSearchTimeDao;
 
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Executors;
 
+import static org.springframework.data.domain.Sort.Direction.ASC;
+import static org.springframework.data.jpa.domain.Specifications.where;
+import static org.thingsboard.server.dao.model.ModelConstants.*;
+
 /**
  * Created by Valerii Sosliuk on 5/29/2017.
  */
@@ -149,15 +164,43 @@ public class JpaRelationDao implements RelationDao {
 
     @Override
     public ListenableFuture<List<EntityRelation>> findRelations(EntityId from, String relationType, RelationTypeGroup typeGroup, EntityType childType, TimePageLink pageLink) {
-// TODO:
-//        executorService.submit(() -> DaoUtil.convertDataList(
-//                relationRepository.findRelations(
-//                        to.getId(),
-//                        to.getEntityType().name(),
-//                        relationType,
-//                        typeGroup.name())));
-        return null;
+        Specification<RelationEntity> timeSearchSpec = JpaAbstractSearchTimeDao.<RelationEntity>getTimeSearchPageSpec(pageLink, RELATION_TO_ID_PROPERTY);
+        Specification<RelationEntity> fieldsSpec = getEntityFieldsSpec(from, relationType, typeGroup, childType);
+        Pageable pageable = new PageRequest(0, pageLink.getLimit(),
+                new Sort(
+                        new Order(ASC, RELATION_TYPE_GROUP_PROPERTY),
+                        new Order(ASC, RELATION_TYPE_PROPERTY),
+                        new Order(ASC, RELATION_TO_TYPE_PROPERTY))
+        );
+        return executorService.submit(() ->
+                DaoUtil.convertDataList(relationRepository.findAll(where(timeSearchSpec).and(fieldsSpec), pageable).getContent()));
     }
 
-
+    private Specification<RelationEntity> getEntityFieldsSpec(EntityId from, String relationType, RelationTypeGroup typeGroup, EntityType childType) {
+        return new Specification<RelationEntity>() {
+            @Override
+            public Predicate toPredicate(Root<RelationEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
+                List<Predicate> predicates = new ArrayList<>();
+                if (from != null) {
+                    Predicate fromIdPredicate = criteriaBuilder.equal(root.get(RELATION_FROM_ID_PROPERTY), from.getId());
+                    predicates.add(fromIdPredicate);
+                    Predicate fromEntityTypePredicate = criteriaBuilder.equal(root.get(RELATION_FROM_TYPE_PROPERTY), from.getEntityType().name());
+                    predicates.add(fromEntityTypePredicate);
+                }
+                if (relationType != null) {
+                    Predicate relationTypePredicate = criteriaBuilder.equal(root.get(RELATION_TYPE_PROPERTY), relationType);
+                    predicates.add(relationTypePredicate);
+                }
+                if (typeGroup != null) {
+                    Predicate typeGroupPredicate = criteriaBuilder.equal(root.get(RELATION_TYPE_GROUP_PROPERTY), typeGroup);
+                    predicates.add(typeGroupPredicate);
+                }
+                if (childType != null) {
+                    Predicate childTypePredicate = criteriaBuilder.equal(root.get(RELATION_TO_TYPE_PROPERTY), childType.name());
+                    predicates.add(childTypePredicate);
+                }
+                return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
+            }
+        };
+    }
 }
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java
index 68243d5..d995b85 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java
@@ -16,6 +16,7 @@
 package org.thingsboard.server.dao.sql.relation;
 
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.repository.CrudRepository;
 import org.thingsboard.server.dao.model.sql.RelationCompositeKey;
 import org.thingsboard.server.dao.model.sql.RelationEntity;
@@ -24,7 +25,8 @@ import java.util.List;
 import java.util.UUID;
 
 @ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true")
-public interface RelationRepository extends CrudRepository<RelationEntity, RelationCompositeKey> {
+public interface RelationRepository
+        extends CrudRepository<RelationEntity, RelationCompositeKey>, JpaSpecificationExecutor<RelationEntity> {
 
     List<RelationEntity> findAllByFromIdAndFromTypeAndRelationTypeGroup(UUID fromId,
                                                                         String fromType,
@@ -46,20 +48,4 @@ public interface RelationRepository extends CrudRepository<RelationEntity, Relat
 
     List<RelationEntity> findAllByFromIdAndFromType(UUID fromId,
                                                     String fromType);
-
-//    @Query(nativeQuery = true, value = "SELECT * FROM RELATION WHERE FROM_ID = :fromId " +
-//            "AND FROM_TYPE = :fromType " +
-//            "AND TO_TYPE = :toType " +
-//            "AND RELATION_TYPE = :relationType " +
-//            "AND RELATION_TYPE_GROUP = :relationTypeGroup " +
-//            "AND ID > :idOffset ORDER BY RELATION_TYPE_GROUP ASC, RELATION_TYPE ASC, TO_TYPE ASC")
-//    List<RelationEntity> findRelations(@Param("fromId") UUID fromId,
-//                                       @Param("fromType") String fromType,
-//                                       @Param("toType") String toType,
-//                                       @Param("relationType") String relationType,
-//                                       @Param("relationTypeGroup") String relationTypeGroup,
-//                                       TimePageLink pageLink);
-
-
-//            pageLink, ModelConstants.RELATION_TO_ID_PROPERTY);
 }