Browse Source

JsonNode values saved to postgres as jsonb type

pull/118/head
mp-loki 10 years ago
parent
commit
e80cb31a15
  1. 5
      dao/pom.xml
  2. 25
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java
  3. 25
      dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java
  4. 21
      dao/src/main/java/org/thingsboard/server/dao/model/sql/CustomerEntity.java
  5. 27
      dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java
  6. 27
      dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java
  7. 24
      dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java
  8. 45
      dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java
  9. 78
      dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java
  10. 25
      dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java
  11. 24
      dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java
  12. 34
      dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java
  13. 3
      dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
  14. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/component/JpaBaseComponentDescriptorDao.java
  15. 2
      dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java
  16. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java
  17. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardDao.java
  18. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java
  19. 7
      dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceCredentialsDao.java
  20. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java
  21. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java
  22. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDao.java
  23. 4
      dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDao.java
  24. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/settings/JpaAdminSettingsDao.java
  25. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDao.java
  26. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java
  27. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java
  28. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDao.java
  29. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java
  30. 60
      dao/src/main/java/org/thingsboard/server/dao/util/JacksonUtil.java
  31. 114
      dao/src/main/java/org/thingsboard/server/dao/util/JsonBinarySqlTypeDescriptor.java
  32. 44
      dao/src/main/java/org/thingsboard/server/dao/util/JsonBinaryType.java
  33. 95
      dao/src/main/java/org/thingsboard/server/dao/util/JsonTypeDescriptor.java
  34. 5
      dao/src/test/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDaoTest.java
  35. 46
      dao/src/test/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDaoTest.java
  36. 3
      dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserDaoTest.java
  37. 4
      dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java
  38. 5
      dao/src/test/resources/dbunit/users.xml

5
dao/pom.xml

@ -173,11 +173,6 @@
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>

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

@ -25,9 +25,12 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;
import org.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 java.io.IOException;
import java.util.UUID;
@ -35,8 +38,8 @@ import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.*;
@Data
@Slf4j
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ADMIN_SETTINGS_COLUMN_FAMILY_NAME)
public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
@ -50,8 +53,9 @@ public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
@Column(name = ADMIN_SETTINGS_KEY_PROPERTY)
private String key;
@Column(name = ADMIN_SETTINGS_JSON_VALUE_PROPERTY)
private String jsonValue;
@Type(type = "jsonb")
@Column(name = ADMIN_SETTINGS_JSON_VALUE_PROPERTY, columnDefinition = "jsonb")
private JsonNode jsonValue;
public AdminSettingsEntity() {
super();
@ -62,9 +66,7 @@ public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
this.id = adminSettings.getId().getId();
}
this.key = adminSettings.getKey();
if (jsonValue != null) {
this.jsonValue = adminSettings.getJsonValue().toString();
}
this.jsonValue = adminSettings.getJsonValue();
}
@Override
@ -132,16 +134,7 @@ public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
AdminSettings adminSettings = new AdminSettings(new AdminSettingsId(id));
adminSettings.setCreatedTime(UUIDs.unixTimestamp(id));
adminSettings.setKey(key);
if (jsonValue != null) {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = null;
try {
jsonNode = mapper.readTree(jsonValue);
adminSettings.setJsonValue(jsonNode);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
adminSettings.setJsonValue(jsonValue);
return adminSettings;
}

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

@ -24,19 +24,22 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.ComponentDescriptorId;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
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 java.io.IOException;
import java.util.UUID;
@Data
@Slf4j
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.COMPONENT_DESCRIPTOR_COLUMN_FAMILY_NAME)
public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDescriptor> {
@ -59,8 +62,9 @@ public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDesc
@Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CLASS_PROPERTY)
private String clazz;
@Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CONFIGURATION_DESCRIPTOR_PROPERTY)
private String configurationDescriptor;
@Type(type = "jsonb")
@Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CONFIGURATION_DESCRIPTOR_PROPERTY, columnDefinition = "jsonb")
private JsonNode configurationDescriptor;
@Column(name = ModelConstants.COMPONENT_DESCRIPTOR_ACTIONS_PROPERTY)
private String actions;
@ -80,9 +84,7 @@ public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDesc
this.scope = component.getScope();
this.name = component.getName();
this.clazz = component.getClazz();
if (configurationDescriptor != null) {
this.configurationDescriptor = component.getConfigurationDescriptor().toString();
}
this.configurationDescriptor = component.getConfigurationDescriptor();
this.searchText = component.getName();
}
@ -94,16 +96,7 @@ public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDesc
data.setName(this.getName());
data.setClazz(this.getClazz());
data.setActions(this.getActions());
if (configurationDescriptor != null) {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = null;
try {
jsonNode = mapper.readTree(configurationDescriptor);
data.setConfigurationDescriptor(jsonNode);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
data.setConfigurationDescriptor(configurationDescriptor);
return data;
}

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

@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
@ -35,7 +36,6 @@ import java.io.IOException;
import java.util.UUID;
@Data
@Slf4j
@Entity
@Table(name = ModelConstants.CUSTOMER_COLUMN_FAMILY_NAME)
public final class CustomerEntity implements SearchTextEntity<Customer> {
@ -80,8 +80,9 @@ public final class CustomerEntity implements SearchTextEntity<Customer> {
@Column(name = ModelConstants.EMAIL_PROPERTY)
private String email;
@Column(name = ModelConstants.CUSTOMER_ADDITIONAL_INFO_PROPERTY)
private String additionalInfo;
@Type(type = "jsonb")
@Column(name = ModelConstants.CUSTOMER_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
private JsonNode additionalInfo;
public CustomerEntity() {
super();
@ -101,9 +102,7 @@ public final class CustomerEntity implements SearchTextEntity<Customer> {
this.zip = customer.getZip();
this.phone = customer.getPhone();
this.email = customer.getEmail();
if (additionalInfo != null) {
this.additionalInfo = customer.getAdditionalInfo().toString();
}
this.additionalInfo = customer.getAdditionalInfo();
}
@Override
@ -262,15 +261,7 @@ public final class CustomerEntity implements SearchTextEntity<Customer> {
customer.setZip(zip);
customer.setPhone(phone);
customer.setEmail(email);
if (additionalInfo != null) {
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode jsonNode = mapper.readTree(additionalInfo);
customer.setAdditionalInfo(jsonNode);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
customer.setAdditionalInfo(additionalInfo);
return customer;
}
}

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

@ -25,19 +25,22 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.id.CustomerId;
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 java.io.IOException;
import java.util.UUID;
@Data
@Slf4j
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.DASHBOARD_COLUMN_FAMILY_NAME)
public final class DashboardEntity implements SearchTextEntity<Dashboard> {
@ -59,9 +62,10 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> {
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
@Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY)
private String configuration;
@Type(type = "jsonb")
@Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY, columnDefinition = "jsonb")
private JsonNode configuration;
public DashboardEntity() {
super();
@ -78,9 +82,7 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> {
this.customerId = dashboard.getCustomerId().getId();
}
this.title = dashboard.getTitle();
if (configuration != null) {
this.configuration = dashboard.getConfiguration().toString();
}
this.configuration = dashboard.getConfiguration();
}
@Override
@ -191,16 +193,7 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> {
dashboard.setCustomerId(new CustomerId(customerId));
}
dashboard.setTitle(title);
if (configuration != null) {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = null;
try {
jsonNode = mapper.readTree(configuration);
dashboard.setConfiguration(jsonNode);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
dashboard.setConfiguration(configuration);
return dashboard;
}
}

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

@ -25,19 +25,22 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.JsonBinaryType;
import java.io.IOException;
import java.util.UUID;
@Data
@Slf4j
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.DEVICE_COLUMN_FAMILY_NAME)
public final class DeviceEntity implements SearchTextEntity<Device> {
@ -59,9 +62,10 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
@Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY)
private String additionalInfo;
@Type(type = "jsonb")
@Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
private JsonNode additionalInfo;
public DeviceEntity() {
super();
@ -78,9 +82,7 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
this.customerId = device.getCustomerId().getId();
}
this.name = device.getName();
if (additionalInfo != null) {
this.additionalInfo = device.getAdditionalInfo().toString();
}
this.additionalInfo = device.getAdditionalInfo();
}
@Override
@ -174,16 +176,7 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
device.setCustomerId(new CustomerId(customerId));
}
device.setName(name);
if (additionalInfo != null) {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = null;
try {
jsonNode = mapper.readTree(additionalInfo);
device.setAdditionalInfo(jsonNode);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
device.setAdditionalInfo(additionalInfo);
return device;
}
}

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

@ -26,10 +26,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.*;
@ -37,9 +40,9 @@ import java.io.IOException;
import java.util.UUID;
@Data
@Slf4j
@NoArgsConstructor
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = EVENT_COLUMN_FAMILY_NAME)
public class EventEntity implements BaseEntity<Event> {
@ -65,8 +68,9 @@ public class EventEntity implements BaseEntity<Event> {
@Column(name = EVENT_UID_PROPERTY)
private String eventUid;
@Column(name = EVENT_BODY_PROPERTY)
private String body;
@Type(type = "jsonb")
@Column(name = EVENT_BODY_PROPERTY, columnDefinition = "jsonb")
private JsonNode body;
public EventEntity(Event event) {
if (event.getId() != null) {
@ -81,9 +85,7 @@ public class EventEntity implements BaseEntity<Event> {
}
this.eventType = event.getType();
this.eventUid = event.getUid();
if (event.getBody() != null) {
this.body = event.getBody().toString();
}
this.body = event.getBody();
}
@Override
@ -118,15 +120,7 @@ public class EventEntity implements BaseEntity<Event> {
event.setEntityId(new PluginId(entityId));
break;
}
ObjectMapper mapper = new ObjectMapper();
if (body != null) {
try {
JsonNode jsonNode = mapper.readTree(body);
event.setBody(jsonNode);
} catch (IOException e) {
log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", body, e.getMessage()), e);
}
}
event.setBody(body);
event.setType(eventType);
event.setUid(eventUid);
return event;

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

@ -25,19 +25,23 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.PluginId;
import org.thingsboard.server.common.data.id.TenantId;
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 java.io.IOException;
import java.util.Objects;
import java.util.UUID;
@Slf4j
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.PLUGIN_COLUMN_FAMILY_NAME)
public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
@ -65,15 +69,17 @@ public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
@Column(name = ModelConstants.PLUGIN_STATE_PROPERTY)
private ComponentLifecycleState state;
@Column(name = ModelConstants.PLUGIN_CONFIGURATION_PROPERTY)
private String configuration;
@Type(type = "jsonb")
@Column(name = ModelConstants.PLUGIN_CONFIGURATION_PROPERTY, columnDefinition = "jsonb")
private JsonNode configuration;
@Type(type = "jsonb")
@Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
private JsonNode additionalInfo;
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
@Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY)
private String additionalInfo;
public PluginMetaDataEntity() {
}
@ -88,12 +94,8 @@ public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
this.publicAccess = pluginMetaData.isPublicAccess();
this.state = pluginMetaData.getState();
this.searchText = pluginMetaData.getName();
if (pluginMetaData.getConfiguration() != null) {
this.configuration = pluginMetaData.getConfiguration().toString();
}
if (pluginMetaData.getAdditionalInfo() != null) {
this.additionalInfo = pluginMetaData.getAdditionalInfo().toString();
}
this.configuration = pluginMetaData.getConfiguration();
this.additionalInfo = pluginMetaData.getAdditionalInfo();
}
@Override
@ -126,23 +128,8 @@ public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
data.setPublicAccess(publicAccess);
data.setState(state);
data.setApiToken(apiToken);
ObjectMapper mapper = new ObjectMapper();
if (configuration != null) {
try {
JsonNode jsonNode = mapper.readTree(configuration);
data.setConfiguration(jsonNode);
} catch (IOException e) {
log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", configuration, e.getMessage()), e);
}
}
if (additionalInfo != null) {
try {
JsonNode jsonNode = mapper.readTree(additionalInfo);
data.setAdditionalInfo(jsonNode);
} catch (IOException e) {
log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
}
}
data.setConfiguration(configuration);
data.setAdditionalInfo(additionalInfo);
return data;
}

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

@ -27,6 +27,8 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.RuleId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
@ -34,14 +36,15 @@ 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 java.io.IOException;
import java.util.Objects;
import java.util.UUID;
@Slf4j
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.RULE_COLUMN_FAMILY_NAME)
public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
@ -62,14 +65,18 @@ public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
private String searchText;
@Column(name = ModelConstants.RULE_PLUGIN_TOKEN_PROPERTY)
private String pluginToken;
@Column(name = ModelConstants.RULE_FILTERS)
private String filters;
@Column(name = ModelConstants.RULE_PROCESSOR)
private String processor;
@Column(name = ModelConstants.RULE_ACTION)
private String action;
@Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY)
private String additionalInfo;
@Type(type = "jsonb")
@Column(name = ModelConstants.RULE_FILTERS, columnDefinition = "jsonb")
private JsonNode filters;
@Type(type = "jsonb")
@Column(name = ModelConstants.RULE_PROCESSOR, columnDefinition = "jsonb")
private JsonNode processor;
@Type(type = "jsonb")
@Column(name = ModelConstants.RULE_ACTION, columnDefinition = "jsonb")
private JsonNode action;
@Type(type = "jsonb")
@Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
private JsonNode additionalInfo;
public RuleMetaDataEntity() {
}
@ -84,18 +91,10 @@ public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
this.state = rule.getState();
this.weight = rule.getWeight();
this.searchText = rule.getName();
if (rule.getFilters() != null) {
this.filters = rule.getFilters().toString();
}
if (rule.getProcessor() != null) {
this.processor = rule.getProcessor().toString();
}
if (rule.getAction() != null) {
this.action = rule.getAction().toString();
}
if (rule.getAdditionalInfo() != null) {
this.additionalInfo = rule.getAdditionalInfo().toString();
}
this.filters = rule.getFilters();
this.processor = rule.getProcessor();
this.action = rule.getAction();
this.additionalInfo = rule.getAdditionalInfo();
}
@Override
@ -127,39 +126,10 @@ public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
rule.setWeight(weight);
rule.setCreatedTime(UUIDs.unixTimestamp(id));
rule.setPluginToken(pluginToken);
ObjectMapper mapper = new ObjectMapper();
if (filters != null) {
try {
JsonNode jsonNode = mapper.readTree(filters);
rule.setFilters(jsonNode);
} catch (IOException e) {
log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", filters, e.getMessage()), e);
}
}
if (processor != null) {
try {
JsonNode jsonNode = mapper.readTree(processor);
rule.setProcessor(jsonNode);
} catch (IOException e) {
log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", processor, e.getMessage()), e);
}
}
if (action != null) {
try {
JsonNode jsonNode = mapper.readTree(action);
rule.setAction(jsonNode);
} catch (IOException e) {
log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", action, e.getMessage()), e);
}
}
if (additionalInfo != null) {
try {
JsonNode jsonNode = mapper.readTree(additionalInfo);
rule.setAdditionalInfo(jsonNode);
} catch (IOException e) {
log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
}
}
rule.setFilters(filters);
rule.setProcessor(processor);
rule.setAction(action);
rule.setAdditionalInfo(additionalInfo);
return rule;
}

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

@ -26,18 +26,21 @@ import javax.persistence.Transient;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
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 java.io.IOException;
import java.util.UUID;
@Slf4j
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.TENANT_COLUMN_FAMILY_NAME)
public final class TenantEntity implements SearchTextEntity<Tenant> {
@ -81,8 +84,9 @@ public final class TenantEntity implements SearchTextEntity<Tenant> {
@Column(name = ModelConstants.EMAIL_PROPERTY)
private String email;
@Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY)
private String additionalInfo;
@Type(type="jsonb")
@Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
private JsonNode additionalInfo;
public TenantEntity() {
super();
@ -102,12 +106,9 @@ public final class TenantEntity implements SearchTextEntity<Tenant> {
this.zip = tenant.getZip();
this.phone = tenant.getPhone();
this.email = tenant.getEmail();
if (tenant.getAdditionalInfo() != null) {
this.additionalInfo = tenant.getAdditionalInfo().toString();
}
this.additionalInfo = tenant.getAdditionalInfo();
}
@Override
public String getSearchTextSource() {
return title;
@ -258,15 +259,7 @@ public final class TenantEntity implements SearchTextEntity<Tenant> {
tenant.setZip(zip);
tenant.setPhone(phone);
tenant.setEmail(email);
ObjectMapper mapper = new ObjectMapper();
if (additionalInfo != null) {
try {
JsonNode jsonNode = mapper.readTree(additionalInfo);
tenant.setAdditionalInfo(jsonNode);
} catch (IOException e) {
log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
}
}
tenant.setAdditionalInfo(additionalInfo);
return tenant;
}

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

@ -20,6 +20,8 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
@ -27,6 +29,7 @@ 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 javax.persistence.*;
import java.io.IOException;
@ -35,9 +38,9 @@ import java.util.UUID;
/**
* Created by Valerii Sosliuk on 4/21/2017.
*/
@Slf4j
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.USER_PG_HIBERNATE_COLUMN_FAMILY_NAME)
public class UserEntity implements SearchTextEntity<User> {
@Transient
@ -68,8 +71,9 @@ public class UserEntity implements SearchTextEntity<User> {
@Column(name = ModelConstants.USER_LAST_NAME_PROPERTY)
private String lastName;
@Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY)
private String additionalInfo;
@Type(type="jsonb")
@Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
private JsonNode additionalInfo;
public UserEntity() {
}
@ -88,9 +92,7 @@ public class UserEntity implements SearchTextEntity<User> {
this.email = user.getEmail();
this.firstName = user.getFirstName();
this.lastName = user.getLastName();
if (user.getAdditionalInfo() != null) {
this.additionalInfo = user.getAdditionalInfo().toString();
}
this.additionalInfo = user.getAdditionalInfo();
}
@Override
@ -150,15 +152,7 @@ public class UserEntity implements SearchTextEntity<User> {
user.setEmail(email);
user.setFirstName(firstName);
user.setLastName(lastName);
ObjectMapper mapper = new ObjectMapper();
if (additionalInfo != null) {
try {
JsonNode jsonNode = mapper.readTree(additionalInfo);
user.setAdditionalInfo(jsonNode);
} catch (IOException e) {
log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
}
}
user.setAdditionalInfo(additionalInfo);
return user;
}

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

@ -16,29 +16,24 @@
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.datastax.driver.mapping.annotations.PartitionKey;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.TenantId;
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 java.io.IOException;
import javax.persistence.*;
import java.util.UUID;
@Slf4j
@Data
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.WIDGET_TYPE_COLUMN_FAMILY_NAME)
public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
@ -63,8 +58,9 @@ public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
@Column(name = ModelConstants.WIDGET_TYPE_NAME_PROPERTY)
private String name;
@Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY)
private String descriptor;
@Type(type="jsonb")
@Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY, columnDefinition = "jsonb")
private JsonNode descriptor;
public WidgetTypeEntity() {
super();
@ -80,9 +76,7 @@ public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
this.bundleAlias = widgetType.getBundleAlias();
this.alias = widgetType.getAlias();
this.name = widgetType.getName();
if (widgetType.getDescriptor() != null) {
this.descriptor = widgetType.getDescriptor().toString();
}
this.descriptor = widgetType.getDescriptor();
}
@Override
@ -144,15 +138,7 @@ public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
widgetType.setBundleAlias(bundleAlias);
widgetType.setAlias(alias);
widgetType.setName(name);
ObjectMapper mapper = new ObjectMapper();
if (descriptor != null) {
try {
JsonNode jsonNode = mapper.readTree(descriptor);
widgetType.setDescriptor(jsonNode);
} catch (IOException e) {
log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", descriptor, e.getMessage()), e);
}
}
widgetType.setDescriptor(descriptor);
return widgetType;
}

3
dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java

@ -41,8 +41,6 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D> implements Dao<
protected abstract Class<E> getEntityClass();
protected abstract String getColumnFamilyName();
protected abstract CrudRepository<E, UUID> getCrudRepository();
protected boolean isSearchTextDao() {
@ -93,7 +91,6 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D> implements Dao<
@Override
public List<D> find() {
log.debug("Get all entities from column family {}", getColumnFamilyName());
List<E> entities = Lists.newArrayList(getCrudRepository().findAll());
return DaoUtil.convertDataList(entities);
}

5
dao/src/main/java/org/thingsboard/server/dao/sql/component/JpaBaseComponentDescriptorDao.java

@ -50,11 +50,6 @@ public class JpaBaseComponentDescriptorDao extends JpaAbstractSearchTextDao<Comp
return ComponentDescriptorEntity.class;
}
@Override
protected String getColumnFamilyName() {
return ModelConstants.COMPONENT_DESCRIPTOR_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<ComponentDescriptorEntity, UUID> getCrudRepository() {
return componentDescriptorRepository;

2
dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java

@ -40,6 +40,4 @@ public interface CustomerRepository extends CrudRepository<CustomerEntity, UUID>
"AND ID > ?4 ORDER BY ID LIMIT ?1")
List<CustomerEntity> findByTenantIdNextPage(int limit, UUID tenantId, String textSearch, UUID idOffset);
@Query(nativeQuery = true, value = "SELECT * FROM CUSTOMER WHERE TENANT_ID = ?1")
List<CustomerEntity> findByTenantId(UUID tenantId);
}

5
dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java

@ -45,11 +45,6 @@ public class JpaCustomerDao extends JpaAbstractSearchTextDao<CustomerEntity, Cus
return CustomerEntity.class;
}
@Override
protected String getColumnFamilyName() {
return ModelConstants.CUSTOMER_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<CustomerEntity, UUID> getCrudRepository() {
return customerRepository;

5
dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardDao.java

@ -43,11 +43,6 @@ public class JpaDashboardDao extends JpaAbstractSearchTextDao<DashboardEntity, D
return DashboardEntity.class;
}
@Override
protected String getColumnFamilyName() {
return DASHBOARD_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<DashboardEntity, UUID> getCrudRepository() {
return dashboardRepository;

5
dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java

@ -46,11 +46,6 @@ public class JpaDashboardInfoDao extends JpaAbstractSearchTextDao<DashboardInfoE
return DashboardInfoEntity.class;
}
@Override
protected String getColumnFamilyName() {
return DASHBOARD_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository getCrudRepository() {
return dashboardInfoRepository;

7
dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceCredentialsDao.java

@ -43,13 +43,6 @@ public class JpaDeviceCredentialsDao extends JpaAbstractDao<DeviceCredentialsEnt
return DeviceCredentialsEntity.class;
}
@Override
protected String getColumnFamilyName() {
{
return ModelConstants.DEVICE_CREDENTIALS_COLUMN_FAMILY_NAME;
}
}
@Override
protected CrudRepository<DeviceCredentialsEntity, UUID> getCrudRepository() {
return deviceCredentialsRepository;

5
dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java

@ -51,11 +51,6 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device>
return DeviceEntity.class;
}
@Override
protected String getColumnFamilyName() {
return DEVICE_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<DeviceEntity, UUID> getCrudRepository() {
return deviceRepository;

5
dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java

@ -66,11 +66,6 @@ public class JpaBaseEventDao extends JpaAbstractSearchTimeDao<EventEntity, Event
return EventEntity.class;
}
@Override
protected String getColumnFamilyName() {
return EVENT_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<EventEntity, UUID> getCrudRepository() {
return eventRepository;

5
dao/src/main/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDao.java

@ -51,11 +51,6 @@ public class JpaBasePluginDao extends JpaAbstractSearchTextDao<PluginMetaDataEnt
return PluginMetaDataEntity.class;
}
@Override
protected String getColumnFamilyName() {
return ModelConstants.PLUGIN_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<PluginMetaDataEntity, UUID> getCrudRepository() {
return pluginMetaDataRepository;

4
dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDao.java

@ -50,10 +50,6 @@ public class JpaBaseRuleDao extends JpaAbstractSearchTextDao<RuleMetaDataEntity,
protected Class<RuleMetaDataEntity> getEntityClass() {
return RuleMetaDataEntity.class;
}
@Override
protected String getColumnFamilyName() {
return ModelConstants.RULE_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<RuleMetaDataEntity, UUID> getCrudRepository() {

5
dao/src/main/java/org/thingsboard/server/dao/sql/settings/JpaAdminSettingsDao.java

@ -40,11 +40,6 @@ public class JpaAdminSettingsDao extends JpaAbstractDao<AdminSettingsEntity, Adm
return AdminSettingsEntity.class;
}
@Override
protected String getColumnFamilyName() {
return ADMIN_SETTINGS_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<AdminSettingsEntity, UUID> getCrudRepository() {
return adminSettingsRepository;

5
dao/src/main/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDao.java

@ -47,11 +47,6 @@ public class JpaTenantDao extends JpaAbstractSearchTextDao<TenantEntity, Tenant>
return TenantEntity.class;
}
@Override
protected String getColumnFamilyName() {
return TENANT_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<TenantEntity, UUID> getCrudRepository() {
return tenantRepository;

5
dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java

@ -44,11 +44,6 @@ public class JpaUserCredentialsDao extends JpaAbstractDao<UserCredentialsEntity,
return UserCredentialsEntity.class;
}
@Override
protected String getColumnFamilyName() {
return ModelConstants.USER_CREDENTIALS_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<UserCredentialsEntity, UUID> getCrudRepository() {
return userCredentialsRepository;

5
dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java

@ -45,11 +45,6 @@ public class JpaUserDao extends JpaAbstractDao<UserEntity, User> implements User
return UserEntity.class;
}
@Override
protected String getColumnFamilyName() {
return ModelConstants.USER_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<UserEntity, UUID> getCrudRepository() {
return userRepository;

5
dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDao.java

@ -45,11 +45,6 @@ public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeEntity, WidgetTyp
return WidgetTypeEntity.class;
}
@Override
protected String getColumnFamilyName() {
return WIDGET_TYPE_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<WidgetTypeEntity, UUID> getCrudRepository() {
return widgetTypeRepository;

5
dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java

@ -47,11 +47,6 @@ public class JpaWidgetsBundleDao extends JpaAbstractSearchTextDao<WidgetsBundleE
return WidgetsBundleEntity.class;
}
@Override
protected String getColumnFamilyName() {
return WIDGETS_BUNDLE_COLUMN_FAMILY_NAME;
}
@Override
protected CrudRepository<WidgetsBundleEntity, UUID> getCrudRepository() {
return widgetsBundleRepository;

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

@ -0,0 +1,60 @@
/**
* 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 com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* Created by Valerii Sosliuk on 5/12/2017.
*/
public class JacksonUtil {
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
public static <T> T fromString(String string, Class<T> clazz) {
try {
return OBJECT_MAPPER.readValue(string, clazz);
} catch (IOException e) {
throw new IllegalArgumentException("The given string value: "
+ string + " cannot be transformed to Json object");
}
}
public static String toString(Object value) {
try {
return OBJECT_MAPPER.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("The given Json object value: "
+ value + " cannot be transformed to a String");
}
}
public static JsonNode toJsonNode(String value) {
try {
return OBJECT_MAPPER.readTree(value);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
public static <T> T clone(T value) {
return fromString(toString(value), (Class<T>) value.getClass());
}
}

114
dao/src/main/java/org/thingsboard/server/dao/util/JsonBinarySqlTypeDescriptor.java

@ -0,0 +1,114 @@
/**
* 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 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.*;
/**
* Created by Valerii Sosliuk on 5/12/2017.
*/
public class JsonBinarySqlTypeDescriptor
implements SqlTypeDescriptor {
public static final JsonBinarySqlTypeDescriptor INSTANCE =
new JsonBinarySqlTypeDescriptor();
@Override
public int getSqlType() {
return Types.OTHER;
}
@Override
public boolean canBeRemapped() {
return true;
}
@Override
public <X> ValueExtractor<X> getExtractor(
final JavaTypeDescriptor<X> javaTypeDescriptor) {
return new BasicExtractor<X>(javaTypeDescriptor, this) {
@Override
protected X doExtract(
ResultSet rs,
String name,
WrapperOptions options) throws SQLException {
return javaTypeDescriptor.wrap(
rs.getObject(name), options
);
}
@Override
protected X doExtract(
CallableStatement statement,
int index,
WrapperOptions options) throws SQLException {
return javaTypeDescriptor.wrap(
statement.getObject(index), options
);
}
@Override
protected X doExtract(
CallableStatement statement,
String name,
WrapperOptions options) throws SQLException {
return javaTypeDescriptor.wrap(
statement.getObject(name), options
);
}
};
}
@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()
);
}
};
}
}

44
dao/src/main/java/org/thingsboard/server/dao/util/JsonBinaryType.java

@ -0,0 +1,44 @@
/**
* 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.AbstractSingleColumnStandardBasicType;
import org.hibernate.usertype.DynamicParameterizedType;
import java.util.Properties;
/**
* Created by Valerii Sosliuk on 5/12/2017.
*/
public class JsonBinaryType extends AbstractSingleColumnStandardBasicType<Object>
implements DynamicParameterizedType {
public JsonBinaryType() {
super(
JsonBinarySqlTypeDescriptor.INSTANCE,
new JsonTypeDescriptor()
);
}
public String getName() {
return "jsonb";
}
@Override
public void setParameterValues(Properties parameters) {
((JsonTypeDescriptor) getJavaTypeDescriptor())
.setParameterValues(parameters);
}}

95
dao/src/main/java/org/thingsboard/server/dao/util/JsonTypeDescriptor.java

@ -0,0 +1,95 @@
/**
* 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.WrapperOptions;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.java.MutableMutabilityPlan;
import org.hibernate.usertype.DynamicParameterizedType;
import java.util.Properties;
/**
* Created by Valerii Sosliuk on 5/12/2017.
*/
public class JsonTypeDescriptor
extends AbstractTypeDescriptor<Object>
implements DynamicParameterizedType {
private Class<?> jsonObjectClass;
@Override
public void setParameterValues(Properties parameters) {
jsonObjectClass = ( (ParameterType) parameters.get( PARAMETER_TYPE ) )
.getReturnedClass();
}
public JsonTypeDescriptor() {
super( Object.class, new MutableMutabilityPlan<Object>() {
@Override
protected Object deepCopyNotNull(Object value) {
return JacksonUtil.clone(value);
}
});
}
@Override
public boolean areEqual(Object one, Object another) {
if ( one == another ) {
return true;
}
if ( one == null || another == null ) {
return false;
}
return JacksonUtil.toJsonNode(JacksonUtil.toString(one)).equals(
JacksonUtil.toJsonNode(JacksonUtil.toString(another)));
}
@Override
public String toString(Object value) {
return JacksonUtil.toString(value);
}
@Override
public Object fromString(String string) {
return JacksonUtil.fromString(string, jsonObjectClass);
}
@SuppressWarnings({ "unchecked" })
@Override
public <X> X unwrap(Object value, Class<X> type, WrapperOptions options) {
if ( value == null ) {
return null;
}
if ( String.class.isAssignableFrom( type ) ) {
return (X) toString(value);
}
if ( Object.class.isAssignableFrom( type ) ) {
return (X) JacksonUtil.toJsonNode(toString(value));
}
throw unknownUnwrap( type );
}
@Override
public <X> Object wrap(X value, WrapperOptions options) {
if ( value == null ) {
return null;
}
return fromString(value.toString());
}
}

5
dao/src/test/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDaoTest.java

@ -16,7 +16,9 @@
package org.thingsboard.server.dao.sql.plugin;
import com.datastax.driver.core.utils.UUIDs;
import com.github.springtestdbunit.annotation.DatabaseOperation;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.DatabaseTearDown;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.server.common.data.id.PluginId;
@ -45,7 +47,6 @@ public class JpaBasePluginDaoTest extends AbstractJpaDaoTest {
UUID tenantId1 = UUIDs.timeBased();
UUID tenantId2 = UUIDs.timeBased();
createPluginsTwoTenants(tenantId1, tenantId2, "plugin_");
assertEquals(60, pluginDao.find().size());
List<PluginMetaData> rules1 = pluginDao.findByTenantIdAndPageLink(
new TenantId(tenantId1), new TextPageLink(20, "plugin_"));
assertEquals(20, rules1.size());
@ -60,7 +61,7 @@ public class JpaBasePluginDaoTest extends AbstractJpaDaoTest {
}
@Test
@DatabaseSetup("classpath:dbunit/empty_dataset.xml")
@DatabaseSetup(value = "classpath:dbunit/empty_dataset.xml")
public void testFindAllTenantRulesByTenantId() {
UUID tenantId1 = UUIDs.timeBased();
UUID tenantId2 = UUIDs.timeBased();

46
dao/src/test/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDaoTest.java

@ -16,6 +16,7 @@
package org.thingsboard.server.dao.sql.rule;
import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.rule.RuleMetaData;
import org.thingsboard.server.dao.AbstractJpaDaoTest;
import org.thingsboard.server.dao.rule.RuleDao;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
@ -38,12 +40,38 @@ import static org.junit.Assert.assertNotNull;
public class JpaBaseRuleDaoTest extends AbstractJpaDaoTest {
@Autowired
private RuleDao jpaBaseRuleDao;
private RuleDao ruleDao;
@Test
@DatabaseSetup("classpath:dbunit/empty_dataset.xml")
public void testSave() throws IOException {
UUID id = UUIDs.timeBased();
RuleMetaData ruleMetaData = new RuleMetaData();
ruleMetaData.setId(new RuleId(id));
ruleMetaData.setTenantId(new TenantId(UUIDs.timeBased()));
ruleMetaData.setName("test");
String filters = "{\"filters\":\"value-1\"}";
String processor = "{\"processor\":\"value-2\"}";
String action = "{\"action\":\"value-3\"}";
String additionalInfo = "{\"additionalInfo\":\"value-4\"}";
ObjectMapper mapper = new ObjectMapper();
ruleMetaData.setFilters(mapper.readTree(filters));
ruleMetaData.setProcessor(mapper.readTree(processor));
ruleMetaData.setAction(mapper.readTree(action));
ruleMetaData.setAdditionalInfo(mapper.readTree(additionalInfo));
ruleDao.save(ruleMetaData);
RuleMetaData savedRule = ruleDao.findById(id);
assertNotNull(savedRule);
assertEquals(filters, savedRule.getFilters().toString());
assertEquals(processor, savedRule.getProcessor().toString());
assertEquals(action, savedRule.getAction().toString());
assertEquals(additionalInfo, savedRule.getAdditionalInfo().toString());
}
@Test
@DatabaseSetup("classpath:dbunit/rule.xml")
public void testFindRulesByPlugin() {
assertEquals(3, jpaBaseRuleDao.findRulesByPlugin("token_1").size());
assertEquals(3, ruleDao.findRulesByPlugin("token_1").size());
}
@Test
@ -52,15 +80,15 @@ public class JpaBaseRuleDaoTest extends AbstractJpaDaoTest {
UUID tenantId1 = UUIDs.timeBased();
UUID tenantId2 = UUIDs.timeBased();
createRulesTwoTenants(tenantId1, tenantId2, "name_", "token");
List<RuleMetaData> rules1 = jpaBaseRuleDao.findByTenantIdAndPageLink(
List<RuleMetaData> rules1 = ruleDao.findByTenantIdAndPageLink(
new TenantId(tenantId1), new TextPageLink(20, "name_"));
assertEquals(20, rules1.size());
List<RuleMetaData> rules2 = jpaBaseRuleDao.findByTenantIdAndPageLink(new TenantId(tenantId1),
List<RuleMetaData> rules2 = ruleDao.findByTenantIdAndPageLink(new TenantId(tenantId1),
new TextPageLink(20, "name_", rules1.get(19).getId().getId(), null));
assertEquals(10, rules2.size());
List<RuleMetaData> rules3 = jpaBaseRuleDao.findByTenantIdAndPageLink(new TenantId(tenantId1),
List<RuleMetaData> rules3 = ruleDao.findByTenantIdAndPageLink(new TenantId(tenantId1),
new TextPageLink(20, "name_", rules2.get(9).getId().getId(), null));
assertEquals(0, rules3.size());
}
@ -71,15 +99,15 @@ public class JpaBaseRuleDaoTest extends AbstractJpaDaoTest {
UUID tenantId1 = UUIDs.timeBased();
UUID tenantId2 = UUIDs.timeBased();
createTenantsAndSystemRules(tenantId1, tenantId2, "name_", "token");
List<RuleMetaData> rules1 = jpaBaseRuleDao.findAllTenantRulesByTenantId(
List<RuleMetaData> rules1 = ruleDao.findAllTenantRulesByTenantId(
tenantId1, new TextPageLink(40, "name_"));
assertEquals(40, rules1.size());
List<RuleMetaData> rules2 = jpaBaseRuleDao.findAllTenantRulesByTenantId(tenantId1,
List<RuleMetaData> rules2 = ruleDao.findAllTenantRulesByTenantId(tenantId1,
new TextPageLink(40, "name_", rules1.get(39).getId().getId(), null));
assertEquals(20, rules2.size());
List<RuleMetaData> rules3 = jpaBaseRuleDao.findAllTenantRulesByTenantId(tenantId1,
List<RuleMetaData> rules3 = ruleDao.findAllTenantRulesByTenantId(tenantId1,
new TextPageLink(40, "name_", rules2.get(19).getId().getId(), null));
assertEquals(0, rules3.size());
}
@ -105,6 +133,6 @@ public class JpaBaseRuleDaoTest extends AbstractJpaDaoTest {
ruleMetaData.setTenantId(new TenantId(tenantId));
ruleMetaData.setName(namePrefix + i);
ruleMetaData.setPluginToken(pluginToken);
jpaBaseRuleDao.save(ruleMetaData);
ruleDao.save(ruleMetaData);
}
}

3
dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserDaoTest.java

@ -62,7 +62,6 @@ public class JpaUserDaoTest extends AbstractJpaDaoTest {
assertEquals(Authority.SYS_ADMIN, user.getAuthority());
assertEquals("John", user.getFirstName());
assertEquals("Doe", user.getLastName());
assertEquals("{\"key\":\"value-0\"}", user.getAdditionalInfo().toString());
}
@Test
@ -114,7 +113,9 @@ public class JpaUserDaoTest extends AbstractJpaDaoTest {
userDao.save(user);
assertEquals(6, userDao.find().size());
User savedUser = userDao.findByEmail("user@thingsboard.org");
//User savedUser = userDao.findById(UUID.fromString("cd481534-27cc-11e7-93ae-92361f002671"));
assertNotNull(savedUser);
assertEquals(additionalInfo, savedUser.getAdditionalInfo().toString());
}
private void create30Adminsand60Users(UUID tenantId, UUID customerId) {

4
dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java

@ -137,12 +137,12 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest {
@Test
@DatabaseSetup("classpath:dbunit/empty_dataset.xml")
@DatabaseTearDown(value = "classpath:dbunit/empty_dataset.xml", type= DatabaseOperation.DELETE_ALL)
public void testNonSearchTextNotFound() {
public void testSearchTextNotFound() {
UUID tenantId = UUIDs.timeBased();
createWidgetBundles(5, tenantId, "ABC_");
createSystemWidgetBundles(5, "SYS_");
TextPageLink textPageLink = new TextPageLink(30, "WB");
TextPageLink textPageLink = new TextPageLink(30, "TEXT_NOT_FOUND");
List<WidgetsBundle> widgetsBundles4 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId, textPageLink);
assertEquals(0, widgetsBundles4.size());
}

5
dao/src/test/resources/dbunit/users.xml

@ -7,7 +7,6 @@
search_text="SYSADM SEARCH TEXT"
first_name="John"
last_name="Doe"
additional_info="{&quot;key&quot;:&quot;value-0&quot;}"
/>
<tb_user id="1312f328-27c7-11e7-93ae-92361f002671"
tenant_id="1e1cd4c8-27c7-11e7-93ae-92361f002671"
@ -16,7 +15,6 @@
search_text="TENANTADM1 SEARCH TEXT"
first_name="Samuel"
last_name="Serif"
additional_info="{&quot;key&quot;:&quot;value-11&quot;}"
/>
<tb_user id="2b090dde-27ca-11e7-93ae-92361f002671"
tenant_id="1e1cd4c8-27c7-11e7-93ae-92361f002671"
@ -25,7 +23,6 @@
search_text="TENANTADM2 SEARCH TEXT"
first_name="Penny"
last_name="Morgan"
additional_info="{&quot;key&quot;:&quot;value-12&quot;}"
/>
<tb_user id="cc8c1ca8-27c7-11e7-93ae-92361f002671"
tenant_id="d2e27caa-27c7-11e7-93ae-92361f002671"
@ -35,7 +32,6 @@
search_text="CUSTOMER USER SEARCH TEXT"
first_name="Norman"
last_name="Gordon"
additional_info="{&quot;key&quot;:&quot;value-2&quot;}"
/>
<tb_user id="edb2de58-27c7-11e7-93ae-92361f002671"
tenant_id="f229675e-27c7-11e7-93ae-92361f002671"
@ -45,6 +41,5 @@
search_text="REFRESH TOKEN SEARCH TEXT"
first_name="Dianne"
last_name="Wensleydale"
additional_info="{&quot;key&quot;:&quot;value-3&quot;}"
/>
</dataset>
Loading…
Cancel
Save