thingsboard-memoizeit

JPA Alarm and Asset Dao added

5/22/2017 12:51:29 AM

Changes

Details

diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java
index 8f32b4c..a178c6e 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java
@@ -20,7 +20,6 @@ import org.thingsboard.server.common.data.alarm.Alarm;
 import org.thingsboard.server.common.data.id.EntityId;
 import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.dao.Dao;
-import org.thingsboard.server.dao.model.AlarmEntity;
 
 import java.util.UUID;
 
@@ -31,8 +30,4 @@ public interface AlarmDao extends Dao<Alarm> {
 
     ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type);
 
-    ListenableFuture<Alarm> findAlarmByIdAsync(UUID key);
-
-    Alarm save(Alarm alarm);
-
 }
diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
index 6d484ba..59ec547 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
@@ -164,7 +164,7 @@ public class BaseAlarmService extends BaseEntityService implements AlarmService 
     public ListenableFuture<Alarm> findAlarmById(AlarmId alarmId) {
         log.trace("Executing findAlarmById [{}]", alarmId);
         validateId(alarmId, "Incorrect alarmId " + alarmId);
-        return alarmDao.findAlarmByIdAsync(alarmId.getId());
+        return alarmDao.findByIdAsync(alarmId.getId());
     }
 
     @Override
@@ -218,7 +218,7 @@ public class BaseAlarmService extends BaseEntityService implements AlarmService 
 
     private ListenableFuture<Boolean> getAndUpdate(AlarmId alarmId, Function<Alarm, Boolean> function) {
         validateId(alarmId, "Alarm id should be specified!");
-        ListenableFuture<Alarm> entity = alarmDao.findAlarmByIdAsync(alarmId.getId());
+        ListenableFuture<Alarm> entity = alarmDao.findByIdAsync(alarmId.getId());
         return Futures.transform(entity, function);
     }
 
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 220cbcb..b002a98 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
@@ -74,7 +74,7 @@ public interface AssetDao extends Dao<Asset> {
      * @param assetIds the asset Ids
      * @return the list of asset objects
      */
-    ListenableFuture<List<Asset>> findAssetsByTenantIdCustomerIdAndIdsAsync(UUID tenantId, UUID customerId, List<UUID> assetIds);
+    ListenableFuture<List<Asset>> findAssetsByTenantIdAndCustomerIdAndIdsAsync(UUID tenantId, UUID customerId, List<UUID> assetIds);
 
     /**
      * Find assets by tenantId and asset name.
diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetSearchQuery.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetSearchQuery.java
index f3c69b2..440f0d2 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetSearchQuery.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetSearchQuery.java
@@ -23,7 +23,6 @@ import org.thingsboard.server.dao.relation.EntityRelationsQuery;
 import org.thingsboard.server.dao.relation.EntityTypeFilter;
 
 import javax.annotation.Nullable;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
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 addf17b..c664e62 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
@@ -38,10 +38,6 @@ import org.thingsboard.server.common.data.relation.EntityRelation;
 import org.thingsboard.server.dao.customer.CustomerDao;
 import org.thingsboard.server.dao.entity.BaseEntityService;
 import org.thingsboard.server.dao.exception.DataValidationException;
-import org.thingsboard.server.dao.model.AssetEntity;
-import org.thingsboard.server.dao.model.nosql.CustomerEntity;
-import org.thingsboard.server.dao.model.nosql.TenantEntity;
-import org.thingsboard.server.dao.relation.EntityRelationsQuery;
 import org.thingsboard.server.dao.relation.EntitySearchDirection;
 import org.thingsboard.server.dao.service.DataValidator;
 import org.thingsboard.server.dao.service.PaginatedRemover;
@@ -156,11 +152,11 @@ public class BaseAssetService extends BaseEntityService implements AssetService 
 
     @Override
     public ListenableFuture<List<Asset>> findAssetsByTenantIdCustomerIdAndIdsAsync(TenantId tenantId, CustomerId customerId, List<AssetId> assetIds) {
-        log.trace("Executing findAssetsByTenantIdCustomerIdAndIdsAsync, tenantId [{}], customerId [{}], assetIds [{}]", tenantId, customerId, assetIds);
+        log.trace("Executing findAssetsByTenantIdAndCustomerIdAndIdsAsync, tenantId [{}], customerId [{}], assetIds [{}]", tenantId, customerId, assetIds);
         validateId(tenantId, "Incorrect tenantId " + tenantId);
         validateId(customerId, "Incorrect customerId " + customerId);
         validateIds(assetIds, "Incorrect assetIds " + assetIds);
-        return assetDao.findAssetsByTenantIdCustomerIdAndIdsAsync(tenantId.getId(), customerId.getId(), toUUIDs(assetIds));
+        return assetDao.findAssetsByTenantIdAndCustomerIdAndIdsAsync(tenantId.getId(), customerId.getId(), toUUIDs(assetIds));
     }
 
     @Override
diff --git a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java
index ba5c9a9..7fa4211 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java
@@ -21,8 +21,6 @@ import java.util.List;
 import java.util.Optional;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -30,7 +28,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.thingsboard.server.common.data.Customer;
 import org.thingsboard.server.common.data.Tenant;
-import org.thingsboard.server.common.data.asset.Asset;
 import org.thingsboard.server.common.data.id.CustomerId;
 import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.common.data.page.TextPageData;
@@ -40,7 +37,6 @@ import org.thingsboard.server.dao.device.DeviceService;
 import org.thingsboard.server.dao.entity.BaseEntityService;
 import org.thingsboard.server.dao.exception.DataValidationException;
 import org.thingsboard.server.dao.exception.IncorrectParameterException;
-import org.thingsboard.server.dao.model.AssetEntity;
 import org.thingsboard.server.dao.service.DataValidator;
 import org.thingsboard.server.dao.service.PaginatedRemover;
 import org.thingsboard.server.dao.service.Validator;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java
new file mode 100644
index 0000000..6806d6b
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java
@@ -0,0 +1,131 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.model.sql;
+
+import com.datastax.driver.core.utils.UUIDs;
+import com.fasterxml.jackson.databind.JsonNode;
+import lombok.Data;
+import org.hibernate.annotations.Type;
+import org.thingsboard.server.common.data.EntityType;
+import org.thingsboard.server.common.data.alarm.Alarm;
+import org.thingsboard.server.common.data.alarm.AlarmId;
+import org.thingsboard.server.common.data.alarm.AlarmSeverity;
+import org.thingsboard.server.common.data.alarm.AlarmStatus;
+import org.thingsboard.server.common.data.id.EntityIdFactory;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.dao.model.BaseEntity;
+import org.thingsboard.server.dao.model.ModelConstants;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+import static org.thingsboard.server.dao.model.ModelConstants.*;
+
+@Data
+@Entity
+@Table(name = ALARM_COLUMN_FAMILY_NAME)
+public final class AlarmEntity implements BaseEntity<Alarm> {
+
+    @Transient
+    private static final long serialVersionUID = -339979717281685984L;
+
+    @Id
+    @Column(name = ID_PROPERTY)
+    private UUID id;
+
+    @Column(name = ALARM_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+
+    @Column(name = ALARM_ORIGINATOR_ID_PROPERTY)
+    private UUID originatorId;
+
+    @Column(name = ALARM_ORIGINATOR_TYPE_PROPERTY)
+    private EntityType originatorType;
+
+    @Column(name = ALARM_TYPE_PROPERTY)
+    private String type;
+
+    @Column(name = ALARM_SEVERITY_PROPERTY)
+    private AlarmSeverity severity;
+
+    @Column(name = ALARM_STATUS_PROPERTY)
+    private AlarmStatus status;
+
+    @Column(name = ALARM_START_TS_PROPERTY)
+    private Long startTs;
+
+    @Column(name = ALARM_END_TS_PROPERTY)
+    private Long endTs;
+
+    @Column(name = ALARM_ACK_TS_PROPERTY)
+    private Long ackTs;
+
+    @Column(name = ALARM_CLEAR_TS_PROPERTY)
+    private Long clearTs;
+
+    @Type(type = "jsonb")
+    @Column(name = ModelConstants.ASSET_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
+    private JsonNode details;
+
+    @Column(name = ALARM_PROPAGATE_PROPERTY)
+    private Boolean propagate;
+
+    public AlarmEntity() {
+        super();
+    }
+
+    public AlarmEntity(Alarm alarm) {
+        if (alarm.getId() != null) {
+            this.id = alarm.getId().getId();
+        }
+        if (alarm.getTenantId() != null) {
+            this.tenantId = alarm.getTenantId().getId();
+        }
+        this.type = alarm.getType();
+        this.originatorId = alarm.getOriginator().getId();
+        this.originatorType = alarm.getOriginator().getEntityType();
+        this.type = alarm.getType();
+        this.severity = alarm.getSeverity();
+        this.status = alarm.getStatus();
+        this.propagate = alarm.isPropagate();
+        this.startTs = alarm.getStartTs();
+        this.endTs = alarm.getEndTs();
+        this.ackTs = alarm.getAckTs();
+        this.clearTs = alarm.getClearTs();
+        this.details = alarm.getDetails();
+    }
+
+    @Override
+    public Alarm toData() {
+        Alarm alarm = new Alarm(new AlarmId(id));
+        alarm.setCreatedTime(UUIDs.unixTimestamp(id));
+        if (tenantId != null) {
+            alarm.setTenantId(new TenantId(tenantId));
+        }
+        alarm.setOriginator(EntityIdFactory.getByTypeAndUuid(originatorType, originatorId));
+        alarm.setType(type);
+        alarm.setSeverity(severity);
+        alarm.setStatus(status);
+        alarm.setPropagate(propagate);
+        alarm.setStartTs(startTs);
+        alarm.setEndTs(endTs);
+        alarm.setAckTs(ackTs);
+        alarm.setClearTs(clearTs);
+        alarm.setDetails(details);
+        return alarm;
+    }
+
+}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java
new file mode 100644
index 0000000..dd73622
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java
@@ -0,0 +1,188 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.model.sql;
+
+import com.datastax.driver.core.utils.UUIDs;
+import com.fasterxml.jackson.databind.JsonNode;
+import lombok.Data;
+import org.hibernate.annotations.Type;
+import org.thingsboard.server.common.data.asset.Asset;
+import org.thingsboard.server.common.data.id.AssetId;
+import org.thingsboard.server.common.data.id.CustomerId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.dao.model.ModelConstants;
+import org.thingsboard.server.dao.model.SearchTextEntity;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+import static org.thingsboard.server.dao.model.ModelConstants.*;
+
+@Data
+@Entity
+@Table(name = ASSET_COLUMN_FAMILY_NAME)
+public final class AssetEntity implements SearchTextEntity<Asset> {
+
+    @Transient
+    private static final long serialVersionUID = -4089175869616037592L;
+
+    @Id
+    @Column(name = ID_PROPERTY)
+    private UUID id;
+
+    @Column(name = ASSET_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+
+    @Column(name = ASSET_CUSTOMER_ID_PROPERTY)
+    private UUID customerId;
+
+    @Column(name = ASSET_NAME_PROPERTY)
+    private String name;
+
+    @Column(name = ASSET_TYPE_PROPERTY)
+    private String type;
+
+    @Column(name = SEARCH_TEXT_PROPERTY)
+    private String searchText;
+
+    @Type(type = "jsonb")
+    @Column(name = ModelConstants.ASSET_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
+    private JsonNode additionalInfo;
+
+    public AssetEntity() {
+        super();
+    }
+
+    public AssetEntity(Asset asset) {
+        if (asset.getId() != null) {
+            this.id = asset.getId().getId();
+        }
+        if (asset.getTenantId() != null) {
+            this.tenantId = asset.getTenantId().getId();
+        }
+        if (asset.getCustomerId() != null) {
+            this.customerId = asset.getCustomerId().getId();
+        }
+        this.name = asset.getName();
+        this.type = asset.getType();
+        this.additionalInfo = asset.getAdditionalInfo();
+    }
+
+    @Override
+    public String getSearchTextSource() {
+        return name;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+
+    public String getSearchText() {
+        return searchText;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode());
+        result = prime * result + ((customerId == null) ? 0 : customerId.hashCode());
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        AssetEntity other = (AssetEntity) obj;
+        if (additionalInfo == null) {
+            if (other.additionalInfo != null)
+                return false;
+        } else if (!additionalInfo.equals(other.additionalInfo))
+            return false;
+        if (customerId == null) {
+            if (other.customerId != null)
+                return false;
+        } else if (!customerId.equals(other.customerId))
+            return false;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        if (type == null) {
+            if (other.type != null)
+                return false;
+        } else if (!type.equals(other.type))
+            return false;
+        if (tenantId == null) {
+            if (other.tenantId != null)
+                return false;
+        } else if (!tenantId.equals(other.tenantId))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("AssetEntity [id=");
+        builder.append(id);
+        builder.append(", tenantId=");
+        builder.append(tenantId);
+        builder.append(", customerId=");
+        builder.append(customerId);
+        builder.append(", name=");
+        builder.append(name);
+        builder.append(", type=");
+        builder.append(type);
+        builder.append(", additionalInfo=");
+        builder.append(additionalInfo);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public Asset toData() {
+        Asset asset = new Asset(new AssetId(id));
+        asset.setCreatedTime(UUIDs.unixTimestamp(id));
+        if (tenantId != null) {
+            asset.setTenantId(new TenantId(tenantId));
+        }
+        if (customerId != null) {
+            asset.setCustomerId(new CustomerId(customerId));
+        }
+        asset.setName(name);
+        asset.setType(type);
+        asset.setAdditionalInfo(additionalInfo);
+        return asset;
+    }
+
+}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/CustomerEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/CustomerEntity.java
index 8105118..b74aa62 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/CustomerEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/CustomerEntity.java
@@ -16,15 +16,8 @@
 package org.thingsboard.server.dao.model.sql;
 
 import com.datastax.driver.core.utils.UUIDs;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-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.extern.slf4j.Slf4j;
 import org.hibernate.annotations.Type;
 import org.thingsboard.server.common.data.Customer;
 import org.thingsboard.server.common.data.id.CustomerId;
@@ -32,7 +25,7 @@ import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.dao.model.ModelConstants;
 import org.thingsboard.server.dao.model.SearchTextEntity;
 
-import java.io.IOException;
+import javax.persistence.*;
 import java.util.UUID;
 
 @Data
diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleService.java
index 1bc0d92..f7c4f6a 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleService.java
@@ -17,13 +17,11 @@ package org.thingsboard.server.dao.rule;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import org.thingsboard.server.common.data.asset.Asset;
 import org.thingsboard.server.common.data.id.RuleId;
 import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.common.data.page.TextPageData;
@@ -38,7 +36,6 @@ import org.thingsboard.server.dao.entity.BaseEntityService;
 import org.thingsboard.server.dao.exception.DataValidationException;
 import org.thingsboard.server.dao.exception.DatabaseException;
 import org.thingsboard.server.dao.exception.IncorrectParameterException;
-import org.thingsboard.server.dao.model.AssetEntity;
 import org.thingsboard.server.dao.plugin.PluginService;
 import org.thingsboard.server.dao.service.DataValidator;
 import org.thingsboard.server.dao.service.PaginatedRemover;
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
new file mode 100644
index 0000000..f14a08f
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.sql.alarm;
+
+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.alarm.Alarm;
+import org.thingsboard.server.dao.model.sql.AlarmEntity;
+
+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> {
+
+    @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")
+    AlarmEntity findLatestByOriginatorAndType(UUID tenantId, UUID originatorId, int entityType, String alarmType);
+}
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
new file mode 100644
index 0000000..f5d69cd
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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 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.alarm.Alarm;
+import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.dao.DaoUtil;
+import org.thingsboard.server.dao.alarm.AlarmDao;
+import org.thingsboard.server.dao.model.sql.AlarmEntity;
+import org.thingsboard.server.dao.sql.JpaAbstractDao;
+
+import java.util.concurrent.Executors;
+
+import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW;
+
+/**
+ * Created by Valerii Sosliuk on 5/19/2017.
+ */
+@Component
+@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
+public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements AlarmDao {
+
+    @Autowired
+    private AlarmRepository alarmRepository;
+
+    @Override
+    protected Class getEntityClass() {
+        return AlarmEntity.class;
+    }
+
+    @Override
+    protected CrudRepository getCrudRepository() {
+        return alarmRepository;
+    }
+
+    @Override
+    @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(
+                alarmRepository.findLatestByOriginatorAndType(tenantId.getId(), originator.getId(),
+                originator.getEntityType().ordinal(), type)));
+        return listenableFuture;
+    }
+}
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
new file mode 100644
index 0000000..cf38c02
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetRepository.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.sql.asset;
+
+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.dao.model.sql.AssetEntity;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * Created by Valerii Sosliuk on 5/21/2017.
+ */
+@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
+public interface AssetRepository extends CrudRepository<AssetEntity, UUID> {
+//
+    @Query(nativeQuery = true, value = "SELECT * FROM ASSET WHERE TENANT_ID = ?2 " +
+            "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?3, '%')) " +
+            "ORDER BY ID LIMIT ?1")
+    List<AssetEntity> findByTenantIdFirstPage(int limit, UUID tenantId, String textSearch);
+
+    @Query(nativeQuery = true, value = "SELECT * FROM ASSET WHERE TENANT_ID = ?2 " +
+            "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?3, '%')) " +
+            "AND ID > ?4 ORDER BY ID LIMIT ?1")
+    List<AssetEntity> findByTenantIdNextPage(int limit, UUID tenantId, String textSearch, UUID idOffset);
+
+    @Query(nativeQuery = true, value = "SELECT * FROM ASSET WHERE TENANT_ID = ?2 " +
+            "AND CUSTOMER_ID = ?3 " +
+            "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?4, '%')) " +
+            "ORDER BY ID LIMIT ?1")
+    List<AssetEntity> findByTenantIdAndCustomerIdFirstPage(int limit, UUID tenantId, UUID customerId, String textSearch);
+
+    @Query(nativeQuery = true, value = "SELECT * FROM ASSET WHERE TENANT_ID = ?2 " +
+            "AND CUSTOMER_ID = ?3 " +
+            "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?4, '%')) " +
+            "AND ID > ?5 ORDER BY ID LIMIT ?1")
+    List<AssetEntity> findByTenantIdAndCustomerIdNextPage(int limit, UUID tenantId, UUID customerId, String textSearch, UUID idOffset);
+
+    List<AssetEntity> findByTenantIdAndIdIn(UUID tenantId, List<UUID> assetIds);
+
+    List<AssetEntity> findByTenantIdAndCustomerIdAndIdIn(UUID tenantId, UUID customerId, List<UUID> assetIds);
+
+    AssetEntity findByTenantIdAndName(UUID tenantId, String name);
+}
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
new file mode 100644
index 0000000..2d301c2
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetDao.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.sql.asset;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+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.thingsboard.server.common.data.asset.Asset;
+import org.thingsboard.server.common.data.page.TextPageLink;
+import org.thingsboard.server.dao.DaoUtil;
+import org.thingsboard.server.dao.asset.AssetDao;
+import org.thingsboard.server.dao.model.sql.AssetEntity;
+import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+
+/**
+ * Created by Valerii Sosliuk on 5/19/2017.
+ */
+@Component
+@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false)
+public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> implements AssetDao {
+
+    @Autowired
+    private AssetRepository assetRepository;
+
+    @Override
+    protected Class getEntityClass() {
+        return AssetEntity.class;
+    }
+
+    @Override
+    protected CrudRepository getCrudRepository() {
+        return assetRepository;
+    }
+
+    @Override
+    public List<Asset> findAssetsByTenantId(UUID tenantId, TextPageLink pageLink) {
+        if (pageLink.getIdOffset() == null) {
+            return DaoUtil.convertDataList(assetRepository.findByTenantIdFirstPage(pageLink.getLimit(), tenantId,
+                    pageLink.getTextSearch()));
+        } else {
+            return DaoUtil.convertDataList(assetRepository.findByTenantIdNextPage(pageLink.getLimit(), tenantId,
+                    pageLink.getTextSearch(), pageLink.getIdOffset()));
+        }
+    }
+
+    @Override
+    public ListenableFuture<List<Asset>> findAssetsByTenantIdAndIdsAsync(UUID tenantId, List<UUID> assetIds) {
+        ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
+        return service.submit(() ->
+                DaoUtil.convertDataList(assetRepository.findByTenantIdAndIdIn(tenantId, assetIds)));
+    }
+
+    @Override
+    public List<Asset> findAssetsByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) {
+        if (pageLink.getIdOffset() == null) {
+            return DaoUtil.convertDataList(assetRepository.findByTenantIdAndCustomerIdFirstPage(pageLink.getLimit(), tenantId,
+                    customerId, pageLink.getTextSearch()));
+        } else {
+            return DaoUtil.convertDataList(assetRepository.findByTenantIdAndCustomerIdNextPage(pageLink.getLimit(), tenantId,
+                    customerId, pageLink.getTextSearch(), pageLink.getIdOffset()));
+        }
+    }
+
+    @Override
+    public ListenableFuture<List<Asset>> findAssetsByTenantIdAndCustomerIdAndIdsAsync(UUID tenantId, UUID customerId, List<UUID> assetIds) {
+        ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
+        return service.submit(() ->
+                DaoUtil.convertDataList( assetRepository.findByTenantIdAndCustomerIdAndIdIn(tenantId, customerId, assetIds)));
+    }
+
+    @Override
+    public Optional<Asset> findAssetsByTenantIdAndName(UUID tenantId, String name) {
+        Asset asset = DaoUtil.getData(assetRepository.findByTenantIdAndName(tenantId, name));
+        return Optional.ofNullable(asset);
+    }
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java
index b26be06..83e2dba 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java
@@ -40,4 +40,6 @@ public interface CustomerRepository extends CrudRepository<CustomerEntity, UUID>
             "AND ID > ?4 ORDER BY ID LIMIT ?1")
     List<CustomerEntity> findByTenantIdNextPage(int limit, UUID tenantId, String textSearch, UUID idOffset);
 
+    CustomerEntity findByTenantIdAndTitle(UUID tenantId, String title);
+
 }
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java
index 9b6c4d1..41fd310 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java
@@ -63,7 +63,7 @@ public class JpaCustomerDao extends JpaAbstractSearchTextDao<CustomerEntity, Cus
 
     @Override
     public Optional<Customer> findCustomersByTenantIdAndTitle(UUID tenantId, String title) {
-        // TODO: vsosliuk implement
-        return null;
+        Customer customer = DaoUtil.getData(customerRepository.findByTenantIdAndTitle(tenantId, title));
+        return Optional.ofNullable(customer);
     }
 }
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 f32c9ce..7073b49 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,7 @@ 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 it be a field?
+        // 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/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDaoTest.java
new file mode 100644
index 0000000..94b6f51
--- /dev/null
+++ b/dao/src/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDaoTest.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.sql.alarm;
+
+import com.datastax.driver.core.utils.UUIDs;
+import com.github.springtestdbunit.annotation.DatabaseSetup;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.thingsboard.server.common.data.EntityType;
+import org.thingsboard.server.common.data.alarm.Alarm;
+import org.thingsboard.server.common.data.alarm.AlarmId;
+import org.thingsboard.server.common.data.alarm.AlarmStatus;
+import org.thingsboard.server.common.data.id.DeviceId;
+import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.dao.AbstractJpaDaoTest;
+import org.thingsboard.server.dao.alarm.AlarmDao;
+import org.thingsboard.server.dao.model.sql.AlarmEntity;
+
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Created by Valerii Sosliuk on 5/21/2017.
+ */
+public class JpaAlarmDaoTest extends AbstractJpaDaoTest {
+
+    @Autowired
+    private AlarmDao alarmDao;
+
+    @Autowired
+    private AlarmRepository alarmRepository;
+
+    @Test
+    public void testFindLatestByOriginatorAndType() throws ExecutionException, InterruptedException {
+        System.out.println(System.currentTimeMillis());
+        UUID tenantId = UUID.fromString("d4b68f40-3e96-11e7-a884-898080180d6b");
+        UUID originator1Id = UUID.fromString("d4b68f41-3e96-11e7-a884-898080180d6b");
+        UUID originator2Id = UUID.fromString("d4b68f42-3e96-11e7-a884-898080180d6b");
+        UUID alarm1Id = UUID.fromString("d4b68f43-3e96-11e7-a884-898080180d6b");
+        UUID alarm2Id = UUID.fromString("d4b68f44-3e96-11e7-a884-898080180d6b");
+        UUID alarm3Id = UUID.fromString("d4b68f45-3e96-11e7-a884-898080180d6b");
+        saveAlarm(alarm1Id, tenantId, originator1Id, "TEST_ALARM");
+        saveAlarm(alarm2Id, tenantId, originator1Id, "TEST_ALARM");
+        saveAlarm(alarm3Id, tenantId, originator2Id, "TEST_ALARM");
+        assertEquals(3, alarmDao.find().size());
+        AlarmEntity alarmEntity = alarmRepository.findLatestByOriginatorAndType(
+                tenantId, originator1Id, EntityType.DEVICE.ordinal(), "TEST_ALARM");
+        assertNotNull(alarmEntity);
+        ListenableFuture<Alarm> future = alarmDao
+                .findLatestByOriginatorAndType(new TenantId(tenantId), new DeviceId(originator1Id), "TEST_ALARM");
+        Alarm alarm = future.get();
+        assertNotNull(alarm);
+        assertEquals(alarm2Id, alarm.getId().getId());
+    }
+
+    private void saveAlarm(UUID id, UUID tenantId, UUID deviceId, String type) {
+        Alarm alarm = new Alarm();
+        alarm.setId(new AlarmId(id));
+        alarm.setTenantId(new TenantId(tenantId));
+        alarm.setOriginator(new DeviceId(deviceId));
+        alarm.setType(type);
+        alarm.setPropagate(true);
+        alarm.setStartTs(System.currentTimeMillis());
+        alarm.setEndTs(System.currentTimeMillis());
+        alarm.setStatus(AlarmStatus.ACTIVE_UNACK);
+        alarmDao.save(alarm);
+    }
+}
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
new file mode 100644
index 0000000..ebee17e
--- /dev/null
+++ b/dao/src/test/java/org/thingsboard/server/dao/sql/asset/JpaAssetDaoTest.java
@@ -0,0 +1,173 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.sql.asset;
+
+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.asset.Asset;
+import org.thingsboard.server.common.data.id.AssetId;
+import org.thingsboard.server.common.data.id.CustomerId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.page.TextPageLink;
+import org.thingsboard.server.dao.AbstractJpaDaoTest;
+import org.thingsboard.server.dao.asset.AssetDao;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import static junit.framework.TestCase.assertFalse;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Created by Valerii Sosliuk on 5/21/2017.
+ */
+public class JpaAssetDaoTest extends AbstractJpaDaoTest {
+
+    @Autowired
+    private AssetDao assetDao;
+
+    @Test
+    public void testFindAssetsByTenantId() {
+        UUID tenantId1 = UUIDs.timeBased();
+        UUID tenantId2 = UUIDs.timeBased();
+        UUID customerId1 = UUIDs.timeBased();
+        UUID customerId2 = UUIDs.timeBased();
+        for (int i = 0; i < 60; i++) {
+            UUID assetId = UUIDs.timeBased();
+            UUID tenantId = i % 2 == 0 ? tenantId1 : tenantId2;
+            UUID customerId = i % 2 == 0 ? customerId1 : customerId2;
+            saveAsset(assetId, tenantId, customerId, "ASSET_" + i);
+        }
+        assertEquals(60, assetDao.find().size());
+
+        TextPageLink pageLink1 = new TextPageLink(20, "ASSET_");
+        List<Asset> assets1 = assetDao.findAssetsByTenantId(tenantId1, pageLink1);
+        assertEquals(20, assets1.size());
+
+        TextPageLink pageLink2 = new TextPageLink(20, "ASSET_", assets1.get(19).getId().getId(), null);
+        List<Asset> assets2 = assetDao.findAssetsByTenantId(tenantId1, pageLink2);
+        assertEquals(10, assets2.size());
+
+        TextPageLink pageLink3 = new TextPageLink(20, "ASSET_", assets2.get(9).getId().getId(), null);
+        List<Asset> assets3 = assetDao.findAssetsByTenantId(tenantId1, pageLink3);
+        assertEquals(0, assets3.size());
+    }
+
+    @Test
+    public void testFindAssetsByTenantIdAndCustomerId() {
+        UUID tenantId1 = UUIDs.timeBased();
+        UUID tenantId2 = UUIDs.timeBased();
+        UUID customerId1 = UUIDs.timeBased();
+        UUID customerId2 = UUIDs.timeBased();
+        for (int i = 0; i < 60; i++) {
+            UUID assetId = UUIDs.timeBased();
+            UUID tenantId = i % 2 == 0 ? tenantId1 : tenantId2;
+            UUID customerId = i % 2 == 0 ? customerId1 : customerId2;
+            saveAsset(assetId, tenantId, customerId, "ASSET_" + i);
+        }
+
+        TextPageLink pageLink1 = new TextPageLink(20, "ASSET_");
+        List<Asset> assets1 = assetDao.findAssetsByTenantIdAndCustomerId(tenantId1, customerId1, pageLink1);
+        assertEquals(20, assets1.size());
+
+        TextPageLink pageLink2 = new TextPageLink(20, "ASSET_", assets1.get(19).getId().getId(), null);
+        List<Asset> assets2 = assetDao.findAssetsByTenantIdAndCustomerId(tenantId1, customerId1, pageLink2);
+        assertEquals(10, assets2.size());
+
+        TextPageLink pageLink3 = new TextPageLink(20, "ASSET_", assets2.get(9).getId().getId(), null);
+        List<Asset> assets3 = assetDao.findAssetsByTenantIdAndCustomerId(tenantId1, customerId1, pageLink3);
+        assertEquals(0, assets3.size());
+    }
+
+    @Test
+    public void testFindAssetsByTenantIdAndIdsAsync() throws ExecutionException, InterruptedException {
+        UUID tenantId = UUIDs.timeBased();
+        UUID customerId = UUIDs.timeBased();
+        List<UUID> searchIds = new ArrayList<>();
+        for (int i = 0; i < 30; i++) {
+            UUID assetId = UUIDs.timeBased();
+            saveAsset(assetId, tenantId, customerId, "ASSET_" + i);
+            if (i % 3 == 0) {
+                searchIds.add(assetId);
+            }
+        }
+
+        ListenableFuture<List<Asset>> assetsFuture = assetDao
+                .findAssetsByTenantIdAndIdsAsync(tenantId, searchIds);
+        List<Asset> assets = assetsFuture.get();
+        assertNotNull(assets);
+        assertEquals(10, assets.size());
+    }
+
+    @Test
+    public void testFindAssetsByTenantIdCustomerIdAndIdsAsync() throws ExecutionException, InterruptedException {
+        UUID tenantId = UUIDs.timeBased();
+        UUID customerId1 = UUIDs.timeBased();
+        UUID customerId2 = UUIDs.timeBased();
+        List<UUID> searchIds = new ArrayList<>();
+        for (int i = 0; i < 30; i++) {
+            UUID assetId = UUIDs.timeBased();
+            UUID customerId = i%2 == 0 ? customerId1 : customerId2;
+            saveAsset(assetId, tenantId, customerId, "ASSET_" + i);
+            if (i % 3 == 0) {
+                searchIds.add(assetId);
+            }
+        }
+
+        ListenableFuture<List<Asset>> assetsFuture = assetDao
+                .findAssetsByTenantIdAndCustomerIdAndIdsAsync(tenantId, customerId1, searchIds);
+        List<Asset> assets = assetsFuture.get();
+        assertNotNull(assets);
+        assertEquals(5, assets.size());
+    }
+
+    @Test
+    public void testFindAssetsByTenantIdAndName() {
+        UUID assetId1 = UUIDs.timeBased();
+        UUID assetId2 = UUIDs.timeBased();
+        UUID tenantId1 = UUIDs.timeBased();
+        UUID tenantId2 = UUIDs.timeBased();
+        UUID customerId1 = UUIDs.timeBased();
+        UUID customerId2 = UUIDs.timeBased();
+        String name = "TEST_ASSET";
+        saveAsset(assetId1, tenantId1, customerId1, name);
+        saveAsset(assetId2, tenantId2, customerId2, name);
+
+        Optional<Asset> assetOpt1 = assetDao.findAssetsByTenantIdAndName(tenantId2, name);
+        assertTrue("Optional expected to be non-empty", assetOpt1.isPresent());
+        assertEquals(assetId2, assetOpt1.get().getId().getId());
+
+        Optional<Asset> assetOpt2 = assetDao.findAssetsByTenantIdAndName(tenantId2, "NON_EXISTENT_NAME");
+        assertFalse("Optional expected to be empty", assetOpt2.isPresent());
+    }
+
+    private void saveAsset(UUID id, UUID tenantId, UUID customerId, String name) {
+        Asset asset = new Asset();
+        asset.setId(new AssetId(id));
+        asset.setTenantId(new TenantId(tenantId));
+        asset.setCustomerId(new CustomerId(customerId));
+        asset.setName(name);
+
+        assetDao.save(asset);
+    }
+}
diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDaoTest.java
index 5ee112a..82ceeb8 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDaoTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDaoTest.java
@@ -26,9 +26,11 @@ import org.thingsboard.server.dao.AbstractJpaDaoTest;
 import org.thingsboard.server.dao.customer.CustomerDao;
 
 import java.util.List;
+import java.util.Optional;
 import java.util.UUID;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Created by Valerii Sosliuk on 5/6/2017.
@@ -57,6 +59,19 @@ public class JpaCustomerDaoTest extends AbstractJpaDaoTest {
         assertEquals(5, customers2.size());
     }
 
+    @Test
+    public void testFindCustomersByTenantIdAndTitle() {
+        UUID tenantId = UUIDs.timeBased();
+
+        for (int i = 0; i < 10; i++) {
+            createCustomer(tenantId, i);
+        }
+
+        Optional<Customer> customerOpt = customerDao.findCustomersByTenantIdAndTitle(tenantId, "CUSTOMER_5");
+        assertTrue(customerOpt.isPresent());
+        assertEquals("CUSTOMER_5", customerOpt.get().getTitle());
+    }
+
     private void createCustomer(UUID tenantId, int index) {
         Customer customer = new Customer();
         customer.setId(new CustomerId(UUIDs.timeBased()));
diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java
index af03ac5..b0af980 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java
@@ -64,7 +64,7 @@ public class JpaBaseEventDaoTest extends AbstractJpaDaoTest {
     }
 
     @Test
-    @DatabaseSetup("classpath:dbunit/events.xml")
+    @DatabaseSetup("classpath:dbunit/event.xml")
     public void findEvent() {
         UUID tenantId = UUID.fromString("be41c7a0-31f5-11e7-9cfd-2786e6aa2046");
         UUID entityId = UUID.fromString("be41c7a1-31f5-11e7-9cfd-2786e6aa2046");
diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserDaoTest.java
index 17463ba..9ec8a68 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserDaoTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserDaoTest.java
@@ -45,14 +45,14 @@ public class JpaUserDaoTest extends AbstractJpaDaoTest {
     private UserDao userDao;
 
     @Test
-    @DatabaseSetup("classpath:dbunit/users.xml")
+    @DatabaseSetup("classpath:dbunit/user.xml")
     public void testFindAll() {
         List<User> users = userDao.find();
         assertEquals(users.size(), 5);
     }
 
     @Test
-    @DatabaseSetup("classpath:dbunit/users.xml")
+    @DatabaseSetup("classpath:dbunit/user.xml")
     public void testFindByEmail() {
         User user = userDao.findByEmail("sysadm@thingsboard.org");
         assertNotNull("User is expected to be not null", user);
@@ -97,7 +97,7 @@ public class JpaUserDaoTest extends AbstractJpaDaoTest {
     }
 
     @Test
-    @DatabaseSetup("classpath:dbunit/users.xml")
+    @DatabaseSetup("classpath:dbunit/user.xml")
     public void testSave() throws IOException {
         User user = new User();
         user.setId(new UserId(UUID.fromString("cd481534-27cc-11e7-93ae-92361f002671")));