diff --git a/dao/pom.xml b/dao/pom.xml index fddc440eea..d95521ddd0 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -56,6 +56,10 @@ ch.qos.logback logback-classic + + org.postgresql + postgresql + org.springframework spring-test diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 584beed2ed..b721780343 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -45,6 +45,7 @@ public class ModelConstants { * Cassandra user constants. */ public static final String USER_COLUMN_FAMILY_NAME = "user"; + public static final String USER_PG_HIBERNATE_COLUMN_FAMILY_NAME = "tb_user"; public static final String USER_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; public static final String USER_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY; public static final String USER_EMAIL_PROPERTY = "email"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java index 56ebc43154..b55b9b36b6 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java @@ -21,6 +21,8 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; + +import lombok.Data; import org.thingsboard.server.common.data.id.DeviceCredentialsId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.security.DeviceCredentials; @@ -30,7 +32,8 @@ import org.thingsboard.server.dao.model.ModelConstants; import java.util.UUID; -//@Entity +@Data +@Entity @Table(name = ModelConstants.DEVICE_CREDENTIALS_COLUMN_FAMILY_NAME) public final class DeviceCredentialsEntity implements BaseEntity { @@ -68,46 +71,6 @@ public final class DeviceCredentialsEntity implements BaseEntity { @@ -55,7 +61,7 @@ public final class DeviceEntity implements SearchTextEntity { private String searchText; @Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY) - private JsonNode additionalInfo; + private String additionalInfo; public DeviceEntity() { super(); @@ -72,49 +78,11 @@ public final class DeviceEntity implements SearchTextEntity { this.customerId = device.getCustomerId().getId(); } this.name = device.getName(); - this.additionalInfo = device.getAdditionalInfo(); - } - - public UUID getId() { - return id; - } - - public void setId(UUID id) { - this.id = id; - } - - public UUID getTenantId() { - return tenantId; - } - - public void setTenantId(UUID tenantId) { - this.tenantId = tenantId; - } - - public UUID getCustomerId() { - return customerId; - } - - public void setCustomerId(UUID customerId) { - this.customerId = customerId; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public JsonNode getAdditionalInfo() { - return additionalInfo; + if (additionalInfo != null) { + this.additionalInfo = device.getAdditionalInfo().toString(); + } } - public void setAdditionalInfo(JsonNode additionalInfo) { - this.additionalInfo = additionalInfo; - } - @Override public String getSearchTextSource() { return name; @@ -206,8 +174,16 @@ public final class DeviceEntity implements SearchTextEntity { device.setCustomerId(new CustomerId(customerId)); } device.setName(name); - device.setAdditionalInfo(additionalInfo); + if (additionalInfo != null) { + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = null; + try { + jsonNode = mapper.readTree(additionalInfo); + device.setAdditionalInfo(jsonNode); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } return device; } - } \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java index 9bfa663213..a0cce5ca22 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java @@ -47,16 +47,16 @@ public class EventEntity implements BaseEntity { private static final long serialVersionUID = -5717830061727466727L; @Id - @Column(name = ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ID_PROPERTY) private UUID id; - @Column(name = EVENT_TENANT_ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = EVENT_TENANT_ID_PROPERTY) private UUID tenantId; @Column(name = EVENT_ENTITY_TYPE_PROPERTY) private EntityType entityType; - @Column(name = EVENT_ENTITY_ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = EVENT_ENTITY_ID_PROPERTY) private UUID entityId; @Column(name = EVENT_TYPE_PROPERTY) diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java index 46f1e32974..1e5d1b09a1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java @@ -44,13 +44,13 @@ public class PluginMetaDataEntity implements SearchTextEntity { @Transient private static final long serialVersionUID = -6164321050824823149L; @Id - @Column(name = ModelConstants.ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.ID_PROPERTY) private UUID id; @Column(name = ModelConstants.PLUGIN_API_TOKEN_PROPERTY) private String apiToken; - @Column(name = ModelConstants.PLUGIN_TENANT_ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.PLUGIN_TENANT_ID_PROPERTY) private UUID tenantId; @Column(name = ModelConstants.PLUGIN_NAME_PROPERTY) diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java index 54b74b43cc..54359a35aa 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java @@ -48,9 +48,9 @@ public class RuleMetaDataEntity implements SearchTextEntity { @Transient private static final long serialVersionUID = -1506905644259463884L; @Id - @Column(name = ModelConstants.ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.ID_PROPERTY) private UUID id; - @Column(name = ModelConstants.RULE_TENANT_ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.RULE_TENANT_ID_PROPERTY) private UUID tenantId; @Column(name = ModelConstants.RULE_NAME_PROPERTY) private String name; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java index aa388d23d0..6a2e8a066b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java @@ -45,7 +45,7 @@ public final class TenantEntity implements SearchTextEntity { private static final long serialVersionUID = -4330655990232136337L; @Id - @Column(name = ModelConstants.ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.ID_PROPERTY) private UUID id; @Column(name = ModelConstants.TENANT_TITLE_PROPERTY) diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java index b750ecea00..8e228d5056 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java @@ -41,10 +41,10 @@ public final class UserCredentialsEntity implements BaseEntity private static final long serialVersionUID = -3989724854149114846L; @Id - @Column(name = ModelConstants.ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.ID_PROPERTY) private UUID id; - @Column(name = ModelConstants.USER_CREDENTIALS_USER_ID_PROPERTY, columnDefinition = "BINARY(16)", unique = true) + @Column(name = ModelConstants.USER_CREDENTIALS_USER_ID_PROPERTY, unique = true) private UUID userId; @Column(name = ModelConstants.USER_CREDENTIALS_ENABLED_PROPERTY) diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java index 9df32e3eda..c85b2aa9d9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java @@ -38,19 +38,19 @@ import java.util.UUID; @Slf4j @Data @Entity -@Table(name = ModelConstants.USER_COLUMN_FAMILY_NAME) +@Table(name = ModelConstants.USER_PG_HIBERNATE_COLUMN_FAMILY_NAME) public class UserEntity implements SearchTextEntity { @Transient private static final long serialVersionUID = -271106508790582977L; @Id - @Column(name = ModelConstants.ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.ID_PROPERTY) private UUID id; - @Column(name = ModelConstants.USER_TENANT_ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.USER_TENANT_ID_PROPERTY) private UUID tenantId; - @Column(name = ModelConstants.USER_CUSTOMER_ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.USER_CUSTOMER_ID_PROPERTY) private UUID customerId; @Column(name = ModelConstants.USER_AUTHORITY_PROPERTY) diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java index 00ff20546d..4f31e70201 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java @@ -46,11 +46,11 @@ public final class WidgetTypeEntity implements BaseEntity { private static final long serialVersionUID = -5436279069884988630L; @Id - @Column(name = ModelConstants.ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.ID_PROPERTY) private UUID id; @PartitionKey(value = 1) - @Column(name = ModelConstants.WIDGET_TYPE_TENANT_ID_PROPERTY, columnDefinition = "BINARY(16)") + @Column(name = ModelConstants.WIDGET_TYPE_TENANT_ID_PROPERTY) private UUID tenantId; @PartitionKey(value = 2) diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java index 92f2e414da..3e72606885 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java @@ -42,10 +42,10 @@ public final class WidgetsBundleEntity implements SearchTextEntity, D> implements Dao< } @Override + @Transactional(propagation = REQUIRES_NEW) public D save(D domain) { E entity; try { @@ -80,6 +84,7 @@ public abstract class JpaAbstractDao, D> implements Dao< } @Override + @Transactional(propagation = REQUIRES_NEW) public boolean removeById(UUID key) { getCrudRepository().delete(key); log.debug("Remove request: {}", key); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceCredentialsRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceCredentialsRepository.java new file mode 100644 index 0000000000..cc0f6003fb --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceCredentialsRepository.java @@ -0,0 +1,19 @@ +package org.thingsboard.server.dao.sql.device; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Component; +import org.thingsboard.server.dao.model.sql.DeviceCredentialsEntity; + +import java.util.UUID; + +/** + * Created by Valerii Sosliuk on 5/6/2017. + */ +@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false) +public interface DeviceCredentialsRepository extends CrudRepository { + + DeviceCredentialsEntity findByDeviceId(UUID deviceId); + + DeviceCredentialsEntity findByCredentialsId(String credentialsId); +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java new file mode 100644 index 0000000000..486305b405 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java @@ -0,0 +1,47 @@ +package org.thingsboard.server.dao.sql.device; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.scheduling.annotation.Async; +import org.springframework.util.concurrent.ListenableFuture; +import org.thingsboard.server.dao.model.sql.DeviceEntity; + +import java.util.List; +import java.util.UUID; + +/** + * Created by Valerii Sosliuk on 5/6/2017. + */ +@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false) +public interface DeviceRepository extends CrudRepository { + + @Query(nativeQuery = true, value = "SELECT * FROM DEVICE WHERE TENANT_ID = ?2 " + + "AND CUSTOMER_ID = ?3 " + + "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?4, '%')) " + + "ORDER BY ID LIMIT ?1") + List findByTenantIdAndCustomerIdFirstPage(int limit, UUID tenantId, UUID customerId, String searchText); + + @Query(nativeQuery = true, value = "SELECT * FROM DEVICE 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 findByTenantIdAndCustomerIdNextPage(int limit, UUID tenantId, UUID customerId, String searchText, UUID idOffset); + + @Query(nativeQuery = true, value = "SELECT * FROM DEVICE WHERE TENANT_ID = ?2 " + + "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?3, '%')) " + + "ORDER BY ID LIMIT ?1") + List findByTenantIdFirstPage(int limit, UUID tenantId, String textSearch); + + @Query(nativeQuery = true, value = "SELECT * FROM DEVICE WHERE TENANT_ID = ?2 " + + "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?3, '%')) " + + "AND ID > ?4 ORDER BY ID LIMIT ?1") + List findByTenantIdNextPage(int limit, UUID tenantId, String textSearch, UUID idOffset); + + DeviceEntity findByTenantIdAndName(UUID tenantId, String name); + + List findDevicesByTenantIdAndCustomerIdAndIdIn(UUID tenantId, UUID customerId, List deviceIds); + + List findDevicesByTenantId(UUID tenantId); + List findDevicesByTenantIdAndIdIn(UUID tenantId, List deviceIds); +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceCredentialsDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceCredentialsDao.java new file mode 100644 index 0000000000..5538d96946 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceCredentialsDao.java @@ -0,0 +1,52 @@ +package org.thingsboard.server.dao.sql.device; + +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.security.DeviceCredentials; +import org.thingsboard.server.dao.DaoUtil; +import org.thingsboard.server.dao.device.DeviceCredentialsDao; +import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.dao.model.sql.DeviceCredentialsEntity; +import org.thingsboard.server.dao.sql.JpaAbstractDao; + +import java.util.UUID; + +/** + * Created by Valerii Sosliuk on 5/6/2017. + */ +@Component +@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false) +public class JpaDeviceCredentialsDao extends JpaAbstractDao implements DeviceCredentialsDao { + + @Autowired + private DeviceCredentialsRepository deviceCredentialsRepository; + + @Override + protected Class getEntityClass() { + return DeviceCredentialsEntity.class; + } + + @Override + protected String getColumnFamilyName() { + { + return ModelConstants.DEVICE_CREDENTIALS_COLUMN_FAMILY_NAME; + } + } + + @Override + protected CrudRepository getCrudRepository() { + return deviceCredentialsRepository; + } + + @Override + public DeviceCredentials findByDeviceId(UUID deviceId) { + return DaoUtil.getData(deviceCredentialsRepository.findByDeviceId(deviceId)); + } + + @Override + public DeviceCredentials findByCredentialsId(String credentialsId) { + return DaoUtil.getData(deviceCredentialsRepository.findByCredentialsId(credentialsId)); + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java new file mode 100644 index 0000000000..eefedd0591 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java @@ -0,0 +1,91 @@ +package org.thingsboard.server.dao.sql.device; + +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.Device; +import org.thingsboard.server.common.data.page.TextPageLink; +import org.thingsboard.server.dao.DaoUtil; +import org.thingsboard.server.dao.device.DeviceDao; +import org.thingsboard.server.dao.model.sql.DeviceEntity; +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.Executors; + +import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_COLUMN_FAMILY_NAME; + +/** + * Created by Valerii Sosliuk on 5/6/2017. + */ +@Component +@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true", matchIfMissing = false) +public class JpaDeviceDao extends JpaAbstractSearchTextDao implements DeviceDao { + + @Autowired + DeviceRepository deviceRepository; + + @Override + protected Class getEntityClass() { + return DeviceEntity.class; + } + + @Override + protected String getColumnFamilyName() { + return DEVICE_COLUMN_FAMILY_NAME; + } + + @Override + protected CrudRepository getCrudRepository() { + return deviceRepository; + } + + @Override + public List findDevicesByTenantId(UUID tenantId, TextPageLink pageLink) { + if (pageLink.getIdOffset() == null) { + return DaoUtil.convertDataList(deviceRepository.findByTenantIdFirstPage( + pageLink.getLimit(), tenantId, pageLink.getTextSearch())); + } else { + return DaoUtil.convertDataList(deviceRepository.findByTenantIdNextPage( + pageLink.getLimit(), tenantId, pageLink.getTextSearch(), pageLink.getIdOffset())); + } + } + + @Override + public ListenableFuture> findDevicesByTenantIdAndIdsAsync(UUID tenantId, List deviceIds) { + System.out.println(deviceRepository.findDevicesByTenantIdAndIdIn(tenantId, deviceIds).size()); + ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)); + return service.submit(() -> DaoUtil.convertDataList(deviceRepository.findDevicesByTenantIdAndIdIn(tenantId, deviceIds))); + } + + @Override + public List findDevicesByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) { + if (pageLink.getIdOffset() == null) { + return DaoUtil.convertDataList(deviceRepository.findByTenantIdAndCustomerIdFirstPage(pageLink.getLimit(), + tenantId, customerId, pageLink.getTextSearch())); + } else { + return DaoUtil.convertDataList(deviceRepository.findByTenantIdAndCustomerIdNextPage(pageLink.getLimit(), + tenantId, customerId, pageLink.getTextSearch(), pageLink.getIdOffset())); + } + } + + @Override + public ListenableFuture> findDevicesByTenantIdCustomerIdAndIdsAsync(UUID tenantId, UUID customerId, List deviceIds) { + ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)); + return service.submit(() -> DaoUtil.convertDataList( + deviceRepository.findDevicesByTenantIdAndCustomerIdAndIdIn(tenantId, customerId, deviceIds))); + } + + @Override + // Probably findDevice, not findDevices? + public Optional findDevicesByTenantIdAndName(UUID tenantId, String name) { + Device device = DaoUtil.getData(deviceRepository.findByTenantIdAndName(tenantId, name)); + return Optional.ofNullable(device); + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java index de32f06f1d..585bf38335 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java @@ -31,22 +31,22 @@ public interface UserRepository extends CrudRepository { UserEntity findByEmail(String email); - @Query(nativeQuery = true, value = "SELECT * FROM USER WHERE TENANT_ID = ?2 " + + @Query(nativeQuery = true, value = "SELECT * FROM TB_USER WHERE TENANT_ID = ?2 " + "AND CUSTOMER_ID IS NULL AND AUTHORITY = 1 " + "ORDER BY ID LIMIT ?1") List findTenantAdminsFirstPage(int limit, UUID tenantId); - @Query(nativeQuery = true, value = "SELECT * FROM USER WHERE TENANT_ID = ?2 " + + @Query(nativeQuery = true, value = "SELECT * FROM TB_USER WHERE TENANT_ID = ?2 " + "AND CUSTOMER_ID IS NULL AND AUTHORITY = 1 " + "AND ID > ?3 ORDER BY ID LIMIT ?1") List findTenantAdminsNextPage(int limit, UUID tenantId, UUID idOffset); - @Query(nativeQuery = true, value = "SELECT * FROM USER WHERE TENANT_ID = ?2 " + + @Query(nativeQuery = true, value = "SELECT * FROM TB_USER WHERE TENANT_ID = ?2 " + "AND CUSTOMER_ID = ?3 AND AUTHORITY = 2 " + "ORDER BY ID LIMIT ?1") List findCustomerUsersFirstPage(int limit, UUID tenantId, UUID customerId); - @Query(nativeQuery = true, value = "SELECT * FROM USER WHERE TENANT_ID = ?2 " + + @Query(nativeQuery = true, value = "SELECT * FROM TB_USER WHERE TENANT_ID = ?2 " + "AND CUSTOMER_ID = ?3 AND AUTHORITY = 2 " + "AND ID > ?4 ORDER BY ID LIMIT ?1") List findCustomerUsersNextPage(int limit, UUID tenantId, UUID customerId, UUID idOffset); diff --git a/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java index e610245f96..f6b6b7353b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java @@ -16,6 +16,7 @@ package org.thingsboard.server.dao; import com.github.springtestdbunit.DbUnitTestExecutionListener; +import com.github.springtestdbunit.annotation.DbUnitConfiguration; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestExecutionListeners; @@ -29,11 +30,12 @@ import org.springframework.test.context.support.DirtiesContextTestExecutionListe * Created by Valerii Sosliuk on 4/22/2017. */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = {JpaDaoConfig.class}) +@ContextConfiguration(classes = {JpaDaoConfig.class, JpaDbunitTestConfig.class}) @TestPropertySource("classpath:jpa-test.properties") @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, DbUnitTestExecutionListener.class }) +@DbUnitConfiguration(databaseConnection = "dbUnitDatabaseConnection") public class AbstractJpaDaoTest extends AbstractTransactionalJUnit4SpringContextTests { } diff --git a/dao/src/test/java/org/thingsboard/server/dao/JpaDbunitTestConfig.java b/dao/src/test/java/org/thingsboard/server/dao/JpaDbunitTestConfig.java new file mode 100644 index 0000000000..0c064d4697 --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/JpaDbunitTestConfig.java @@ -0,0 +1,39 @@ +package org.thingsboard.server.dao; + +import com.github.springtestdbunit.bean.DatabaseConfigBean; +import com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean; +import org.dbunit.DatabaseUnitException; +import org.dbunit.ext.postgresql.PostgresqlDataTypeFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.SQLException; + +/** + * Created by Valerii Sosliuk on 5/6/2017. + */ +@Configuration +public class JpaDbunitTestConfig { + + @Autowired + private DataSource dataSource; + + @Bean + public DatabaseConfigBean databaseConfigBean() { + DatabaseConfigBean databaseConfigBean = new DatabaseConfigBean(); + databaseConfigBean.setDatatypeFactory(new PostgresqlDataTypeFactory()); + return databaseConfigBean; + } + + @Bean(name = "dbUnitDatabaseConnection") + public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection() throws SQLException, DatabaseUnitException, IOException { + DatabaseDataSourceConnectionFactoryBean databaseDataSourceConnectionFactoryBean = new DatabaseDataSourceConnectionFactoryBean(); + databaseDataSourceConnectionFactoryBean.setDatabaseConfig(databaseConfigBean()); + databaseDataSourceConnectionFactoryBean.setDataSource(dataSource); + databaseDataSourceConnectionFactoryBean.setSchema("public"); + return databaseDataSourceConnectionFactoryBean; + } +} diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/device/JpaDeviceCredentialsDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/device/JpaDeviceCredentialsDaoTest.java new file mode 100644 index 0000000000..dce6113e3e --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/device/JpaDeviceCredentialsDaoTest.java @@ -0,0 +1,41 @@ +package org.thingsboard.server.dao.sql.device; + +import com.github.springtestdbunit.annotation.DatabaseSetup; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.dao.AbstractJpaDaoTest; +import org.thingsboard.server.dao.device.DeviceCredentialsDao; + +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Created by Valerii Sosliuk on 5/6/2017. + */ +public class JpaDeviceCredentialsDaoTest extends AbstractJpaDaoTest { + + @Autowired + DeviceCredentialsDao deviceCredentialsDao; + + @Test + @DatabaseSetup("classpath:dbunit/device_credentials.xml") + public void testFindByDeviceId() { + UUID deviceId = UUID.fromString("958e3a30-3215-11e7-93ae-92361f002671"); + DeviceCredentials deviceCredentials = deviceCredentialsDao.findByDeviceId(deviceId); + assertNotNull(deviceCredentials); + assertEquals("958e3314-3215-11e7-93ae-92361f002671", deviceCredentials.getId().getId().toString()); + assertEquals("ID_1", deviceCredentials.getCredentialsId()); + } + + @Test + @DatabaseSetup("classpath:dbunit/device_credentials.xml") + public void findByCredentialsId() { + String credentialsId = "ID_2"; + DeviceCredentials deviceCredentials = deviceCredentialsDao.findByCredentialsId(credentialsId); + assertNotNull(deviceCredentials); + assertEquals("958e3c74-3215-11e7-93ae-92361f002671", deviceCredentials.getId().getId().toString()); + } +} diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/device/JpaDeviceDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/device/JpaDeviceDaoTest.java new file mode 100644 index 0000000000..4f1b31598a --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/device/JpaDeviceDaoTest.java @@ -0,0 +1,146 @@ +package org.thingsboard.server.dao.sql.device; + +import com.datastax.driver.core.utils.UUIDs; +import com.github.springtestdbunit.annotation.DatabaseOperation; +import com.github.springtestdbunit.annotation.DatabaseSetup; +import com.github.springtestdbunit.annotation.DatabaseTearDown; +import com.google.common.util.concurrent.*; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DeviceId; +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.device.DeviceDao; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Created by Valerii Sosliuk on 5/6/2017. + */ +@Transactional +public class JpaDeviceDaoTest extends AbstractJpaDaoTest { + + @Autowired + private DeviceDao deviceDao; + + @Test + @DatabaseSetup(value = "classpath:dbunit/empty_dataset.xml",type = DatabaseOperation.DELETE_ALL) + @DatabaseTearDown(value = "classpath:dbunit/empty_dataset.xml",type = DatabaseOperation.DELETE_ALL) + public void testFindDevicesByTenantId() { + UUID tenantId1 = UUIDs.timeBased(); + UUID tenantId2 = UUIDs.timeBased(); + UUID customerId1 = UUIDs.timeBased(); + UUID customerId2 = UUIDs.timeBased(); + createDevices(tenantId1, tenantId2, customerId1, customerId2, 40); + + TextPageLink pageLink1 = new TextPageLink(15, "SEARCH_TEXT"); + List devices1 = deviceDao.findDevicesByTenantId(tenantId1, pageLink1); + assertEquals(15, devices1.size()); + + TextPageLink pageLink2 = new TextPageLink(15, "SEARCH_TEXT", devices1.get(14).getId().getId(), null); + List devices2 = deviceDao.findDevicesByTenantId(tenantId1, pageLink2); + assertEquals(5, devices2.size()); + } + + @Test + @DatabaseSetup(value = "classpath:dbunit/empty_dataset.xml",type = DatabaseOperation.DELETE_ALL) + @DatabaseTearDown(value = "classpath:dbunit/empty_dataset.xml",type = DatabaseOperation.DELETE_ALL) + public void testFindAsync() throws ExecutionException, InterruptedException { + UUID tenantId = UUIDs.timeBased(); + UUID customerId = UUIDs.timeBased(); + Device device = getDevice(tenantId, customerId); + deviceDao.save(device); + + UUID uuid = device.getId().getId(); + Device entity = deviceDao.findById(uuid); + assertNotNull(entity); + assertEquals(uuid, entity.getId().getId()); + + ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)); + ListenableFuture future = service.submit(() -> deviceDao.findById(uuid)); + Device asyncDevice = future.get(); + assertNotNull("Async device expected to be not null", asyncDevice); + } + + @Test + @DatabaseSetup(value = "classpath:dbunit/empty_dataset.xml",type = DatabaseOperation.DELETE_ALL) + @DatabaseTearDown(value = "classpath:dbunit/empty_dataset.xml",type = DatabaseOperation.DELETE_ALL) + public void testFindDevicesByTenantIdAndIdsAsync() throws ExecutionException, InterruptedException { + UUID tenantId1 = UUIDs.timeBased(); + UUID customerId1 = UUIDs.timeBased(); + UUID tenantId2 = UUIDs.timeBased(); + UUID customerId2 = UUIDs.timeBased(); + + List deviceIds = new ArrayList<>(); + + for(int i = 0; i < 5; i++) { + UUID deviceId1 = UUIDs.timeBased(); + UUID deviceId2 = UUIDs.timeBased(); + deviceDao.save(getDevice(tenantId1, customerId1, deviceId1)); + deviceDao.save(getDevice(tenantId2, customerId2, deviceId2)); + deviceIds.add(deviceId1); + deviceIds.add(deviceId2); + } + + ListenableFuture> devicesFuture = deviceDao.findDevicesByTenantIdAndIdsAsync(tenantId1, deviceIds); + List devices = devicesFuture.get(); + assertEquals(5, devices.size()); + } + + @Test + @DatabaseSetup(value = "classpath:dbunit/empty_dataset.xml",type = DatabaseOperation.DELETE_ALL) + @DatabaseTearDown(value = "classpath:dbunit/empty_dataset.xml",type = DatabaseOperation.DELETE_ALL) + public void testFindDevicesByTenantIdAndCustomerIdAndIdsAsync() throws ExecutionException, InterruptedException { + UUID tenantId1 = UUIDs.timeBased(); + UUID customerId1 = UUIDs.timeBased(); + UUID tenantId2 = UUIDs.timeBased(); + UUID customerId2 = UUIDs.timeBased(); + + List deviceIds = new ArrayList<>(); + + for(int i = 0; i < 20; i++) { + UUID deviceId1 = UUIDs.timeBased(); + UUID deviceId2 = UUIDs.timeBased(); + deviceDao.save(getDevice(tenantId1, customerId1, deviceId1)); + deviceDao.save(getDevice(tenantId2, customerId2, deviceId2)); + deviceIds.add(deviceId1); + deviceIds.add(deviceId2); + } + + ListenableFuture> devicesFuture = deviceDao.findDevicesByTenantIdCustomerIdAndIdsAsync(tenantId1, customerId1, deviceIds); + List devices = devicesFuture.get(); + assertEquals(20, devices.size()); + } + + private void createDevices(UUID tenantId1, UUID tenantId2, UUID customerId1, UUID customerId2, int count) { + for (int i = 0; i < count / 2; i++) { + deviceDao.save(getDevice(tenantId1, customerId1)); + deviceDao.save(getDevice(tenantId2, customerId2)); + } + } + + private Device getDevice(UUID tenantId, UUID customerID) { + return getDevice(tenantId, customerID, UUIDs.timeBased()); + } + + private Device getDevice(UUID tenantId, UUID customerID, UUID deviceId) { + Device device = new Device(); + device.setId(new DeviceId(deviceId)); + device.setTenantId(new TenantId(tenantId)); + device.setCustomerId(new CustomerId(customerID)); + device.setName("SEARCH_TEXT"); + return device; + } +} 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 cdebaddb51..30667faba6 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 @@ -1,6 +1,5 @@ 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; @@ -18,8 +17,6 @@ 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; diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDaoTest.java index f968b68e6e..31a6c58376 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDaoTest.java @@ -23,7 +23,6 @@ import org.thingsboard.server.common.data.id.PluginId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.plugin.PluginMetaData; -import org.thingsboard.server.common.data.rule.RuleMetaData; import org.thingsboard.server.dao.AbstractJpaDaoTest; import org.thingsboard.server.dao.plugin.PluginDao; 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 fe540fa017..9d719ba4bd 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 @@ -71,7 +71,6 @@ public class JpaUserDaoTest extends AbstractJpaDaoTest { UUID tenantId = UUIDs.timeBased(); UUID customerId = UUIDs.timeBased(); create30Adminsand60Users(tenantId, customerId); - assertEquals(90, userDao.find().size()); List tenantAdmins1 = userDao.findTenantAdmins(tenantId, new TextPageLink(20)); assertEquals(20, tenantAdmins1.size()); List tenantAdmins2 = userDao.findTenantAdmins(tenantId, @@ -88,7 +87,6 @@ public class JpaUserDaoTest extends AbstractJpaDaoTest { UUID tenantId = UUIDs.timeBased(); UUID customerId = UUIDs.timeBased(); create30Adminsand60Users(tenantId, customerId); - assertEquals(90, userDao.find().size()); List customerUsers1 = userDao.findCustomerUsers(tenantId, customerId, new TextPageLink(40)); assertEquals(40, customerUsers1.size()); List customerUsers2 = userDao.findCustomerUsers(tenantId, customerId, diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDaoTest.java index c38ccbd892..87ce37a1a6 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDaoTest.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.dao.sql.widget; -import com.datastax.driver.core.utils.UUIDs; import com.github.springtestdbunit.annotation.DatabaseSetup; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java index eafcfd3820..7c1df06203 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java @@ -16,7 +16,9 @@ package org.thingsboard.server.dao.sql.widget; import com.datastax.driver.core.utils.UUIDs; +import com.github.springtestdbunit.annotation.DatabaseOperation; import com.github.springtestdbunit.annotation.DatabaseSetup; +import com.github.springtestdbunit.annotation.DatabaseTearDown; import org.junit.Ignore; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -41,13 +43,15 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest { private WidgetsBundleDao widgetsBundleDao; @Test - @DatabaseSetup("classpath:dbunit/widgets_bundle.xml") + @DatabaseSetup(value = "classpath:dbunit/widgets_bundle.xml",type= DatabaseOperation.CLEAN_INSERT) + @DatabaseTearDown(value = "classpath:dbunit/widgets_bundle.xml", type= DatabaseOperation.DELETE_ALL) public void testFindAll() { assertEquals(7, widgetsBundleDao.find().size()); } @Test - @DatabaseSetup("classpath:dbunit/widgets_bundle.xml") + @DatabaseSetup(value = "classpath:dbunit/widgets_bundle.xml",type= DatabaseOperation.CLEAN_INSERT) + @DatabaseTearDown(value = "classpath:dbunit/widgets_bundle.xml", type= DatabaseOperation.DELETE_ALL) public void testFindWidgetsBundleByTenantIdAndAlias() { WidgetsBundle widgetsBundle = widgetsBundleDao.findWidgetsBundleByTenantIdAndAlias( UUID.fromString("250aca8e-2825-11e7-93ae-92361f002671"), "WB3"); @@ -55,7 +59,8 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest { } @Test - @DatabaseSetup("classpath:dbunit/empty_dataset.xml") + @DatabaseSetup(value = "classpath:dbunit/widgets_bundle.xml", type= DatabaseOperation.DELETE_ALL) + // @DatabaseTearDown(value = "classpath:dbunit/empty_dataset.xml", type= DatabaseOperation.DELETE_ALL) public void testFindSystemWidgetsBundles() { createSystemWidgetBundles(30, "WB_"); assertEquals(30, widgetsBundleDao.find().size()); @@ -70,7 +75,7 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest { } @Test - @DatabaseSetup("classpath:dbunit/empty_dataset.xml") + @DatabaseSetup(value = "classpath:dbunit/widgets_bundle.xml", type= DatabaseOperation.DELETE_ALL) public void testFindWidgetsBundlesByTenantId() { UUID tenantId1 = UUIDs.timeBased(); UUID tenantId2 = UUIDs.timeBased(); @@ -97,7 +102,7 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest { } @Test - @DatabaseSetup("classpath:dbunit/empty_dataset.xml") + @DatabaseSetup(value = "classpath:dbunit/widgets_bundle.xml", type= DatabaseOperation.DELETE_ALL) public void testFindAllWidgetsBundlesByTenantId() { UUID tenantId1 = UUIDs.timeBased(); UUID tenantId2 = UUIDs.timeBased(); @@ -129,9 +134,9 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest { assertEquals(0, widgetsBundles4.size()); } - @Test @DatabaseSetup("classpath:dbunit/empty_dataset.xml") + @DatabaseTearDown(value = "classpath:dbunit/empty_dataset.xml", type= DatabaseOperation.DELETE_ALL) public void testNonSearchTextNotFound() { UUID tenantId = UUIDs.timeBased(); createWidgetBundles(5, tenantId, "ABC_"); diff --git a/dao/src/test/resources/dbunit/device_credentials.xml b/dao/src/test/resources/dbunit/device_credentials.xml new file mode 100644 index 0000000000..aee6b1ec19 --- /dev/null +++ b/dao/src/test/resources/dbunit/device_credentials.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/dao/src/test/resources/dbunit/events.xml b/dao/src/test/resources/dbunit/events.xml index 8f8875882b..2c02c19564 100644 --- a/dao/src/test/resources/dbunit/events.xml +++ b/dao/src/test/resources/dbunit/events.xml @@ -1,16 +1,16 @@ - - - - - - \ No newline at end of file diff --git a/dao/src/test/resources/jpa-test.properties b/dao/src/test/resources/jpa-test.properties index 7fff922c93..f887e08db0 100644 --- a/dao/src/test/resources/jpa-test.properties +++ b/dao/src/test/resources/jpa-test.properties @@ -1,7 +1,17 @@ cassandra.enabled=false sql.enabled=true -sql.datasource.url=jdbc:h2:mem:thingsboard -sql.datasource.username=sa -sql.datasource.password= +#sql.datasource.url=jdbc:h2:mem:thingsboard +#sql.datasource.username=sa +#sql.datasource.password= +#spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.show-sql=false +spring.jpa.hibernate.ddl-auto=create-drop + +spring.database.driverClassName=org.postgresql.Driver +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +spring.datasource.url=jdbc:postgresql://localhost:5432/thingsboard-test +spring.datasource.username=thingsboard +spring.datasource.password=thingsboard +spring.jpa.generate-ddl=true diff --git a/pom.xml b/pom.xml index 909936f074..0d813f0bfc 100755 --- a/pom.xml +++ b/pom.xml @@ -74,6 +74,7 @@ 1.4.194 2.5.3 1.2.1 + 9.4.1211 @@ -419,6 +420,11 @@ spring-boot-starter-data-jpa ${spring-boot.version} + + org.postgresql + postgresql + ${postgresql.driver.version} + org.springframework spring-context