Commit e80cb31a150ed47d9193962091e810c785c675b2

Authored by mp-loki
1 parent 27976929

JsonNode values saved to postgres as jsonb type

Showing 38 changed files with 478 additions and 339 deletions
... ... @@ -174,11 +174,6 @@
174 174 <scope>test</scope>
175 175 </dependency>
176 176 <dependency>
177   - <groupId>org.springframework</groupId>
178   - <artifactId>spring-test</artifactId>
179   - <scope>compile</scope>
180   - </dependency>
181   - <dependency>
182 177 <groupId>com.h2database</groupId>
183 178 <artifactId>h2</artifactId>
184 179 </dependency>
... ...
... ... @@ -25,9 +25,12 @@ import com.fasterxml.jackson.databind.JsonNode;
25 25 import com.fasterxml.jackson.databind.ObjectMapper;
26 26 import lombok.Data;
27 27 import lombok.extern.slf4j.Slf4j;
  28 +import org.hibernate.annotations.Type;
  29 +import org.hibernate.annotations.TypeDef;
28 30 import org.thingsboard.server.common.data.AdminSettings;
29 31 import org.thingsboard.server.common.data.id.AdminSettingsId;
30 32 import org.thingsboard.server.dao.model.BaseEntity;
  33 +import org.thingsboard.server.dao.util.JsonBinaryType;
31 34
32 35 import java.io.IOException;
33 36 import java.util.UUID;
... ... @@ -35,8 +38,8 @@ import java.util.UUID;
35 38 import static org.thingsboard.server.dao.model.ModelConstants.*;
36 39
37 40 @Data
38   -@Slf4j
39 41 @Entity
  42 +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
40 43 @Table(name = ADMIN_SETTINGS_COLUMN_FAMILY_NAME)
41 44 public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
42 45
... ... @@ -50,8 +53,9 @@ public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
50 53 @Column(name = ADMIN_SETTINGS_KEY_PROPERTY)
51 54 private String key;
52 55
53   - @Column(name = ADMIN_SETTINGS_JSON_VALUE_PROPERTY)
54   - private String jsonValue;
  56 + @Type(type = "jsonb")
  57 + @Column(name = ADMIN_SETTINGS_JSON_VALUE_PROPERTY, columnDefinition = "jsonb")
  58 + private JsonNode jsonValue;
55 59
56 60 public AdminSettingsEntity() {
57 61 super();
... ... @@ -62,9 +66,7 @@ public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
62 66 this.id = adminSettings.getId().getId();
63 67 }
64 68 this.key = adminSettings.getKey();
65   - if (jsonValue != null) {
66   - this.jsonValue = adminSettings.getJsonValue().toString();
67   - }
  69 + this.jsonValue = adminSettings.getJsonValue();
68 70 }
69 71
70 72 @Override
... ... @@ -132,16 +134,7 @@ public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
132 134 AdminSettings adminSettings = new AdminSettings(new AdminSettingsId(id));
133 135 adminSettings.setCreatedTime(UUIDs.unixTimestamp(id));
134 136 adminSettings.setKey(key);
135   - if (jsonValue != null) {
136   - ObjectMapper mapper = new ObjectMapper();
137   - JsonNode jsonNode = null;
138   - try {
139   - jsonNode = mapper.readTree(jsonValue);
140   - adminSettings.setJsonValue(jsonNode);
141   - } catch (IOException e) {
142   - log.error(e.getMessage(), e);
143   - }
144   - }
  137 + adminSettings.setJsonValue(jsonValue);
145 138 return adminSettings;
146 139 }
147 140
... ...
... ... @@ -24,19 +24,22 @@ import com.fasterxml.jackson.databind.JsonNode;
24 24 import com.fasterxml.jackson.databind.ObjectMapper;
25 25 import lombok.Data;
26 26 import lombok.extern.slf4j.Slf4j;
  27 +import org.hibernate.annotations.Type;
  28 +import org.hibernate.annotations.TypeDef;
27 29 import org.thingsboard.server.common.data.id.ComponentDescriptorId;
28 30 import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
29 31 import org.thingsboard.server.common.data.plugin.ComponentScope;
30 32 import org.thingsboard.server.common.data.plugin.ComponentType;
31 33 import org.thingsboard.server.dao.model.ModelConstants;
32 34 import org.thingsboard.server.dao.model.SearchTextEntity;
  35 +import org.thingsboard.server.dao.util.JsonBinaryType;
33 36
34 37 import java.io.IOException;
35 38 import java.util.UUID;
36 39
37 40 @Data
38   -@Slf4j
39 41 @Entity
  42 +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
40 43 @Table(name = ModelConstants.COMPONENT_DESCRIPTOR_COLUMN_FAMILY_NAME)
41 44 public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDescriptor> {
42 45
... ... @@ -59,8 +62,9 @@ public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDesc
59 62 @Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CLASS_PROPERTY)
60 63 private String clazz;
61 64
62   - @Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CONFIGURATION_DESCRIPTOR_PROPERTY)
63   - private String configurationDescriptor;
  65 + @Type(type = "jsonb")
  66 + @Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CONFIGURATION_DESCRIPTOR_PROPERTY, columnDefinition = "jsonb")
  67 + private JsonNode configurationDescriptor;
64 68
65 69 @Column(name = ModelConstants.COMPONENT_DESCRIPTOR_ACTIONS_PROPERTY)
66 70 private String actions;
... ... @@ -80,9 +84,7 @@ public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDesc
80 84 this.scope = component.getScope();
81 85 this.name = component.getName();
82 86 this.clazz = component.getClazz();
83   - if (configurationDescriptor != null) {
84   - this.configurationDescriptor = component.getConfigurationDescriptor().toString();
85   - }
  87 + this.configurationDescriptor = component.getConfigurationDescriptor();
86 88 this.searchText = component.getName();
87 89 }
88 90
... ... @@ -94,16 +96,7 @@ public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDesc
94 96 data.setName(this.getName());
95 97 data.setClazz(this.getClazz());
96 98 data.setActions(this.getActions());
97   - if (configurationDescriptor != null) {
98   - ObjectMapper mapper = new ObjectMapper();
99   - JsonNode jsonNode = null;
100   - try {
101   - jsonNode = mapper.readTree(configurationDescriptor);
102   - data.setConfigurationDescriptor(jsonNode);
103   - } catch (IOException e) {
104   - log.error(e.getMessage(), e);
105   - }
106   - }
  99 + data.setConfigurationDescriptor(configurationDescriptor);
107 100 return data;
108 101 }
109 102
... ...
... ... @@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.JsonNode;
25 25 import com.fasterxml.jackson.databind.ObjectMapper;
26 26 import lombok.Data;
27 27 import lombok.extern.slf4j.Slf4j;
  28 +import org.hibernate.annotations.Type;
28 29 import org.thingsboard.server.common.data.Customer;
29 30 import org.thingsboard.server.common.data.id.CustomerId;
30 31 import org.thingsboard.server.common.data.id.TenantId;
... ... @@ -35,7 +36,6 @@ import java.io.IOException;
35 36 import java.util.UUID;
36 37
37 38 @Data
38   -@Slf4j
39 39 @Entity
40 40 @Table(name = ModelConstants.CUSTOMER_COLUMN_FAMILY_NAME)
41 41 public final class CustomerEntity implements SearchTextEntity<Customer> {
... ... @@ -80,8 +80,9 @@ public final class CustomerEntity implements SearchTextEntity<Customer> {
80 80 @Column(name = ModelConstants.EMAIL_PROPERTY)
81 81 private String email;
82 82
83   - @Column(name = ModelConstants.CUSTOMER_ADDITIONAL_INFO_PROPERTY)
84   - private String additionalInfo;
  83 + @Type(type = "jsonb")
  84 + @Column(name = ModelConstants.CUSTOMER_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
  85 + private JsonNode additionalInfo;
85 86
86 87 public CustomerEntity() {
87 88 super();
... ... @@ -101,9 +102,7 @@ public final class CustomerEntity implements SearchTextEntity<Customer> {
101 102 this.zip = customer.getZip();
102 103 this.phone = customer.getPhone();
103 104 this.email = customer.getEmail();
104   - if (additionalInfo != null) {
105   - this.additionalInfo = customer.getAdditionalInfo().toString();
106   - }
  105 + this.additionalInfo = customer.getAdditionalInfo();
107 106 }
108 107
109 108 @Override
... ... @@ -262,15 +261,7 @@ public final class CustomerEntity implements SearchTextEntity<Customer> {
262 261 customer.setZip(zip);
263 262 customer.setPhone(phone);
264 263 customer.setEmail(email);
265   - if (additionalInfo != null) {
266   - ObjectMapper mapper = new ObjectMapper();
267   - try {
268   - JsonNode jsonNode = mapper.readTree(additionalInfo);
269   - customer.setAdditionalInfo(jsonNode);
270   - } catch (IOException e) {
271   - log.error(e.getMessage(), e);
272   - }
273   - }
  264 + customer.setAdditionalInfo(additionalInfo);
274 265 return customer;
275 266 }
276 267 }
\ No newline at end of file
... ...
... ... @@ -25,19 +25,22 @@ import com.fasterxml.jackson.databind.JsonNode;
25 25 import com.fasterxml.jackson.databind.ObjectMapper;
26 26 import lombok.Data;
27 27 import lombok.extern.slf4j.Slf4j;
  28 +import org.hibernate.annotations.Type;
  29 +import org.hibernate.annotations.TypeDef;
28 30 import org.thingsboard.server.common.data.Dashboard;
29 31 import org.thingsboard.server.common.data.id.CustomerId;
30 32 import org.thingsboard.server.common.data.id.DashboardId;
31 33 import org.thingsboard.server.common.data.id.TenantId;
32 34 import org.thingsboard.server.dao.model.ModelConstants;
33 35 import org.thingsboard.server.dao.model.SearchTextEntity;
  36 +import org.thingsboard.server.dao.util.JsonBinaryType;
34 37
35 38 import java.io.IOException;
36 39 import java.util.UUID;
37 40
38 41 @Data
39   -@Slf4j
40 42 @Entity
  43 +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
41 44 @Table(name = ModelConstants.DASHBOARD_COLUMN_FAMILY_NAME)
42 45 public final class DashboardEntity implements SearchTextEntity<Dashboard> {
43 46
... ... @@ -59,9 +62,10 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> {
59 62
60 63 @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
61 64 private String searchText;
62   -
63   - @Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY)
64   - private String configuration;
  65 +
  66 + @Type(type = "jsonb")
  67 + @Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY, columnDefinition = "jsonb")
  68 + private JsonNode configuration;
65 69
66 70 public DashboardEntity() {
67 71 super();
... ... @@ -78,9 +82,7 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> {
78 82 this.customerId = dashboard.getCustomerId().getId();
79 83 }
80 84 this.title = dashboard.getTitle();
81   - if (configuration != null) {
82   - this.configuration = dashboard.getConfiguration().toString();
83   - }
  85 + this.configuration = dashboard.getConfiguration();
84 86 }
85 87
86 88 @Override
... ... @@ -191,16 +193,7 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> {
191 193 dashboard.setCustomerId(new CustomerId(customerId));
192 194 }
193 195 dashboard.setTitle(title);
194   - if (configuration != null) {
195   - ObjectMapper mapper = new ObjectMapper();
196   - JsonNode jsonNode = null;
197   - try {
198   - jsonNode = mapper.readTree(configuration);
199   - dashboard.setConfiguration(jsonNode);
200   - } catch (IOException e) {
201   - log.error(e.getMessage(), e);
202   - }
203   - }
  196 + dashboard.setConfiguration(configuration);
204 197 return dashboard;
205 198 }
206 199 }
\ No newline at end of file
... ...
... ... @@ -25,19 +25,22 @@ import com.fasterxml.jackson.databind.JsonNode;
25 25 import com.fasterxml.jackson.databind.ObjectMapper;
26 26 import lombok.Data;
27 27 import lombok.extern.slf4j.Slf4j;
  28 +import org.hibernate.annotations.Type;
  29 +import org.hibernate.annotations.TypeDef;
28 30 import org.thingsboard.server.common.data.Device;
29 31 import org.thingsboard.server.common.data.id.CustomerId;
30 32 import org.thingsboard.server.common.data.id.DeviceId;
31 33 import org.thingsboard.server.common.data.id.TenantId;
32 34 import org.thingsboard.server.dao.model.ModelConstants;
33 35 import org.thingsboard.server.dao.model.SearchTextEntity;
  36 +import org.thingsboard.server.dao.util.JsonBinaryType;
34 37
35 38 import java.io.IOException;
36 39 import java.util.UUID;
37 40
38 41 @Data
39   -@Slf4j
40 42 @Entity
  43 +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
41 44 @Table(name = ModelConstants.DEVICE_COLUMN_FAMILY_NAME)
42 45 public final class DeviceEntity implements SearchTextEntity<Device> {
43 46
... ... @@ -59,9 +62,10 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
59 62
60 63 @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
61 64 private String searchText;
62   -
63   - @Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY)
64   - private String additionalInfo;
  65 +
  66 + @Type(type = "jsonb")
  67 + @Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
  68 + private JsonNode additionalInfo;
65 69
66 70 public DeviceEntity() {
67 71 super();
... ... @@ -78,9 +82,7 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
78 82 this.customerId = device.getCustomerId().getId();
79 83 }
80 84 this.name = device.getName();
81   - if (additionalInfo != null) {
82   - this.additionalInfo = device.getAdditionalInfo().toString();
83   - }
  85 + this.additionalInfo = device.getAdditionalInfo();
84 86 }
85 87
86 88 @Override
... ... @@ -174,16 +176,7 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
174 176 device.setCustomerId(new CustomerId(customerId));
175 177 }
176 178 device.setName(name);
177   - if (additionalInfo != null) {
178   - ObjectMapper mapper = new ObjectMapper();
179   - JsonNode jsonNode = null;
180   - try {
181   - jsonNode = mapper.readTree(additionalInfo);
182   - device.setAdditionalInfo(jsonNode);
183   - } catch (IOException e) {
184   - log.error(e.getMessage(), e);
185   - }
186   - }
  179 + device.setAdditionalInfo(additionalInfo);
187 180 return device;
188 181 }
189 182 }
\ No newline at end of file
... ...
... ... @@ -26,10 +26,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
26 26 import lombok.Data;
27 27 import lombok.NoArgsConstructor;
28 28 import lombok.extern.slf4j.Slf4j;
  29 +import org.hibernate.annotations.Type;
  30 +import org.hibernate.annotations.TypeDef;
29 31 import org.thingsboard.server.common.data.EntityType;
30 32 import org.thingsboard.server.common.data.Event;
31 33 import org.thingsboard.server.common.data.id.*;
32 34 import org.thingsboard.server.dao.model.BaseEntity;
  35 +import org.thingsboard.server.dao.util.JsonBinaryType;
33 36
34 37 import static org.thingsboard.server.dao.model.ModelConstants.*;
35 38
... ... @@ -37,9 +40,9 @@ import java.io.IOException;
37 40 import java.util.UUID;
38 41
39 42 @Data
40   -@Slf4j
41 43 @NoArgsConstructor
42 44 @Entity
  45 +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
43 46 @Table(name = EVENT_COLUMN_FAMILY_NAME)
44 47 public class EventEntity implements BaseEntity<Event> {
45 48
... ... @@ -65,8 +68,9 @@ public class EventEntity implements BaseEntity<Event> {
65 68 @Column(name = EVENT_UID_PROPERTY)
66 69 private String eventUid;
67 70
68   - @Column(name = EVENT_BODY_PROPERTY)
69   - private String body;
  71 + @Type(type = "jsonb")
  72 + @Column(name = EVENT_BODY_PROPERTY, columnDefinition = "jsonb")
  73 + private JsonNode body;
70 74
71 75 public EventEntity(Event event) {
72 76 if (event.getId() != null) {
... ... @@ -81,9 +85,7 @@ public class EventEntity implements BaseEntity<Event> {
81 85 }
82 86 this.eventType = event.getType();
83 87 this.eventUid = event.getUid();
84   - if (event.getBody() != null) {
85   - this.body = event.getBody().toString();
86   - }
  88 + this.body = event.getBody();
87 89 }
88 90
89 91 @Override
... ... @@ -118,15 +120,7 @@ public class EventEntity implements BaseEntity<Event> {
118 120 event.setEntityId(new PluginId(entityId));
119 121 break;
120 122 }
121   - ObjectMapper mapper = new ObjectMapper();
122   - if (body != null) {
123   - try {
124   - JsonNode jsonNode = mapper.readTree(body);
125   - event.setBody(jsonNode);
126   - } catch (IOException e) {
127   - log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", body, e.getMessage()), e);
128   - }
129   - }
  123 + event.setBody(body);
130 124 event.setType(eventType);
131 125 event.setUid(eventUid);
132 126 return event;
... ...
... ... @@ -25,19 +25,23 @@ import com.fasterxml.jackson.databind.JsonNode;
25 25 import com.fasterxml.jackson.databind.ObjectMapper;
26 26 import lombok.Data;
27 27 import lombok.extern.slf4j.Slf4j;
  28 +import org.hibernate.annotations.Type;
  29 +import org.hibernate.annotations.TypeDef;
28 30 import org.thingsboard.server.common.data.id.PluginId;
29 31 import org.thingsboard.server.common.data.id.TenantId;
30 32 import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
31 33 import org.thingsboard.server.common.data.plugin.PluginMetaData;
32 34 import org.thingsboard.server.dao.model.ModelConstants;
33 35 import org.thingsboard.server.dao.model.SearchTextEntity;
  36 +import org.thingsboard.server.dao.util.JsonBinaryType;
34 37
35 38 import java.io.IOException;
36 39 import java.util.Objects;
37 40 import java.util.UUID;
38   -@Slf4j
  41 +
39 42 @Data
40 43 @Entity
  44 +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
41 45 @Table(name = ModelConstants.PLUGIN_COLUMN_FAMILY_NAME)
42 46 public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
43 47
... ... @@ -65,15 +69,17 @@ public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
65 69 @Column(name = ModelConstants.PLUGIN_STATE_PROPERTY)
66 70 private ComponentLifecycleState state;
67 71
68   - @Column(name = ModelConstants.PLUGIN_CONFIGURATION_PROPERTY)
69   - private String configuration;
  72 + @Type(type = "jsonb")
  73 + @Column(name = ModelConstants.PLUGIN_CONFIGURATION_PROPERTY, columnDefinition = "jsonb")
  74 + private JsonNode configuration;
  75 +
  76 + @Type(type = "jsonb")
  77 + @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
  78 + private JsonNode additionalInfo;
70 79
71 80 @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
72 81 private String searchText;
73 82
74   - @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY)
75   - private String additionalInfo;
76   -
77 83 public PluginMetaDataEntity() {
78 84 }
79 85
... ... @@ -88,12 +94,8 @@ public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
88 94 this.publicAccess = pluginMetaData.isPublicAccess();
89 95 this.state = pluginMetaData.getState();
90 96 this.searchText = pluginMetaData.getName();
91   - if (pluginMetaData.getConfiguration() != null) {
92   - this.configuration = pluginMetaData.getConfiguration().toString();
93   - }
94   - if (pluginMetaData.getAdditionalInfo() != null) {
95   - this.additionalInfo = pluginMetaData.getAdditionalInfo().toString();
96   - }
  97 + this.configuration = pluginMetaData.getConfiguration();
  98 + this.additionalInfo = pluginMetaData.getAdditionalInfo();
97 99 }
98 100
99 101 @Override
... ... @@ -126,23 +128,8 @@ public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
126 128 data.setPublicAccess(publicAccess);
127 129 data.setState(state);
128 130 data.setApiToken(apiToken);
129   - ObjectMapper mapper = new ObjectMapper();
130   - if (configuration != null) {
131   - try {
132   - JsonNode jsonNode = mapper.readTree(configuration);
133   - data.setConfiguration(jsonNode);
134   - } catch (IOException e) {
135   - log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", configuration, e.getMessage()), e);
136   - }
137   - }
138   - if (additionalInfo != null) {
139   - try {
140   - JsonNode jsonNode = mapper.readTree(additionalInfo);
141   - data.setAdditionalInfo(jsonNode);
142   - } catch (IOException e) {
143   - log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
144   - }
145   - }
  131 + data.setConfiguration(configuration);
  132 + data.setAdditionalInfo(additionalInfo);
146 133 return data;
147 134 }
148 135
... ...
... ... @@ -27,6 +27,8 @@ import com.fasterxml.jackson.databind.JsonNode;
27 27 import com.fasterxml.jackson.databind.ObjectMapper;
28 28 import lombok.Data;
29 29 import lombok.extern.slf4j.Slf4j;
  30 +import org.hibernate.annotations.Type;
  31 +import org.hibernate.annotations.TypeDef;
30 32 import org.thingsboard.server.common.data.id.RuleId;
31 33 import org.thingsboard.server.common.data.id.TenantId;
32 34 import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
... ... @@ -34,14 +36,15 @@ import org.thingsboard.server.common.data.rule.RuleMetaData;
34 36 import org.thingsboard.server.dao.DaoUtil;
35 37 import org.thingsboard.server.dao.model.ModelConstants;
36 38 import org.thingsboard.server.dao.model.SearchTextEntity;
  39 +import org.thingsboard.server.dao.util.JsonBinaryType;
37 40
38 41 import java.io.IOException;
39 42 import java.util.Objects;
40 43 import java.util.UUID;
41 44
42   -@Slf4j
43 45 @Data
44 46 @Entity
  47 +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
45 48 @Table(name = ModelConstants.RULE_COLUMN_FAMILY_NAME)
46 49 public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
47 50
... ... @@ -62,14 +65,18 @@ public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
62 65 private String searchText;
63 66 @Column(name = ModelConstants.RULE_PLUGIN_TOKEN_PROPERTY)
64 67 private String pluginToken;
65   - @Column(name = ModelConstants.RULE_FILTERS)
66   - private String filters;
67   - @Column(name = ModelConstants.RULE_PROCESSOR)
68   - private String processor;
69   - @Column(name = ModelConstants.RULE_ACTION)
70   - private String action;
71   - @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY)
72   - private String additionalInfo;
  68 + @Type(type = "jsonb")
  69 + @Column(name = ModelConstants.RULE_FILTERS, columnDefinition = "jsonb")
  70 + private JsonNode filters;
  71 + @Type(type = "jsonb")
  72 + @Column(name = ModelConstants.RULE_PROCESSOR, columnDefinition = "jsonb")
  73 + private JsonNode processor;
  74 + @Type(type = "jsonb")
  75 + @Column(name = ModelConstants.RULE_ACTION, columnDefinition = "jsonb")
  76 + private JsonNode action;
  77 + @Type(type = "jsonb")
  78 + @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
  79 + private JsonNode additionalInfo;
73 80
74 81 public RuleMetaDataEntity() {
75 82 }
... ... @@ -84,18 +91,10 @@ public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
84 91 this.state = rule.getState();
85 92 this.weight = rule.getWeight();
86 93 this.searchText = rule.getName();
87   - if (rule.getFilters() != null) {
88   - this.filters = rule.getFilters().toString();
89   - }
90   - if (rule.getProcessor() != null) {
91   - this.processor = rule.getProcessor().toString();
92   - }
93   - if (rule.getAction() != null) {
94   - this.action = rule.getAction().toString();
95   - }
96   - if (rule.getAdditionalInfo() != null) {
97   - this.additionalInfo = rule.getAdditionalInfo().toString();
98   - }
  94 + this.filters = rule.getFilters();
  95 + this.processor = rule.getProcessor();
  96 + this.action = rule.getAction();
  97 + this.additionalInfo = rule.getAdditionalInfo();
99 98 }
100 99
101 100 @Override
... ... @@ -127,39 +126,10 @@ public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
127 126 rule.setWeight(weight);
128 127 rule.setCreatedTime(UUIDs.unixTimestamp(id));
129 128 rule.setPluginToken(pluginToken);
130   - ObjectMapper mapper = new ObjectMapper();
131   - if (filters != null) {
132   - try {
133   - JsonNode jsonNode = mapper.readTree(filters);
134   - rule.setFilters(jsonNode);
135   - } catch (IOException e) {
136   - log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", filters, e.getMessage()), e);
137   - }
138   - }
139   - if (processor != null) {
140   - try {
141   - JsonNode jsonNode = mapper.readTree(processor);
142   - rule.setProcessor(jsonNode);
143   - } catch (IOException e) {
144   - log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", processor, e.getMessage()), e);
145   - }
146   - }
147   - if (action != null) {
148   - try {
149   - JsonNode jsonNode = mapper.readTree(action);
150   - rule.setAction(jsonNode);
151   - } catch (IOException e) {
152   - log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", action, e.getMessage()), e);
153   - }
154   - }
155   - if (additionalInfo != null) {
156   - try {
157   - JsonNode jsonNode = mapper.readTree(additionalInfo);
158   - rule.setAdditionalInfo(jsonNode);
159   - } catch (IOException e) {
160   - log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
161   - }
162   - }
  129 + rule.setFilters(filters);
  130 + rule.setProcessor(processor);
  131 + rule.setAction(action);
  132 + rule.setAdditionalInfo(additionalInfo);
163 133 return rule;
164 134 }
165 135
... ...
... ... @@ -26,18 +26,21 @@ import javax.persistence.Transient;
26 26 import com.fasterxml.jackson.databind.ObjectMapper;
27 27 import lombok.Data;
28 28 import lombok.extern.slf4j.Slf4j;
  29 +import org.hibernate.annotations.Type;
  30 +import org.hibernate.annotations.TypeDef;
29 31 import org.thingsboard.server.common.data.Tenant;
30 32 import org.thingsboard.server.common.data.id.TenantId;
31 33 import org.thingsboard.server.dao.model.ModelConstants;
32 34 import org.thingsboard.server.dao.model.SearchTextEntity;
33 35 import com.fasterxml.jackson.databind.JsonNode;
  36 +import org.thingsboard.server.dao.util.JsonBinaryType;
34 37
35 38 import java.io.IOException;
36 39 import java.util.UUID;
37 40
38   -@Slf4j
39 41 @Data
40 42 @Entity
  43 +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
41 44 @Table(name = ModelConstants.TENANT_COLUMN_FAMILY_NAME)
42 45 public final class TenantEntity implements SearchTextEntity<Tenant> {
43 46
... ... @@ -81,8 +84,9 @@ public final class TenantEntity implements SearchTextEntity<Tenant> {
81 84 @Column(name = ModelConstants.EMAIL_PROPERTY)
82 85 private String email;
83 86
84   - @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY)
85   - private String additionalInfo;
  87 + @Type(type="jsonb")
  88 + @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
  89 + private JsonNode additionalInfo;
86 90
87 91 public TenantEntity() {
88 92 super();
... ... @@ -102,12 +106,9 @@ public final class TenantEntity implements SearchTextEntity<Tenant> {
102 106 this.zip = tenant.getZip();
103 107 this.phone = tenant.getPhone();
104 108 this.email = tenant.getEmail();
105   - if (tenant.getAdditionalInfo() != null) {
106   - this.additionalInfo = tenant.getAdditionalInfo().toString();
107   - }
  109 + this.additionalInfo = tenant.getAdditionalInfo();
108 110 }
109 111
110   -
111 112 @Override
112 113 public String getSearchTextSource() {
113 114 return title;
... ... @@ -258,15 +259,7 @@ public final class TenantEntity implements SearchTextEntity<Tenant> {
258 259 tenant.setZip(zip);
259 260 tenant.setPhone(phone);
260 261 tenant.setEmail(email);
261   - ObjectMapper mapper = new ObjectMapper();
262   - if (additionalInfo != null) {
263   - try {
264   - JsonNode jsonNode = mapper.readTree(additionalInfo);
265   - tenant.setAdditionalInfo(jsonNode);
266   - } catch (IOException e) {
267   - log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
268   - }
269   - }
  262 + tenant.setAdditionalInfo(additionalInfo);
270 263 return tenant;
271 264 }
272 265
... ...
... ... @@ -20,6 +20,8 @@ import com.fasterxml.jackson.databind.JsonNode;
20 20 import com.fasterxml.jackson.databind.ObjectMapper;
21 21 import lombok.Data;
22 22 import lombok.extern.slf4j.Slf4j;
  23 +import org.hibernate.annotations.Type;
  24 +import org.hibernate.annotations.TypeDef;
23 25 import org.thingsboard.server.common.data.User;
24 26 import org.thingsboard.server.common.data.id.CustomerId;
25 27 import org.thingsboard.server.common.data.id.TenantId;
... ... @@ -27,6 +29,7 @@ import org.thingsboard.server.common.data.id.UserId;
27 29 import org.thingsboard.server.common.data.security.Authority;
28 30 import org.thingsboard.server.dao.model.ModelConstants;
29 31 import org.thingsboard.server.dao.model.SearchTextEntity;
  32 +import org.thingsboard.server.dao.util.JsonBinaryType;
30 33
31 34 import javax.persistence.*;
32 35 import java.io.IOException;
... ... @@ -35,9 +38,9 @@ import java.util.UUID;
35 38 /**
36 39 * Created by Valerii Sosliuk on 4/21/2017.
37 40 */
38   -@Slf4j
39 41 @Data
40 42 @Entity
  43 +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
41 44 @Table(name = ModelConstants.USER_PG_HIBERNATE_COLUMN_FAMILY_NAME)
42 45 public class UserEntity implements SearchTextEntity<User> {
43 46 @Transient
... ... @@ -68,8 +71,9 @@ public class UserEntity implements SearchTextEntity<User> {
68 71 @Column(name = ModelConstants.USER_LAST_NAME_PROPERTY)
69 72 private String lastName;
70 73
71   - @Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY)
72   - private String additionalInfo;
  74 + @Type(type="jsonb")
  75 + @Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
  76 + private JsonNode additionalInfo;
73 77
74 78 public UserEntity() {
75 79 }
... ... @@ -88,9 +92,7 @@ public class UserEntity implements SearchTextEntity<User> {
88 92 this.email = user.getEmail();
89 93 this.firstName = user.getFirstName();
90 94 this.lastName = user.getLastName();
91   - if (user.getAdditionalInfo() != null) {
92   - this.additionalInfo = user.getAdditionalInfo().toString();
93   - }
  95 + this.additionalInfo = user.getAdditionalInfo();
94 96 }
95 97
96 98 @Override
... ... @@ -150,15 +152,7 @@ public class UserEntity implements SearchTextEntity<User> {
150 152 user.setEmail(email);
151 153 user.setFirstName(firstName);
152 154 user.setLastName(lastName);
153   - ObjectMapper mapper = new ObjectMapper();
154   - if (additionalInfo != null) {
155   - try {
156   - JsonNode jsonNode = mapper.readTree(additionalInfo);
157   - user.setAdditionalInfo(jsonNode);
158   - } catch (IOException e) {
159   - log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
160   - }
161   - }
  155 + user.setAdditionalInfo(additionalInfo);
162 156 return user;
163 157 }
164 158
... ...
... ... @@ -16,29 +16,24 @@
16 16 package org.thingsboard.server.dao.model.sql;
17 17
18 18 import com.datastax.driver.core.utils.UUIDs;
19   -import javax.persistence.Column;
20   -import javax.persistence.Entity;
21   -import javax.persistence.Id;
22   -import javax.persistence.Table;
23   -import javax.persistence.Transient;
24   -
25 19 import com.datastax.driver.mapping.annotations.PartitionKey;
26 20 import com.fasterxml.jackson.databind.JsonNode;
27   -import com.fasterxml.jackson.databind.ObjectMapper;
28 21 import lombok.Data;
29   -import lombok.extern.slf4j.Slf4j;
  22 +import org.hibernate.annotations.Type;
  23 +import org.hibernate.annotations.TypeDef;
30 24 import org.thingsboard.server.common.data.id.TenantId;
31 25 import org.thingsboard.server.common.data.id.WidgetTypeId;
32 26 import org.thingsboard.server.common.data.widget.WidgetType;
33 27 import org.thingsboard.server.dao.model.BaseEntity;
34 28 import org.thingsboard.server.dao.model.ModelConstants;
  29 +import org.thingsboard.server.dao.util.JsonBinaryType;
35 30
36   -import java.io.IOException;
  31 +import javax.persistence.*;
37 32 import java.util.UUID;
38 33
39   -@Slf4j
40 34 @Data
41 35 @Entity
  36 +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
42 37 @Table(name = ModelConstants.WIDGET_TYPE_COLUMN_FAMILY_NAME)
43 38 public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
44 39
... ... @@ -63,8 +58,9 @@ public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
63 58 @Column(name = ModelConstants.WIDGET_TYPE_NAME_PROPERTY)
64 59 private String name;
65 60
66   - @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY)
67   - private String descriptor;
  61 + @Type(type="jsonb")
  62 + @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY, columnDefinition = "jsonb")
  63 + private JsonNode descriptor;
68 64
69 65 public WidgetTypeEntity() {
70 66 super();
... ... @@ -80,9 +76,7 @@ public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
80 76 this.bundleAlias = widgetType.getBundleAlias();
81 77 this.alias = widgetType.getAlias();
82 78 this.name = widgetType.getName();
83   - if (widgetType.getDescriptor() != null) {
84   - this.descriptor = widgetType.getDescriptor().toString();
85   - }
  79 + this.descriptor = widgetType.getDescriptor();
86 80 }
87 81
88 82 @Override
... ... @@ -144,15 +138,7 @@ public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
144 138 widgetType.setBundleAlias(bundleAlias);
145 139 widgetType.setAlias(alias);
146 140 widgetType.setName(name);
147   - ObjectMapper mapper = new ObjectMapper();
148   - if (descriptor != null) {
149   - try {
150   - JsonNode jsonNode = mapper.readTree(descriptor);
151   - widgetType.setDescriptor(jsonNode);
152   - } catch (IOException e) {
153   - log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", descriptor, e.getMessage()), e);
154   - }
155   - }
  141 + widgetType.setDescriptor(descriptor);
156 142 return widgetType;
157 143 }
158 144
... ...
... ... @@ -41,8 +41,6 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D> implements Dao<
41 41
42 42 protected abstract Class<E> getEntityClass();
43 43
44   - protected abstract String getColumnFamilyName();
45   -
46 44 protected abstract CrudRepository<E, UUID> getCrudRepository();
47 45
48 46 protected boolean isSearchTextDao() {
... ... @@ -93,7 +91,6 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D> implements Dao<
93 91
94 92 @Override
95 93 public List<D> find() {
96   - log.debug("Get all entities from column family {}", getColumnFamilyName());
97 94 List<E> entities = Lists.newArrayList(getCrudRepository().findAll());
98 95 return DaoUtil.convertDataList(entities);
99 96 }
... ...
... ... @@ -51,11 +51,6 @@ public class JpaBaseComponentDescriptorDao extends JpaAbstractSearchTextDao<Comp
51 51 }
52 52
53 53 @Override
54   - protected String getColumnFamilyName() {
55   - return ModelConstants.COMPONENT_DESCRIPTOR_COLUMN_FAMILY_NAME;
56   - }
57   -
58   - @Override
59 54 protected CrudRepository<ComponentDescriptorEntity, UUID> getCrudRepository() {
60 55 return componentDescriptorRepository;
61 56 }
... ...
... ... @@ -40,6 +40,4 @@ public interface CustomerRepository extends CrudRepository<CustomerEntity, UUID>
40 40 "AND ID > ?4 ORDER BY ID LIMIT ?1")
41 41 List<CustomerEntity> findByTenantIdNextPage(int limit, UUID tenantId, String textSearch, UUID idOffset);
42 42
43   - @Query(nativeQuery = true, value = "SELECT * FROM CUSTOMER WHERE TENANT_ID = ?1")
44   - List<CustomerEntity> findByTenantId(UUID tenantId);
45 43 }
... ...
... ... @@ -46,11 +46,6 @@ public class JpaCustomerDao extends JpaAbstractSearchTextDao<CustomerEntity, Cus
46 46 }
47 47
48 48 @Override
49   - protected String getColumnFamilyName() {
50   - return ModelConstants.CUSTOMER_COLUMN_FAMILY_NAME;
51   - }
52   -
53   - @Override
54 49 protected CrudRepository<CustomerEntity, UUID> getCrudRepository() {
55 50 return customerRepository;
56 51 }
... ...
... ... @@ -44,11 +44,6 @@ public class JpaDashboardDao extends JpaAbstractSearchTextDao<DashboardEntity, D
44 44 }
45 45
46 46 @Override
47   - protected String getColumnFamilyName() {
48   - return DASHBOARD_COLUMN_FAMILY_NAME;
49   - }
50   -
51   - @Override
52 47 protected CrudRepository<DashboardEntity, UUID> getCrudRepository() {
53 48 return dashboardRepository;
54 49 }
... ...
... ... @@ -47,11 +47,6 @@ public class JpaDashboardInfoDao extends JpaAbstractSearchTextDao<DashboardInfoE
47 47 }
48 48
49 49 @Override
50   - protected String getColumnFamilyName() {
51   - return DASHBOARD_COLUMN_FAMILY_NAME;
52   - }
53   -
54   - @Override
55 50 protected CrudRepository getCrudRepository() {
56 51 return dashboardInfoRepository;
57 52 }
... ...
... ... @@ -44,13 +44,6 @@ public class JpaDeviceCredentialsDao extends JpaAbstractDao<DeviceCredentialsEnt
44 44 }
45 45
46 46 @Override
47   - protected String getColumnFamilyName() {
48   - {
49   - return ModelConstants.DEVICE_CREDENTIALS_COLUMN_FAMILY_NAME;
50   - }
51   - }
52   -
53   - @Override
54 47 protected CrudRepository<DeviceCredentialsEntity, UUID> getCrudRepository() {
55 48 return deviceCredentialsRepository;
56 49 }
... ...
... ... @@ -52,11 +52,6 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device>
52 52 }
53 53
54 54 @Override
55   - protected String getColumnFamilyName() {
56   - return DEVICE_COLUMN_FAMILY_NAME;
57   - }
58   -
59   - @Override
60 55 protected CrudRepository<DeviceEntity, UUID> getCrudRepository() {
61 56 return deviceRepository;
62 57 }
... ...
... ... @@ -67,11 +67,6 @@ public class JpaBaseEventDao extends JpaAbstractSearchTimeDao<EventEntity, Event
67 67 }
68 68
69 69 @Override
70   - protected String getColumnFamilyName() {
71   - return EVENT_COLUMN_FAMILY_NAME;
72   - }
73   -
74   - @Override
75 70 protected CrudRepository<EventEntity, UUID> getCrudRepository() {
76 71 return eventRepository;
77 72 }
... ...
... ... @@ -52,11 +52,6 @@ public class JpaBasePluginDao extends JpaAbstractSearchTextDao<PluginMetaDataEnt
52 52 }
53 53
54 54 @Override
55   - protected String getColumnFamilyName() {
56   - return ModelConstants.PLUGIN_COLUMN_FAMILY_NAME;
57   - }
58   -
59   - @Override
60 55 protected CrudRepository<PluginMetaDataEntity, UUID> getCrudRepository() {
61 56 return pluginMetaDataRepository;
62 57 }
... ...
... ... @@ -50,10 +50,6 @@ public class JpaBaseRuleDao extends JpaAbstractSearchTextDao<RuleMetaDataEntity,
50 50 protected Class<RuleMetaDataEntity> getEntityClass() {
51 51 return RuleMetaDataEntity.class;
52 52 }
53   - @Override
54   - protected String getColumnFamilyName() {
55   - return ModelConstants.RULE_COLUMN_FAMILY_NAME;
56   - }
57 53
58 54 @Override
59 55 protected CrudRepository<RuleMetaDataEntity, UUID> getCrudRepository() {
... ...
... ... @@ -41,11 +41,6 @@ public class JpaAdminSettingsDao extends JpaAbstractDao<AdminSettingsEntity, Adm
41 41 }
42 42
43 43 @Override
44   - protected String getColumnFamilyName() {
45   - return ADMIN_SETTINGS_COLUMN_FAMILY_NAME;
46   - }
47   -
48   - @Override
49 44 protected CrudRepository<AdminSettingsEntity, UUID> getCrudRepository() {
50 45 return adminSettingsRepository;
51 46 }
... ...
... ... @@ -48,11 +48,6 @@ public class JpaTenantDao extends JpaAbstractSearchTextDao<TenantEntity, Tenant>
48 48 }
49 49
50 50 @Override
51   - protected String getColumnFamilyName() {
52   - return TENANT_COLUMN_FAMILY_NAME;
53   - }
54   -
55   - @Override
56 51 protected CrudRepository<TenantEntity, UUID> getCrudRepository() {
57 52 return tenantRepository;
58 53 }
... ...
... ... @@ -45,11 +45,6 @@ public class JpaUserCredentialsDao extends JpaAbstractDao<UserCredentialsEntity,
45 45 }
46 46
47 47 @Override
48   - protected String getColumnFamilyName() {
49   - return ModelConstants.USER_CREDENTIALS_COLUMN_FAMILY_NAME;
50   - }
51   -
52   - @Override
53 48 protected CrudRepository<UserCredentialsEntity, UUID> getCrudRepository() {
54 49 return userCredentialsRepository;
55 50 }
... ...
... ... @@ -46,11 +46,6 @@ public class JpaUserDao extends JpaAbstractDao<UserEntity, User> implements User
46 46 }
47 47
48 48 @Override
49   - protected String getColumnFamilyName() {
50   - return ModelConstants.USER_COLUMN_FAMILY_NAME;
51   - }
52   -
53   - @Override
54 49 protected CrudRepository<UserEntity, UUID> getCrudRepository() {
55 50 return userRepository;
56 51 }
... ...
... ... @@ -46,11 +46,6 @@ public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeEntity, WidgetTyp
46 46 }
47 47
48 48 @Override
49   - protected String getColumnFamilyName() {
50   - return WIDGET_TYPE_COLUMN_FAMILY_NAME;
51   - }
52   -
53   - @Override
54 49 protected CrudRepository<WidgetTypeEntity, UUID> getCrudRepository() {
55 50 return widgetTypeRepository;
56 51 }
... ...
... ... @@ -48,11 +48,6 @@ public class JpaWidgetsBundleDao extends JpaAbstractSearchTextDao<WidgetsBundleE
48 48 }
49 49
50 50 @Override
51   - protected String getColumnFamilyName() {
52   - return WIDGETS_BUNDLE_COLUMN_FAMILY_NAME;
53   - }
54   -
55   - @Override
56 51 protected CrudRepository<WidgetsBundleEntity, UUID> getCrudRepository() {
57 52 return widgetsBundleRepository;
58 53 }
... ...
  1 +/**
  2 + * Copyright © 2016-2017 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.util;
  17 +
  18 +import com.fasterxml.jackson.core.JsonProcessingException;
  19 +import com.fasterxml.jackson.databind.JsonNode;
  20 +import com.fasterxml.jackson.databind.ObjectMapper;
  21 +
  22 +import java.io.IOException;
  23 +
  24 +/**
  25 + * Created by Valerii Sosliuk on 5/12/2017.
  26 + */
  27 +public class JacksonUtil {
  28 +
  29 + public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
  30 +
  31 + public static <T> T fromString(String string, Class<T> clazz) {
  32 + try {
  33 + return OBJECT_MAPPER.readValue(string, clazz);
  34 + } catch (IOException e) {
  35 + throw new IllegalArgumentException("The given string value: "
  36 + + string + " cannot be transformed to Json object");
  37 + }
  38 + }
  39 +
  40 + public static String toString(Object value) {
  41 + try {
  42 + return OBJECT_MAPPER.writeValueAsString(value);
  43 + } catch (JsonProcessingException e) {
  44 + throw new IllegalArgumentException("The given Json object value: "
  45 + + value + " cannot be transformed to a String");
  46 + }
  47 + }
  48 +
  49 + public static JsonNode toJsonNode(String value) {
  50 + try {
  51 + return OBJECT_MAPPER.readTree(value);
  52 + } catch (IOException e) {
  53 + throw new IllegalArgumentException(e);
  54 + }
  55 + }
  56 +
  57 + public static <T> T clone(T value) {
  58 + return fromString(toString(value), (Class<T>) value.getClass());
  59 + }
  60 +}
\ No newline at end of file
... ...
  1 +/**
  2 + * Copyright © 2016-2017 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.util;
  17 +
  18 +import com.fasterxml.jackson.databind.JsonNode;
  19 +import org.hibernate.type.descriptor.ValueBinder;
  20 +import org.hibernate.type.descriptor.ValueExtractor;
  21 +import org.hibernate.type.descriptor.WrapperOptions;
  22 +import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
  23 +import org.hibernate.type.descriptor.sql.BasicBinder;
  24 +import org.hibernate.type.descriptor.sql.BasicExtractor;
  25 +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
  26 +
  27 +import java.sql.*;
  28 +
  29 +/**
  30 + * Created by Valerii Sosliuk on 5/12/2017.
  31 + */
  32 +public class JsonBinarySqlTypeDescriptor
  33 + implements SqlTypeDescriptor {
  34 +
  35 + public static final JsonBinarySqlTypeDescriptor INSTANCE =
  36 + new JsonBinarySqlTypeDescriptor();
  37 +
  38 + @Override
  39 + public int getSqlType() {
  40 + return Types.OTHER;
  41 + }
  42 +
  43 + @Override
  44 + public boolean canBeRemapped() {
  45 + return true;
  46 + }
  47 +
  48 + @Override
  49 + public <X> ValueExtractor<X> getExtractor(
  50 + final JavaTypeDescriptor<X> javaTypeDescriptor) {
  51 + return new BasicExtractor<X>(javaTypeDescriptor, this) {
  52 + @Override
  53 + protected X doExtract(
  54 + ResultSet rs,
  55 + String name,
  56 + WrapperOptions options) throws SQLException {
  57 + return javaTypeDescriptor.wrap(
  58 + rs.getObject(name), options
  59 + );
  60 + }
  61 +
  62 + @Override
  63 + protected X doExtract(
  64 + CallableStatement statement,
  65 + int index,
  66 + WrapperOptions options) throws SQLException {
  67 + return javaTypeDescriptor.wrap(
  68 + statement.getObject(index), options
  69 + );
  70 + }
  71 +
  72 + @Override
  73 + protected X doExtract(
  74 + CallableStatement statement,
  75 + String name,
  76 + WrapperOptions options) throws SQLException {
  77 + return javaTypeDescriptor.wrap(
  78 + statement.getObject(name), options
  79 + );
  80 + }
  81 + };
  82 + }
  83 +
  84 + @Override
  85 + public <X> ValueBinder<X> getBinder(
  86 + final JavaTypeDescriptor<X> javaTypeDescriptor) {
  87 + return new BasicBinder<X>(javaTypeDescriptor, this) {
  88 + @Override
  89 + protected void doBind(
  90 + PreparedStatement st,
  91 + X value,
  92 + int index,
  93 + WrapperOptions options) throws SQLException {
  94 + st.setObject(index,
  95 + javaTypeDescriptor.unwrap(
  96 + value, JsonNode.class, options), getSqlType()
  97 + );
  98 + }
  99 +
  100 + @Override
  101 + protected void doBind(
  102 + CallableStatement st,
  103 + X value,
  104 + String name,
  105 + WrapperOptions options)
  106 + throws SQLException {
  107 + st.setObject(name,
  108 + javaTypeDescriptor.unwrap(
  109 + value, JsonNode.class, options), getSqlType()
  110 + );
  111 + }
  112 + };
  113 + }
  114 +}
\ No newline at end of file
... ...
  1 +/**
  2 + * Copyright © 2016-2017 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.util;
  17 +
  18 +import org.hibernate.type.AbstractSingleColumnStandardBasicType;
  19 +import org.hibernate.usertype.DynamicParameterizedType;
  20 +
  21 +import java.util.Properties;
  22 +
  23 +/**
  24 + * Created by Valerii Sosliuk on 5/12/2017.
  25 + */
  26 +public class JsonBinaryType extends AbstractSingleColumnStandardBasicType<Object>
  27 + implements DynamicParameterizedType {
  28 +
  29 + public JsonBinaryType() {
  30 + super(
  31 + JsonBinarySqlTypeDescriptor.INSTANCE,
  32 + new JsonTypeDescriptor()
  33 + );
  34 + }
  35 +
  36 + public String getName() {
  37 + return "jsonb";
  38 + }
  39 +
  40 + @Override
  41 + public void setParameterValues(Properties parameters) {
  42 + ((JsonTypeDescriptor) getJavaTypeDescriptor())
  43 + .setParameterValues(parameters);
  44 + }}
\ No newline at end of file
... ...
  1 +/**
  2 + * Copyright © 2016-2017 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.util;
  17 +
  18 +import org.hibernate.type.descriptor.WrapperOptions;
  19 +import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
  20 +import org.hibernate.type.descriptor.java.MutableMutabilityPlan;
  21 +import org.hibernate.usertype.DynamicParameterizedType;
  22 +
  23 +import java.util.Properties;
  24 +
  25 +/**
  26 + * Created by Valerii Sosliuk on 5/12/2017.
  27 + */
  28 +public class JsonTypeDescriptor
  29 + extends AbstractTypeDescriptor<Object>
  30 + implements DynamicParameterizedType {
  31 +
  32 + private Class<?> jsonObjectClass;
  33 +
  34 + @Override
  35 + public void setParameterValues(Properties parameters) {
  36 + jsonObjectClass = ( (ParameterType) parameters.get( PARAMETER_TYPE ) )
  37 + .getReturnedClass();
  38 +
  39 + }
  40 +
  41 + public JsonTypeDescriptor() {
  42 + super( Object.class, new MutableMutabilityPlan<Object>() {
  43 + @Override
  44 + protected Object deepCopyNotNull(Object value) {
  45 + return JacksonUtil.clone(value);
  46 + }
  47 + });
  48 + }
  49 +
  50 + @Override
  51 + public boolean areEqual(Object one, Object another) {
  52 + if ( one == another ) {
  53 + return true;
  54 + }
  55 + if ( one == null || another == null ) {
  56 + return false;
  57 + }
  58 + return JacksonUtil.toJsonNode(JacksonUtil.toString(one)).equals(
  59 + JacksonUtil.toJsonNode(JacksonUtil.toString(another)));
  60 + }
  61 +
  62 + @Override
  63 + public String toString(Object value) {
  64 + return JacksonUtil.toString(value);
  65 + }
  66 +
  67 + @Override
  68 + public Object fromString(String string) {
  69 + return JacksonUtil.fromString(string, jsonObjectClass);
  70 + }
  71 +
  72 + @SuppressWarnings({ "unchecked" })
  73 + @Override
  74 + public <X> X unwrap(Object value, Class<X> type, WrapperOptions options) {
  75 + if ( value == null ) {
  76 + return null;
  77 + }
  78 + if ( String.class.isAssignableFrom( type ) ) {
  79 + return (X) toString(value);
  80 + }
  81 + if ( Object.class.isAssignableFrom( type ) ) {
  82 + return (X) JacksonUtil.toJsonNode(toString(value));
  83 + }
  84 + throw unknownUnwrap( type );
  85 + }
  86 +
  87 + @Override
  88 + public <X> Object wrap(X value, WrapperOptions options) {
  89 + if ( value == null ) {
  90 + return null;
  91 + }
  92 + return fromString(value.toString());
  93 + }
  94 +
  95 +}
\ No newline at end of file
... ...
... ... @@ -16,7 +16,9 @@
16 16 package org.thingsboard.server.dao.sql.plugin;
17 17
18 18 import com.datastax.driver.core.utils.UUIDs;
  19 +import com.github.springtestdbunit.annotation.DatabaseOperation;
19 20 import com.github.springtestdbunit.annotation.DatabaseSetup;
  21 +import com.github.springtestdbunit.annotation.DatabaseTearDown;
20 22 import org.junit.Test;
21 23 import org.springframework.beans.factory.annotation.Autowired;
22 24 import org.thingsboard.server.common.data.id.PluginId;
... ... @@ -45,7 +47,6 @@ public class JpaBasePluginDaoTest extends AbstractJpaDaoTest {
45 47 UUID tenantId1 = UUIDs.timeBased();
46 48 UUID tenantId2 = UUIDs.timeBased();
47 49 createPluginsTwoTenants(tenantId1, tenantId2, "plugin_");
48   - assertEquals(60, pluginDao.find().size());
49 50 List<PluginMetaData> rules1 = pluginDao.findByTenantIdAndPageLink(
50 51 new TenantId(tenantId1), new TextPageLink(20, "plugin_"));
51 52 assertEquals(20, rules1.size());
... ... @@ -60,7 +61,7 @@ public class JpaBasePluginDaoTest extends AbstractJpaDaoTest {
60 61 }
61 62
62 63 @Test
63   - @DatabaseSetup("classpath:dbunit/empty_dataset.xml")
  64 + @DatabaseSetup(value = "classpath:dbunit/empty_dataset.xml")
64 65 public void testFindAllTenantRulesByTenantId() {
65 66 UUID tenantId1 = UUIDs.timeBased();
66 67 UUID tenantId2 = UUIDs.timeBased();
... ...
... ... @@ -16,6 +16,7 @@
16 16 package org.thingsboard.server.dao.sql.rule;
17 17
18 18 import com.datastax.driver.core.utils.UUIDs;
  19 +import com.fasterxml.jackson.databind.ObjectMapper;
19 20 import com.github.springtestdbunit.annotation.DatabaseSetup;
20 21 import org.junit.Test;
21 22 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.rule.RuleMetaData;
26 27 import org.thingsboard.server.dao.AbstractJpaDaoTest;
27 28 import org.thingsboard.server.dao.rule.RuleDao;
28 29
  30 +import java.io.IOException;
29 31 import java.util.List;
30 32 import java.util.UUID;
31 33
... ... @@ -38,12 +40,38 @@ import static org.junit.Assert.assertNotNull;
38 40 public class JpaBaseRuleDaoTest extends AbstractJpaDaoTest {
39 41
40 42 @Autowired
41   - private RuleDao jpaBaseRuleDao;
  43 + private RuleDao ruleDao;
  44 +
  45 + @Test
  46 + @DatabaseSetup("classpath:dbunit/empty_dataset.xml")
  47 + public void testSave() throws IOException {
  48 + UUID id = UUIDs.timeBased();
  49 + RuleMetaData ruleMetaData = new RuleMetaData();
  50 + ruleMetaData.setId(new RuleId(id));
  51 + ruleMetaData.setTenantId(new TenantId(UUIDs.timeBased()));
  52 + ruleMetaData.setName("test");
  53 + String filters = "{\"filters\":\"value-1\"}";
  54 + String processor = "{\"processor\":\"value-2\"}";
  55 + String action = "{\"action\":\"value-3\"}";
  56 + String additionalInfo = "{\"additionalInfo\":\"value-4\"}";
  57 + ObjectMapper mapper = new ObjectMapper();
  58 + ruleMetaData.setFilters(mapper.readTree(filters));
  59 + ruleMetaData.setProcessor(mapper.readTree(processor));
  60 + ruleMetaData.setAction(mapper.readTree(action));
  61 + ruleMetaData.setAdditionalInfo(mapper.readTree(additionalInfo));
  62 + ruleDao.save(ruleMetaData);
  63 + RuleMetaData savedRule = ruleDao.findById(id);
  64 + assertNotNull(savedRule);
  65 + assertEquals(filters, savedRule.getFilters().toString());
  66 + assertEquals(processor, savedRule.getProcessor().toString());
  67 + assertEquals(action, savedRule.getAction().toString());
  68 + assertEquals(additionalInfo, savedRule.getAdditionalInfo().toString());
  69 + }
42 70
43 71 @Test
44 72 @DatabaseSetup("classpath:dbunit/rule.xml")
45 73 public void testFindRulesByPlugin() {
46   - assertEquals(3, jpaBaseRuleDao.findRulesByPlugin("token_1").size());
  74 + assertEquals(3, ruleDao.findRulesByPlugin("token_1").size());
47 75 }
48 76
49 77 @Test
... ... @@ -52,15 +80,15 @@ public class JpaBaseRuleDaoTest extends AbstractJpaDaoTest {
52 80 UUID tenantId1 = UUIDs.timeBased();
53 81 UUID tenantId2 = UUIDs.timeBased();
54 82 createRulesTwoTenants(tenantId1, tenantId2, "name_", "token");
55   - List<RuleMetaData> rules1 = jpaBaseRuleDao.findByTenantIdAndPageLink(
  83 + List<RuleMetaData> rules1 = ruleDao.findByTenantIdAndPageLink(
56 84 new TenantId(tenantId1), new TextPageLink(20, "name_"));
57 85 assertEquals(20, rules1.size());
58 86
59   - List<RuleMetaData> rules2 = jpaBaseRuleDao.findByTenantIdAndPageLink(new TenantId(tenantId1),
  87 + List<RuleMetaData> rules2 = ruleDao.findByTenantIdAndPageLink(new TenantId(tenantId1),
60 88 new TextPageLink(20, "name_", rules1.get(19).getId().getId(), null));
61 89 assertEquals(10, rules2.size());
62 90
63   - List<RuleMetaData> rules3 = jpaBaseRuleDao.findByTenantIdAndPageLink(new TenantId(tenantId1),
  91 + List<RuleMetaData> rules3 = ruleDao.findByTenantIdAndPageLink(new TenantId(tenantId1),
64 92 new TextPageLink(20, "name_", rules2.get(9).getId().getId(), null));
65 93 assertEquals(0, rules3.size());
66 94 }
... ... @@ -71,15 +99,15 @@ public class JpaBaseRuleDaoTest extends AbstractJpaDaoTest {
71 99 UUID tenantId1 = UUIDs.timeBased();
72 100 UUID tenantId2 = UUIDs.timeBased();
73 101 createTenantsAndSystemRules(tenantId1, tenantId2, "name_", "token");
74   - List<RuleMetaData> rules1 = jpaBaseRuleDao.findAllTenantRulesByTenantId(
  102 + List<RuleMetaData> rules1 = ruleDao.findAllTenantRulesByTenantId(
75 103 tenantId1, new TextPageLink(40, "name_"));
76 104 assertEquals(40, rules1.size());
77 105
78   - List<RuleMetaData> rules2 = jpaBaseRuleDao.findAllTenantRulesByTenantId(tenantId1,
  106 + List<RuleMetaData> rules2 = ruleDao.findAllTenantRulesByTenantId(tenantId1,
79 107 new TextPageLink(40, "name_", rules1.get(39).getId().getId(), null));
80 108 assertEquals(20, rules2.size());
81 109
82   - List<RuleMetaData> rules3 = jpaBaseRuleDao.findAllTenantRulesByTenantId(tenantId1,
  110 + List<RuleMetaData> rules3 = ruleDao.findAllTenantRulesByTenantId(tenantId1,
83 111 new TextPageLink(40, "name_", rules2.get(19).getId().getId(), null));
84 112 assertEquals(0, rules3.size());
85 113 }
... ... @@ -105,6 +133,6 @@ public class JpaBaseRuleDaoTest extends AbstractJpaDaoTest {
105 133 ruleMetaData.setTenantId(new TenantId(tenantId));
106 134 ruleMetaData.setName(namePrefix + i);
107 135 ruleMetaData.setPluginToken(pluginToken);
108   - jpaBaseRuleDao.save(ruleMetaData);
  136 + ruleDao.save(ruleMetaData);
109 137 }
110 138 }
... ...
... ... @@ -62,7 +62,6 @@ public class JpaUserDaoTest extends AbstractJpaDaoTest {
62 62 assertEquals(Authority.SYS_ADMIN, user.getAuthority());
63 63 assertEquals("John", user.getFirstName());
64 64 assertEquals("Doe", user.getLastName());
65   - assertEquals("{\"key\":\"value-0\"}", user.getAdditionalInfo().toString());
66 65 }
67 66
68 67 @Test
... ... @@ -114,7 +113,9 @@ public class JpaUserDaoTest extends AbstractJpaDaoTest {
114 113 userDao.save(user);
115 114 assertEquals(6, userDao.find().size());
116 115 User savedUser = userDao.findByEmail("user@thingsboard.org");
  116 + //User savedUser = userDao.findById(UUID.fromString("cd481534-27cc-11e7-93ae-92361f002671"));
117 117 assertNotNull(savedUser);
  118 + assertEquals(additionalInfo, savedUser.getAdditionalInfo().toString());
118 119 }
119 120
120 121 private void create30Adminsand60Users(UUID tenantId, UUID customerId) {
... ...
... ... @@ -137,12 +137,12 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest {
137 137 @Test
138 138 @DatabaseSetup("classpath:dbunit/empty_dataset.xml")
139 139 @DatabaseTearDown(value = "classpath:dbunit/empty_dataset.xml", type= DatabaseOperation.DELETE_ALL)
140   - public void testNonSearchTextNotFound() {
  140 + public void testSearchTextNotFound() {
141 141 UUID tenantId = UUIDs.timeBased();
142 142 createWidgetBundles(5, tenantId, "ABC_");
143 143 createSystemWidgetBundles(5, "SYS_");
144 144
145   - TextPageLink textPageLink = new TextPageLink(30, "WB");
  145 + TextPageLink textPageLink = new TextPageLink(30, "TEXT_NOT_FOUND");
146 146 List<WidgetsBundle> widgetsBundles4 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId, textPageLink);
147 147 assertEquals(0, widgetsBundles4.size());
148 148 }
... ...
... ... @@ -7,7 +7,6 @@
7 7 search_text="SYSADM SEARCH TEXT"
8 8 first_name="John"
9 9 last_name="Doe"
10   - additional_info="{&quot;key&quot;:&quot;value-0&quot;}"
11 10 />
12 11 <tb_user id="1312f328-27c7-11e7-93ae-92361f002671"
13 12 tenant_id="1e1cd4c8-27c7-11e7-93ae-92361f002671"
... ... @@ -16,7 +15,6 @@
16 15 search_text="TENANTADM1 SEARCH TEXT"
17 16 first_name="Samuel"
18 17 last_name="Serif"
19   - additional_info="{&quot;key&quot;:&quot;value-11&quot;}"
20 18 />
21 19 <tb_user id="2b090dde-27ca-11e7-93ae-92361f002671"
22 20 tenant_id="1e1cd4c8-27c7-11e7-93ae-92361f002671"
... ... @@ -25,7 +23,6 @@
25 23 search_text="TENANTADM2 SEARCH TEXT"
26 24 first_name="Penny"
27 25 last_name="Morgan"
28   - additional_info="{&quot;key&quot;:&quot;value-12&quot;}"
29 26 />
30 27 <tb_user id="cc8c1ca8-27c7-11e7-93ae-92361f002671"
31 28 tenant_id="d2e27caa-27c7-11e7-93ae-92361f002671"
... ... @@ -35,7 +32,6 @@
35 32 search_text="CUSTOMER USER SEARCH TEXT"
36 33 first_name="Norman"
37 34 last_name="Gordon"
38   - additional_info="{&quot;key&quot;:&quot;value-2&quot;}"
39 35 />
40 36 <tb_user id="edb2de58-27c7-11e7-93ae-92361f002671"
41 37 tenant_id="f229675e-27c7-11e7-93ae-92361f002671"
... ... @@ -45,6 +41,5 @@
45 41 search_text="REFRESH TOKEN SEARCH TEXT"
46 42 first_name="Dianne"
47 43 last_name="Wensleydale"
48   - additional_info="{&quot;key&quot;:&quot;value-3&quot;}"
49 44 />
50 45 </dataset>
\ No newline at end of file
... ...