JpaAbstractSearchTimeDao JpaBaseEventDao
This commit is contained in:
		
							parent
							
								
									d65d788b5d
								
							
						
					
					
						commit
						bfd0118881
					
				@ -142,7 +142,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE
 | 
			
		||||
                .value(ModelConstants.EVENT_ENTITY_TYPE_PROPERTY, entity.getEntityType())
 | 
			
		||||
                .value(ModelConstants.EVENT_ENTITY_ID_PROPERTY, entity.getEntityId())
 | 
			
		||||
                .value(ModelConstants.EVENT_TYPE_PROPERTY, entity.getEventType())
 | 
			
		||||
                .value(ModelConstants.EVENT_UID_PROPERTY, entity.getEventUId())
 | 
			
		||||
                .value(ModelConstants.EVENT_UID_PROPERTY, entity.getEventUid())
 | 
			
		||||
                .value(ModelConstants.EVENT_BODY_PROPERTY, entity.getBody());
 | 
			
		||||
        if (ifNotExists) {
 | 
			
		||||
            insert = insert.ifNotExists();
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ import java.util.UUID;
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@Table(name = DEVICE_COLUMN_FAMILY_NAME)
 | 
			
		||||
@Table(name = EVENT_COLUMN_FAMILY_NAME)
 | 
			
		||||
public class EventEntity implements BaseEntity<Event> {
 | 
			
		||||
 | 
			
		||||
    @Transient
 | 
			
		||||
@ -63,7 +63,7 @@ public class EventEntity implements BaseEntity<Event> {
 | 
			
		||||
 | 
			
		||||
    @ClusteringColumn(value = 1)
 | 
			
		||||
    @Column(name = EVENT_UID_PROPERTY)
 | 
			
		||||
    private String eventUId;
 | 
			
		||||
    private String eventUid;
 | 
			
		||||
 | 
			
		||||
    @Column(name = EVENT_BODY_PROPERTY, codec = JsonCodec.class)
 | 
			
		||||
    private JsonNode body;
 | 
			
		||||
@ -80,7 +80,7 @@ public class EventEntity implements BaseEntity<Event> {
 | 
			
		||||
            this.entityId = event.getEntityId().getId();
 | 
			
		||||
        }
 | 
			
		||||
        this.eventType = event.getType();
 | 
			
		||||
        this.eventUId = event.getUid();
 | 
			
		||||
        this.eventUid = event.getUid();
 | 
			
		||||
        this.body = event.getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -118,7 +118,7 @@ public class EventEntity implements BaseEntity<Event> {
 | 
			
		||||
        }
 | 
			
		||||
        event.setBody(body);
 | 
			
		||||
        event.setType(eventType);
 | 
			
		||||
        event.setUid(eventUId);
 | 
			
		||||
        event.setUid(eventUid);
 | 
			
		||||
        return event;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -22,46 +22,51 @@ import javax.persistence.Id;
 | 
			
		||||
import javax.persistence.Table;
 | 
			
		||||
import javax.persistence.Transient;
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.Event;
 | 
			
		||||
import org.thingsboard.server.common.data.id.*;
 | 
			
		||||
import org.thingsboard.server.dao.model.BaseEntity;
 | 
			
		||||
import org.thingsboard.server.dao.model.ModelConstants;
 | 
			
		||||
 | 
			
		||||
import static org.thingsboard.server.dao.model.ModelConstants.*;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
@Slf4j
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
//@Entity
 | 
			
		||||
@Table(name = ModelConstants.DEVICE_COLUMN_FAMILY_NAME)
 | 
			
		||||
@Entity
 | 
			
		||||
@Table(name = EVENT_COLUMN_FAMILY_NAME)
 | 
			
		||||
public class EventEntity implements BaseEntity<Event> {
 | 
			
		||||
 | 
			
		||||
    @Transient
 | 
			
		||||
    private static final long serialVersionUID = -5717830061727466727L;
 | 
			
		||||
 | 
			
		||||
    @Column(name = ModelConstants.ID_PROPERTY)
 | 
			
		||||
    @Id
 | 
			
		||||
    @Column(name = ID_PROPERTY, columnDefinition = "BINARY(16)")
 | 
			
		||||
    private UUID id;
 | 
			
		||||
 | 
			
		||||
    @Id
 | 
			
		||||
    @Column(name = ModelConstants.EVENT_TENANT_ID_PROPERTY)
 | 
			
		||||
    @Column(name = EVENT_TENANT_ID_PROPERTY, columnDefinition = "BINARY(16)")
 | 
			
		||||
    private UUID tenantId;
 | 
			
		||||
 | 
			
		||||
    @Column(name = ModelConstants.EVENT_ENTITY_TYPE_PROPERTY)
 | 
			
		||||
    @Column(name = EVENT_ENTITY_TYPE_PROPERTY)
 | 
			
		||||
    private EntityType entityType;
 | 
			
		||||
 | 
			
		||||
    @Column(name = ModelConstants.EVENT_ENTITY_ID_PROPERTY)
 | 
			
		||||
    @Column(name = EVENT_ENTITY_ID_PROPERTY, columnDefinition = "BINARY(16)")
 | 
			
		||||
    private UUID entityId;
 | 
			
		||||
 | 
			
		||||
    @Column(name = ModelConstants.EVENT_TYPE_PROPERTY)
 | 
			
		||||
    @Column(name = EVENT_TYPE_PROPERTY)
 | 
			
		||||
    private String eventType;
 | 
			
		||||
 | 
			
		||||
    @Column(name = ModelConstants.EVENT_UID_PROPERTY)
 | 
			
		||||
    private String eventUId;
 | 
			
		||||
    @Column(name = EVENT_UID_PROPERTY)
 | 
			
		||||
    private String eventUid;
 | 
			
		||||
 | 
			
		||||
    @Column(name = ModelConstants.EVENT_BODY_PROPERTY)
 | 
			
		||||
    private JsonNode body;
 | 
			
		||||
    @Column(name = EVENT_BODY_PROPERTY)
 | 
			
		||||
    private String body;
 | 
			
		||||
 | 
			
		||||
    public EventEntity(Event event) {
 | 
			
		||||
        if (event.getId() != null) {
 | 
			
		||||
@ -75,8 +80,10 @@ public class EventEntity implements BaseEntity<Event> {
 | 
			
		||||
            this.entityId = event.getEntityId().getId();
 | 
			
		||||
        }
 | 
			
		||||
        this.eventType = event.getType();
 | 
			
		||||
        this.eventUId = event.getUid();
 | 
			
		||||
        this.body = event.getBody();
 | 
			
		||||
        this.eventUid = event.getUid();
 | 
			
		||||
        if (event.getBody() != null) {
 | 
			
		||||
            this.body = event.getBody().toString();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -111,9 +118,17 @@ public class EventEntity implements BaseEntity<Event> {
 | 
			
		||||
                event.setEntityId(new PluginId(entityId));
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        event.setBody(body);
 | 
			
		||||
        ObjectMapper mapper = new ObjectMapper();
 | 
			
		||||
        if (body != null) {
 | 
			
		||||
            try {
 | 
			
		||||
                JsonNode jsonNode = mapper.readTree(body);
 | 
			
		||||
                event.setBody(jsonNode);
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", body, e.getMessage()), e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        event.setType(eventType);
 | 
			
		||||
        event.setUid(eventUId);
 | 
			
		||||
        event.setUid(eventUid);
 | 
			
		||||
        return event;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,14 @@
 | 
			
		||||
package org.thingsboard.server.dao.sql;
 | 
			
		||||
 | 
			
		||||
import org.thingsboard.server.dao.model.BaseEntity;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Valerii Sosliuk on 5/6/2017.
 | 
			
		||||
 */
 | 
			
		||||
public abstract class JpaAbstractSearchTextDao <E extends BaseEntity<D>, D> extends JpaAbstractDao<E, D> {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected boolean isSearchTextDao() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,62 @@
 | 
			
		||||
package org.thingsboard.server.dao.sql;
 | 
			
		||||
 | 
			
		||||
import com.datastax.driver.core.utils.UUIDs;
 | 
			
		||||
import org.springframework.data.jpa.domain.Specification;
 | 
			
		||||
import org.thingsboard.server.common.data.page.TimePageLink;
 | 
			
		||||
import org.thingsboard.server.dao.model.BaseEntity;
 | 
			
		||||
import  static org.thingsboard.server.dao.model.ModelConstants.*;
 | 
			
		||||
 | 
			
		||||
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.UUID;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Valerii Sosliuk on 5/4/2017.
 | 
			
		||||
 */
 | 
			
		||||
public abstract class JpaAbstractSearchTimeDao<E extends BaseEntity<D>, D> extends JpaAbstractDao<E, D> {
 | 
			
		||||
 | 
			
		||||
    protected Specification<E> getTimeSearchPageSpec(TimePageLink pageLink) {
 | 
			
		||||
        return new Specification<E>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public Predicate toPredicate(Root<E> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
 | 
			
		||||
                Predicate lowerBound = null;
 | 
			
		||||
                Predicate upperBound = null;
 | 
			
		||||
                List<Predicate> predicates = new ArrayList<>();
 | 
			
		||||
                if (pageLink.isAscOrder()) {
 | 
			
		||||
                    if (pageLink.getIdOffset() != null) {
 | 
			
		||||
                        lowerBound = criteriaBuilder.greaterThan(root.get(ID_PROPERTY), pageLink.getIdOffset());
 | 
			
		||||
                        predicates.add(lowerBound);
 | 
			
		||||
                    } else if (pageLink.getStartTime() != null) {
 | 
			
		||||
                        UUID startOf = UUIDs.startOf(pageLink.getStartTime());
 | 
			
		||||
                        lowerBound = criteriaBuilder.greaterThanOrEqualTo(root.get(ID_PROPERTY), startOf);
 | 
			
		||||
                        predicates.add(lowerBound);
 | 
			
		||||
                    }
 | 
			
		||||
                    if (pageLink.getEndTime() != null) {
 | 
			
		||||
                        UUID endOf = UUIDs.endOf(pageLink.getEndTime());
 | 
			
		||||
                        upperBound = criteriaBuilder.lessThanOrEqualTo(root.get(ID_PROPERTY), endOf);
 | 
			
		||||
                        predicates.add(upperBound);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (pageLink.getIdOffset() != null) {
 | 
			
		||||
                        lowerBound = criteriaBuilder.lessThan(root.get(ID_PROPERTY), pageLink.getIdOffset());
 | 
			
		||||
                        predicates.add(lowerBound);
 | 
			
		||||
                    } else if (pageLink.getEndTime() != null) {
 | 
			
		||||
                        UUID endOf = UUIDs.endOf(pageLink.getEndTime());
 | 
			
		||||
                        lowerBound = criteriaBuilder.lessThanOrEqualTo(root.get(ID_PROPERTY), endOf);
 | 
			
		||||
                        predicates.add(lowerBound);
 | 
			
		||||
                    }
 | 
			
		||||
                    if (pageLink.getStartTime() != null) {
 | 
			
		||||
                        UUID startOf = UUIDs.startOf(pageLink.getStartTime());
 | 
			
		||||
                        upperBound = criteriaBuilder.greaterThanOrEqualTo(root.get(ID_PROPERTY), startOf);
 | 
			
		||||
                        predicates.add(upperBound);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return  criteriaBuilder.and(predicates.toArray(new Predicate[0]));
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,24 @@
 | 
			
		||||
package org.thingsboard.server.dao.sql.event;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 | 
			
		||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 | 
			
		||||
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.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.Event;
 | 
			
		||||
import org.thingsboard.server.dao.model.sql.EventEntity;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Valerii Sosliuk on 5/3/2017.
 | 
			
		||||
 */
 | 
			
		||||
@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
 | 
			
		||||
public interface EventRepository extends CrudRepository<EventEntity, UUID>, JpaSpecificationExecutor<EventEntity> {
 | 
			
		||||
 | 
			
		||||
    EventEntity findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid(
 | 
			
		||||
            UUID tenantId, EntityType entityType, UUID id, String eventType, String eventUid);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,137 @@
 | 
			
		||||
package org.thingsboard.server.dao.sql.event;
 | 
			
		||||
 | 
			
		||||
import com.datastax.driver.core.utils.UUIDs;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
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.jpa.domain.Specification;
 | 
			
		||||
import org.springframework.data.repository.CrudRepository;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.thingsboard.server.common.data.Event;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
import org.thingsboard.server.common.data.page.TimePageLink;
 | 
			
		||||
import org.thingsboard.server.dao.DaoUtil;
 | 
			
		||||
import org.thingsboard.server.dao.event.EventDao;
 | 
			
		||||
import org.thingsboard.server.dao.model.sql.EventEntity;
 | 
			
		||||
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.Optional;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import static org.springframework.data.jpa.domain.Specifications.where;
 | 
			
		||||
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_COLUMN_FAMILY_NAME;
 | 
			
		||||
import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
 | 
			
		||||
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Valerii Sosliuk on 5/3/2017.
 | 
			
		||||
 */
 | 
			
		||||
@Slf4j
 | 
			
		||||
@Component
 | 
			
		||||
@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
 | 
			
		||||
public class JpaBaseEventDao extends JpaAbstractSearchTimeDao<EventEntity, Event> implements EventDao {
 | 
			
		||||
 | 
			
		||||
    private final UUID systemTenantId = NULL_UUID;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private EventRepository eventRepository;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Class<EventEntity> getEntityClass() {
 | 
			
		||||
        return EventEntity.class;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected String getColumnFamilyName() {
 | 
			
		||||
        return EVENT_COLUMN_FAMILY_NAME;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected CrudRepository<EventEntity, UUID> getCrudRepository() {
 | 
			
		||||
        return eventRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Event save(Event event) {
 | 
			
		||||
        if (StringUtils.isEmpty(event.getUid())) {
 | 
			
		||||
            event.setUid(event.getId().toString());
 | 
			
		||||
        }
 | 
			
		||||
        return save(new EventEntity(event), false).orElse(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Optional<Event> saveIfNotExists(Event event) {
 | 
			
		||||
        return save(new EventEntity(event), true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Event findEvent(UUID tenantId, EntityId entityId, String eventType, String eventUid) {
 | 
			
		||||
        return DaoUtil.getData(eventRepository.findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid(
 | 
			
		||||
                tenantId, entityId.getEntityType(), entityId.getId(), eventType, eventUid));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<Event> findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink) {
 | 
			
		||||
        return findEvents(tenantId, entityId, null, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<Event> findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink) {
 | 
			
		||||
        Specification<EventEntity> timeSearchSpec = getTimeSearchPageSpec(pageLink);
 | 
			
		||||
        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);
 | 
			
		||||
        return DaoUtil.convertDataList(eventRepository.findAll(where(timeSearchSpec).and(fieldsSpec), pageable).getContent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<Event> save(EventEntity entity, boolean ifNotExists) {
 | 
			
		||||
        log.debug("Save event [{}] ", entity);
 | 
			
		||||
        if (entity.getTenantId() == null) {
 | 
			
		||||
            log.trace("Save system event with predefined id {}", systemTenantId);
 | 
			
		||||
            entity.setTenantId(systemTenantId);
 | 
			
		||||
        }
 | 
			
		||||
        if (entity.getId() == null) {
 | 
			
		||||
            entity.setId(UUIDs.timeBased());
 | 
			
		||||
        }
 | 
			
		||||
        if (StringUtils.isEmpty(entity.getEventUid())) {
 | 
			
		||||
            entity.setEventUid(entity.getId().toString());
 | 
			
		||||
        }
 | 
			
		||||
        if (ifNotExists && findById(entity.getId()) != null) {
 | 
			
		||||
            return Optional.empty();
 | 
			
		||||
        }
 | 
			
		||||
        return Optional.of(DaoUtil.getData(eventRepository.save(entity)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Specification<EventEntity> getEntityFieldsSpec(UUID tenantId, EntityId entityId, String eventType) {
 | 
			
		||||
        return new Specification<EventEntity>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public Predicate toPredicate(Root<EventEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
 | 
			
		||||
                List<Predicate> predicates = new ArrayList<Predicate>();
 | 
			
		||||
                if (tenantId != null) {
 | 
			
		||||
                    Predicate tenantIdPredicate = criteriaBuilder.equal(root.get("tenantId"), tenantId);
 | 
			
		||||
                    predicates.add(tenantIdPredicate);
 | 
			
		||||
                }
 | 
			
		||||
                if (entityId != null) {
 | 
			
		||||
                    Predicate entityTypePredicate = criteriaBuilder.equal(root.get("entityType"), entityId.getEntityType());
 | 
			
		||||
                    Predicate entityIdPredicate = criteriaBuilder.equal(root.get("entityId"), entityId.getId());
 | 
			
		||||
                    predicates.add(entityTypePredicate);
 | 
			
		||||
                    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]));
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -29,6 +29,7 @@ import org.thingsboard.server.dao.model.ModelConstants;
 | 
			
		||||
import org.thingsboard.server.dao.model.sql.PluginMetaDataEntity;
 | 
			
		||||
import org.thingsboard.server.dao.plugin.PluginDao;
 | 
			
		||||
import org.thingsboard.server.dao.sql.JpaAbstractDao;
 | 
			
		||||
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@ -40,7 +41,7 @@ import java.util.UUID;
 | 
			
		||||
@Slf4j
 | 
			
		||||
@Component
 | 
			
		||||
@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
 | 
			
		||||
public class JpaBasePluginDao extends JpaAbstractDao<PluginMetaDataEntity, PluginMetaData> implements PluginDao {
 | 
			
		||||
public class JpaBasePluginDao extends JpaAbstractSearchTextDao<PluginMetaDataEntity, PluginMetaData> implements PluginDao {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private PluginMetaDataRepository pluginMetaDataRepository;
 | 
			
		||||
@ -60,11 +61,6 @@ public class JpaBasePluginDao extends JpaAbstractDao<PluginMetaDataEntity, Plugi
 | 
			
		||||
        return pluginMetaDataRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected boolean isSearchTextDao() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public PluginMetaData findById(PluginId pluginId) {
 | 
			
		||||
        log.debug("Search plugin meta-data entity by id [{}]", pluginId);
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@ import org.thingsboard.server.dao.model.ModelConstants;
 | 
			
		||||
import org.thingsboard.server.dao.model.sql.RuleMetaDataEntity;
 | 
			
		||||
import org.thingsboard.server.dao.rule.RuleDao;
 | 
			
		||||
import org.thingsboard.server.dao.sql.JpaAbstractDao;
 | 
			
		||||
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@ -40,7 +41,7 @@ import java.util.UUID;
 | 
			
		||||
@Slf4j
 | 
			
		||||
@Component
 | 
			
		||||
@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
 | 
			
		||||
public class JpaBaseRuleDao extends JpaAbstractDao<RuleMetaDataEntity, RuleMetaData> implements RuleDao {
 | 
			
		||||
public class JpaBaseRuleDao extends JpaAbstractSearchTextDao<RuleMetaDataEntity, RuleMetaData> implements RuleDao {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private RuleMetaDataRepository ruleMetaDataRepository;
 | 
			
		||||
@ -59,11 +60,6 @@ public class JpaBaseRuleDao extends JpaAbstractDao<RuleMetaDataEntity, RuleMetaD
 | 
			
		||||
        return ruleMetaDataRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected boolean isSearchTextDao() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public RuleMetaData findById(RuleId ruleId) {
 | 
			
		||||
        return findById(ruleId.getId());
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.page.TextPageLink;
 | 
			
		||||
import org.thingsboard.server.dao.DaoUtil;
 | 
			
		||||
import org.thingsboard.server.dao.model.sql.TenantEntity;
 | 
			
		||||
import org.thingsboard.server.dao.sql.JpaAbstractDao;
 | 
			
		||||
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
 | 
			
		||||
import org.thingsboard.server.dao.tenant.TenantDao;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@ -36,7 +37,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.TENANT_COLUMN_FAMI
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
 | 
			
		||||
public class JpaTenantDao extends JpaAbstractDao<TenantEntity, Tenant> implements TenantDao {
 | 
			
		||||
public class JpaTenantDao extends JpaAbstractSearchTextDao<TenantEntity, Tenant> implements TenantDao {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private TenantRepository tenantRepository;
 | 
			
		||||
@ -56,11 +57,6 @@ public class JpaTenantDao extends JpaAbstractDao<TenantEntity, Tenant> implement
 | 
			
		||||
        return tenantRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected boolean isSearchTextDao() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<Tenant> findTenantsByRegion(String region, TextPageLink pageLink) {
 | 
			
		||||
        if (pageLink.getIdOffset() == null) {
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle;
 | 
			
		||||
import org.thingsboard.server.dao.DaoUtil;
 | 
			
		||||
import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity;
 | 
			
		||||
import org.thingsboard.server.dao.sql.JpaAbstractDao;
 | 
			
		||||
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
 | 
			
		||||
import org.thingsboard.server.dao.widget.WidgetsBundleDao;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@ -36,7 +37,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.WIDGETS_BUNDLE_COL
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
 | 
			
		||||
public class JpaWidgetsBundleDao extends JpaAbstractDao<WidgetsBundleEntity, WidgetsBundle> implements WidgetsBundleDao {
 | 
			
		||||
public class JpaWidgetsBundleDao extends JpaAbstractSearchTextDao<WidgetsBundleEntity, WidgetsBundle> implements WidgetsBundleDao {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private WidgetsBundleRepository widgetsBundleRepository;
 | 
			
		||||
@ -61,10 +62,6 @@ public class JpaWidgetsBundleDao extends JpaAbstractDao<WidgetsBundleEntity, Wid
 | 
			
		||||
        return DaoUtil.getData(widgetsBundleRepository.findWidgetsBundleByTenantIdAndAlias(tenantId, alias));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected boolean isSearchTextDao() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<WidgetsBundle> findSystemWidgetsBundles(TextPageLink pageLink) {
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,145 @@
 | 
			
		||||
package org.thingsboard.server.dao.sql.event;
 | 
			
		||||
 | 
			
		||||
import ch.qos.logback.core.net.SyslogOutputStream;
 | 
			
		||||
import com.datastax.driver.core.utils.UUIDs;
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
			
		||||
import com.github.springtestdbunit.annotation.DatabaseSetup;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.thingsboard.server.common.data.Event;
 | 
			
		||||
import org.thingsboard.server.common.data.id.DeviceId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EventId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.page.TimePageLink;
 | 
			
		||||
import org.thingsboard.server.dao.AbstractJpaDaoTest;
 | 
			
		||||
import org.thingsboard.server.dao.event.EventDao;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.*;
 | 
			
		||||
import static org.thingsboard.server.common.data.DataConstants.STATS;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Valerii Sosliuk on 5/5/2017.
 | 
			
		||||
 */
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class JpaBaseEventDaoTest extends AbstractJpaDaoTest {
 | 
			
		||||
 | 
			
		||||
    public static final long HOUR_MILLISECONDS = (long) 3.6e+6;
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private EventDao eventDao;
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @DatabaseSetup("classpath:dbunit/empty_dataset.xml")
 | 
			
		||||
    public void testSaveIfNotExists() {
 | 
			
		||||
        UUID eventId = UUIDs.timeBased();
 | 
			
		||||
        UUID tenantId = UUIDs.timeBased();
 | 
			
		||||
        UUID entityId = UUIDs.timeBased();
 | 
			
		||||
        Event event = getEvent(eventId, tenantId, entityId);
 | 
			
		||||
        Optional<Event> optEvent1 = eventDao.saveIfNotExists(event);
 | 
			
		||||
        assertTrue("Optional is expected to be non-empty", optEvent1.isPresent());
 | 
			
		||||
        assertEquals(optEvent1.get(), event);
 | 
			
		||||
        Optional<Event> optEvent2 = eventDao.saveIfNotExists(event);
 | 
			
		||||
        assertFalse("Optional is expected to be empty", optEvent2.isPresent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @DatabaseSetup("classpath:dbunit/events.xml")
 | 
			
		||||
    public void findEvent() {
 | 
			
		||||
        UUID tenantId = UUID.fromString("be41c7a0-31f5-11e7-9cfd-2786e6aa2046");
 | 
			
		||||
        UUID entityId = UUID.fromString("be41c7a1-31f5-11e7-9cfd-2786e6aa2046");
 | 
			
		||||
        String eventType = STATS;
 | 
			
		||||
        String eventUid = "be41c7a3-31f5-11e7-9cfd-2786e6aa2046";
 | 
			
		||||
        Event event = eventDao.findEvent(tenantId, new DeviceId(entityId), eventType, eventUid);
 | 
			
		||||
        assertNotNull("Event expected to be not null", event);
 | 
			
		||||
        assertEquals("be41c7a2-31f5-11e7-9cfd-2786e6aa2046", event.getId().getId().toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @DatabaseSetup("classpath:dbunit/empty_dataset.xml")
 | 
			
		||||
    public void findEventsByEntityIdAndPageLink() {
 | 
			
		||||
        UUID tenantId = UUIDs.timeBased();
 | 
			
		||||
        UUID entityId1 = UUIDs.timeBased();
 | 
			
		||||
        UUID entityId2 = UUIDs.timeBased();
 | 
			
		||||
        long startTime = System.currentTimeMillis();
 | 
			
		||||
        long endTime = createEventsTwoEntities(tenantId, entityId1, entityId2, startTime, 20);
 | 
			
		||||
        List<Event> allEvents = eventDao.find();
 | 
			
		||||
 | 
			
		||||
        assertEquals(20, allEvents.size());
 | 
			
		||||
 | 
			
		||||
        TimePageLink pageLink1 = new TimePageLink(30, null, null, true);
 | 
			
		||||
        List<Event> events1 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink1);
 | 
			
		||||
        assertEquals(10, events1.size());
 | 
			
		||||
 | 
			
		||||
        TimePageLink pageLink2 = new TimePageLink(30, startTime, null, true);
 | 
			
		||||
        List<Event> events2 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink2);
 | 
			
		||||
        assertEquals(10, events2.size());
 | 
			
		||||
 | 
			
		||||
        TimePageLink pageLink3 = new TimePageLink(30, startTime, endTime, true);
 | 
			
		||||
        List<Event> events3 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink3);
 | 
			
		||||
        assertEquals(10, events3.size());
 | 
			
		||||
 | 
			
		||||
        TimePageLink pageLink4 = new TimePageLink(5, startTime, endTime, true);
 | 
			
		||||
        List<Event> events4 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink4);
 | 
			
		||||
        assertEquals(5, events4.size());
 | 
			
		||||
 | 
			
		||||
        UUID idOffset = events4.get(4).getId().getId();
 | 
			
		||||
        TimePageLink pageLink5 = new TimePageLink(10, startTime, endTime, true, idOffset);
 | 
			
		||||
        List<Event> events5 = eventDao.findEvents(tenantId, new DeviceId(entityId1), pageLink5);
 | 
			
		||||
        assertEquals(5, events5.size());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private long createEventsTwoEntities(UUID tenantId, UUID entityId1, UUID entityId2, long startTime, int count) {
 | 
			
		||||
        // Generate #count events for two entities with timestamps from an hour ago till now
 | 
			
		||||
 | 
			
		||||
        // Distribute events uniformly
 | 
			
		||||
        long step = HOUR_MILLISECONDS / count;
 | 
			
		||||
        long timestamp = startTime;
 | 
			
		||||
        for (int i = 0; i < count / 2; i++) {
 | 
			
		||||
            //UUID eventId1 = UUIDs.startOf(timestamp);
 | 
			
		||||
            UUID eventId1 = UUIDs.timeBased();
 | 
			
		||||
            Event event1 = getEvent(eventId1, tenantId, entityId1);
 | 
			
		||||
            eventDao.save(event1);
 | 
			
		||||
            timestamp += step;
 | 
			
		||||
            //UUID eventId2 = UUIDs.startOf(timestamp);
 | 
			
		||||
            UUID eventId2 = UUIDs.timeBased();
 | 
			
		||||
            Event event2 = getEvent(eventId2, tenantId, entityId2);
 | 
			
		||||
            eventDao.save(event2);
 | 
			
		||||
            timestamp += step;
 | 
			
		||||
        }
 | 
			
		||||
        return System.currentTimeMillis();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @DatabaseSetup("classpath:dbunit/empty_dataset.xml")
 | 
			
		||||
    public void findEventsByEntityIdAndEventTypeAndPageLink() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Event getEvent(UUID eventId, UUID tenantId, UUID entityId) {
 | 
			
		||||
        Event event = new Event();
 | 
			
		||||
        event.setId(new EventId(eventId));
 | 
			
		||||
        event.setTenantId(new TenantId(tenantId));
 | 
			
		||||
        EntityId deviceId = new DeviceId(entityId);
 | 
			
		||||
        event.setEntityId(deviceId);
 | 
			
		||||
        event.setUid(entityId.toString());
 | 
			
		||||
        event.setType(STATS);
 | 
			
		||||
        ObjectMapper mapper = new ObjectMapper();
 | 
			
		||||
        try {
 | 
			
		||||
            JsonNode jsonNode = mapper.readTree("{\"key\":\"value\"}");
 | 
			
		||||
            event.setBody(jsonNode);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error(e.getMessage(), e);
 | 
			
		||||
        }
 | 
			
		||||
        return event;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								dao/src/test/resources/dbunit/events.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								dao/src/test/resources/dbunit/events.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
<dataset>
 | 
			
		||||
    <event
 | 
			
		||||
        id="uuid'be41c7a2-31f5-11e7-9cfd-2786e6aa2046'"
 | 
			
		||||
        tenant_id="uuid'be41c7a0-31f5-11e7-9cfd-2786e6aa2046'"
 | 
			
		||||
        entity_id="uuid'be41c7a1-31f5-11e7-9cfd-2786e6aa2046'"
 | 
			
		||||
        entity_type="1"
 | 
			
		||||
        event_type="STATS"
 | 
			
		||||
        event_uid="be41c7a3-31f5-11e7-9cfd-2786e6aa2046"
 | 
			
		||||
    />
 | 
			
		||||
    <event
 | 
			
		||||
        id="uuid'be41c7a4-31f5-11e7-9cfd-2786e6aa2046'"
 | 
			
		||||
        tenant_id="uuid'be41c7a0-31f5-11e7-9cfd-2786e6aa2046'"
 | 
			
		||||
        entity_id="uuid'be41c7a1-31f5-11e7-9cfd-2786e6aa2046'"
 | 
			
		||||
        entity_type="1"
 | 
			
		||||
        event_type="STATS"
 | 
			
		||||
        event_uid="be41c7a5-31f5-11e7-9cfd-2786e6aa2046"
 | 
			
		||||
    />
 | 
			
		||||
</dataset>
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user