Browse Source

Changed blobd type to json text

Added JPA support for service test
pull/152/head
Volodymyr Babak 9 years ago
parent
commit
1141a26a17
  1. 17
      application/src/test/java/org/thingsboard/server/ApplicationServerTestSuite.java
  2. 49
      application/src/test/java/org/thingsboard/server/ThingsboardApplicationTests.java
  3. 20
      application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java
  4. 1
      application/src/test/java/org/thingsboard/server/controller/AssetControllerTest.java
  5. 38
      application/src/test/java/org/thingsboard/server/controller/CassandraControllerTestSuite.java
  6. 71
      application/src/test/java/org/thingsboard/server/mqtt/AbstractFeatureIntegrationTest.java
  7. 98
      application/src/test/java/org/thingsboard/server/mqtt/rpc/MqttServerSideRpcIntegrationTest.java
  8. 31
      application/src/test/java/org/thingsboard/server/mqtt/telemetry/MqttTelemetryIntegrationTest.java
  9. 7
      application/src/test/java/org/thingsboard/server/system/SystemTestSuite.java
  10. 3
      application/src/test/resources/thingsboard-test.properties
  11. 71
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java
  12. 12
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java
  13. 86
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java
  14. 6
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvCompositeKey.java
  15. 18
      dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java
  16. 133
      dao/src/main/java/org/thingsboard/server/dao/model/sql/CustomerEntity.java
  17. 95
      dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java
  18. 77
      dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java
  19. 71
      dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java
  20. 89
      dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java
  21. 25
      dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java
  22. 47
      dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java
  23. 6
      dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationCompositeKey.java
  24. 7
      dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationEntity.java
  25. 64
      dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java
  26. 4
      dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantDeviceTypeEntity.java
  27. 147
      dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java
  28. 6
      dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvCompositeKey.java
  29. 6
      dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvLatestCompositeKey.java
  30. 64
      dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java
  31. 101
      dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java
  32. 54
      dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java
  33. 51
      dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java
  34. 10
      dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetRepository.java
  35. 8
      dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetDao.java
  36. 2
      dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/DashboardInfoRepository.java
  37. 48
      dao/src/main/java/org/thingsboard/server/dao/util/AbstractJsonSqlTypeDescriptor.java
  38. 3
      dao/src/main/java/org/thingsboard/server/dao/util/JacksonUtil.java
  39. 61
      dao/src/main/java/org/thingsboard/server/dao/util/JsonStringSqlTypeDescriptor.java
  40. 20
      dao/src/main/java/org/thingsboard/server/dao/util/JsonStringType.java
  41. 70
      dao/src/main/resources/postgres/schema.sql
  42. 106
      dao/src/main/resources/postgres/system-data.sql
  43. 4
      dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java
  44. 2
      dao/src/test/java/org/thingsboard/server/dao/plugin/BasePluginServiceTest.java
  45. 5
      dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java
  46. 188
      dao/src/test/java/org/thingsboard/server/dao/service/UserServiceImplTest.java
  47. 4
      dao/src/test/resources/application-test.properties
  48. 15
      dao/src/test/resources/jpa-test.properties
  49. 66
      extensions/extension-kafka/src/test/java/org/thingsboard/server/extensions/kafka/KafkaDemoClient.java
  50. 10
      extensions/extension-kafka/src/test/resources/logback.xml
  51. 3
      tools/test.properties
  52. 28
      transport/coap/src/test/java/org/thingsboard/server/transport/coap/CoapServerTest.java

17
application/src/test/java/org/thingsboard/server/mqtt/MqttSuite.java → application/src/test/java/org/thingsboard/server/ApplicationServerTestSuite.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.mqtt;
package org.thingsboard.server;
import org.cassandraunit.dataset.cql.ClassPathCQLDataSet;
import org.junit.ClassRule;
@ -23,19 +23,18 @@ import org.thingsboard.server.dao.CustomCassandraCQLUnit;
import java.util.Arrays;
/**
* @author Valerii Sosliuk
*/
@RunWith(ClasspathSuite.class)
@ClasspathSuite.ClassnameFilters({"org.thingsboard.server.mqtt.*.*Test"})
public class MqttSuite {
@ClasspathSuite.ClassnameFilters({
"org.thingsboard.server.controller.*Test",
"org.thingsboard.server.mqtt.*.*Test"})
public class ApplicationServerTestSuite {
@ClassRule
public static CustomCassandraCQLUnit cassandraUnit =
new CustomCassandraCQLUnit(
Arrays.asList(new ClassPathCQLDataSet("cassandra/schema.cql", false, false),
Arrays.asList(
new ClassPathCQLDataSet("cassandra/schema.cql", false, false),
new ClassPathCQLDataSet("cassandra/system-data.cql", false, false),
new ClassPathCQLDataSet("cassandra/demo-data.cql", false, false)),
new ClassPathCQLDataSet("system-test.cql", false, false)),
"cassandra-test.yaml", 30000l);
}

49
application/src/test/java/org/thingsboard/server/ThingsboardApplicationTests.java

@ -1,49 +0,0 @@
/**
* 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;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ThingsboardServerApplication.class)
@WebAppConfiguration
@IntegrationTest("server.port:0")
public class ThingsboardApplicationTests {
@Test
public void contextLoads() {
String test = "[ \n" +
" {\n" +
" \"key\": \"name\",\n" +
"\t\"type\": \"text\" \n" +
" },\n" +
" {\n" +
"\t\"key\": \"name2\",\n" +
"\t\"type\": \"color\"\n" +
" },\n" +
" {\n" +
"\t\"key\": \"name3\",\n" +
"\t\"type\": \"javascript\"\n" +
" } \n" +
"]";
}
}

20
application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java

@ -29,8 +29,8 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationContextLoader;
import org.springframework.boot.test.context.SpringBootContextLoader;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
@ -43,7 +43,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
@ -78,14 +78,14 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
@ActiveProfiles("test")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=AbstractControllerTest.class, loader=SpringApplicationContextLoader.class)
@TestPropertySource(locations = {"classpath:cassandra-test.properties", "classpath:thingsboard-test.properties"})
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = AbstractControllerTest.class, loader = SpringBootContextLoader.class)
@TestPropertySource(locations = {"classpath:cassandra-test.properties", "classpath:application-test.properties"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@Configuration
@ComponentScan({"org.thingsboard.server"})
@WebAppConfiguration
@IntegrationTest("server.port:0")
@SpringBootTest
public abstract class AbstractControllerTest {
protected static final String TEST_TENANT_NAME = "TEST TENANT";
@ -294,7 +294,7 @@ public abstract class AbstractControllerTest {
protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception {
return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass);
}
protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception {
return readResponse(doDelete(urlTemplate, params).andExpect(status().isOk()), responseClass);
}
@ -353,8 +353,8 @@ public abstract class AbstractControllerTest {
ObjectMapper mapper = new ObjectMapper();
return mapper.readerFor(type).readValue(content);
}
class IdComparator<D extends BaseData<? extends UUIDBased>> implements Comparator<D> {
public class IdComparator<D extends BaseData<? extends UUIDBased>> implements Comparator<D> {
@Override
public int compare(D o1, D o2) {
return o1.getId().getId().compareTo(o2.getId().getId());

1
application/src/test/java/org/thingsboard/server/controller/AssetControllerTest.java

@ -28,7 +28,6 @@ import org.thingsboard.server.common.data.*;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.TenantAssetType;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.security.Authority;

38
application/src/test/java/org/thingsboard/server/controller/CassandraControllerTestSuite.java

@ -1,38 +0,0 @@
/**
* 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.controller;
import org.cassandraunit.dataset.cql.ClassPathCQLDataSet;
import org.junit.ClassRule;
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.extensions.cpsuite.ClasspathSuite.ClassnameFilters;
import org.junit.runner.RunWith;
import org.thingsboard.server.dao.CustomCassandraCQLUnit;
import java.util.Arrays;
@RunWith(ClasspathSuite.class)
@ClassnameFilters({"org.thingsboard.server.controller.*Test"})
public class CassandraControllerTestSuite {
@ClassRule
public static CustomCassandraCQLUnit cassandraUnit =
new CustomCassandraCQLUnit(Arrays.asList(
new ClassPathCQLDataSet("cassandra/schema.cql", false, false),
new ClassPathCQLDataSet("cassandra/system-data.cql", false, false),
new ClassPathCQLDataSet("system-test.cql", false, false)),
"cassandra-test.yaml", 30000l);
}

71
application/src/test/java/org/thingsboard/server/mqtt/AbstractFeatureIntegrationTest.java

@ -1,71 +0,0 @@
/**
* 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.mqtt;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationContextLoader;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.context.WebApplicationContext;
import org.thingsboard.server.mqtt.telemetry.MqttTelemetryIntergrationTest;
import java.util.Arrays;
import static org.junit.Assert.assertNotNull;
/**
* @author Valerii Sosliuk
*/
@ActiveProfiles("default")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes= MqttTelemetryIntergrationTest.class, loader=SpringApplicationContextLoader.class)
@TestPropertySource(locations = {"classpath:cassandra-test.properties", "classpath:thingsboard-test.properties"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@Configuration
@ComponentScan({"org.thingsboard.server"})
@WebAppConfiguration
@IntegrationTest("server.port:8080")
public class AbstractFeatureIntegrationTest {
@SuppressWarnings("rawtypes")
private HttpMessageConverter mappingJackson2HttpMessageConverter;
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
void setConverters(HttpMessageConverter<?>[] converters) {
this.mappingJackson2HttpMessageConverter = Arrays.stream(converters)
.filter(hmc -> hmc instanceof MappingJackson2HttpMessageConverter)
.findAny()
.get();
assertNotNull("the JSON message converter must not be null",
this.mappingJackson2HttpMessageConverter);
}
}

98
application/src/test/java/org/thingsboard/server/mqtt/rpc/MqttServerSideRpcIntegrationTest.java

@ -17,47 +17,67 @@ package org.thingsboard.server.mqtt.rpc;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.thingsboard.client.tools.RestClient;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.mqtt.AbstractFeatureIntegrationTest;
import org.thingsboard.server.controller.AbstractControllerTest;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Valerii Sosliuk
*/
@Slf4j
public class MqttServerSideRpcIntegrationTest extends AbstractFeatureIntegrationTest {
public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest {
private static final String MQTT_URL = "tcp://localhost:1883";
private static final String BASE_URL = "http://localhost:8080";
private static final String FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED = "HttpClientErrorException expected, but not encountered";
private static final String USERNAME = "tenant@thingsboard.org";
private static final String PASSWORD = "tenant";
private RestClient restClient;
private Tenant savedTenant;
private User tenantAdmin;
@Before
public void beforeTest() throws Exception {
restClient = new RestClient(BASE_URL);
restClient.login(USERNAME, PASSWORD);
loginSysAdmin();
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
savedTenant = doPost("/api/tenant", tenant, Tenant.class);
Assert.assertNotNull(savedTenant);
tenantAdmin = new User();
tenantAdmin.setAuthority(Authority.TENANT_ADMIN);
tenantAdmin.setTenantId(savedTenant.getId());
tenantAdmin.setEmail("tenant2@thingsboard.org");
tenantAdmin.setFirstName("Joe");
tenantAdmin.setLastName("Downs");
createUserAndLogin(tenantAdmin, "testPassword1");
}
@After
public void afterTest() throws Exception {
loginSysAdmin();
doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk());
}
@Test
@Ignore
public void testServerMqttOneWayRpc() throws Exception {
Device device = new Device();
device.setName("Test One-Way Server-Side RPC");
device.setType("default");
Device savedDevice = getSavedDevice(device);
DeviceCredentials deviceCredentials = getDeviceCredentials(savedDevice);
assertEquals(savedDevice.getId(), deviceCredentials.getDeviceId());
@ -69,22 +89,22 @@ public class MqttServerSideRpcIntegrationTest extends AbstractFeatureIntegration
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(accessToken);
client.connect(options);
Thread.sleep(3000);
client.connect(options).waitForCompletion();
client.subscribe("v1/devices/me/rpc/request/+", 1);
client.setCallback(new TestMqttCallback(client));
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String deviceId = savedDevice.getId().getId().toString();
ResponseEntity result = restClient.getRestTemplate().postForEntity(BASE_URL + "api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class);
Assert.assertEquals(HttpStatus.OK, result.getStatusCode());
Assert.assertNull(result.getBody());
String result = doPost("api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class);
Assert.assertNull(result);
}
@Test
@Ignore
public void testServerMqttOneWayRpcDeviceOffline() throws Exception {
Device device = new Device();
device.setName("Test One-Way Server-Side RPC Device Offline");
device.setType("default");
Device savedDevice = getSavedDevice(device);
DeviceCredentials deviceCredentials = getDeviceCredentials(savedDevice);
assertEquals(savedDevice.getId(), deviceCredentials.getDeviceId());
@ -94,8 +114,8 @@ public class MqttServerSideRpcIntegrationTest extends AbstractFeatureIntegration
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String deviceId = savedDevice.getId().getId().toString();
try {
restClient.getRestTemplate().postForEntity(BASE_URL + "api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class);
Assert.fail("HttpClientErrorException expected, but not encountered");
doPost("api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class);
Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED);
} catch (HttpClientErrorException e) {
log.error(e.getMessage(), e);
Assert.assertEquals(HttpStatus.REQUEST_TIMEOUT, e.getStatusCode());
@ -104,12 +124,13 @@ public class MqttServerSideRpcIntegrationTest extends AbstractFeatureIntegration
}
@Test
@Ignore
public void testServerMqttOneWayRpcDeviceDoesNotExist() throws Exception {
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String nonExistentDeviceId = UUID.randomUUID().toString();
try {
restClient.getRestTemplate().postForEntity(BASE_URL + "api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class);
Assert.fail("HttpClientErrorException expected, but not encountered");
doPost("api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class);
Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED);
} catch (HttpClientErrorException e) {
log.error(e.getMessage(), e);
Assert.assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode());
@ -118,10 +139,11 @@ public class MqttServerSideRpcIntegrationTest extends AbstractFeatureIntegration
}
@Test
@Ignore
public void testServerMqttTwoWayRpc() throws Exception {
Device device = new Device();
device.setName("Test Two-Way Server-Side RPC");
device.setType("default");
Device savedDevice = getSavedDevice(device);
DeviceCredentials deviceCredentials = getDeviceCredentials(savedDevice);
assertEquals(savedDevice.getId(), deviceCredentials.getDeviceId());
@ -133,8 +155,7 @@ public class MqttServerSideRpcIntegrationTest extends AbstractFeatureIntegration
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(accessToken);
client.connect(options);
Thread.sleep(3000);
client.connect(options).waitForCompletion();
client.subscribe("v1/devices/me/rpc/request/+", 1);
client.setCallback(new TestMqttCallback(client));
@ -145,9 +166,11 @@ public class MqttServerSideRpcIntegrationTest extends AbstractFeatureIntegration
}
@Test
@Ignore
public void testServerMqttTwoWayRpcDeviceOffline() throws Exception {
Device device = new Device();
device.setName("Test Two-Way Server-Side RPC Device Offline");
device.setType("default");
Device savedDevice = getSavedDevice(device);
DeviceCredentials deviceCredentials = getDeviceCredentials(savedDevice);
assertEquals(savedDevice.getId(), deviceCredentials.getDeviceId());
@ -157,8 +180,8 @@ public class MqttServerSideRpcIntegrationTest extends AbstractFeatureIntegration
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String deviceId = savedDevice.getId().getId().toString();
try {
restClient.getRestTemplate().postForEntity(BASE_URL + "api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class);
Assert.fail("HttpClientErrorException expected, but not encountered");
doPost("api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class);
Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED);
} catch (HttpClientErrorException e) {
log.error(e.getMessage(), e);
Assert.assertEquals(HttpStatus.REQUEST_TIMEOUT, e.getStatusCode());
@ -167,12 +190,13 @@ public class MqttServerSideRpcIntegrationTest extends AbstractFeatureIntegration
}
@Test
@Ignore
public void testServerMqttTwoWayRpcDeviceDoesNotExist() throws Exception {
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String nonExistentDeviceId = UUID.randomUUID().toString();
try {
restClient.getRestTemplate().postForEntity(BASE_URL + "api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class);
Assert.fail("HttpClientErrorException expected, but not encountered");
doPost("api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class);
Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED);
} catch (HttpClientErrorException e) {
log.error(e.getMessage(), e);
Assert.assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode());
@ -180,16 +204,16 @@ public class MqttServerSideRpcIntegrationTest extends AbstractFeatureIntegration
}
}
private Device getSavedDevice(Device device) {
return restClient.getRestTemplate().postForEntity(BASE_URL + "/api/device", device, Device.class).getBody();
private Device getSavedDevice(Device device) throws Exception {
return doPost("/api/device", device, Device.class);
}
private DeviceCredentials getDeviceCredentials(Device savedDevice) {
return restClient.getRestTemplate().getForEntity(BASE_URL + "/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class).getBody();
private DeviceCredentials getDeviceCredentials(Device savedDevice) throws Exception {
return doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class);
}
private String getStringResult(String requestData, String callType, String deviceId) {
return restClient.getRestTemplate().postForEntity(BASE_URL + "api/plugins/rpc/" + callType + "/" + deviceId, requestData, String.class).getBody();
private String getStringResult(String requestData, String callType, String deviceId) throws Exception {
return doPost("api/plugins/rpc/" + callType + "/" + deviceId, requestData, String.class);
}
private static class TestMqttCallback implements MqttCallback {

31
application/src/test/java/org/thingsboard/server/mqtt/telemetry/MqttTelemetryIntergrationTest.java → application/src/test/java/org/thingsboard/server/mqtt/telemetry/MqttTelemetryIntegrationTest.java

@ -20,12 +20,12 @@ import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.web.util.UriComponentsBuilder;
import org.thingsboard.client.tools.RestClient;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.mqtt.AbstractFeatureIntegrationTest;
import org.thingsboard.server.controller.AbstractControllerTest;
import java.net.URI;
import java.util.Arrays;
@ -39,35 +39,32 @@ import static org.junit.Assert.assertNotNull;
* @author Valerii Sosliuk
*/
@Slf4j
public class MqttTelemetryIntergrationTest extends AbstractFeatureIntegrationTest {
public class MqttTelemetryIntegrationTest extends AbstractControllerTest {
private static final String MQTT_URL = "tcp://localhost:1883";
private static final String BASE_URL = "http://localhost:8080";
private static final String USERNAME = "tenant@thingsboard.org";
private static final String PASSWORD = "tenant";
private Device savedDevice;
private String accessToken;
private RestClient restClient;
@Before
public void beforeTest() throws Exception {
restClient = new RestClient(BASE_URL);
restClient.login(USERNAME, PASSWORD);
loginTenantAdmin();
Device device = new Device();
device.setName("Test device");
savedDevice = restClient.getRestTemplate().postForEntity(BASE_URL + "/api/device", device, Device.class).getBody();
device.setType("default");
savedDevice = doPost("/api/device", device, Device.class);
DeviceCredentials deviceCredentials =
restClient.getRestTemplate().getForEntity(BASE_URL + "/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class).getBody();
doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class);
assertEquals(savedDevice.getId(), deviceCredentials.getDeviceId());
accessToken = deviceCredentials.getCredentialsId();
assertNotNull(accessToken);
}
@Test
@Ignore
public void testPushMqttRpcData() throws Exception {
String clientId = MqttAsyncClient.generateClientId();
MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId);
@ -83,13 +80,13 @@ public class MqttTelemetryIntergrationTest extends AbstractFeatureIntegrationTes
String deviceId = savedDevice.getId().getId().toString();
Thread.sleep(1000);
List keys = restClient.getRestTemplate().getForEntity(BASE_URL + "/api/plugins/telemetry/" + deviceId + "/keys/timeseries", List.class).getBody();
Object keys = doGet("/api/plugins/telemetry/" + deviceId + "/keys/timeseries", Object.class);
assertEquals(Arrays.asList("key1", "key2", "key3", "key4"), keys);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(BASE_URL + "/api/plugins/telemetry/" + deviceId + "/values/timeseries")
.queryParam("keys", String.join(",", keys));
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("/api/plugins/telemetry/" + deviceId + "/values/timeseries")
.queryParam("keys", String.join(",", (CharSequence[]) keys));
URI uri = builder.build().encode().toUri();
Map<String, List<Map<String, String>>> values = restClient.getRestTemplate().getForEntity(uri, Map.class).getBody();
Map<String, List<Map<String, String>>> values = doGet(uri.getPath(), Map.class);
assertEquals("value1", values.get("key1").get(0).get("value"));
assertEquals("true", values.get("key2").get(0).get("value"));

7
application/src/test/java/org/thingsboard/server/system/SystemTestSuite.java

@ -32,8 +32,9 @@ public class SystemTestSuite {
@ClassRule
public static CustomCassandraCQLUnit cassandraUnit =
new CustomCassandraCQLUnit(Arrays.asList(
new ClassPathCQLDataSet("cassandra/schema.cql", false, false),
new ClassPathCQLDataSet("cassandra/system-data.cql", false, false)),
new CustomCassandraCQLUnit(
Arrays.asList(
new ClassPathCQLDataSet("cassandra/schema.cql", false, false),
new ClassPathCQLDataSet("cassandra/system-data.cql", false, false)),
"cassandra-test.yaml", 30000l);
}

3
application/src/test/resources/thingsboard-test.properties

@ -1,3 +0,0 @@
updates.enabled=false
cassandra.enabled=true
sql.enabled=false

71
dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java

@ -16,31 +16,28 @@
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 lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.id.AdminSettingsId;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.util.JsonBinaryType;
import org.thingsboard.server.dao.util.JsonStringType;
import java.io.IOException;
import javax.persistence.*;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.*;
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ADMIN_SETTINGS_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
@Transient
@ -53,8 +50,8 @@ public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
@Column(name = ADMIN_SETTINGS_KEY_PROPERTY)
private String key;
@Type(type = "jsonb")
@Column(name = ADMIN_SETTINGS_JSON_VALUE_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ADMIN_SETTINGS_JSON_VALUE_PROPERTY, columnDefinition = "json")
private JsonNode jsonValue;
public AdminSettingsEntity() {
@ -79,56 +76,6 @@ public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
this.id = id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((jsonValue == null) ? 0 : jsonValue.hashCode());
result = prime * result + ((key == null) ? 0 : key.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;
AdminSettingsEntity other = (AdminSettingsEntity) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (jsonValue == null) {
if (other.jsonValue != null)
return false;
} else if (!jsonValue.equals(other.jsonValue))
return false;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
return true;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("AdminSettingsEntity [id=");
builder.append(id);
builder.append(", key=");
builder.append(key);
builder.append(", jsonValue=");
builder.append(jsonValue);
builder.append("]");
return builder.toString();
}
@Override
public AdminSettings toData() {
AdminSettings adminSettings = new AdminSettings(new AdminSettingsId(id));

12
dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java

@ -18,7 +18,10 @@ package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmId;
@ -28,6 +31,8 @@ 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 org.thingsboard.server.dao.util.JacksonUtil;
import org.thingsboard.server.dao.util.JsonStringType;
import javax.persistence.*;
import java.util.UUID;
@ -36,7 +41,10 @@ import static org.thingsboard.server.dao.model.ModelConstants.*;
@Data
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ALARM_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class AlarmEntity implements BaseEntity<Alarm> {
@Transient
@ -78,8 +86,8 @@ public final class AlarmEntity implements BaseEntity<Alarm> {
@Column(name = ALARM_CLEAR_TS_PROPERTY)
private Long clearTs;
@Type(type = "jsonb")
@Column(name = ModelConstants.ASSET_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.ASSET_ADDITIONAL_INFO_PROPERTY, columnDefinition = "json")
private JsonNode details;
@Column(name = ALARM_PROPAGATE_PROPERTY)

86
dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java

@ -18,13 +18,18 @@ package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
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 org.thingsboard.server.dao.util.JacksonUtil;
import org.thingsboard.server.dao.util.JsonStringType;
import javax.persistence.*;
import java.util.UUID;
@ -33,7 +38,10 @@ import static org.thingsboard.server.dao.model.ModelConstants.*;
@Data
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ASSET_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class AssetEntity implements SearchTextEntity<Asset> {
@Transient
@ -58,8 +66,8 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
@Column(name = SEARCH_TEXT_PROPERTY)
private String searchText;
@Type(type = "jsonb")
@Column(name = ModelConstants.ASSET_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.ASSET_ADDITIONAL_INFO_PROPERTY, columnDefinition = "json")
private JsonNode additionalInfo;
public AssetEntity() {
@ -95,80 +103,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
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));

6
dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvCompositeKey.java

@ -15,9 +15,7 @@
*/
package org.thingsboard.server.dao.model.sql;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.*;
import java.io.Serializable;
import java.util.UUID;
@ -25,6 +23,8 @@ import java.util.UUID;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class AttributeKvCompositeKey implements Serializable {
private String entityType;
private UUID entityId;

18
dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java

@ -15,12 +15,10 @@
*/
package org.thingsboard.server.dao.model.sql;
import javax.persistence.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.ComponentDescriptorId;
@ -29,15 +27,17 @@ import org.thingsboard.server.common.data.plugin.ComponentScope;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.JsonBinaryType;
import org.thingsboard.server.dao.util.JsonStringType;
import java.io.IOException;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.COMPONENT_DESCRIPTOR_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDescriptor> {
@Transient
@ -61,8 +61,8 @@ public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDesc
@Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CLASS_PROPERTY)
private String clazz;
@Type(type = "jsonb")
@Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CONFIGURATION_DESCRIPTOR_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CONFIGURATION_DESCRIPTOR_PROPERTY, columnDefinition = "json")
private JsonNode configurationDescriptor;
@Column(name = ModelConstants.COMPONENT_DESCRIPTOR_ACTIONS_PROPERTY)

133
dao/src/main/java/org/thingsboard/server/dao/model/sql/CustomerEntity.java

@ -18,19 +18,26 @@ package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Customer;
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 org.thingsboard.server.dao.util.JsonStringType;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.CUSTOMER_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class CustomerEntity implements SearchTextEntity<Customer> {
@Transient
@ -73,8 +80,8 @@ public final class CustomerEntity implements SearchTextEntity<Customer> {
@Column(name = ModelConstants.EMAIL_PROPERTY)
private String email;
@Type(type = "jsonb")
@Column(name = ModelConstants.CUSTOMER_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.CUSTOMER_ADDITIONAL_INFO_PROPERTY, columnDefinition = "json")
private JsonNode additionalInfo;
public CustomerEntity() {
@ -117,128 +124,6 @@ public final class CustomerEntity implements SearchTextEntity<Customer> {
public void setSearchText(String searchText) {
this.searchText = searchText;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode());
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + ((address2 == null) ? 0 : address2.hashCode());
result = prime * result + ((city == null) ? 0 : city.hashCode());
result = prime * result + ((country == null) ? 0 : country.hashCode());
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((phone == null) ? 0 : phone.hashCode());
result = prime * result + ((state == null) ? 0 : state.hashCode());
result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
result = prime * result + ((zip == null) ? 0 : zip.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;
CustomerEntity other = (CustomerEntity) obj;
if (additionalInfo == null) {
if (other.additionalInfo != null)
return false;
} else if (!additionalInfo.equals(other.additionalInfo))
return false;
if (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (address2 == null) {
if (other.address2 != null)
return false;
} else if (!address2.equals(other.address2))
return false;
if (city == null) {
if (other.city != null)
return false;
} else if (!city.equals(other.city))
return false;
if (country == null) {
if (other.country != null)
return false;
} else if (!country.equals(other.country))
return false;
if (email == null) {
if (other.email != null)
return false;
} else if (!email.equals(other.email))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (phone == null) {
if (other.phone != null)
return false;
} else if (!phone.equals(other.phone))
return false;
if (state == null) {
if (other.state != null)
return false;
} else if (!state.equals(other.state))
return false;
if (tenantId == null) {
if (other.tenantId != null)
return false;
} else if (!tenantId.equals(other.tenantId))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
if (zip == null) {
if (other.zip != null)
return false;
} else if (!zip.equals(other.zip))
return false;
return true;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("CustomerEntity [id=");
builder.append(id);
builder.append(", tenantId=");
builder.append(tenantId);
builder.append(", title=");
builder.append(title);
builder.append(", country=");
builder.append(country);
builder.append(", state=");
builder.append(state);
builder.append(", city=");
builder.append(city);
builder.append(", address=");
builder.append(address);
builder.append(", address2=");
builder.append(address2);
builder.append(", zip=");
builder.append(zip);
builder.append(", phone=");
builder.append(phone);
builder.append(", email=");
builder.append(email);
builder.append(", additionalInfo=");
builder.append(additionalInfo);
builder.append("]");
return builder.toString();
}
@Override
public Customer toData() {

95
dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java

@ -16,15 +16,10 @@
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 lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Dashboard;
@ -33,15 +28,17 @@ import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.JsonBinaryType;
import org.thingsboard.server.dao.util.JsonStringType;
import java.io.IOException;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.DASHBOARD_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class DashboardEntity implements SearchTextEntity<Dashboard> {
@Transient
@ -63,8 +60,8 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> {
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
@Type(type = "jsonb")
@Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY, columnDefinition = "json")
private JsonNode configuration;
public DashboardEntity() {
@ -108,80 +105,6 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> {
return searchText;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((configuration == null) ? 0 : configuration.hashCode());
result = prime * result + ((customerId == null) ? 0 : customerId.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((searchText == null) ? 0 : searchText.hashCode());
result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode());
result = prime * result + ((title == null) ? 0 : title.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;
DashboardEntity other = (DashboardEntity) obj;
if (configuration == null) {
if (other.configuration != null)
return false;
} else if (!configuration.equals(other.configuration))
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 (searchText == null) {
if (other.searchText != null)
return false;
} else if (!searchText.equals(other.searchText))
return false;
if (tenantId == null) {
if (other.tenantId != null)
return false;
} else if (!tenantId.equals(other.tenantId))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("DashboardEntity [id=");
builder.append(id);
builder.append(", tenantId=");
builder.append(tenantId);
builder.append(", customerId=");
builder.append(customerId);
builder.append(", title=");
builder.append(title);
builder.append(", searchText=");
builder.append(searchText);
builder.append(", configuration=");
builder.append(configuration);
builder.append("]");
return builder.toString();
}
@Override
public Dashboard toData() {
Dashboard dashboard = new Dashboard(new DashboardId(id));

77
dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java

@ -16,13 +16,9 @@
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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
@ -30,11 +26,14 @@ 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;
@Data
@Entity
@Table(name = ModelConstants.DASHBOARD_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> {
@Transient
@ -87,72 +86,6 @@ public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> {
return searchText;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((customerId == null) ? 0 : customerId.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((searchText == null) ? 0 : searchText.hashCode());
result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode());
result = prime * result + ((title == null) ? 0 : title.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;
DashboardInfoEntity other = (DashboardInfoEntity) obj;
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 (searchText == null) {
if (other.searchText != null)
return false;
} else if (!searchText.equals(other.searchText))
return false;
if (tenantId == null) {
if (other.tenantId != null)
return false;
} else if (!tenantId.equals(other.tenantId))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("DashboardInfoEntity [id=");
builder.append(id);
builder.append(", tenantId=");
builder.append(tenantId);
builder.append(", customerId=");
builder.append(customerId);
builder.append(", title=");
builder.append(title);
builder.append(", searchText=");
builder.append(searchText);
builder.append("]");
return builder.toString();
}
@Override
public DashboardInfo toData() {
DashboardInfo dashboardInfo = new DashboardInfo(new DashboardId(id));

71
dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java

@ -16,10 +16,9 @@
package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import javax.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.thingsboard.server.common.data.id.DeviceCredentialsId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.security.DeviceCredentials;
@ -27,11 +26,14 @@ import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@Table(name = ModelConstants.DEVICE_CREDENTIALS_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class DeviceCredentialsEntity implements BaseEntity<DeviceCredentials> {
@Transient
@ -69,69 +71,6 @@ public final class DeviceCredentialsEntity implements BaseEntity<DeviceCredentia
this.credentialsValue = deviceCredentials.getCredentialsValue();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((credentialsId == null) ? 0 : credentialsId.hashCode());
result = prime * result + ((credentialsType == null) ? 0 : credentialsType.hashCode());
result = prime * result + ((credentialsValue == null) ? 0 : credentialsValue.hashCode());
result = prime * result + ((deviceId == null) ? 0 : deviceId.hashCode());
result = prime * result + ((id == null) ? 0 : id.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;
DeviceCredentialsEntity other = (DeviceCredentialsEntity) obj;
if (credentialsId == null) {
if (other.credentialsId != null)
return false;
} else if (!credentialsId.equals(other.credentialsId))
return false;
if (credentialsType != other.credentialsType)
return false;
if (credentialsValue == null) {
if (other.credentialsValue != null)
return false;
} else if (!credentialsValue.equals(other.credentialsValue))
return false;
if (deviceId == null) {
if (other.deviceId != null)
return false;
} else if (!deviceId.equals(other.deviceId))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("DeviceCredentialsEntity [id=");
builder.append(id);
builder.append(", deviceId=");
builder.append(deviceId);
builder.append(", credentialsType=");
builder.append(credentialsType);
builder.append(", credentialsId=");
builder.append(credentialsId);
builder.append(", credentialsValue=");
builder.append(credentialsValue);
builder.append("]");
return builder.toString();
}
@Override
public DeviceCredentials toData() {
DeviceCredentials deviceCredentials = new DeviceCredentials(new DeviceCredentialsId(id));

89
dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java

@ -16,15 +16,10 @@
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 lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Device;
@ -33,15 +28,17 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.JsonBinaryType;
import org.thingsboard.server.dao.util.JsonStringType;
import java.io.IOException;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.DEVICE_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class DeviceEntity implements SearchTextEntity<Device> {
@Transient
@ -66,8 +63,8 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
@Type(type = "jsonb")
@Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY, columnDefinition = "json")
private JsonNode additionalInfo;
public DeviceEntity() {
@ -85,6 +82,7 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
this.customerId = device.getCustomerId().getId();
}
this.name = device.getName();
this.type = device.getType();
this.additionalInfo = device.getAdditionalInfo();
}
@ -102,72 +100,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
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 + ((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;
DeviceEntity other = (DeviceEntity) 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 (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("DeviceEntity [id=");
builder.append(id);
builder.append(", tenantId=");
builder.append(tenantId);
builder.append(", customerId=");
builder.append(customerId);
builder.append(", name=");
builder.append(name);
builder.append(", additionalInfo=");
builder.append(additionalInfo);
builder.append("]");
return builder.toString();
}
@Override
public Device toData() {
Device device = new Device(new DeviceId(id));
@ -179,6 +111,7 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
device.setCustomerId(new CustomerId(customerId));
}
device.setName(name);
device.setType(type);
device.setAdditionalInfo(additionalInfo);
return device;
}

25
dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java

@ -16,32 +16,31 @@
package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import javax.persistence.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Event;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.util.JsonBinaryType;
import static org.thingsboard.server.dao.model.ModelConstants.*;
import org.thingsboard.server.dao.util.JsonStringType;
import java.io.IOException;
import javax.persistence.*;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.*;
@Data
@NoArgsConstructor
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = EVENT_COLUMN_FAMILY_NAME)
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class EventEntity implements BaseEntity<Event> {
@Transient
@ -67,8 +66,8 @@ public class EventEntity implements BaseEntity<Event> {
@Column(name = EVENT_UID_PROPERTY)
private String eventUid;
@Type(type = "jsonb")
@Column(name = EVENT_BODY_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = EVENT_BODY_PROPERTY, columnDefinition = "json")
private JsonNode body;
public EventEntity(Event event) {

47
dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java

@ -16,13 +16,10 @@
package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import javax.persistence.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.PluginId;
@ -31,16 +28,17 @@ import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.JsonBinaryType;
import org.thingsboard.server.dao.util.JsonStringType;
import java.io.IOException;
import java.util.Objects;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.PLUGIN_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
@Transient
@ -68,12 +66,12 @@ public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
@Column(name = ModelConstants.PLUGIN_STATE_PROPERTY)
private ComponentLifecycleState state;
@Type(type = "jsonb")
@Column(name = ModelConstants.PLUGIN_CONFIGURATION_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.PLUGIN_CONFIGURATION_PROPERTY, columnDefinition = "json")
private JsonNode configuration;
@Type(type = "jsonb")
@Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY, columnDefinition = "json")
private JsonNode additionalInfo;
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
@ -132,27 +130,4 @@ public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
return data;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
PluginMetaDataEntity entity = (PluginMetaDataEntity) o;
return Objects.equals(id, entity.id) && Objects.equals(apiToken, entity.apiToken) && Objects.equals(tenantId, entity.tenantId)
&& Objects.equals(name, entity.name) && Objects.equals(clazz, entity.clazz) && Objects.equals(state, entity.state)
&& Objects.equals(configuration, entity.configuration)
&& Objects.equals(searchText, entity.searchText);
}
@Override
public int hashCode() {
return Objects.hash(id, apiToken, tenantId, name, clazz, state, configuration, searchText);
}
@Override
public String toString() {
return "PluginMetaDataEntity{" + "id=" + id + ", apiToken='" + apiToken + '\'' + ", tenantId=" + tenantId + ", name='" + name + '\'' + ", clazz='"
+ clazz + '\'' + ", state=" + state + ", configuration=" + configuration + ", searchText='" + searchText + '\'' + '}';
}
}

6
dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationCompositeKey.java

@ -15,16 +15,14 @@
*/
package org.thingsboard.server.dao.model.sql;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.*;
import org.thingsboard.server.common.data.relation.EntityRelation;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.UUID;
@NoArgsConstructor
@AllArgsConstructor
@Data
@EqualsAndHashCode

7
dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationEntity.java

@ -20,10 +20,12 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.model.ToData;
import org.thingsboard.server.dao.util.JsonStringType;
import javax.persistence.*;
import java.util.UUID;
@ -32,6 +34,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.*;
@Data
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = RELATION_COLUMN_FAMILY_NAME)
@IdClass(RelationCompositeKey.class)
@EqualsAndHashCode
@ -62,8 +65,8 @@ public final class RelationEntity implements ToData<EntityRelation> {
@Column(name = RELATION_TYPE_PROPERTY)
private String relationType;
@Type(type = "jsonb")
@Column(name = ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ADDITIONAL_INFO_PROPERTY, columnDefinition = "json")
private JsonNode additionalInfo;
public RelationEntity() {

64
dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java

@ -16,13 +16,10 @@
package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import javax.persistence.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.RuleId;
@ -32,16 +29,17 @@ import org.thingsboard.server.common.data.rule.RuleMetaData;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.JsonBinaryType;
import org.thingsboard.server.dao.util.JsonStringType;
import java.io.IOException;
import java.util.Objects;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.RULE_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
@Transient
@ -69,20 +67,20 @@ public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
@Column(name = ModelConstants.RULE_PLUGIN_TOKEN_PROPERTY)
private String pluginToken;
@Type(type = "jsonb")
@Column(name = ModelConstants.RULE_FILTERS, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.RULE_FILTERS, columnDefinition = "json")
private JsonNode filters;
@Type(type = "jsonb")
@Column(name = ModelConstants.RULE_PROCESSOR, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.RULE_PROCESSOR, columnDefinition = "json")
private JsonNode processor;
@Type(type = "jsonb")
@Column(name = ModelConstants.RULE_ACTION, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.RULE_ACTION, columnDefinition = "json")
private JsonNode action;
@Type(type = "jsonb")
@Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
@Type(type = "json")
@Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY, columnDefinition = "json")
private JsonNode additionalInfo;
public RuleMetaDataEntity() {
@ -139,36 +137,4 @@ public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
rule.setAdditionalInfo(additionalInfo);
return rule;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RuleMetaDataEntity that = (RuleMetaDataEntity) o;
return weight == that.weight &&
Objects.equals(id, that.id) &&
Objects.equals(tenantId, that.tenantId) &&
Objects.equals(name, that.name) &&
Objects.equals(pluginToken, that.pluginToken) &&
Objects.equals(state, that.state) &&
Objects.equals(searchText, that.searchText);
}
@Override
public int hashCode() {
return Objects.hash(id, tenantId, name, pluginToken, state, weight, searchText);
}
@Override
public String toString() {
return "RuleMetaDataEntity{" +
"id=" + id +
", tenantId=" + tenantId +
", name='" + name + '\'' +
", pluginToken='" + pluginToken + '\'' +
", state='" + state + '\'' +
", weight=" + weight +
", searchText='" + searchText + '\'' +
'}';
}
}

4
dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantDeviceTypeEntity.java

@ -17,11 +17,15 @@ package org.thingsboard.server.dao.model.sql;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.UUID;
@AllArgsConstructor
@Data
@EqualsAndHashCode
@ToString
public class TenantDeviceTypeEntity {
private UUID tenantId;
private String type;

147
dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java

@ -16,32 +16,27 @@
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.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import com.fasterxml.jackson.databind.JsonNode;
import org.thingsboard.server.dao.util.JsonBinaryType;
import org.thingsboard.server.dao.util.JsonStringType;
import java.io.IOException;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.TENANT_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class TenantEntity implements SearchTextEntity<Tenant> {
@Transient
@ -84,8 +79,8 @@ public final class TenantEntity implements SearchTextEntity<Tenant> {
@Column(name = ModelConstants.EMAIL_PROPERTY)
private String email;
@Type(type="jsonb")
@Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
@Type(type="json")
@Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY, columnDefinition = "json")
private JsonNode additionalInfo;
public TenantEntity() {
@ -123,128 +118,6 @@ public final class TenantEntity implements SearchTextEntity<Tenant> {
return searchText;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode());
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + ((address2 == null) ? 0 : address2.hashCode());
result = prime * result + ((city == null) ? 0 : city.hashCode());
result = prime * result + ((country == null) ? 0 : country.hashCode());
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((phone == null) ? 0 : phone.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((state == null) ? 0 : state.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
result = prime * result + ((zip == null) ? 0 : zip.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;
TenantEntity other = (TenantEntity) obj;
if (additionalInfo == null) {
if (other.additionalInfo != null)
return false;
} else if (!additionalInfo.equals(other.additionalInfo))
return false;
if (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (address2 == null) {
if (other.address2 != null)
return false;
} else if (!address2.equals(other.address2))
return false;
if (city == null) {
if (other.city != null)
return false;
} else if (!city.equals(other.city))
return false;
if (country == null) {
if (other.country != null)
return false;
} else if (!country.equals(other.country))
return false;
if (email == null) {
if (other.email != null)
return false;
} else if (!email.equals(other.email))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (phone == null) {
if (other.phone != null)
return false;
} else if (!phone.equals(other.phone))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (state == null) {
if (other.state != null)
return false;
} else if (!state.equals(other.state))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
if (zip == null) {
if (other.zip != null)
return false;
} else if (!zip.equals(other.zip))
return false;
return true;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("TenantEntity [id=");
builder.append(id);
builder.append(", title=");
builder.append(title);
builder.append(", region=");
builder.append(region);
builder.append(", country=");
builder.append(country);
builder.append(", state=");
builder.append(state);
builder.append(", city=");
builder.append(city);
builder.append(", address=");
builder.append(address);
builder.append(", address2=");
builder.append(address2);
builder.append(", zip=");
builder.append(zip);
builder.append(", phone=");
builder.append(phone);
builder.append(", email=");
builder.append(email);
builder.append(", additionalInfo=");
builder.append(additionalInfo);
builder.append("]");
return builder.toString();
}
@Override
public Tenant toData() {
Tenant tenant = new Tenant(new TenantId(id));

6
dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvCompositeKey.java

@ -15,10 +15,7 @@
*/
package org.thingsboard.server.dao.model.sql;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.*;
import javax.persistence.Transient;
import java.io.Serializable;
@ -26,6 +23,7 @@ import java.util.UUID;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class TsKvCompositeKey implements Serializable{

6
dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvLatestCompositeKey.java

@ -15,16 +15,14 @@
*/
package org.thingsboard.server.dao.model.sql;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.*;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.UUID;
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString

64
dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java

@ -16,25 +16,23 @@
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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.thingsboard.server.common.data.id.UserCredentialsId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@Table(name = ModelConstants.USER_CREDENTIALS_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class UserCredentialsEntity implements BaseEntity<UserCredentials> {
@Transient
@ -76,58 +74,6 @@ public final class UserCredentialsEntity implements BaseEntity<UserCredentials>
this.resetToken = userCredentials.getResetToken();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((activateToken == null) ? 0 : activateToken.hashCode());
result = prime * result + (enabled ? 1231 : 1237);
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((password == null) ? 0 : password.hashCode());
result = prime * result + ((resetToken == null) ? 0 : resetToken.hashCode());
result = prime * result + ((userId == null) ? 0 : userId.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;
UserCredentialsEntity other = (UserCredentialsEntity) obj;
if (activateToken == null) {
if (other.activateToken != null)
return false;
} else if (!activateToken.equals(other.activateToken))
return false;
if (enabled != other.enabled)
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (resetToken == null) {
if (other.resetToken != null)
return false;
} else if (!resetToken.equals(other.resetToken))
return false;
if (userId == null) {
if (other.userId != null)
return false;
} else if (!userId.equals(other.userId))
return false;
return true;
}
@Override
public UserCredentials toData() {
UserCredentials userCredentials = new UserCredentials(new UserCredentialsId(id));

101
dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java

@ -17,9 +17,9 @@ package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.User;
@ -29,10 +29,9 @@ import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.JsonBinaryType;
import org.thingsboard.server.dao.util.JsonStringType;
import javax.persistence.*;
import java.io.IOException;
import java.util.UUID;
/**
@ -40,8 +39,10 @@ import java.util.UUID;
*/
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.USER_PG_HIBERNATE_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public class UserEntity implements SearchTextEntity<User> {
@Transient
private static final long serialVersionUID = -271106508790582977L;
@ -72,8 +73,8 @@ public class UserEntity implements SearchTextEntity<User> {
@Column(name = ModelConstants.USER_LAST_NAME_PROPERTY)
private String lastName;
@Type(type="jsonb")
@Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
@Type(type="json")
@Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY, columnDefinition = "json")
private JsonNode additionalInfo;
public UserEntity() {
@ -116,28 +117,7 @@ public class UserEntity implements SearchTextEntity<User> {
this.id = id;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("UserEntity [id=");
builder.append(id);
builder.append(", authority=");
builder.append(authority);
builder.append(", tenantId=");
builder.append(tenantId);
builder.append(", customerId=");
builder.append(customerId);
builder.append(", email=");
builder.append(email);
builder.append(", firstName=");
builder.append(firstName);
builder.append(", lastName=");
builder.append(lastName);
builder.append(", additionalInfo=");
builder.append(additionalInfo);
builder.append("]");
return builder.toString();
}
@Override
public User toData() {
@ -157,67 +137,4 @@ public class UserEntity implements SearchTextEntity<User> {
return user;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode());
result = prime * result + ((authority == null) ? 0 : authority.hashCode());
result = prime * result + ((customerId == null) ? 0 : customerId.hashCode());
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((lastName == null) ? 0 : lastName.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;
UserEntity other = (UserEntity) obj;
if (additionalInfo == null) {
if (other.additionalInfo != null)
return false;
} else if (!additionalInfo.equals(other.additionalInfo))
return false;
if (authority != other.authority)
return false;
if (customerId == null) {
if (other.customerId != null)
return false;
} else if (!customerId.equals(other.customerId))
return false;
if (email == null) {
if (other.email != null)
return false;
} else if (!email.equals(other.email))
return false;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
if (tenantId == null) {
if (other.tenantId != null)
return false;
} else if (!tenantId.equals(other.tenantId))
return false;
return true;
}
}

54
dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java

@ -16,9 +16,10 @@
package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import com.datastax.driver.mapping.annotations.PartitionKey;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.TenantId;
@ -26,15 +27,17 @@ import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.JsonBinaryType;
import org.thingsboard.server.dao.util.JsonStringType;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.WIDGET_TYPE_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
@Transient
@ -44,11 +47,9 @@ public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
@Column(name = ModelConstants.ID_PROPERTY)
private UUID id;
@PartitionKey(value = 1)
@Column(name = ModelConstants.WIDGET_TYPE_TENANT_ID_PROPERTY)
private UUID tenantId;
@PartitionKey(value = 2)
@Column(name = ModelConstants.WIDGET_TYPE_BUNDLE_ALIAS_PROPERTY)
private String bundleAlias;
@ -58,8 +59,8 @@ public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
@Column(name = ModelConstants.WIDGET_TYPE_NAME_PROPERTY)
private String name;
@Type(type="jsonb")
@Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY, columnDefinition = "jsonb")
@Type(type="json")
@Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY, columnDefinition = "json")
private JsonNode descriptor;
public WidgetTypeEntity() {
@ -89,45 +90,6 @@ public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
this.id = id;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (tenantId != null ? tenantId.hashCode() : 0);
result = 31 * result + (bundleAlias != null ? bundleAlias.hashCode() : 0);
result = 31 * result + (alias != null ? alias.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (descriptor != null ? descriptor.hashCode() : 0);
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WidgetTypeEntity that = (WidgetTypeEntity) o;
if (id != null ? !id.equals(that.id) : that.id != null) return false;
if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) return false;
if (bundleAlias != null ? !bundleAlias.equals(that.bundleAlias) : that.bundleAlias != null) return false;
if (alias != null ? !alias.equals(that.alias) : that.alias != null) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
return descriptor != null ? descriptor.equals(that.descriptor) : that.descriptor == null;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("WidgetTypeEntity{");
sb.append("id=").append(id);
sb.append(", tenantId=").append(tenantId);
sb.append(", bundleAlias='").append(bundleAlias).append('\'');
sb.append(", alias='").append(alias).append('\'');
sb.append(", name='").append(name).append('\'');
sb.append(", descriptor=").append(descriptor);
sb.append('}');
return sb.toString();
}
@Override
public WidgetType toData() {
WidgetType widgetType = new WidgetType(new WidgetTypeId(id));

51
dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java

@ -17,25 +17,23 @@ 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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import java.nio.ByteBuffer;
import javax.persistence.*;
import java.util.UUID;
@Data
@Entity
@Table(name = ModelConstants.WIDGETS_BUNDLE_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle> {
@Transient
@ -98,45 +96,6 @@ public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle
this.searchText = searchText;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (tenantId != null ? tenantId.hashCode() : 0);
result = 31 * result + (alias != null ? alias.hashCode() : 0);
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + (searchText != null ? searchText.hashCode() : 0);
result = 31 * result + (image != null ? image.hashCode() : 0);
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WidgetsBundleEntity that = (WidgetsBundleEntity) o;
if (id != null ? !id.equals(that.id) : that.id != null) return false;
if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) return false;
if (alias != null ? !alias.equals(that.alias) : that.alias != null) return false;
if (title != null ? !title.equals(that.title) : that.title != null) return false;
if (searchText != null ? !searchText.equals(that.searchText) : that.searchText != null) return false;
return image != null ? image.equals(that.image) : that.image == null;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("WidgetsBundleEntity{");
sb.append("id=").append(id);
sb.append(", tenantId=").append(tenantId);
sb.append(", alias='").append(alias).append('\'');
sb.append(", title='").append(title).append('\'');
sb.append(", searchText='").append(searchText).append('\'');
sb.append(", image=").append(image);
sb.append('}');
return sb.toString();
}
@Override
public WidgetsBundle toData() {
WidgetsBundle widgetsBundle = new WidgetsBundle(new WidgetsBundleId(id));

10
dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetRepository.java

@ -55,6 +55,16 @@ public interface AssetRepository extends CrudRepository<AssetEntity, UUID> {
AssetEntity findByTenantIdAndName(UUID tenantId, String name);
@Query(nativeQuery = true, value = "SELECT * FROM ASSET WHERE TENANT_ID = :tenantId " +
"AND TYPE = :type " +
"AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(:textSearch, '%')) " +
"AND ID > :idOffset ORDER BY ID LIMIT :limit")
List<AssetEntity> findByTenantIdAndType(@Param("limit") int limit,
@Param("tenantId") UUID tenantId,
@Param("type") String type,
@Param("textSearch") String textSearch,
@Param("idOffset") UUID idOffset);
@Query(nativeQuery = true, value = "SELECT * FROM ASSET WHERE TENANT_ID = :tenantId " +
"AND CUSTOMER_ID = :customerId AND TYPE = :type " +
"AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(:textSearch, '%')) " +

8
dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetDao.java

@ -95,7 +95,13 @@ public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> im
@Override
public List<Asset> findAssetsByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) {
return null;
return DaoUtil.convertDataList(assetRepository
.findByTenantIdAndType(
pageLink.getLimit(),
tenantId,
type,
pageLink.getTextSearch(),
pageLink.getIdOffset() == null ? NULL_UUID : pageLink.getIdOffset()));
}
@Override

2
dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/DashboardInfoRepository.java

@ -40,7 +40,7 @@ public interface DashboardInfoRepository extends CrudRepository<DashboardInfoEnt
@Query(nativeQuery = true, value = "SELECT * FROM DASHBOARD WHERE TENANT_ID = :tenantId " +
"AND CUSTOMER_ID = :customerId AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(:textSearch, '%')) " +
"AND ID > :idOffset ORDER BY ID LIMIT :limit?1")
"AND ID > :idOffset ORDER BY ID LIMIT :limit")
List<DashboardInfoEntity> findByTenantIdAndCustomerId(@Param("limit") int limit,
@Param("tenantId") UUID tenantId,
@Param("customerId") UUID customerId,

48
dao/src/main/java/org/thingsboard/server/dao/util/JsonBinarySqlTypeDescriptor.java → dao/src/main/java/org/thingsboard/server/dao/util/AbstractJsonSqlTypeDescriptor.java

@ -15,29 +15,23 @@
*/
package org.thingsboard.server.dao.util;
import com.fasterxml.jackson.databind.JsonNode;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.BasicBinder;
import org.hibernate.type.descriptor.sql.BasicExtractor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import java.sql.*;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
/**
* Created by Valerii Sosliuk on 5/12/2017.
*/
public class JsonBinarySqlTypeDescriptor
public abstract class AbstractJsonSqlTypeDescriptor
implements SqlTypeDescriptor {
public static final JsonBinarySqlTypeDescriptor INSTANCE =
new JsonBinarySqlTypeDescriptor();
@Override
public int getSqlType() {
return Types.OTHER;
return Types.VARCHAR;
}
@Override
@ -81,34 +75,4 @@ public class JsonBinarySqlTypeDescriptor
};
}
@Override
public <X> ValueBinder<X> getBinder(
final JavaTypeDescriptor<X> javaTypeDescriptor) {
return new BasicBinder<X>(javaTypeDescriptor, this) {
@Override
protected void doBind(
PreparedStatement st,
X value,
int index,
WrapperOptions options) throws SQLException {
st.setObject(index,
javaTypeDescriptor.unwrap(
value, JsonNode.class, options), getSqlType()
);
}
@Override
protected void doBind(
CallableStatement st,
X value,
String name,
WrapperOptions options)
throws SQLException {
st.setObject(name,
javaTypeDescriptor.unwrap(
value, JsonNode.class, options), getSqlType()
);
}
};
}
}

3
dao/src/main/java/org/thingsboard/server/dao/util/JacksonUtil.java

@ -47,6 +47,9 @@ public class JacksonUtil {
}
public static JsonNode toJsonNode(String value) {
if (value == null || value.isEmpty()) {
return null;
}
try {
return OBJECT_MAPPER.readTree(value);
} catch (IOException e) {

61
dao/src/main/java/org/thingsboard/server/dao/util/JsonStringSqlTypeDescriptor.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.util;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.BasicBinder;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JsonStringSqlTypeDescriptor
extends AbstractJsonSqlTypeDescriptor {
public static final JsonStringSqlTypeDescriptor INSTANCE =
new JsonStringSqlTypeDescriptor();
@Override
public <X> ValueBinder<X> getBinder(
final JavaTypeDescriptor<X> javaTypeDescriptor) {
return new BasicBinder<X>(javaTypeDescriptor, this) {
@Override
protected void doBind(
PreparedStatement st,
X value,
int index,
WrapperOptions options) throws SQLException {
st.setString(index,
javaTypeDescriptor.unwrap(value, String.class, options)
);
}
@Override
protected void doBind(
CallableStatement st,
X value,
String name,
WrapperOptions options)
throws SQLException {
st.setString(name,
javaTypeDescriptor.unwrap(value, String.class, options
));
}
};
}
}

20
dao/src/main/java/org/thingsboard/server/dao/util/JsonBinaryType.java → dao/src/main/java/org/thingsboard/server/dao/util/JsonStringType.java

@ -20,25 +20,29 @@ import org.hibernate.usertype.DynamicParameterizedType;
import java.util.Properties;
/**
* Created by Valerii Sosliuk on 5/12/2017.
*/
public class JsonBinaryType extends AbstractSingleColumnStandardBasicType<Object>
public class JsonStringType
extends AbstractSingleColumnStandardBasicType<Object>
implements DynamicParameterizedType {
public JsonBinaryType() {
public JsonStringType() {
super(
JsonBinarySqlTypeDescriptor.INSTANCE,
JsonStringSqlTypeDescriptor.INSTANCE,
new JsonTypeDescriptor()
);
}
public String getName() {
return "jsonb";
return "json";
}
@Override
protected boolean registerUnderJavaType() {
return true;
}
@Override
public void setParameterValues(Properties parameters) {
((JsonTypeDescriptor) getJavaTypeDescriptor())
.setParameterValues(parameters);
}}
}
}

70
dao/src/main/resources/postgres/schema.sql

@ -14,31 +14,18 @@
-- limitations under the License.
--
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
CREATE TABLE IF NOT EXISTS admin_settings (
id uuid NOT NULL CONSTRAINT admin_settings_pkey PRIMARY KEY,
json_value jsonb,
json_value varchar,
key character varying(255)
);
ALTER TABLE admin_settings OWNER TO postgres;
CREATE TABLE IF NOT EXISTS alarm (
id uuid NOT NULL CONSTRAINT alarm_pkey PRIMARY KEY,
ack_ts bigint,
clear_ts bigint,
additional_info jsonb,
additional_info varchar,
end_ts bigint,
originator_id uuid,
originator_type integer,
@ -49,18 +36,16 @@ CREATE TABLE IF NOT EXISTS alarm (
tenant_id uuid,
type character varying(255)
);
ALTER TABLE alarm OWNER TO postgres;
CREATE TABLE IF NOT EXISTS asset (
id uuid NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
additional_info jsonb,
additional_info varchar,
customer_id uuid,
name character varying(255),
search_text character varying(255),
tenant_id uuid,
type character varying(255)
);
ALTER TABLE asset OWNER TO postgres;
CREATE TABLE IF NOT EXISTS attribute_kv (
entity_type character varying(255),
@ -74,23 +59,21 @@ CREATE TABLE IF NOT EXISTS attribute_kv (
last_update_ts bigint,
CONSTRAINT attribute_kv_unq_key UNIQUE (entity_type, entity_id, attribute_type, attribute_key)
);
ALTER TABLE relation OWNER TO postgres;
CREATE TABLE IF NOT EXISTS component_descriptor (
id uuid NOT NULL CONSTRAINT component_descriptor_pkey PRIMARY KEY,
actions character varying(255),
clazz character varying(255),
configuration_descriptor jsonb,
configuration_descriptor varchar,
name character varying(255),
scope character varying(255),
search_text character varying(255),
type character varying(255)
);
ALTER TABLE component_descriptor OWNER TO postgres;
CREATE TABLE IF NOT EXISTS customer (
id uuid NOT NULL CONSTRAINT customer_pkey PRIMARY KEY,
additional_info jsonb,
additional_info varchar,
address character varying(255),
address2 character varying(255),
city character varying(255),
@ -103,28 +86,25 @@ CREATE TABLE IF NOT EXISTS customer (
title character varying(255),
zip character varying(255)
);
ALTER TABLE customer OWNER TO postgres;
CREATE TABLE IF NOT EXISTS dashboard (
id uuid NOT NULL CONSTRAINT dashboard_pkey PRIMARY KEY,
configuration jsonb,
configuration varchar,
customer_id uuid,
search_text character varying(255),
tenant_id uuid,
title character varying(255)
);
ALTER TABLE dashboard OWNER TO postgres;
CREATE TABLE IF NOT EXISTS device (
id uuid NOT NULL CONSTRAINT device_pkey PRIMARY KEY,
additional_info jsonb,
additional_info varchar,
customer_id uuid,
type character varying(255),
name character varying(255),
search_text character varying(255),
tenant_id uuid
);
ALTER TABLE device OWNER TO postgres;
CREATE TABLE IF NOT EXISTS device_credentials (
id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY,
@ -133,32 +113,29 @@ CREATE TABLE IF NOT EXISTS device_credentials (
credentials_value character varying(255),
device_id uuid
);
ALTER TABLE device_credentials OWNER TO postgres;
CREATE TABLE IF NOT EXISTS event (
id uuid NOT NULL CONSTRAINT event_pkey PRIMARY KEY,
body jsonb,
body varchar,
entity_id uuid,
entity_type character varying(255),
event_type character varying(255),
event_uid character varying(255),
tenant_id uuid
);
ALTER TABLE event OWNER TO postgres;
CREATE TABLE IF NOT EXISTS plugin (
id uuid NOT NULL CONSTRAINT plugin_pkey PRIMARY KEY,
additional_info jsonb,
additional_info varchar,
api_token character varying(255),
plugin_class character varying(255),
configuration jsonb,
configuration varchar,
name character varying(255),
public_access boolean,
search_text character varying(255),
state character varying(255),
tenant_id uuid
);
ALTER TABLE plugin OWNER TO postgres;
CREATE TABLE IF NOT EXISTS relation (
from_id uuid,
@ -167,29 +144,27 @@ CREATE TABLE IF NOT EXISTS relation (
to_type character varying(255),
relation_type_group character varying(255),
relation_type character varying(255),
additional_info jsonb,
additional_info varchar,
CONSTRAINT relation_unq_key UNIQUE (from_id, from_type, relation_type_group, relation_type, to_id, to_type)
);
ALTER TABLE relation OWNER TO postgres;
CREATE TABLE IF NOT EXISTS rule (
id uuid NOT NULL CONSTRAINT rule_pkey PRIMARY KEY,
action jsonb,
additional_info jsonb,
filters jsonb,
action varchar,
additional_info varchar,
filters varchar,
name character varying(255),
plugin_token character varying(255),
processor jsonb,
processor varchar,
search_text character varying(255),
state character varying(255),
tenant_id uuid,
weight integer
);
ALTER TABLE rule OWNER TO postgres;
CREATE TABLE IF NOT EXISTS tb_user (
id uuid NOT NULL CONSTRAINT tb_user_pkey PRIMARY KEY,
additional_info jsonb,
additional_info varchar,
authority character varying(255),
customer_id uuid,
email character varying(255) UNIQUE,
@ -198,11 +173,10 @@ CREATE TABLE IF NOT EXISTS tb_user (
search_text character varying(255),
tenant_id uuid
);
ALTER TABLE tb_user OWNER TO postgres;
CREATE TABLE IF NOT EXISTS tenant (
id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY,
additional_info jsonb,
additional_info varchar,
address character varying(255),
address2 character varying(255),
city character varying(255),
@ -215,7 +189,6 @@ CREATE TABLE IF NOT EXISTS tenant (
title character varying(255),
zip character varying(255)
);
ALTER TABLE tenant OWNER TO postgres;
CREATE TABLE IF NOT EXISTS ts_kv (
entity_type character varying(255) NOT NULL,
@ -228,7 +201,6 @@ CREATE TABLE IF NOT EXISTS ts_kv (
dbl_v double precision,
CONSTRAINT ts_kv_unq_key UNIQUE (entity_type, entity_id, key, ts)
);
ALTER TABLE ts_kv OWNER TO postgres;
CREATE TABLE IF NOT EXISTS ts_kv_latest (
entity_type character varying(255) NOT NULL,
@ -241,7 +213,6 @@ CREATE TABLE IF NOT EXISTS ts_kv_latest (
dbl_v double precision,
CONSTRAINT ts_kv_latest_unq_key UNIQUE (entity_type, entity_id, key)
);
ALTER TABLE ts_kv OWNER TO postgres;
CREATE TABLE IF NOT EXISTS user_credentials (
id uuid NOT NULL CONSTRAINT user_credentials_pkey PRIMARY KEY,
@ -251,17 +222,15 @@ CREATE TABLE IF NOT EXISTS user_credentials (
reset_token character varying(255) UNIQUE,
user_id uuid UNIQUE
);
ALTER TABLE user_credentials OWNER TO postgres;
CREATE TABLE IF NOT EXISTS widget_type (
id uuid NOT NULL CONSTRAINT widget_type_pkey PRIMARY KEY,
alias character varying(255),
bundle_alias character varying(255),
descriptor jsonb,
descriptor varchar,
name character varying(255),
tenant_id uuid
);
ALTER TABLE widget_type OWNER TO postgres;
CREATE TABLE IF NOT EXISTS widgets_bundle (
id uuid NOT NULL CONSTRAINT widgets_bundle_pkey PRIMARY KEY,
@ -270,5 +239,4 @@ CREATE TABLE IF NOT EXISTS widgets_bundle (
search_text character varying(255),
tenant_id uuid,
title character varying(255)
);
ALTER TABLE widgets_bundle OWNER TO postgres;
);

106
dao/src/main/resources/postgres/system-data.sql

File diff suppressed because one or more lines are too long

4
dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java

@ -22,14 +22,14 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
/**
* Created by Valerii Sosliuk on 4/22/2017.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {JpaDaoConfig.class, JpaDbunitTestConfig.class})
@TestPropertySource("classpath:jpa-test.properties")
@TestExecutionListeners({

2
dao/src/test/java/org/thingsboard/server/dao/plugin/BasePluginServiceTest.java

@ -25,8 +25,6 @@ import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.service.AbstractServiceTest;
import org.junit.Assert;
import org.junit.Test;
import java.util.UUID;

5
dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java

@ -27,7 +27,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.Event;
@ -62,7 +62,8 @@ import java.util.Comparator;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = AbstractServiceTest.class, loader = AnnotationConfigContextLoader.class)
@TestPropertySource(locations = {"classpath:cassandra-test.properties", "classpath:application-test.properties"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)

188
dao/src/test/java/org/thingsboard/server/dao/service/UserServiceImplTest.java

@ -15,13 +15,11 @@
*/
package org.thingsboard.server.dao.service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
@ -32,11 +30,13 @@ import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class UserServiceImplTest extends AbstractServiceTest {
private IdComparator<User> idComparator = new IdComparator<>();
private TenantId tenantId;
@ -96,7 +96,7 @@ public class UserServiceImplTest extends AbstractServiceTest {
Assert.assertNotNull(foundUser);
Assert.assertEquals(user, foundUser);
}
@Test
public void testFindUserCredentials() {
User user = userService.findUserByEmail("sysadmin@thingsboard.org");
@ -104,7 +104,7 @@ public class UserServiceImplTest extends AbstractServiceTest {
UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getId());
Assert.assertNotNull(userCredentials);
}
@Test
public void testSaveUser() {
User tenantAdminUser = userService.findUserByEmail("tenant@thingsboard.org");
@ -124,46 +124,46 @@ public class UserServiceImplTest extends AbstractServiceTest {
Assert.assertNotNull(userCredentials.getId());
Assert.assertNotNull(userCredentials.getUserId());
Assert.assertNotNull(userCredentials.getActivateToken());
savedUser.setFirstName("Joe");
savedUser.setLastName("Downs");
userService.saveUser(savedUser);
savedUser = userService.findUserById(savedUser.getId());
Assert.assertEquals("Joe", savedUser.getFirstName());
Assert.assertEquals("Downs", savedUser.getLastName());
Assert.assertEquals("Downs", savedUser.getLastName());
userService.deleteUser(savedUser.getId());
}
@Test(expected = DataValidationException.class)
public void testSaveUserWithSameEmail() {
User tenantAdminUser = userService.findUserByEmail("tenant@thingsboard.org");
tenantAdminUser.setEmail("sysadmin@thingsboard.org");
userService.saveUser(tenantAdminUser);
}
@Test(expected = DataValidationException.class)
public void testSaveUserWithInvalidEmail() {
User tenantAdminUser = userService.findUserByEmail("tenant@thingsboard.org");
tenantAdminUser.setEmail("tenant_thingsboard.org");
userService.saveUser(tenantAdminUser);
}
@Test(expected = DataValidationException.class)
public void testSaveUserWithEmptyEmail() {
User tenantAdminUser = userService.findUserByEmail("tenant@thingsboard.org");
tenantAdminUser.setEmail(null);
userService.saveUser(tenantAdminUser);
}
@Test(expected = DataValidationException.class)
public void testSaveUserWithoutTenant() {
User tenantAdminUser = userService.findUserByEmail("tenant@thingsboard.org");
tenantAdminUser.setTenantId(null);
userService.saveUser(tenantAdminUser);
}
@Test
public void testDeleteUser() {
User tenantAdminUser = userService.findUserByEmail("tenant@thingsboard.org");
@ -184,7 +184,7 @@ public class UserServiceImplTest extends AbstractServiceTest {
Assert.assertNull(foundUser);
Assert.assertNull(userCredentials);
}
@Test
public void testFindTenantAdmins() {
User tenantAdminUser = userService.findUserByEmail("tenant@thingsboard.org");
@ -193,22 +193,22 @@ public class UserServiceImplTest extends AbstractServiceTest {
List<User> users = pageData.getData();
Assert.assertEquals(1, users.size());
Assert.assertEquals(tenantAdminUser, users.get(0));
Tenant tenant = new Tenant();
tenant.setTitle("Test tenant");
tenant = tenantService.saveTenant(tenant);
TenantId tenantId = tenant.getId();
List<User> tenantAdmins = new ArrayList<>();
for (int i=0;i<124;i++) {
for (int i = 0; i < 124; i++) {
User user = new User();
user.setAuthority(Authority.TENANT_ADMIN);
user.setTenantId(tenantId);
user.setEmail("testTenant" + i + "@thingsboard.org");
tenantAdmins.add(userService.saveUser(user));
}
List<User> loadedTenantAdmins = new ArrayList<>();
TextPageLink pageLink = new TextPageLink(33);
do {
@ -218,57 +218,57 @@ public class UserServiceImplTest extends AbstractServiceTest {
pageLink = pageData.getNextPageLink();
}
} while (pageData.hasNext());
Collections.sort(tenantAdmins, idComparator);
Collections.sort(loadedTenantAdmins, idComparator);
Assert.assertEquals(tenantAdmins, loadedTenantAdmins);
tenantService.deleteTenant(tenantId);
pageLink = new TextPageLink(33);
pageData = userService.findTenantAdmins(tenantId, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertTrue(pageData.getData().isEmpty());
}
@Test
public void testFindTenantAdminsByEmail() {
Tenant tenant = new Tenant();
tenant.setTitle("Test tenant");
tenant = tenantService.saveTenant(tenant);
TenantId tenantId = tenant.getId();
String email1 = "testEmail1";
String email1 = "testEmail1";
List<User> tenantAdminsEmail1 = new ArrayList<>();
for (int i=0;i<94;i++) {
for (int i = 0; i < 94; i++) {
User user = new User();
user.setAuthority(Authority.TENANT_ADMIN);
user.setTenantId(tenantId);
String suffix = RandomStringUtils.randomAlphanumeric((int)(5 + Math.random()*10));
String email = email1+suffix+ "@thingsboard.org";
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String email = email1 + suffix + "@thingsboard.org";
email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase();
user.setEmail(email);
tenantAdminsEmail1.add(userService.saveUser(user));
}
String email2 = "testEmail2";
String email2 = "testEmail2";
List<User> tenantAdminsEmail2 = new ArrayList<>();
for (int i=0;i<132;i++) {
for (int i = 0; i < 132; i++) {
User user = new User();
user.setAuthority(Authority.TENANT_ADMIN);
user.setTenantId(tenantId);
String suffix = RandomStringUtils.randomAlphanumeric((int)(5 + Math.random()*10));
String email = email2+suffix+ "@thingsboard.org";
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String email = email2 + suffix + "@thingsboard.org";
email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase();
user.setEmail(email);
tenantAdminsEmail2.add(userService.saveUser(user));
}
List<User> loadedTenantAdminsEmail1 = new ArrayList<>();
TextPageLink pageLink = new TextPageLink(33, email1);
TextPageData<User> pageData = null;
@ -279,12 +279,12 @@ public class UserServiceImplTest extends AbstractServiceTest {
pageLink = pageData.getNextPageLink();
}
} while (pageData.hasNext());
Collections.sort(tenantAdminsEmail1, idComparator);
Collections.sort(loadedTenantAdminsEmail1, idComparator);
Assert.assertEquals(tenantAdminsEmail1, loadedTenantAdminsEmail1);
List<User> loadedTenantAdminsEmail2 = new ArrayList<>();
pageLink = new TextPageLink(16, email2);
do {
@ -294,33 +294,33 @@ public class UserServiceImplTest extends AbstractServiceTest {
pageLink = pageData.getNextPageLink();
}
} while (pageData.hasNext());
Collections.sort(tenantAdminsEmail2, idComparator);
Collections.sort(loadedTenantAdminsEmail2, idComparator);
Assert.assertEquals(tenantAdminsEmail2, loadedTenantAdminsEmail2);
for (User user : loadedTenantAdminsEmail1) {
userService.deleteUser(user.getId());
}
pageLink = new TextPageLink(4, email1);
pageData = userService.findTenantAdmins(tenantId, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(0, pageData.getData().size());
for (User user : loadedTenantAdminsEmail2) {
userService.deleteUser(user.getId());
}
pageLink = new TextPageLink(4, email2);
pageData = userService.findTenantAdmins(tenantId, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(0, pageData.getData().size());
tenantService.deleteTenant(tenantId);
}
@Test
public void testFindCustomerUsers() {
User customerUser = userService.findUserByEmail("customer@thingsboard.org");
@ -330,22 +330,22 @@ public class UserServiceImplTest extends AbstractServiceTest {
List<User> users = pageData.getData();
Assert.assertEquals(1, users.size());
Assert.assertEquals(customerUser, users.get(0));
Tenant tenant = new Tenant();
tenant.setTitle("Test tenant");
tenant = tenantService.saveTenant(tenant);
TenantId tenantId = tenant.getId();
Customer customer = new Customer();
customer.setTitle("Test customer");
customer.setTenantId(tenantId);
customer = customerService.saveCustomer(customer);
CustomerId customerId = customer.getId();
List<User> customerUsers = new ArrayList<>();
for (int i=0;i<156;i++) {
for (int i = 0; i < 156; i++) {
User user = new User();
user.setAuthority(Authority.CUSTOMER_USER);
user.setTenantId(tenantId);
@ -353,7 +353,7 @@ public class UserServiceImplTest extends AbstractServiceTest {
user.setEmail("testCustomer" + i + "@thingsboard.org");
customerUsers.add(userService.saveUser(user));
}
List<User> loadedCustomerUsers = new ArrayList<>();
TextPageLink pageLink = new TextPageLink(33);
do {
@ -363,65 +363,65 @@ public class UserServiceImplTest extends AbstractServiceTest {
pageLink = pageData.getNextPageLink();
}
} while (pageData.hasNext());
Collections.sort(customerUsers, idComparator);
Collections.sort(loadedCustomerUsers, idComparator);
Assert.assertEquals(customerUsers, loadedCustomerUsers);
tenantService.deleteTenant(tenantId);
pageData = userService.findCustomerUsers(tenantId, customerId, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertTrue(pageData.getData().isEmpty());
}
@Test
public void testFindCustomerUsersByEmail() {
Tenant tenant = new Tenant();
tenant.setTitle("Test tenant");
tenant = tenantService.saveTenant(tenant);
TenantId tenantId = tenant.getId();
Customer customer = new Customer();
customer.setTitle("Test customer");
customer.setTenantId(tenantId);
customer = customerService.saveCustomer(customer);
CustomerId customerId = customer.getId();
String email1 = "testEmail1";
String email1 = "testEmail1";
List<User> customerUsersEmail1 = new ArrayList<>();
for (int i=0;i<124;i++) {
for (int i = 0; i < 124; i++) {
User user = new User();
user.setAuthority(Authority.CUSTOMER_USER);
user.setTenantId(tenantId);
user.setCustomerId(customerId);
String suffix = RandomStringUtils.randomAlphanumeric((int)(5 + Math.random()*10));
String email = email1+suffix+ "@thingsboard.org";
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String email = email1 + suffix + "@thingsboard.org";
email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase();
user.setEmail(email);
customerUsersEmail1.add(userService.saveUser(user));
}
String email2 = "testEmail2";
String email2 = "testEmail2";
List<User> customerUsersEmail2 = new ArrayList<>();
for (int i=0;i<132;i++) {
for (int i = 0; i < 132; i++) {
User user = new User();
user.setAuthority(Authority.CUSTOMER_USER);
user.setTenantId(tenantId);
user.setCustomerId(customerId);
String suffix = RandomStringUtils.randomAlphanumeric((int)(5 + Math.random()*10));
String email = email2+suffix+ "@thingsboard.org";
String suffix = RandomStringUtils.randomAlphanumeric((int) (5 + Math.random() * 10));
String email = email2 + suffix + "@thingsboard.org";
email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase();
user.setEmail(email);
customerUsersEmail2.add(userService.saveUser(user));
}
List<User> loadedCustomerUsersEmail1 = new ArrayList<>();
TextPageLink pageLink = new TextPageLink(33, email1);
TextPageData<User> pageData = null;
@ -432,12 +432,12 @@ public class UserServiceImplTest extends AbstractServiceTest {
pageLink = pageData.getNextPageLink();
}
} while (pageData.hasNext());
Collections.sort(customerUsersEmail1, idComparator);
Collections.sort(loadedCustomerUsersEmail1, idComparator);
Assert.assertEquals(customerUsersEmail1, loadedCustomerUsersEmail1);
List<User> loadedCustomerUsersEmail2 = new ArrayList<>();
pageLink = new TextPageLink(16, email2);
do {
@ -447,30 +447,30 @@ public class UserServiceImplTest extends AbstractServiceTest {
pageLink = pageData.getNextPageLink();
}
} while (pageData.hasNext());
Collections.sort(customerUsersEmail2, idComparator);
Collections.sort(loadedCustomerUsersEmail2, idComparator);
Assert.assertEquals(customerUsersEmail2, loadedCustomerUsersEmail2);
for (User user : loadedCustomerUsersEmail1) {
userService.deleteUser(user.getId());
}
pageLink = new TextPageLink(4, email1);
pageData = userService.findCustomerUsers(tenantId, customerId, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(0, pageData.getData().size());
for (User user : loadedCustomerUsersEmail2) {
userService.deleteUser(user.getId());
}
pageLink = new TextPageLink(4, email2);
pageData = userService.findCustomerUsers(tenantId, customerId, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(0, pageData.getData().size());
tenantService.deleteTenant(tenantId);
}

4
dao/src/test/resources/application-test.properties

@ -9,4 +9,6 @@ zk.zk_dir=/thingsboard
sql.enabled=false
cassandra.enabled=true
cassandra.enabled=true
updates.enabled=false

15
dao/src/test/resources/jpa-test.properties

@ -3,11 +3,10 @@ cassandra.enabled=false
sql.enabled=true
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
spring.jpa.hibernate.ddl-auto=validate
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test;MODE=PostgreSQL
spring.datasource.schema=classpath:postgres/schema.sql
spring.datasource.data=classpath:postgres/system-data.sql;classpath:system-test.sql

66
extensions/extension-kafka/src/test/java/org/thingsboard/server/extensions/kafka/KafkaDemoClient.java

@ -15,6 +15,13 @@
*/
package org.thingsboard.server.extensions.kafka;
import kafka.consumer.Consumer;
import kafka.consumer.ConsumerConfig;
import kafka.consumer.ConsumerIterator;
import kafka.consumer.KafkaStream;
import kafka.javaapi.consumer.ConsumerConnector;
import kafka.message.MessageAndMetadata;
import kafka.serializer.StringDecoder;
import kafka.server.KafkaConfig;
import kafka.server.KafkaServerStartable;
import org.apache.zookeeper.server.ServerConfig;
@ -23,8 +30,14 @@ import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Starts build-in ZK and Kafka and prints messages from CONSUMER_TOPIC
*/
public class KafkaDemoClient {
private static final int ZK_PORT = 2222;
@ -32,17 +45,48 @@ public class KafkaDemoClient {
private static final String ZOOKEEPER_CONNECT = HOSTNAME + ":" + ZK_PORT;
private static final int KAFKA_PORT = 9092;
private static final int BROKER_ID = 1;
private static final String CONSUMER_TOPIC = "test_topic";
public static void main(String[] args) {
try {
startZkLocal();
startKafkaLocal();
startConsumer();
} catch (Exception e) {
System.out.println("Error running local Kafka broker");
e.printStackTrace(System.out);
}
}
private static void startConsumer() throws InterruptedException {
ConsumerIterator<String, String> it = buildConsumer(CONSUMER_TOPIC);
do {
if (it.hasNext()) {
MessageAndMetadata<String, String> messageAndMetadata = it.next();
System.out.println(String.format("Kafka message [%s]", messageAndMetadata.message()));
}
Thread.sleep(100);
} while (true);
}
private static ConsumerIterator<String, String> buildConsumer(String topic) {
Map<String, Integer> topicCountMap = new HashMap<>();
topicCountMap.put(topic, 1);
ConsumerConfig consumerConfig = new ConsumerConfig(consumerProperties());
ConsumerConnector consumerConnector = Consumer.createJavaConsumerConnector(consumerConfig);
Map<String, List<KafkaStream<String, String>>> consumers = consumerConnector.createMessageStreams(topicCountMap, new StringDecoder(null), new StringDecoder(null));
KafkaStream<String, String> stream = consumers.get(topic).get(0);
return stream.iterator();
}
private static Properties consumerProperties() {
Properties props = new Properties();
props.put("zookeeper.connect", ZOOKEEPER_CONNECT);
props.put("group.id", "group1");
props.put("auto.offset.reset", "smallest");
return props;
}
private static void startZkLocal() throws Exception {
final File zkTmpDir = File.createTempFile("zookeeper", "test");
if (zkTmpDir.delete() && zkTmpDir.mkdir()) {
@ -70,14 +114,18 @@ public class KafkaDemoClient {
}
}
private static void startKafkaLocal() {
Properties kafkaProperties = new Properties();
kafkaProperties.setProperty("host.name", HOSTNAME);
kafkaProperties.setProperty("port", String.valueOf(KAFKA_PORT));
kafkaProperties.setProperty("broker.id", String.valueOf(BROKER_ID));
kafkaProperties.setProperty("zookeeper.connect", ZOOKEEPER_CONNECT);
KafkaConfig kafkaConfig = new KafkaConfig(kafkaProperties);
KafkaServerStartable kafka = new KafkaServerStartable(kafkaConfig);
kafka.startup();
private static void startKafkaLocal() throws Exception {
final File kafkaTmpLogsDir = File.createTempFile("zookeeper", "test");
if (kafkaTmpLogsDir.delete() && kafkaTmpLogsDir.mkdir()) {
Properties kafkaProperties = new Properties();
kafkaProperties.setProperty("host.name", HOSTNAME);
kafkaProperties.setProperty("port", String.valueOf(KAFKA_PORT));
kafkaProperties.setProperty("broker.id", String.valueOf(BROKER_ID));
kafkaProperties.setProperty("zookeeper.connect", ZOOKEEPER_CONNECT);
kafkaProperties.setProperty("log.dirs", kafkaTmpLogsDir.getAbsolutePath());
KafkaConfig kafkaConfig = new KafkaConfig(kafkaProperties);
KafkaServerStartable kafka = new KafkaServerStartable(kafkaConfig);
kafka.startup();
}
}
}

10
extensions/extension-kafka/src/test/resources/logback.xml

@ -0,0 +1,10 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

3
tools/test.properties

@ -1,3 +0,0 @@
deviceCount=1000
durationMs=5000
iterationIntervalMs=250

28
transport/coap/src/test/java/org/thingsboard/server/transport/coap/CoapServerTest.java

@ -20,6 +20,16 @@ import org.eclipse.californium.core.CoapClient;
import org.eclipse.californium.core.CoapResponse;
import org.eclipse.californium.core.coap.CoAP.ResponseCode;
import org.eclipse.californium.core.coap.MediaTypeRegistry;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.junit4.SpringRunner;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
@ -37,21 +47,7 @@ import org.thingsboard.server.common.msg.core.BasicRequest;
import org.thingsboard.server.common.msg.core.BasicStatusCodeResponse;
import org.thingsboard.server.common.msg.kv.BasicAttributeKVMsg;
import org.thingsboard.server.common.msg.session.*;
import org.thingsboard.server.common.msg.session.ex.SessionAuthException;
import org.thingsboard.server.common.transport.SessionMsgProcessor;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.thingsboard.server.common.transport.auth.DeviceAuthResult;
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
@ -60,8 +56,7 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@RunWith(SpringRunner.class)
@DirtiesContext(classMode = ClassMode.BEFORE_CLASS)
@Slf4j
public class CoapServerTest {
@ -70,7 +65,6 @@ public class CoapServerTest {
private static final String TELEMETRY_POST_MESSAGE = "[{\"key1\":\"value1\"}]";
private static final String TEST_ATTRIBUTES_RESPONSE = "{\"key1\":\"value1\",\"key2\":42}";
private static final String DEVICE1_TOKEN = "Device1Token";
private static final String DEVICE2_TOKEN = "Device2Token";
@Configuration
public static class EchoCoapServerITConfiguration extends CoapServerTestConfiguration {

Loading…
Cancel
Save