Commit ad87924437b99ccdf0cf3ea6d4ea79599d524469
1 parent
07738c31
Tenant and Device profile improvements
Showing
33 changed files
with
783 additions
and
129 deletions
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.controller; | 16 | package org.thingsboard.server.controller; |
17 | 17 | ||
18 | +import com.datastax.oss.driver.api.core.uuid.Uuids; | ||
18 | import com.fasterxml.jackson.core.type.TypeReference; | 19 | import com.fasterxml.jackson.core.type.TypeReference; |
19 | import com.fasterxml.jackson.databind.JsonNode; | 20 | import com.fasterxml.jackson.databind.JsonNode; |
20 | import com.fasterxml.jackson.databind.ObjectMapper; | 21 | import com.fasterxml.jackson.databind.ObjectMapper; |
@@ -59,9 +60,14 @@ import org.springframework.util.MultiValueMap; | @@ -59,9 +60,14 @@ import org.springframework.util.MultiValueMap; | ||
59 | import org.springframework.web.context.WebApplicationContext; | 60 | import org.springframework.web.context.WebApplicationContext; |
60 | import org.thingsboard.server.common.data.BaseData; | 61 | import org.thingsboard.server.common.data.BaseData; |
61 | import org.thingsboard.server.common.data.Customer; | 62 | import org.thingsboard.server.common.data.Customer; |
63 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
64 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
62 | import org.thingsboard.server.common.data.Tenant; | 65 | import org.thingsboard.server.common.data.Tenant; |
63 | import org.thingsboard.server.common.data.User; | 66 | import org.thingsboard.server.common.data.User; |
67 | +import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; | ||
68 | +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | ||
64 | import org.thingsboard.server.common.data.id.HasId; | 69 | import org.thingsboard.server.common.data.id.HasId; |
70 | +import org.thingsboard.server.common.data.id.RuleChainId; | ||
65 | import org.thingsboard.server.common.data.id.TenantId; | 71 | import org.thingsboard.server.common.data.id.TenantId; |
66 | import org.thingsboard.server.common.data.id.UUIDBased; | 72 | import org.thingsboard.server.common.data.id.UUIDBased; |
67 | import org.thingsboard.server.common.data.page.PageLink; | 73 | import org.thingsboard.server.common.data.page.PageLink; |
@@ -305,6 +311,20 @@ public abstract class AbstractWebTest { | @@ -305,6 +311,20 @@ public abstract class AbstractWebTest { | ||
305 | } | 311 | } |
306 | } | 312 | } |
307 | 313 | ||
314 | + protected DeviceProfile createDeviceProfile(String name) { | ||
315 | + DeviceProfile deviceProfile = new DeviceProfile(); | ||
316 | + deviceProfile.setName(name); | ||
317 | + deviceProfile.setType(DeviceProfileType.DEFAULT); | ||
318 | + deviceProfile.setDescription(name + " Test"); | ||
319 | + DeviceProfileData deviceProfileData = new DeviceProfileData(); | ||
320 | + DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration(); | ||
321 | + deviceProfileData.setConfiguration(configuration); | ||
322 | + deviceProfile.setProfileData(deviceProfileData); | ||
323 | + deviceProfile.setDefault(false); | ||
324 | + deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased())); | ||
325 | + return deviceProfile; | ||
326 | + } | ||
327 | + | ||
308 | protected ResultActions doGet(String urlTemplate, Object... urlVariables) throws Exception { | 328 | protected ResultActions doGet(String urlTemplate, Object... urlVariables) throws Exception { |
309 | MockHttpServletRequestBuilder getRequest = get(urlTemplate, urlVariables); | 329 | MockHttpServletRequestBuilder getRequest = get(urlTemplate, urlVariables); |
310 | setJwtToken(getRequest); | 330 | setJwtToken(getRequest); |
@@ -24,6 +24,7 @@ import org.junit.Before; | @@ -24,6 +24,7 @@ import org.junit.Before; | ||
24 | import org.junit.Test; | 24 | import org.junit.Test; |
25 | import org.thingsboard.server.common.data.Customer; | 25 | import org.thingsboard.server.common.data.Customer; |
26 | import org.thingsboard.server.common.data.Device; | 26 | import org.thingsboard.server.common.data.Device; |
27 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
27 | import org.thingsboard.server.common.data.EntitySubtype; | 28 | import org.thingsboard.server.common.data.EntitySubtype; |
28 | import org.thingsboard.server.common.data.Tenant; | 29 | import org.thingsboard.server.common.data.Tenant; |
29 | import org.thingsboard.server.common.data.User; | 30 | import org.thingsboard.server.common.data.User; |
@@ -237,6 +238,21 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { | @@ -237,6 +238,21 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { | ||
237 | } | 238 | } |
238 | 239 | ||
239 | @Test | 240 | @Test |
241 | + public void testSaveSameDeviceWithDifferentDeviceProfileId() throws Exception { | ||
242 | + Device device = new Device(); | ||
243 | + device.setName("My device"); | ||
244 | + device.setType("default"); | ||
245 | + Device savedDevice = doPost("/api/device", device, Device.class); | ||
246 | + DeviceProfile deviceProfile2 = this.createDeviceProfile("Device Profile 2"); | ||
247 | + DeviceProfile savedDeviceProfile2 = doPost("/api/deviceProfile", deviceProfile2, DeviceProfile.class); | ||
248 | + | ||
249 | + savedDevice.setDeviceProfileId(savedDeviceProfile2.getId()); | ||
250 | + | ||
251 | + doPost("/api/device/", savedDevice).andExpect(status().isBadRequest()) | ||
252 | + .andExpect(statusReason(containsString("Changing device profile is prohibited"))); | ||
253 | + } | ||
254 | + | ||
255 | + @Test | ||
240 | public void testAssignDeviceToCustomerFromDifferentTenant() throws Exception { | 256 | public void testAssignDeviceToCustomerFromDifferentTenant() throws Exception { |
241 | loginSysAdmin(); | 257 | loginSysAdmin(); |
242 | 258 |
@@ -15,21 +15,20 @@ | @@ -15,21 +15,20 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.controller; | 16 | package org.thingsboard.server.controller; |
17 | 17 | ||
18 | -import com.datastax.oss.driver.api.core.uuid.Uuids; | ||
19 | import com.fasterxml.jackson.core.type.TypeReference; | 18 | import com.fasterxml.jackson.core.type.TypeReference; |
20 | import org.junit.After; | 19 | import org.junit.After; |
21 | import org.junit.Assert; | 20 | import org.junit.Assert; |
22 | import org.junit.Before; | 21 | import org.junit.Before; |
23 | import org.junit.Test; | 22 | import org.junit.Test; |
23 | +import org.thingsboard.server.common.data.Device; | ||
24 | import org.thingsboard.server.common.data.DeviceProfile; | 24 | import org.thingsboard.server.common.data.DeviceProfile; |
25 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
25 | import org.thingsboard.server.common.data.EntityInfo; | 26 | import org.thingsboard.server.common.data.EntityInfo; |
26 | import org.thingsboard.server.common.data.Tenant; | 27 | import org.thingsboard.server.common.data.Tenant; |
27 | import org.thingsboard.server.common.data.User; | 28 | import org.thingsboard.server.common.data.User; |
28 | -import org.thingsboard.server.common.data.id.RuleChainId; | ||
29 | import org.thingsboard.server.common.data.page.PageData; | 29 | import org.thingsboard.server.common.data.page.PageData; |
30 | import org.thingsboard.server.common.data.page.PageLink; | 30 | import org.thingsboard.server.common.data.page.PageLink; |
31 | import org.thingsboard.server.common.data.security.Authority; | 31 | import org.thingsboard.server.common.data.security.Authority; |
32 | -import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
33 | 32 | ||
34 | import java.util.ArrayList; | 33 | import java.util.ArrayList; |
35 | import java.util.Collections; | 34 | import java.util.Collections; |
@@ -149,6 +148,32 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController | @@ -149,6 +148,32 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController | ||
149 | } | 148 | } |
150 | 149 | ||
151 | @Test | 150 | @Test |
151 | + public void testSaveSameDeviceProfileWithDifferentType() throws Exception { | ||
152 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | ||
153 | + DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); | ||
154 | + savedDeviceProfile.setType(DeviceProfileType.LWM2M); | ||
155 | + doPost("/api/deviceProfile", savedDeviceProfile).andExpect(status().isBadRequest()) | ||
156 | + .andExpect(statusReason(containsString("Changing type of device profile is prohibited"))); | ||
157 | + } | ||
158 | + | ||
159 | + @Test | ||
160 | + public void testDeleteDeviceProfileWithExistingDevice() throws Exception { | ||
161 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | ||
162 | + DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); | ||
163 | + | ||
164 | + Device device = new Device(); | ||
165 | + device.setName("Test device"); | ||
166 | + device.setType("default"); | ||
167 | + device.setDeviceProfileId(savedDeviceProfile.getId()); | ||
168 | + | ||
169 | + Device savedDevice = doPost("/api/device", device, Device.class); | ||
170 | + | ||
171 | + doDelete("/api/deviceProfile/" + savedDeviceProfile.getId().getId().toString()) | ||
172 | + .andExpect(status().isBadRequest()) | ||
173 | + .andExpect(statusReason(containsString("The device profile referenced by the devices cannot be deleted"))); | ||
174 | + } | ||
175 | + | ||
176 | + @Test | ||
152 | public void testDeleteDeviceProfile() throws Exception { | 177 | public void testDeleteDeviceProfile() throws Exception { |
153 | DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | 178 | DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); |
154 | DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); | 179 | DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); |
@@ -254,13 +279,4 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController | @@ -254,13 +279,4 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController | ||
254 | Assert.assertEquals(1, pageData.getTotalElements()); | 279 | Assert.assertEquals(1, pageData.getTotalElements()); |
255 | } | 280 | } |
256 | 281 | ||
257 | - private DeviceProfile createDeviceProfile(String name) { | ||
258 | - DeviceProfile deviceProfile = new DeviceProfile(); | ||
259 | - deviceProfile.setName(name); | ||
260 | - deviceProfile.setDescription(name + " Test"); | ||
261 | - deviceProfile.setProfileData(JacksonUtil.OBJECT_MAPPER.createObjectNode()); | ||
262 | - deviceProfile.setDefault(false); | ||
263 | - deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased())); | ||
264 | - return deviceProfile; | ||
265 | - } | ||
266 | } | 282 | } |
@@ -20,16 +20,14 @@ import org.junit.After; | @@ -20,16 +20,14 @@ import org.junit.After; | ||
20 | import org.junit.Assert; | 20 | import org.junit.Assert; |
21 | import org.junit.Test; | 21 | import org.junit.Test; |
22 | import org.springframework.beans.factory.annotation.Autowired; | 22 | import org.springframework.beans.factory.annotation.Autowired; |
23 | -import org.thingsboard.server.common.data.Device; | ||
24 | import org.thingsboard.server.common.data.EntityInfo; | 23 | import org.thingsboard.server.common.data.EntityInfo; |
25 | import org.thingsboard.server.common.data.Tenant; | 24 | import org.thingsboard.server.common.data.Tenant; |
26 | import org.thingsboard.server.common.data.TenantProfile; | 25 | import org.thingsboard.server.common.data.TenantProfile; |
26 | +import org.thingsboard.server.common.data.TenantProfileData; | ||
27 | import org.thingsboard.server.common.data.id.TenantId; | 27 | import org.thingsboard.server.common.data.id.TenantId; |
28 | import org.thingsboard.server.common.data.page.PageData; | 28 | import org.thingsboard.server.common.data.page.PageData; |
29 | import org.thingsboard.server.common.data.page.PageLink; | 29 | import org.thingsboard.server.common.data.page.PageLink; |
30 | -import org.thingsboard.server.dao.exception.DataValidationException; | ||
31 | import org.thingsboard.server.dao.tenant.TenantProfileService; | 30 | import org.thingsboard.server.dao.tenant.TenantProfileService; |
32 | -import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
33 | 31 | ||
34 | import java.util.ArrayList; | 32 | import java.util.ArrayList; |
35 | import java.util.Collections; | 33 | import java.util.Collections; |
@@ -48,7 +46,9 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController | @@ -48,7 +46,9 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController | ||
48 | private TenantProfileService tenantProfileService; | 46 | private TenantProfileService tenantProfileService; |
49 | 47 | ||
50 | @After | 48 | @After |
51 | - public void after() { | 49 | + @Override |
50 | + public void teardown() throws Exception { | ||
51 | + super.teardown(); | ||
52 | tenantProfileService.deleteTenantProfiles(TenantId.SYS_TENANT_ID); | 52 | tenantProfileService.deleteTenantProfiles(TenantId.SYS_TENANT_ID); |
53 | } | 53 | } |
54 | 54 | ||
@@ -134,6 +134,45 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController | @@ -134,6 +134,45 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController | ||
134 | } | 134 | } |
135 | 135 | ||
136 | @Test | 136 | @Test |
137 | + public void testSaveSameTenantProfileWithDifferentIsolatedTbRuleEngine() throws Exception { | ||
138 | + loginSysAdmin(); | ||
139 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
140 | + TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class); | ||
141 | + savedTenantProfile.setIsolatedTbRuleEngine(true); | ||
142 | + doPost("/api/tenantProfile", savedTenantProfile).andExpect(status().isBadRequest()) | ||
143 | + .andExpect(statusReason(containsString("Can't update isolatedTbRuleEngine property"))); | ||
144 | + } | ||
145 | + | ||
146 | + @Test | ||
147 | + public void testSaveSameTenantProfileWithDifferentIsolatedTbCore() throws Exception { | ||
148 | + loginSysAdmin(); | ||
149 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
150 | + TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class); | ||
151 | + savedTenantProfile.setIsolatedTbCore(true); | ||
152 | + doPost("/api/tenantProfile", savedTenantProfile).andExpect(status().isBadRequest()) | ||
153 | + .andExpect(statusReason(containsString("Can't update isolatedTbCore property"))); | ||
154 | + } | ||
155 | + | ||
156 | + @Test | ||
157 | + public void testDeleteTenantProfileWithExistingTenant() throws Exception { | ||
158 | + loginSysAdmin(); | ||
159 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
160 | + TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class); | ||
161 | + | ||
162 | + Tenant tenant = new Tenant(); | ||
163 | + tenant.setTitle("My tenant with tenant profile"); | ||
164 | + tenant.setTenantProfileId(savedTenantProfile.getId()); | ||
165 | + Tenant savedTenant = doPost("/api/tenant", tenant, Tenant.class); | ||
166 | + | ||
167 | + doDelete("/api/tenantProfile/" + savedTenantProfile.getId().getId().toString()) | ||
168 | + .andExpect(status().isBadRequest()) | ||
169 | + .andExpect(statusReason(containsString("The tenant profile referenced by the tenants cannot be deleted"))); | ||
170 | + | ||
171 | + doDelete("/api/tenant/"+savedTenant.getId().getId().toString()) | ||
172 | + .andExpect(status().isOk()); | ||
173 | + } | ||
174 | + | ||
175 | + @Test | ||
137 | public void testDeleteTenantProfile() throws Exception { | 176 | public void testDeleteTenantProfile() throws Exception { |
138 | loginSysAdmin(); | 177 | loginSysAdmin(); |
139 | TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | 178 | TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); |
@@ -246,7 +285,7 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController | @@ -246,7 +285,7 @@ public abstract class BaseTenantProfileControllerTest extends AbstractController | ||
246 | TenantProfile tenantProfile = new TenantProfile(); | 285 | TenantProfile tenantProfile = new TenantProfile(); |
247 | tenantProfile.setName(name); | 286 | tenantProfile.setName(name); |
248 | tenantProfile.setDescription(name + " Test"); | 287 | tenantProfile.setDescription(name + " Test"); |
249 | - tenantProfile.setProfileData(JacksonUtil.OBJECT_MAPPER.createObjectNode()); | 288 | + tenantProfile.setProfileData(new TenantProfileData()); |
250 | tenantProfile.setDefault(false); | 289 | tenantProfile.setDefault(false); |
251 | tenantProfile.setIsolatedTbCore(false); | 290 | tenantProfile.setIsolatedTbCore(false); |
252 | tenantProfile.setIsolatedTbRuleEngine(false); | 291 | tenantProfile.setIsolatedTbRuleEngine(false); |
@@ -15,13 +15,22 @@ | @@ -15,13 +15,22 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.common.data; | 16 | package org.thingsboard.server.common.data; |
17 | 17 | ||
18 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | +import com.fasterxml.jackson.core.JsonProcessingException; | ||
18 | import lombok.EqualsAndHashCode; | 20 | import lombok.EqualsAndHashCode; |
21 | +import lombok.extern.slf4j.Slf4j; | ||
22 | +import org.thingsboard.server.common.data.device.data.DeviceData; | ||
23 | +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | ||
19 | import org.thingsboard.server.common.data.id.CustomerId; | 24 | import org.thingsboard.server.common.data.id.CustomerId; |
20 | import org.thingsboard.server.common.data.id.DeviceId; | 25 | import org.thingsboard.server.common.data.id.DeviceId; |
21 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 26 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
22 | import org.thingsboard.server.common.data.id.TenantId; | 27 | import org.thingsboard.server.common.data.id.TenantId; |
23 | 28 | ||
29 | +import java.io.ByteArrayInputStream; | ||
30 | +import java.io.IOException; | ||
31 | + | ||
24 | @EqualsAndHashCode(callSuper = true) | 32 | @EqualsAndHashCode(callSuper = true) |
33 | +@Slf4j | ||
25 | public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasName, HasTenantId, HasCustomerId { | 34 | public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasName, HasTenantId, HasCustomerId { |
26 | 35 | ||
27 | private static final long serialVersionUID = 2807343040519543363L; | 36 | private static final long serialVersionUID = 2807343040519543363L; |
@@ -32,6 +41,9 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -32,6 +41,9 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
32 | private String type; | 41 | private String type; |
33 | private String label; | 42 | private String label; |
34 | private DeviceProfileId deviceProfileId; | 43 | private DeviceProfileId deviceProfileId; |
44 | + private transient DeviceData deviceData; | ||
45 | + @JsonIgnore | ||
46 | + private byte[] deviceDataBytes; | ||
35 | 47 | ||
36 | public Device() { | 48 | public Device() { |
37 | super(); | 49 | super(); |
@@ -49,6 +61,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -49,6 +61,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
49 | this.type = device.getType(); | 61 | this.type = device.getType(); |
50 | this.label = device.getLabel(); | 62 | this.label = device.getLabel(); |
51 | this.deviceProfileId = device.getDeviceProfileId(); | 63 | this.deviceProfileId = device.getDeviceProfileId(); |
64 | + this.setDeviceData(device.getDeviceData()); | ||
52 | } | 65 | } |
53 | 66 | ||
54 | public TenantId getTenantId() { | 67 | public TenantId getTenantId() { |
@@ -100,6 +113,33 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -100,6 +113,33 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
100 | this.deviceProfileId = deviceProfileId; | 113 | this.deviceProfileId = deviceProfileId; |
101 | } | 114 | } |
102 | 115 | ||
116 | + public DeviceData getDeviceData() { | ||
117 | + if (deviceData != null) { | ||
118 | + return deviceData; | ||
119 | + } else { | ||
120 | + if (deviceDataBytes != null) { | ||
121 | + try { | ||
122 | + deviceData = mapper.readValue(new ByteArrayInputStream(deviceDataBytes), DeviceData.class); | ||
123 | + } catch (IOException e) { | ||
124 | + log.warn("Can't deserialize device data: ", e); | ||
125 | + return null; | ||
126 | + } | ||
127 | + return deviceData; | ||
128 | + } else { | ||
129 | + return null; | ||
130 | + } | ||
131 | + } | ||
132 | + } | ||
133 | + | ||
134 | + public void setDeviceData(DeviceData data) { | ||
135 | + this.deviceData = data; | ||
136 | + try { | ||
137 | + this.deviceDataBytes = data != null ? mapper.writeValueAsBytes(data) : null; | ||
138 | + } catch (JsonProcessingException e) { | ||
139 | + log.warn("Can't serialize device data: ", e); | ||
140 | + } | ||
141 | + } | ||
142 | + | ||
103 | @Override | 143 | @Override |
104 | public String getSearchText() { | 144 | public String getSearchText() { |
105 | return getName(); | 145 | return getName(); |
@@ -120,6 +160,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -120,6 +160,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
120 | builder.append(label); | 160 | builder.append(label); |
121 | builder.append(", deviceProfileId="); | 161 | builder.append(", deviceProfileId="); |
122 | builder.append(deviceProfileId); | 162 | builder.append(deviceProfileId); |
163 | + builder.append(", deviceData="); | ||
164 | + builder.append(deviceData); | ||
123 | builder.append(", additionalInfo="); | 165 | builder.append(", additionalInfo="); |
124 | builder.append(getAdditionalInfo()); | 166 | builder.append(getAdditionalInfo()); |
125 | builder.append(", createdTime="); | 167 | builder.append(", createdTime="); |
@@ -16,26 +16,32 @@ | @@ -16,26 +16,32 @@ | ||
16 | package org.thingsboard.server.common.data; | 16 | package org.thingsboard.server.common.data; |
17 | 17 | ||
18 | import com.fasterxml.jackson.annotation.JsonIgnore; | 18 | import com.fasterxml.jackson.annotation.JsonIgnore; |
19 | -import com.fasterxml.jackson.databind.JsonNode; | 19 | +import com.fasterxml.jackson.core.JsonProcessingException; |
20 | import lombok.Data; | 20 | import lombok.Data; |
21 | import lombok.EqualsAndHashCode; | 21 | import lombok.EqualsAndHashCode; |
22 | +import lombok.extern.slf4j.Slf4j; | ||
23 | +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | ||
22 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 24 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
23 | import org.thingsboard.server.common.data.id.RuleChainId; | 25 | import org.thingsboard.server.common.data.id.RuleChainId; |
24 | import org.thingsboard.server.common.data.id.TenantId; | 26 | import org.thingsboard.server.common.data.id.TenantId; |
25 | 27 | ||
26 | -import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.getJson; | ||
27 | -import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.setJson; | 28 | +import java.io.ByteArrayInputStream; |
29 | +import java.io.IOException; | ||
30 | + | ||
31 | +import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.mapper; | ||
28 | 32 | ||
29 | @Data | 33 | @Data |
30 | @EqualsAndHashCode(callSuper = true) | 34 | @EqualsAndHashCode(callSuper = true) |
35 | +@Slf4j | ||
31 | public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements HasName, HasTenantId { | 36 | public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements HasName, HasTenantId { |
32 | 37 | ||
33 | private TenantId tenantId; | 38 | private TenantId tenantId; |
34 | private String name; | 39 | private String name; |
35 | private String description; | 40 | private String description; |
36 | private boolean isDefault; | 41 | private boolean isDefault; |
42 | + private DeviceProfileType type; | ||
37 | private RuleChainId defaultRuleChainId; | 43 | private RuleChainId defaultRuleChainId; |
38 | - private transient JsonNode profileData; | 44 | + private transient DeviceProfileData profileData; |
39 | @JsonIgnore | 45 | @JsonIgnore |
40 | private byte[] profileDataBytes; | 46 | private byte[] profileDataBytes; |
41 | 47 | ||
@@ -67,12 +73,31 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H | @@ -67,12 +73,31 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H | ||
67 | return name; | 73 | return name; |
68 | } | 74 | } |
69 | 75 | ||
70 | - public JsonNode getProfileData() { | ||
71 | - return getJson(() -> profileData, () -> profileDataBytes); | 76 | + public DeviceProfileData getProfileData() { |
77 | + if (profileData != null) { | ||
78 | + return profileData; | ||
79 | + } else { | ||
80 | + if (profileDataBytes != null) { | ||
81 | + try { | ||
82 | + profileData = mapper.readValue(new ByteArrayInputStream(profileDataBytes), DeviceProfileData.class); | ||
83 | + } catch (IOException e) { | ||
84 | + log.warn("Can't deserialize device profile data: ", e); | ||
85 | + return null; | ||
86 | + } | ||
87 | + return profileData; | ||
88 | + } else { | ||
89 | + return null; | ||
90 | + } | ||
91 | + } | ||
72 | } | 92 | } |
73 | 93 | ||
74 | - public void setProfileData(JsonNode data) { | ||
75 | - setJson(data, json -> this.profileData = json, bytes -> this.profileDataBytes = bytes); | 94 | + public void setProfileData(DeviceProfileData data) { |
95 | + this.profileData = data; | ||
96 | + try { | ||
97 | + this.profileDataBytes = data != null ? mapper.writeValueAsBytes(data) : null; | ||
98 | + } catch (JsonProcessingException e) { | ||
99 | + log.warn("Can't serialize device profile data: ", e); | ||
100 | + } | ||
76 | } | 101 | } |
77 | 102 | ||
78 | } | 103 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2020 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.common.data; | ||
17 | + | ||
18 | +public enum DeviceProfileType { | ||
19 | + DEFAULT, | ||
20 | + LWM2M | ||
21 | +} |
@@ -35,7 +35,7 @@ import java.util.function.Consumer; | @@ -35,7 +35,7 @@ import java.util.function.Consumer; | ||
35 | @Slf4j | 35 | @Slf4j |
36 | public abstract class SearchTextBasedWithAdditionalInfo<I extends UUIDBased> extends SearchTextBased<I> implements HasAdditionalInfo { | 36 | public abstract class SearchTextBasedWithAdditionalInfo<I extends UUIDBased> extends SearchTextBased<I> implements HasAdditionalInfo { |
37 | 37 | ||
38 | - private static final ObjectMapper mapper = new ObjectMapper(); | 38 | + public static final ObjectMapper mapper = new ObjectMapper(); |
39 | private transient JsonNode additionalInfo; | 39 | private transient JsonNode additionalInfo; |
40 | @JsonIgnore | 40 | @JsonIgnore |
41 | private byte[] additionalInfoBytes; | 41 | private byte[] additionalInfoBytes; |
@@ -84,7 +84,7 @@ public abstract class SearchTextBasedWithAdditionalInfo<I extends UUIDBased> ext | @@ -84,7 +84,7 @@ public abstract class SearchTextBasedWithAdditionalInfo<I extends UUIDBased> ext | ||
84 | byte[] data = binaryData.get(); | 84 | byte[] data = binaryData.get(); |
85 | if (data != null) { | 85 | if (data != null) { |
86 | try { | 86 | try { |
87 | - return new ObjectMapper().readTree(new ByteArrayInputStream(data)); | 87 | + return mapper.readTree(new ByteArrayInputStream(data)); |
88 | } catch (IOException e) { | 88 | } catch (IOException e) { |
89 | log.warn("Can't deserialize json data: ", e); | 89 | log.warn("Can't deserialize json data: ", e); |
90 | return null; | 90 | return null; |
@@ -16,16 +16,20 @@ | @@ -16,16 +16,20 @@ | ||
16 | package org.thingsboard.server.common.data; | 16 | package org.thingsboard.server.common.data; |
17 | 17 | ||
18 | import com.fasterxml.jackson.annotation.JsonIgnore; | 18 | import com.fasterxml.jackson.annotation.JsonIgnore; |
19 | -import com.fasterxml.jackson.databind.JsonNode; | 19 | +import com.fasterxml.jackson.core.JsonProcessingException; |
20 | import lombok.Data; | 20 | import lombok.Data; |
21 | import lombok.EqualsAndHashCode; | 21 | import lombok.EqualsAndHashCode; |
22 | +import lombok.extern.slf4j.Slf4j; | ||
22 | import org.thingsboard.server.common.data.id.TenantProfileId; | 23 | import org.thingsboard.server.common.data.id.TenantProfileId; |
23 | 24 | ||
24 | -import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.getJson; | ||
25 | -import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.setJson; | 25 | +import java.io.ByteArrayInputStream; |
26 | +import java.io.IOException; | ||
27 | + | ||
28 | +import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.mapper; | ||
26 | 29 | ||
27 | @Data | 30 | @Data |
28 | @EqualsAndHashCode(callSuper = true) | 31 | @EqualsAndHashCode(callSuper = true) |
32 | +@Slf4j | ||
29 | public class TenantProfile extends SearchTextBased<TenantProfileId> implements HasName { | 33 | public class TenantProfile extends SearchTextBased<TenantProfileId> implements HasName { |
30 | 34 | ||
31 | private String name; | 35 | private String name; |
@@ -33,7 +37,7 @@ public class TenantProfile extends SearchTextBased<TenantProfileId> implements H | @@ -33,7 +37,7 @@ public class TenantProfile extends SearchTextBased<TenantProfileId> implements H | ||
33 | private boolean isDefault; | 37 | private boolean isDefault; |
34 | private boolean isolatedTbCore; | 38 | private boolean isolatedTbCore; |
35 | private boolean isolatedTbRuleEngine; | 39 | private boolean isolatedTbRuleEngine; |
36 | - private transient JsonNode profileData; | 40 | + private transient TenantProfileData profileData; |
37 | @JsonIgnore | 41 | @JsonIgnore |
38 | private byte[] profileDataBytes; | 42 | private byte[] profileDataBytes; |
39 | 43 | ||
@@ -65,12 +69,31 @@ public class TenantProfile extends SearchTextBased<TenantProfileId> implements H | @@ -65,12 +69,31 @@ public class TenantProfile extends SearchTextBased<TenantProfileId> implements H | ||
65 | return name; | 69 | return name; |
66 | } | 70 | } |
67 | 71 | ||
68 | - public JsonNode getProfileData() { | ||
69 | - return getJson(() -> profileData, () -> profileDataBytes); | 72 | + public TenantProfileData getProfileData() { |
73 | + if (profileData != null) { | ||
74 | + return profileData; | ||
75 | + } else { | ||
76 | + if (profileDataBytes != null) { | ||
77 | + try { | ||
78 | + profileData = mapper.readValue(new ByteArrayInputStream(profileDataBytes), TenantProfileData.class); | ||
79 | + } catch (IOException e) { | ||
80 | + log.warn("Can't deserialize tenant profile data: ", e); | ||
81 | + return null; | ||
82 | + } | ||
83 | + return profileData; | ||
84 | + } else { | ||
85 | + return null; | ||
86 | + } | ||
87 | + } | ||
70 | } | 88 | } |
71 | 89 | ||
72 | - public void setProfileData(JsonNode data) { | ||
73 | - setJson(data, json -> this.profileData = json, bytes -> this.profileDataBytes = bytes); | 90 | + public void setProfileData(TenantProfileData data) { |
91 | + this.profileData = data; | ||
92 | + try { | ||
93 | + this.profileDataBytes = data != null ? mapper.writeValueAsBytes(data) : null; | ||
94 | + } catch (JsonProcessingException e) { | ||
95 | + log.warn("Can't serialize tenant profile data: ", e); | ||
96 | + } | ||
74 | } | 97 | } |
75 | 98 | ||
76 | } | 99 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2020 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.common.data; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.annotation.JsonAnyGetter; | ||
19 | +import com.fasterxml.jackson.annotation.JsonAnySetter; | ||
20 | +import lombok.Data; | ||
21 | + | ||
22 | +import java.util.HashMap; | ||
23 | +import java.util.Map; | ||
24 | + | ||
25 | +@Data | ||
26 | +public class TenantProfileData { | ||
27 | + | ||
28 | + private Map<String, String> properties = new HashMap<>(); | ||
29 | + | ||
30 | + @JsonAnyGetter | ||
31 | + public Map<String, String> properties() { | ||
32 | + return this.properties; | ||
33 | + } | ||
34 | + | ||
35 | + @JsonAnySetter | ||
36 | + public void put(String name, String value) { | ||
37 | + this.properties.put(name, value); | ||
38 | + } | ||
39 | + | ||
40 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 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.common.data.device.data; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
20 | + | ||
21 | +@Data | ||
22 | +public class DefaultDeviceConfiguration implements DeviceConfiguration { | ||
23 | + | ||
24 | + @Override | ||
25 | + public DeviceProfileType getType() { | ||
26 | + return DeviceProfileType.DEFAULT; | ||
27 | + } | ||
28 | + | ||
29 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 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.common.data.device.data; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
20 | +import com.fasterxml.jackson.annotation.JsonSubTypes; | ||
21 | +import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
22 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
23 | + | ||
24 | +@JsonIgnoreProperties(ignoreUnknown = true) | ||
25 | +@JsonTypeInfo( | ||
26 | + use = JsonTypeInfo.Id.NAME, | ||
27 | + include = JsonTypeInfo.As.PROPERTY, | ||
28 | + property = "type") | ||
29 | +@JsonSubTypes({ | ||
30 | + @JsonSubTypes.Type(value = DefaultDeviceConfiguration.class, name = "DEFAULT"), | ||
31 | + @JsonSubTypes.Type(value = Lwm2mDeviceConfiguration.class, name = "LWM2M")}) | ||
32 | +public interface DeviceConfiguration { | ||
33 | + | ||
34 | + @JsonIgnore | ||
35 | + DeviceProfileType getType(); | ||
36 | + | ||
37 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 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.common.data.device.data; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
21 | +public class DeviceData { | ||
22 | + | ||
23 | + private DeviceConfiguration configuration; | ||
24 | + | ||
25 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 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.common.data.device.data; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
20 | + | ||
21 | +@Data | ||
22 | +public class Lwm2mDeviceConfiguration implements DeviceConfiguration { | ||
23 | + | ||
24 | + @Override | ||
25 | + public DeviceProfileType getType() { | ||
26 | + return DeviceProfileType.LWM2M; | ||
27 | + } | ||
28 | + | ||
29 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 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.common.data.device.profile; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
20 | + | ||
21 | +@Data | ||
22 | +public class DefaultDeviceProfileConfiguration implements DeviceProfileConfiguration { | ||
23 | + | ||
24 | + @Override | ||
25 | + public DeviceProfileType getType() { | ||
26 | + return DeviceProfileType.DEFAULT; | ||
27 | + } | ||
28 | + | ||
29 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 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.common.data.device.profile; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
20 | +import com.fasterxml.jackson.annotation.JsonSubTypes; | ||
21 | +import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
22 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
23 | + | ||
24 | +@JsonIgnoreProperties(ignoreUnknown = true) | ||
25 | +@JsonTypeInfo( | ||
26 | + use = JsonTypeInfo.Id.NAME, | ||
27 | + include = JsonTypeInfo.As.PROPERTY, | ||
28 | + property = "type") | ||
29 | +@JsonSubTypes({ | ||
30 | + @JsonSubTypes.Type(value = DefaultDeviceProfileConfiguration.class, name = "DEFAULT"), | ||
31 | + @JsonSubTypes.Type(value = Lwm2mDeviceProfileConfiguration.class, name = "LWM2M")}) | ||
32 | +public interface DeviceProfileConfiguration { | ||
33 | + | ||
34 | + @JsonIgnore | ||
35 | + DeviceProfileType getType(); | ||
36 | + | ||
37 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 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.common.data.device.profile; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
21 | +public class DeviceProfileData { | ||
22 | + | ||
23 | + private DeviceProfileConfiguration configuration; | ||
24 | + | ||
25 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 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.common.data.device.profile; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
20 | + | ||
21 | +@Data | ||
22 | +public class Lwm2mDeviceProfileConfiguration implements DeviceProfileConfiguration { | ||
23 | + | ||
24 | + @Override | ||
25 | + public DeviceProfileType getType() { | ||
26 | + return DeviceProfileType.LWM2M; | ||
27 | + } | ||
28 | + | ||
29 | +} |
@@ -24,8 +24,11 @@ import org.springframework.cache.CacheManager; | @@ -24,8 +24,11 @@ import org.springframework.cache.CacheManager; | ||
24 | import org.springframework.cache.annotation.Cacheable; | 24 | import org.springframework.cache.annotation.Cacheable; |
25 | import org.springframework.stereotype.Service; | 25 | import org.springframework.stereotype.Service; |
26 | import org.thingsboard.server.common.data.DeviceProfile; | 26 | import org.thingsboard.server.common.data.DeviceProfile; |
27 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
27 | import org.thingsboard.server.common.data.EntityInfo; | 28 | import org.thingsboard.server.common.data.EntityInfo; |
28 | import org.thingsboard.server.common.data.Tenant; | 29 | import org.thingsboard.server.common.data.Tenant; |
30 | +import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; | ||
31 | +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | ||
29 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 32 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
30 | import org.thingsboard.server.common.data.id.TenantId; | 33 | import org.thingsboard.server.common.data.id.TenantId; |
31 | import org.thingsboard.server.common.data.page.PageData; | 34 | import org.thingsboard.server.common.data.page.PageData; |
@@ -113,8 +116,17 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | @@ -113,8 +116,17 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | ||
113 | } | 116 | } |
114 | 117 | ||
115 | private void removeDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId) { | 118 | private void removeDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId) { |
119 | + try { | ||
120 | + deviceProfileDao.removeById(tenantId, deviceProfileId.getId()); | ||
121 | + } catch (Exception t) { | ||
122 | + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); | ||
123 | + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_device_profile")) { | ||
124 | + throw new DataValidationException("The device profile referenced by the devices cannot be deleted!"); | ||
125 | + } else { | ||
126 | + throw t; | ||
127 | + } | ||
128 | + } | ||
116 | deleteEntityRelations(tenantId, deviceProfileId); | 129 | deleteEntityRelations(tenantId, deviceProfileId); |
117 | - deviceProfileDao.removeById(tenantId, deviceProfileId.getId()); | ||
118 | Cache cache = cacheManager.getCache(DEVICE_PROFILE_CACHE); | 130 | Cache cache = cacheManager.getCache(DEVICE_PROFILE_CACHE); |
119 | cache.evict(Collections.singletonList(deviceProfileId.getId())); | 131 | cache.evict(Collections.singletonList(deviceProfileId.getId())); |
120 | cache.evict(Arrays.asList("info", deviceProfileId.getId())); | 132 | cache.evict(Arrays.asList("info", deviceProfileId.getId())); |
@@ -144,8 +156,12 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | @@ -144,8 +156,12 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | ||
144 | deviceProfile.setTenantId(tenantId); | 156 | deviceProfile.setTenantId(tenantId); |
145 | deviceProfile.setDefault(true); | 157 | deviceProfile.setDefault(true); |
146 | deviceProfile.setName("Default"); | 158 | deviceProfile.setName("Default"); |
159 | + deviceProfile.setType(DeviceProfileType.DEFAULT); | ||
147 | deviceProfile.setDescription("Default device profile"); | 160 | deviceProfile.setDescription("Default device profile"); |
148 | - deviceProfile.setProfileData(JacksonUtil.OBJECT_MAPPER.createObjectNode()); | 161 | + DeviceProfileData deviceProfileData = new DeviceProfileData(); |
162 | + DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration(); | ||
163 | + deviceProfileData.setConfiguration(configuration); | ||
164 | + deviceProfile.setProfileData(deviceProfileData); | ||
149 | return saveDeviceProfile(deviceProfile); | 165 | return saveDeviceProfile(deviceProfile); |
150 | } | 166 | } |
151 | 167 | ||
@@ -226,6 +242,16 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | @@ -226,6 +242,16 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | ||
226 | } | 242 | } |
227 | } | 243 | } |
228 | } | 244 | } |
245 | + | ||
246 | + @Override | ||
247 | + protected void validateUpdate(TenantId tenantId, DeviceProfile deviceProfile) { | ||
248 | + DeviceProfile old = deviceProfileDao.findById(deviceProfile.getTenantId(), deviceProfile.getId().getId()); | ||
249 | + if (old == null) { | ||
250 | + throw new DataValidationException("Can't update non existing device profile!"); | ||
251 | + } else if (!old.getType().equals(deviceProfile.getType())) { | ||
252 | + throw new DataValidationException("Changing type of device profile is prohibited!"); | ||
253 | + } | ||
254 | + } | ||
229 | }; | 255 | }; |
230 | 256 | ||
231 | private PaginatedRemover<TenantId, DeviceProfile> tenantDeviceProfilesRemover = | 257 | private PaginatedRemover<TenantId, DeviceProfile> tenantDeviceProfilesRemover = |
@@ -41,6 +41,8 @@ import org.thingsboard.server.common.data.EntityType; | @@ -41,6 +41,8 @@ import org.thingsboard.server.common.data.EntityType; | ||
41 | import org.thingsboard.server.common.data.EntityView; | 41 | import org.thingsboard.server.common.data.EntityView; |
42 | import org.thingsboard.server.common.data.Tenant; | 42 | import org.thingsboard.server.common.data.Tenant; |
43 | import org.thingsboard.server.common.data.device.DeviceSearchQuery; | 43 | import org.thingsboard.server.common.data.device.DeviceSearchQuery; |
44 | +import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration; | ||
45 | +import org.thingsboard.server.common.data.device.data.DeviceData; | ||
44 | import org.thingsboard.server.common.data.id.CustomerId; | 46 | import org.thingsboard.server.common.data.id.CustomerId; |
45 | import org.thingsboard.server.common.data.id.DeviceId; | 47 | import org.thingsboard.server.common.data.id.DeviceId; |
46 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 48 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
@@ -168,6 +170,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | @@ -168,6 +170,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | ||
168 | if (device.getDeviceProfileId() == null) { | 170 | if (device.getDeviceProfileId() == null) { |
169 | EntityInfo deviceProfile = this.deviceProfileService.findDefaultDeviceProfileInfo(device.getTenantId()); | 171 | EntityInfo deviceProfile = this.deviceProfileService.findDefaultDeviceProfileInfo(device.getTenantId()); |
170 | device.setDeviceProfileId(new DeviceProfileId(deviceProfile.getId().getId())); | 172 | device.setDeviceProfileId(new DeviceProfileId(deviceProfile.getId().getId())); |
173 | + DeviceData deviceData = new DeviceData(); | ||
174 | + deviceData.setConfiguration(new DefaultDeviceConfiguration()); | ||
175 | + device.setDeviceData(deviceData); | ||
171 | } | 176 | } |
172 | savedDevice = deviceDao.save(device.getTenantId(), device); | 177 | savedDevice = deviceDao.save(device.getTenantId(), device); |
173 | } catch (Exception t) { | 178 | } catch (Exception t) { |
@@ -411,6 +416,12 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | @@ -411,6 +416,12 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | ||
411 | 416 | ||
412 | @Override | 417 | @Override |
413 | protected void validateUpdate(TenantId tenantId, Device device) { | 418 | protected void validateUpdate(TenantId tenantId, Device device) { |
419 | + Device old = deviceDao.findById(device.getTenantId(), device.getId().getId()); | ||
420 | + if (old == null) { | ||
421 | + throw new DataValidationException("Can't update non existing device!"); | ||
422 | + } else if (!old.getDeviceProfileId().equals(device.getDeviceProfileId())) { | ||
423 | + throw new DataValidationException("Changing device profile is prohibited!"); | ||
424 | + } | ||
414 | } | 425 | } |
415 | 426 | ||
416 | @Override | 427 | @Override |
@@ -152,6 +152,8 @@ public class ModelConstants { | @@ -152,6 +152,8 @@ public class ModelConstants { | ||
152 | public static final String DEVICE_LABEL_PROPERTY = "label"; | 152 | public static final String DEVICE_LABEL_PROPERTY = "label"; |
153 | public static final String DEVICE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; | 153 | public static final String DEVICE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; |
154 | public static final String DEVICE_DEVICE_PROFILE_ID_PROPERTY = "device_profile_id"; | 154 | public static final String DEVICE_DEVICE_PROFILE_ID_PROPERTY = "device_profile_id"; |
155 | + public static final String DEVICE_DEVICE_DATA_PROPERTY = "device_data"; | ||
156 | + | ||
155 | public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text"; | 157 | public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text"; |
156 | public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text"; | 158 | public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text"; |
157 | public static final String DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_customer_and_search_text"; | 159 | public static final String DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_customer_and_search_text"; |
@@ -165,6 +167,7 @@ public class ModelConstants { | @@ -165,6 +167,7 @@ public class ModelConstants { | ||
165 | public static final String DEVICE_PROFILE_COLUMN_FAMILY_NAME = "device_profile"; | 167 | public static final String DEVICE_PROFILE_COLUMN_FAMILY_NAME = "device_profile"; |
166 | public static final String DEVICE_PROFILE_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; | 168 | public static final String DEVICE_PROFILE_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; |
167 | public static final String DEVICE_PROFILE_NAME_PROPERTY = "name"; | 169 | public static final String DEVICE_PROFILE_NAME_PROPERTY = "name"; |
170 | + public static final String DEVICE_PROFILE_TYPE_PROPERTY = "type"; | ||
168 | public static final String DEVICE_PROFILE_PROFILE_DATA_PROPERTY = "profile_data"; | 171 | public static final String DEVICE_PROFILE_PROFILE_DATA_PROPERTY = "profile_data"; |
169 | public static final String DEVICE_PROFILE_DESCRIPTION_PROPERTY = "description"; | 172 | public static final String DEVICE_PROFILE_DESCRIPTION_PROPERTY = "description"; |
170 | public static final String DEVICE_PROFILE_IS_DEFAULT_PROPERTY = "is_default"; | 173 | public static final String DEVICE_PROFILE_IS_DEFAULT_PROPERTY = "is_default"; |
@@ -16,11 +16,13 @@ | @@ -16,11 +16,13 @@ | ||
16 | package org.thingsboard.server.dao.model.sql; | 16 | package org.thingsboard.server.dao.model.sql; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | import lombok.Data; | 20 | import lombok.Data; |
20 | import lombok.EqualsAndHashCode; | 21 | import lombok.EqualsAndHashCode; |
21 | import org.hibernate.annotations.Type; | 22 | import org.hibernate.annotations.Type; |
22 | import org.hibernate.annotations.TypeDef; | 23 | import org.hibernate.annotations.TypeDef; |
23 | import org.thingsboard.server.common.data.Device; | 24 | import org.thingsboard.server.common.data.Device; |
25 | +import org.thingsboard.server.common.data.device.data.DeviceData; | ||
24 | import org.thingsboard.server.common.data.id.CustomerId; | 26 | import org.thingsboard.server.common.data.id.CustomerId; |
25 | import org.thingsboard.server.common.data.id.DeviceId; | 27 | import org.thingsboard.server.common.data.id.DeviceId; |
26 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 28 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
@@ -28,6 +30,7 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -28,6 +30,7 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
28 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 30 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
29 | import org.thingsboard.server.dao.model.ModelConstants; | 31 | import org.thingsboard.server.dao.model.ModelConstants; |
30 | import org.thingsboard.server.dao.model.SearchTextEntity; | 32 | import org.thingsboard.server.dao.model.SearchTextEntity; |
33 | +import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
31 | import org.thingsboard.server.dao.util.mapping.JsonStringType; | 34 | import org.thingsboard.server.dao.util.mapping.JsonStringType; |
32 | 35 | ||
33 | import javax.persistence.Column; | 36 | import javax.persistence.Column; |
@@ -65,6 +68,10 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -65,6 +68,10 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
65 | @Column(name = ModelConstants.DEVICE_DEVICE_PROFILE_ID_PROPERTY, columnDefinition = "uuid") | 68 | @Column(name = ModelConstants.DEVICE_DEVICE_PROFILE_ID_PROPERTY, columnDefinition = "uuid") |
66 | private UUID deviceProfileId; | 69 | private UUID deviceProfileId; |
67 | 70 | ||
71 | + @Type(type = "json") | ||
72 | + @Column(name = ModelConstants.DEVICE_DEVICE_DATA_PROPERTY) | ||
73 | + private JsonNode deviceData; | ||
74 | + | ||
68 | public AbstractDeviceEntity() { | 75 | public AbstractDeviceEntity() { |
69 | super(); | 76 | super(); |
70 | } | 77 | } |
@@ -83,6 +90,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -83,6 +90,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
83 | if (device.getDeviceProfileId() != null) { | 90 | if (device.getDeviceProfileId() != null) { |
84 | this.deviceProfileId = device.getDeviceProfileId().getId(); | 91 | this.deviceProfileId = device.getDeviceProfileId().getId(); |
85 | } | 92 | } |
93 | + this.deviceData = JacksonUtil.convertValue(device.getDeviceData(), ObjectNode.class); | ||
86 | this.name = device.getName(); | 94 | this.name = device.getName(); |
87 | this.type = device.getType(); | 95 | this.type = device.getType(); |
88 | this.label = device.getLabel(); | 96 | this.label = device.getLabel(); |
@@ -95,6 +103,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -95,6 +103,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
95 | this.tenantId = deviceEntity.getTenantId(); | 103 | this.tenantId = deviceEntity.getTenantId(); |
96 | this.customerId = deviceEntity.getCustomerId(); | 104 | this.customerId = deviceEntity.getCustomerId(); |
97 | this.deviceProfileId = deviceEntity.getDeviceProfileId(); | 105 | this.deviceProfileId = deviceEntity.getDeviceProfileId(); |
106 | + this.deviceData = deviceEntity.getDeviceData(); | ||
98 | this.type = deviceEntity.getType(); | 107 | this.type = deviceEntity.getType(); |
99 | this.name = deviceEntity.getName(); | 108 | this.name = deviceEntity.getName(); |
100 | this.label = deviceEntity.getLabel(); | 109 | this.label = deviceEntity.getLabel(); |
@@ -124,6 +133,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -124,6 +133,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
124 | if (deviceProfileId != null) { | 133 | if (deviceProfileId != null) { |
125 | device.setDeviceProfileId(new DeviceProfileId(deviceProfileId)); | 134 | device.setDeviceProfileId(new DeviceProfileId(deviceProfileId)); |
126 | } | 135 | } |
136 | + device.setDeviceData(JacksonUtil.convertValue(deviceData, DeviceData.class)); | ||
127 | device.setName(name); | 137 | device.setName(name); |
128 | device.setType(type); | 138 | device.setType(type); |
129 | device.setLabel(label); | 139 | device.setLabel(label); |
@@ -16,21 +16,27 @@ | @@ -16,21 +16,27 @@ | ||
16 | package org.thingsboard.server.dao.model.sql; | 16 | package org.thingsboard.server.dao.model.sql; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | import lombok.Data; | 20 | import lombok.Data; |
20 | import lombok.EqualsAndHashCode; | 21 | import lombok.EqualsAndHashCode; |
21 | import org.hibernate.annotations.Type; | 22 | import org.hibernate.annotations.Type; |
22 | import org.hibernate.annotations.TypeDef; | 23 | import org.hibernate.annotations.TypeDef; |
23 | import org.thingsboard.server.common.data.DeviceProfile; | 24 | import org.thingsboard.server.common.data.DeviceProfile; |
25 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
26 | +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | ||
24 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 27 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
25 | import org.thingsboard.server.common.data.id.RuleChainId; | 28 | import org.thingsboard.server.common.data.id.RuleChainId; |
26 | import org.thingsboard.server.common.data.id.TenantId; | 29 | import org.thingsboard.server.common.data.id.TenantId; |
27 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 30 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
28 | import org.thingsboard.server.dao.model.ModelConstants; | 31 | import org.thingsboard.server.dao.model.ModelConstants; |
29 | import org.thingsboard.server.dao.model.SearchTextEntity; | 32 | import org.thingsboard.server.dao.model.SearchTextEntity; |
33 | +import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
30 | import org.thingsboard.server.dao.util.mapping.JsonStringType; | 34 | import org.thingsboard.server.dao.util.mapping.JsonStringType; |
31 | 35 | ||
32 | import javax.persistence.Column; | 36 | import javax.persistence.Column; |
33 | import javax.persistence.Entity; | 37 | import javax.persistence.Entity; |
38 | +import javax.persistence.EnumType; | ||
39 | +import javax.persistence.Enumerated; | ||
34 | import javax.persistence.Table; | 40 | import javax.persistence.Table; |
35 | import java.util.UUID; | 41 | import java.util.UUID; |
36 | 42 | ||
@@ -47,6 +53,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | @@ -47,6 +53,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | ||
47 | @Column(name = ModelConstants.DEVICE_PROFILE_NAME_PROPERTY) | 53 | @Column(name = ModelConstants.DEVICE_PROFILE_NAME_PROPERTY) |
48 | private String name; | 54 | private String name; |
49 | 55 | ||
56 | + @Enumerated(EnumType.STRING) | ||
57 | + @Column(name = ModelConstants.DEVICE_PROFILE_TYPE_PROPERTY) | ||
58 | + private DeviceProfileType type; | ||
59 | + | ||
50 | @Column(name = ModelConstants.DEVICE_PROFILE_DESCRIPTION_PROPERTY) | 60 | @Column(name = ModelConstants.DEVICE_PROFILE_DESCRIPTION_PROPERTY) |
51 | private String description; | 61 | private String description; |
52 | 62 | ||
@@ -76,9 +86,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | @@ -76,9 +86,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | ||
76 | } | 86 | } |
77 | this.setCreatedTime(deviceProfile.getCreatedTime()); | 87 | this.setCreatedTime(deviceProfile.getCreatedTime()); |
78 | this.name = deviceProfile.getName(); | 88 | this.name = deviceProfile.getName(); |
89 | + this.type = deviceProfile.getType(); | ||
79 | this.description = deviceProfile.getDescription(); | 90 | this.description = deviceProfile.getDescription(); |
80 | this.isDefault = deviceProfile.isDefault(); | 91 | this.isDefault = deviceProfile.isDefault(); |
81 | - this.profileData = deviceProfile.getProfileData(); | 92 | + this.profileData = JacksonUtil.convertValue(deviceProfile.getProfileData(), ObjectNode.class); |
82 | if (deviceProfile.getDefaultRuleChainId() != null) { | 93 | if (deviceProfile.getDefaultRuleChainId() != null) { |
83 | this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId().getId(); | 94 | this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId().getId(); |
84 | } | 95 | } |
@@ -106,9 +117,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | @@ -106,9 +117,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | ||
106 | deviceProfile.setTenantId(new TenantId(tenantId)); | 117 | deviceProfile.setTenantId(new TenantId(tenantId)); |
107 | } | 118 | } |
108 | deviceProfile.setName(name); | 119 | deviceProfile.setName(name); |
120 | + deviceProfile.setType(type); | ||
109 | deviceProfile.setDescription(description); | 121 | deviceProfile.setDescription(description); |
110 | deviceProfile.setDefault(isDefault); | 122 | deviceProfile.setDefault(isDefault); |
111 | - deviceProfile.setProfileData(profileData); | 123 | + deviceProfile.setProfileData(JacksonUtil.convertValue(profileData, DeviceProfileData.class)); |
112 | if (defaultRuleChainId != null) { | 124 | if (defaultRuleChainId != null) { |
113 | deviceProfile.setDefaultRuleChainId(new RuleChainId(defaultRuleChainId)); | 125 | deviceProfile.setDefaultRuleChainId(new RuleChainId(defaultRuleChainId)); |
114 | } | 126 | } |
@@ -16,15 +16,18 @@ | @@ -16,15 +16,18 @@ | ||
16 | package org.thingsboard.server.dao.model.sql; | 16 | package org.thingsboard.server.dao.model.sql; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | import lombok.Data; | 20 | import lombok.Data; |
20 | import lombok.EqualsAndHashCode; | 21 | import lombok.EqualsAndHashCode; |
21 | import org.hibernate.annotations.Type; | 22 | import org.hibernate.annotations.Type; |
22 | import org.hibernate.annotations.TypeDef; | 23 | import org.hibernate.annotations.TypeDef; |
23 | import org.thingsboard.server.common.data.TenantProfile; | 24 | import org.thingsboard.server.common.data.TenantProfile; |
25 | +import org.thingsboard.server.common.data.TenantProfileData; | ||
24 | import org.thingsboard.server.common.data.id.TenantProfileId; | 26 | import org.thingsboard.server.common.data.id.TenantProfileId; |
25 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 27 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
26 | import org.thingsboard.server.dao.model.ModelConstants; | 28 | import org.thingsboard.server.dao.model.ModelConstants; |
27 | import org.thingsboard.server.dao.model.SearchTextEntity; | 29 | import org.thingsboard.server.dao.model.SearchTextEntity; |
30 | +import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
28 | import org.thingsboard.server.dao.util.mapping.JsonStringType; | 31 | import org.thingsboard.server.dao.util.mapping.JsonStringType; |
29 | 32 | ||
30 | import javax.persistence.Column; | 33 | import javax.persistence.Column; |
@@ -74,7 +77,7 @@ public final class TenantProfileEntity extends BaseSqlEntity<TenantProfile> impl | @@ -74,7 +77,7 @@ public final class TenantProfileEntity extends BaseSqlEntity<TenantProfile> impl | ||
74 | this.isDefault = tenantProfile.isDefault(); | 77 | this.isDefault = tenantProfile.isDefault(); |
75 | this.isolatedTbCore = tenantProfile.isIsolatedTbCore(); | 78 | this.isolatedTbCore = tenantProfile.isIsolatedTbCore(); |
76 | this.isolatedTbRuleEngine = tenantProfile.isIsolatedTbRuleEngine(); | 79 | this.isolatedTbRuleEngine = tenantProfile.isIsolatedTbRuleEngine(); |
77 | - this.profileData = tenantProfile.getProfileData(); | 80 | + this.profileData = JacksonUtil.convertValue(tenantProfile.getProfileData(), ObjectNode.class); |
78 | } | 81 | } |
79 | 82 | ||
80 | @Override | 83 | @Override |
@@ -100,9 +103,8 @@ public final class TenantProfileEntity extends BaseSqlEntity<TenantProfile> impl | @@ -100,9 +103,8 @@ public final class TenantProfileEntity extends BaseSqlEntity<TenantProfile> impl | ||
100 | tenantProfile.setDefault(isDefault); | 103 | tenantProfile.setDefault(isDefault); |
101 | tenantProfile.setIsolatedTbCore(isolatedTbCore); | 104 | tenantProfile.setIsolatedTbCore(isolatedTbCore); |
102 | tenantProfile.setIsolatedTbRuleEngine(isolatedTbRuleEngine); | 105 | tenantProfile.setIsolatedTbRuleEngine(isolatedTbRuleEngine); |
103 | - tenantProfile.setProfileData(profileData); | 106 | + tenantProfile.setProfileData(JacksonUtil.convertValue(profileData, TenantProfileData.class)); |
104 | return tenantProfile; | 107 | return tenantProfile; |
105 | } | 108 | } |
106 | 109 | ||
107 | - | ||
108 | } | 110 | } |
@@ -23,8 +23,10 @@ import org.springframework.cache.Cache; | @@ -23,8 +23,10 @@ import org.springframework.cache.Cache; | ||
23 | import org.springframework.cache.CacheManager; | 23 | import org.springframework.cache.CacheManager; |
24 | import org.springframework.cache.annotation.Cacheable; | 24 | import org.springframework.cache.annotation.Cacheable; |
25 | import org.springframework.stereotype.Service; | 25 | import org.springframework.stereotype.Service; |
26 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
26 | import org.thingsboard.server.common.data.EntityInfo; | 27 | import org.thingsboard.server.common.data.EntityInfo; |
27 | import org.thingsboard.server.common.data.TenantProfile; | 28 | import org.thingsboard.server.common.data.TenantProfile; |
29 | +import org.thingsboard.server.common.data.TenantProfileData; | ||
28 | import org.thingsboard.server.common.data.id.TenantId; | 30 | import org.thingsboard.server.common.data.id.TenantId; |
29 | import org.thingsboard.server.common.data.id.TenantProfileId; | 31 | import org.thingsboard.server.common.data.id.TenantProfileId; |
30 | import org.thingsboard.server.common.data.page.PageData; | 32 | import org.thingsboard.server.common.data.page.PageData; |
@@ -107,8 +109,17 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T | @@ -107,8 +109,17 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T | ||
107 | } | 109 | } |
108 | 110 | ||
109 | private void removeTenantProfile(TenantId tenantId, TenantProfileId tenantProfileId) { | 111 | private void removeTenantProfile(TenantId tenantId, TenantProfileId tenantProfileId) { |
112 | + try { | ||
113 | + tenantProfileDao.removeById(tenantId, tenantProfileId.getId()); | ||
114 | + } catch (Exception t) { | ||
115 | + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); | ||
116 | + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_tenant_profile")) { | ||
117 | + throw new DataValidationException("The tenant profile referenced by the tenants cannot be deleted!"); | ||
118 | + } else { | ||
119 | + throw t; | ||
120 | + } | ||
121 | + } | ||
110 | deleteEntityRelations(tenantId, tenantProfileId); | 122 | deleteEntityRelations(tenantId, tenantProfileId); |
111 | - tenantProfileDao.removeById(tenantId, tenantProfileId.getId()); | ||
112 | Cache cache = cacheManager.getCache(TENANT_PROFILE_CACHE); | 123 | Cache cache = cacheManager.getCache(TENANT_PROFILE_CACHE); |
113 | cache.evict(Collections.singletonList(tenantProfileId.getId())); | 124 | cache.evict(Collections.singletonList(tenantProfileId.getId())); |
114 | cache.evict(Arrays.asList("info", tenantProfileId.getId())); | 125 | cache.evict(Arrays.asList("info", tenantProfileId.getId())); |
@@ -136,7 +147,7 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T | @@ -136,7 +147,7 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T | ||
136 | defaultTenantProfile = new TenantProfile(); | 147 | defaultTenantProfile = new TenantProfile(); |
137 | defaultTenantProfile.setDefault(true); | 148 | defaultTenantProfile.setDefault(true); |
138 | defaultTenantProfile.setName("Default"); | 149 | defaultTenantProfile.setName("Default"); |
139 | - defaultTenantProfile.setProfileData(JacksonUtil.OBJECT_MAPPER.createObjectNode()); | 150 | + defaultTenantProfile.setProfileData(new TenantProfileData()); |
140 | defaultTenantProfile.setDescription("Default tenant profile"); | 151 | defaultTenantProfile.setDescription("Default tenant profile"); |
141 | defaultTenantProfile.setIsolatedTbCore(false); | 152 | defaultTenantProfile.setIsolatedTbCore(false); |
142 | defaultTenantProfile.setIsolatedTbRuleEngine(false); | 153 | defaultTenantProfile.setIsolatedTbRuleEngine(false); |
@@ -211,6 +222,18 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T | @@ -211,6 +222,18 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T | ||
211 | } | 222 | } |
212 | } | 223 | } |
213 | } | 224 | } |
225 | + | ||
226 | + @Override | ||
227 | + protected void validateUpdate(TenantId tenantId, TenantProfile tenantProfile) { | ||
228 | + TenantProfile old = tenantProfileDao.findById(TenantId.SYS_TENANT_ID, tenantProfile.getId().getId()); | ||
229 | + if (old == null) { | ||
230 | + throw new DataValidationException("Can't update non existing tenant profile!"); | ||
231 | + } else if (old.isIsolatedTbRuleEngine() != tenantProfile.isIsolatedTbRuleEngine()) { | ||
232 | + throw new DataValidationException("Can't update isolatedTbRuleEngine property!"); | ||
233 | + } else if (old.isIsolatedTbCore() != tenantProfile.isIsolatedTbCore()) { | ||
234 | + throw new DataValidationException("Can't update isolatedTbCore property!"); | ||
235 | + } | ||
236 | + } | ||
214 | }; | 237 | }; |
215 | 238 | ||
216 | private PaginatedRemover<String, TenantProfile> tenantProfilesRemover = | 239 | private PaginatedRemover<String, TenantProfile> tenantProfilesRemover = |
@@ -163,12 +163,6 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | @@ -163,12 +163,6 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | ||
163 | if (old == null) { | 163 | if (old == null) { |
164 | throw new DataValidationException("Can't update non existing tenant!"); | 164 | throw new DataValidationException("Can't update non existing tenant!"); |
165 | } | 165 | } |
166 | - // TODO: Move validation to tenant profile | ||
167 | - /* else if (old.isIsolatedTbRuleEngine() != tenant.isIsolatedTbRuleEngine()) { | ||
168 | - throw new DataValidationException("Can't update isolatedTbRuleEngine property!"); | ||
169 | - } else if (old.isIsolatedTbCore() != tenant.isIsolatedTbCore()) { | ||
170 | - throw new DataValidationException("Can't update isolatedTbCore property!"); | ||
171 | - } */ | ||
172 | } | 166 | } |
173 | }; | 167 | }; |
174 | 168 |
@@ -30,7 +30,7 @@ public class JacksonUtil { | @@ -30,7 +30,7 @@ public class JacksonUtil { | ||
30 | 30 | ||
31 | public static <T> T convertValue(Object fromValue, Class<T> toValueType) { | 31 | public static <T> T convertValue(Object fromValue, Class<T> toValueType) { |
32 | try { | 32 | try { |
33 | - return OBJECT_MAPPER.convertValue(fromValue, toValueType); | 33 | + return fromValue != null ? OBJECT_MAPPER.convertValue(fromValue, toValueType) : null; |
34 | } catch (IllegalArgumentException e) { | 34 | } catch (IllegalArgumentException e) { |
35 | throw new IllegalArgumentException("The given object value: " | 35 | throw new IllegalArgumentException("The given object value: " |
36 | + fromValue + " cannot be converted to " + toValueType); | 36 | + fromValue + " cannot be converted to " + toValueType); |
@@ -39,7 +39,7 @@ public class JacksonUtil { | @@ -39,7 +39,7 @@ public class JacksonUtil { | ||
39 | 39 | ||
40 | public static <T> T fromString(String string, Class<T> clazz) { | 40 | public static <T> T fromString(String string, Class<T> clazz) { |
41 | try { | 41 | try { |
42 | - return OBJECT_MAPPER.readValue(string, clazz); | 42 | + return string != null ? OBJECT_MAPPER.readValue(string, clazz) : null; |
43 | } catch (IOException e) { | 43 | } catch (IOException e) { |
44 | throw new IllegalArgumentException("The given string value: " | 44 | throw new IllegalArgumentException("The given string value: " |
45 | + string + " cannot be transformed to Json object"); | 45 | + string + " cannot be transformed to Json object"); |
@@ -48,7 +48,7 @@ public class JacksonUtil { | @@ -48,7 +48,7 @@ public class JacksonUtil { | ||
48 | 48 | ||
49 | public static String toString(Object value) { | 49 | public static String toString(Object value) { |
50 | try { | 50 | try { |
51 | - return OBJECT_MAPPER.writeValueAsString(value); | 51 | + return value != null ? OBJECT_MAPPER.writeValueAsString(value) : null; |
52 | } catch (JsonProcessingException e) { | 52 | } catch (JsonProcessingException e) { |
53 | throw new IllegalArgumentException("The given Json object value: " | 53 | throw new IllegalArgumentException("The given Json object value: " |
54 | + value + " cannot be transformed to a String"); | 54 | + value + " cannot be transformed to a String"); |
@@ -122,24 +122,12 @@ CREATE TABLE IF NOT EXISTS dashboard ( | @@ -122,24 +122,12 @@ CREATE TABLE IF NOT EXISTS dashboard ( | ||
122 | title varchar(255) | 122 | title varchar(255) |
123 | ); | 123 | ); |
124 | 124 | ||
125 | -CREATE TABLE IF NOT EXISTS device ( | ||
126 | - id uuid NOT NULL CONSTRAINT device_pkey PRIMARY KEY, | ||
127 | - created_time bigint NOT NULL, | ||
128 | - additional_info varchar, | ||
129 | - customer_id uuid, | ||
130 | - device_profile_id uuid NOT NULL, | ||
131 | - type varchar(255), | ||
132 | - name varchar(255), | ||
133 | - label varchar(255), | ||
134 | - search_text varchar(255), | ||
135 | - tenant_id uuid, | ||
136 | - CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name) | ||
137 | -); | ||
138 | 125 | ||
139 | CREATE TABLE IF NOT EXISTS device_profile ( | 126 | CREATE TABLE IF NOT EXISTS device_profile ( |
140 | id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY, | 127 | id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY, |
141 | created_time bigint NOT NULL, | 128 | created_time bigint NOT NULL, |
142 | name varchar(255), | 129 | name varchar(255), |
130 | + type varchar(255), | ||
143 | profile_data varchar, | 131 | profile_data varchar, |
144 | description varchar, | 132 | description varchar, |
145 | search_text varchar(255), | 133 | search_text varchar(255), |
@@ -149,6 +137,22 @@ CREATE TABLE IF NOT EXISTS device_profile ( | @@ -149,6 +137,22 @@ CREATE TABLE IF NOT EXISTS device_profile ( | ||
149 | CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name) | 137 | CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name) |
150 | ); | 138 | ); |
151 | 139 | ||
140 | +CREATE TABLE IF NOT EXISTS device ( | ||
141 | + id uuid NOT NULL CONSTRAINT device_pkey PRIMARY KEY, | ||
142 | + created_time bigint NOT NULL, | ||
143 | + additional_info varchar, | ||
144 | + customer_id uuid, | ||
145 | + device_profile_id uuid NOT NULL, | ||
146 | + device_data varchar, | ||
147 | + type varchar(255), | ||
148 | + name varchar(255), | ||
149 | + label varchar(255), | ||
150 | + search_text varchar(255), | ||
151 | + tenant_id uuid, | ||
152 | + CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name), | ||
153 | + CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id) | ||
154 | +); | ||
155 | + | ||
152 | CREATE TABLE IF NOT EXISTS device_credentials ( | 156 | CREATE TABLE IF NOT EXISTS device_credentials ( |
153 | id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, | 157 | id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, |
154 | created_time bigint NOT NULL, | 158 | created_time bigint NOT NULL, |
@@ -197,6 +201,19 @@ CREATE TABLE IF NOT EXISTS tb_user ( | @@ -197,6 +201,19 @@ CREATE TABLE IF NOT EXISTS tb_user ( | ||
197 | tenant_id uuid | 201 | tenant_id uuid |
198 | ); | 202 | ); |
199 | 203 | ||
204 | +CREATE TABLE IF NOT EXISTS tenant_profile ( | ||
205 | + id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY, | ||
206 | + created_time bigint NOT NULL, | ||
207 | + name varchar(255), | ||
208 | + profile_data varchar, | ||
209 | + description varchar, | ||
210 | + search_text varchar(255), | ||
211 | + is_default boolean, | ||
212 | + isolated_tb_core boolean, | ||
213 | + isolated_tb_rule_engine boolean, | ||
214 | + CONSTRAINT tenant_profile_name_unq_key UNIQUE (name) | ||
215 | +); | ||
216 | + | ||
200 | CREATE TABLE IF NOT EXISTS tenant ( | 217 | CREATE TABLE IF NOT EXISTS tenant ( |
201 | id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY, | 218 | id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY, |
202 | created_time bigint NOT NULL, | 219 | created_time bigint NOT NULL, |
@@ -214,20 +231,8 @@ CREATE TABLE IF NOT EXISTS tenant ( | @@ -214,20 +231,8 @@ CREATE TABLE IF NOT EXISTS tenant ( | ||
214 | title varchar(255), | 231 | title varchar(255), |
215 | zip varchar(255), | 232 | zip varchar(255), |
216 | isolated_tb_core boolean, | 233 | isolated_tb_core boolean, |
217 | - isolated_tb_rule_engine boolean | ||
218 | -); | ||
219 | - | ||
220 | -CREATE TABLE IF NOT EXISTS tenant_profile ( | ||
221 | - id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY, | ||
222 | - created_time bigint NOT NULL, | ||
223 | - name varchar(255), | ||
224 | - profile_data varchar, | ||
225 | - description varchar, | ||
226 | - search_text varchar(255), | ||
227 | - is_default boolean, | ||
228 | - isolated_tb_core boolean, | ||
229 | isolated_tb_rule_engine boolean, | 234 | isolated_tb_rule_engine boolean, |
230 | - CONSTRAINT tenant_profile_name_unq_key UNIQUE (name) | 235 | + CONSTRAINT fk_tenant_profile FOREIGN KEY (tenant_profile_id) REFERENCES tenant_profile(id) |
231 | ); | 236 | ); |
232 | 237 | ||
233 | CREATE TABLE IF NOT EXISTS user_credentials ( | 238 | CREATE TABLE IF NOT EXISTS user_credentials ( |
@@ -139,24 +139,12 @@ CREATE TABLE IF NOT EXISTS dashboard ( | @@ -139,24 +139,12 @@ CREATE TABLE IF NOT EXISTS dashboard ( | ||
139 | title varchar(255) | 139 | title varchar(255) |
140 | ); | 140 | ); |
141 | 141 | ||
142 | -CREATE TABLE IF NOT EXISTS device ( | ||
143 | - id uuid NOT NULL CONSTRAINT device_pkey PRIMARY KEY, | ||
144 | - created_time bigint NOT NULL, | ||
145 | - additional_info varchar, | ||
146 | - customer_id uuid, | ||
147 | - device_profile_id uuid NOT NULL, | ||
148 | - type varchar(255), | ||
149 | - name varchar(255), | ||
150 | - label varchar(255), | ||
151 | - search_text varchar(255), | ||
152 | - tenant_id uuid, | ||
153 | - CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name) | ||
154 | -); | ||
155 | 142 | ||
156 | CREATE TABLE IF NOT EXISTS device_profile ( | 143 | CREATE TABLE IF NOT EXISTS device_profile ( |
157 | id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY, | 144 | id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY, |
158 | created_time bigint NOT NULL, | 145 | created_time bigint NOT NULL, |
159 | name varchar(255), | 146 | name varchar(255), |
147 | + type varchar(255), | ||
160 | profile_data varchar, | 148 | profile_data varchar, |
161 | description varchar, | 149 | description varchar, |
162 | search_text varchar(255), | 150 | search_text varchar(255), |
@@ -166,6 +154,22 @@ CREATE TABLE IF NOT EXISTS device_profile ( | @@ -166,6 +154,22 @@ CREATE TABLE IF NOT EXISTS device_profile ( | ||
166 | CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name) | 154 | CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name) |
167 | ); | 155 | ); |
168 | 156 | ||
157 | +CREATE TABLE IF NOT EXISTS device ( | ||
158 | + id uuid NOT NULL CONSTRAINT device_pkey PRIMARY KEY, | ||
159 | + created_time bigint NOT NULL, | ||
160 | + additional_info varchar, | ||
161 | + customer_id uuid, | ||
162 | + device_profile_id uuid NOT NULL, | ||
163 | + device_data varchar, | ||
164 | + type varchar(255), | ||
165 | + name varchar(255), | ||
166 | + label varchar(255), | ||
167 | + search_text varchar(255), | ||
168 | + tenant_id uuid, | ||
169 | + CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name), | ||
170 | + CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id) | ||
171 | +); | ||
172 | + | ||
169 | CREATE TABLE IF NOT EXISTS device_credentials ( | 173 | CREATE TABLE IF NOT EXISTS device_credentials ( |
170 | id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, | 174 | id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, |
171 | created_time bigint NOT NULL, | 175 | created_time bigint NOT NULL, |
@@ -221,6 +225,19 @@ CREATE TABLE IF NOT EXISTS tb_user ( | @@ -221,6 +225,19 @@ CREATE TABLE IF NOT EXISTS tb_user ( | ||
221 | tenant_id uuid | 225 | tenant_id uuid |
222 | ); | 226 | ); |
223 | 227 | ||
228 | +CREATE TABLE IF NOT EXISTS tenant_profile ( | ||
229 | + id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY, | ||
230 | + created_time bigint NOT NULL, | ||
231 | + name varchar(255), | ||
232 | + profile_data varchar, | ||
233 | + description varchar, | ||
234 | + search_text varchar(255), | ||
235 | + is_default boolean, | ||
236 | + isolated_tb_core boolean, | ||
237 | + isolated_tb_rule_engine boolean, | ||
238 | + CONSTRAINT tenant_profile_name_unq_key UNIQUE (name) | ||
239 | +); | ||
240 | + | ||
224 | CREATE TABLE IF NOT EXISTS tenant ( | 241 | CREATE TABLE IF NOT EXISTS tenant ( |
225 | id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY, | 242 | id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY, |
226 | created_time bigint NOT NULL, | 243 | created_time bigint NOT NULL, |
@@ -238,20 +255,8 @@ CREATE TABLE IF NOT EXISTS tenant ( | @@ -238,20 +255,8 @@ CREATE TABLE IF NOT EXISTS tenant ( | ||
238 | title varchar(255), | 255 | title varchar(255), |
239 | zip varchar(255), | 256 | zip varchar(255), |
240 | isolated_tb_core boolean, | 257 | isolated_tb_core boolean, |
241 | - isolated_tb_rule_engine boolean | ||
242 | -); | ||
243 | - | ||
244 | -CREATE TABLE IF NOT EXISTS tenant_profile ( | ||
245 | - id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY, | ||
246 | - created_time bigint NOT NULL, | ||
247 | - name varchar(255), | ||
248 | - profile_data varchar, | ||
249 | - description varchar, | ||
250 | - search_text varchar(255), | ||
251 | - is_default boolean, | ||
252 | - isolated_tb_core boolean, | ||
253 | isolated_tb_rule_engine boolean, | 258 | isolated_tb_rule_engine boolean, |
254 | - CONSTRAINT tenant_profile_name_unq_key UNIQUE (name) | 259 | + CONSTRAINT fk_tenant_profile FOREIGN KEY (tenant_profile_id) REFERENCES tenant_profile(id) |
255 | ); | 260 | ); |
256 | 261 | ||
257 | CREATE TABLE IF NOT EXISTS user_credentials ( | 262 | CREATE TABLE IF NOT EXISTS user_credentials ( |
@@ -28,10 +28,15 @@ import org.springframework.test.context.ContextConfiguration; | @@ -28,10 +28,15 @@ import org.springframework.test.context.ContextConfiguration; | ||
28 | import org.springframework.test.context.junit4.SpringRunner; | 28 | import org.springframework.test.context.junit4.SpringRunner; |
29 | import org.springframework.test.context.support.AnnotationConfigContextLoader; | 29 | import org.springframework.test.context.support.AnnotationConfigContextLoader; |
30 | import org.thingsboard.server.common.data.BaseData; | 30 | import org.thingsboard.server.common.data.BaseData; |
31 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
32 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
31 | import org.thingsboard.server.common.data.EntityType; | 33 | import org.thingsboard.server.common.data.EntityType; |
32 | import org.thingsboard.server.common.data.Event; | 34 | import org.thingsboard.server.common.data.Event; |
35 | +import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; | ||
36 | +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | ||
33 | import org.thingsboard.server.common.data.id.EntityId; | 37 | import org.thingsboard.server.common.data.id.EntityId; |
34 | import org.thingsboard.server.common.data.id.HasId; | 38 | import org.thingsboard.server.common.data.id.HasId; |
39 | +import org.thingsboard.server.common.data.id.RuleChainId; | ||
35 | import org.thingsboard.server.common.data.id.TenantId; | 40 | import org.thingsboard.server.common.data.id.TenantId; |
36 | import org.thingsboard.server.common.data.id.UUIDBased; | 41 | import org.thingsboard.server.common.data.id.UUIDBased; |
37 | import org.thingsboard.server.dao.alarm.AlarmService; | 42 | import org.thingsboard.server.dao.alarm.AlarmService; |
@@ -187,4 +192,19 @@ public abstract class AbstractServiceTest { | @@ -187,4 +192,19 @@ public abstract class AbstractServiceTest { | ||
187 | return new AuditLogLevelFilter(mask); | 192 | return new AuditLogLevelFilter(mask); |
188 | } | 193 | } |
189 | 194 | ||
195 | + protected DeviceProfile createDeviceProfile(TenantId tenantId, String name) { | ||
196 | + DeviceProfile deviceProfile = new DeviceProfile(); | ||
197 | + deviceProfile.setTenantId(tenantId); | ||
198 | + deviceProfile.setName(name); | ||
199 | + deviceProfile.setType(DeviceProfileType.DEFAULT); | ||
200 | + deviceProfile.setDescription(name + " Test"); | ||
201 | + DeviceProfileData deviceProfileData = new DeviceProfileData(); | ||
202 | + DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration(); | ||
203 | + deviceProfileData.setConfiguration(configuration); | ||
204 | + deviceProfile.setProfileData(deviceProfileData); | ||
205 | + deviceProfile.setDefault(false); | ||
206 | + deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased())); | ||
207 | + return deviceProfile; | ||
208 | + } | ||
209 | + | ||
190 | } | 210 | } |
@@ -15,20 +15,19 @@ | @@ -15,20 +15,19 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.dao.service; | 16 | package org.thingsboard.server.dao.service; |
17 | 17 | ||
18 | -import com.datastax.oss.driver.api.core.uuid.Uuids; | ||
19 | import org.junit.After; | 18 | import org.junit.After; |
20 | import org.junit.Assert; | 19 | import org.junit.Assert; |
21 | import org.junit.Before; | 20 | import org.junit.Before; |
22 | import org.junit.Test; | 21 | import org.junit.Test; |
22 | +import org.thingsboard.server.common.data.Device; | ||
23 | import org.thingsboard.server.common.data.DeviceProfile; | 23 | import org.thingsboard.server.common.data.DeviceProfile; |
24 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
24 | import org.thingsboard.server.common.data.EntityInfo; | 25 | import org.thingsboard.server.common.data.EntityInfo; |
25 | import org.thingsboard.server.common.data.Tenant; | 26 | import org.thingsboard.server.common.data.Tenant; |
26 | -import org.thingsboard.server.common.data.id.RuleChainId; | ||
27 | import org.thingsboard.server.common.data.id.TenantId; | 27 | import org.thingsboard.server.common.data.id.TenantId; |
28 | import org.thingsboard.server.common.data.page.PageData; | 28 | import org.thingsboard.server.common.data.page.PageData; |
29 | import org.thingsboard.server.common.data.page.PageLink; | 29 | import org.thingsboard.server.common.data.page.PageLink; |
30 | import org.thingsboard.server.dao.exception.DataValidationException; | 30 | import org.thingsboard.server.dao.exception.DataValidationException; |
31 | -import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
32 | 31 | ||
33 | import java.util.ArrayList; | 32 | import java.util.ArrayList; |
34 | import java.util.Collections; | 33 | import java.util.Collections; |
@@ -58,7 +57,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | @@ -58,7 +57,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
58 | 57 | ||
59 | @Test | 58 | @Test |
60 | public void testSaveDeviceProfile() { | 59 | public void testSaveDeviceProfile() { |
61 | - DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | 60 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); |
62 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | 61 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
63 | Assert.assertNotNull(savedDeviceProfile); | 62 | Assert.assertNotNull(savedDeviceProfile); |
64 | Assert.assertNotNull(savedDeviceProfile.getId()); | 63 | Assert.assertNotNull(savedDeviceProfile.getId()); |
@@ -76,7 +75,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | @@ -76,7 +75,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
76 | 75 | ||
77 | @Test | 76 | @Test |
78 | public void testFindDeviceProfileById() { | 77 | public void testFindDeviceProfileById() { |
79 | - DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | 78 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); |
80 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | 79 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
81 | DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); | 80 | DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); |
82 | Assert.assertNotNull(foundDeviceProfile); | 81 | Assert.assertNotNull(foundDeviceProfile); |
@@ -85,7 +84,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | @@ -85,7 +84,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
85 | 84 | ||
86 | @Test | 85 | @Test |
87 | public void testFindDeviceProfileInfoById() { | 86 | public void testFindDeviceProfileInfoById() { |
88 | - DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | 87 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); |
89 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | 88 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
90 | EntityInfo foundDeviceProfileInfo = deviceProfileService.findDeviceProfileInfoById(tenantId, savedDeviceProfile.getId()); | 89 | EntityInfo foundDeviceProfileInfo = deviceProfileService.findDeviceProfileInfoById(tenantId, savedDeviceProfile.getId()); |
91 | Assert.assertNotNull(foundDeviceProfileInfo); | 90 | Assert.assertNotNull(foundDeviceProfileInfo); |
@@ -111,8 +110,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | @@ -111,8 +110,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
111 | 110 | ||
112 | @Test | 111 | @Test |
113 | public void testSetDefaultDeviceProfile() { | 112 | public void testSetDefaultDeviceProfile() { |
114 | - DeviceProfile deviceProfile1 = this.createDeviceProfile("Device Profile 1"); | ||
115 | - DeviceProfile deviceProfile2 = this.createDeviceProfile("Device Profile 2"); | 113 | + DeviceProfile deviceProfile1 = this.createDeviceProfile(tenantId,"Device Profile 1"); |
114 | + DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId,"Device Profile 2"); | ||
116 | 115 | ||
117 | DeviceProfile savedDeviceProfile1 = deviceProfileService.saveDeviceProfile(deviceProfile1); | 116 | DeviceProfile savedDeviceProfile1 = deviceProfileService.saveDeviceProfile(deviceProfile1); |
118 | DeviceProfile savedDeviceProfile2 = deviceProfileService.saveDeviceProfile(deviceProfile2); | 117 | DeviceProfile savedDeviceProfile2 = deviceProfileService.saveDeviceProfile(deviceProfile2); |
@@ -138,15 +137,36 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | @@ -138,15 +137,36 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
138 | 137 | ||
139 | @Test(expected = DataValidationException.class) | 138 | @Test(expected = DataValidationException.class) |
140 | public void testSaveDeviceProfileWithSameName() { | 139 | public void testSaveDeviceProfileWithSameName() { |
141 | - DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | 140 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); |
142 | deviceProfileService.saveDeviceProfile(deviceProfile); | 141 | deviceProfileService.saveDeviceProfile(deviceProfile); |
143 | - DeviceProfile deviceProfile2 = this.createDeviceProfile("Device Profile"); | 142 | + DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId,"Device Profile"); |
144 | deviceProfileService.saveDeviceProfile(deviceProfile2); | 143 | deviceProfileService.saveDeviceProfile(deviceProfile2); |
145 | } | 144 | } |
146 | 145 | ||
146 | + @Test(expected = DataValidationException.class) | ||
147 | + public void testSaveSameDeviceProfileWithDifferentType() { | ||
148 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | ||
149 | + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | ||
150 | + savedDeviceProfile.setType(DeviceProfileType.LWM2M); | ||
151 | + deviceProfileService.saveDeviceProfile(savedDeviceProfile); | ||
152 | + } | ||
153 | + | ||
154 | + @Test(expected = DataValidationException.class) | ||
155 | + public void testDeleteDeviceProfileWithExistingDevice() { | ||
156 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | ||
157 | + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | ||
158 | + Device device = new Device(); | ||
159 | + device.setTenantId(tenantId); | ||
160 | + device.setName("Test device"); | ||
161 | + device.setType("default"); | ||
162 | + device.setDeviceProfileId(savedDeviceProfile.getId()); | ||
163 | + deviceService.saveDevice(device); | ||
164 | + deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); | ||
165 | + } | ||
166 | + | ||
147 | @Test | 167 | @Test |
148 | public void testDeleteDeviceProfile() { | 168 | public void testDeleteDeviceProfile() { |
149 | - DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | 169 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); |
150 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | 170 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
151 | deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); | 171 | deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); |
152 | DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); | 172 | DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); |
@@ -164,7 +184,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | @@ -164,7 +184,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
164 | deviceProfiles.addAll(pageData.getData()); | 184 | deviceProfiles.addAll(pageData.getData()); |
165 | 185 | ||
166 | for (int i=0;i<28;i++) { | 186 | for (int i=0;i<28;i++) { |
167 | - DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"+i); | 187 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"+i); |
168 | deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile)); | 188 | deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile)); |
169 | } | 189 | } |
170 | 190 | ||
@@ -206,7 +226,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | @@ -206,7 +226,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
206 | deviceProfiles.addAll(deviceProfilePageData.getData()); | 226 | deviceProfiles.addAll(deviceProfilePageData.getData()); |
207 | 227 | ||
208 | for (int i=0;i<28;i++) { | 228 | for (int i=0;i<28;i++) { |
209 | - DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"+i); | 229 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"+i); |
210 | deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile)); | 230 | deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile)); |
211 | } | 231 | } |
212 | 232 | ||
@@ -242,15 +262,6 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | @@ -242,15 +262,6 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
242 | Assert.assertEquals(1, pageData.getTotalElements()); | 262 | Assert.assertEquals(1, pageData.getTotalElements()); |
243 | } | 263 | } |
244 | 264 | ||
245 | - private DeviceProfile createDeviceProfile(String name) { | ||
246 | - DeviceProfile deviceProfile = new DeviceProfile(); | ||
247 | - deviceProfile.setTenantId(tenantId); | ||
248 | - deviceProfile.setName(name); | ||
249 | - deviceProfile.setDescription(name + " Test"); | ||
250 | - deviceProfile.setProfileData(JacksonUtil.OBJECT_MAPPER.createObjectNode()); | ||
251 | - deviceProfile.setDefault(false); | ||
252 | - deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased())); | ||
253 | - return deviceProfile; | ||
254 | - } | 265 | + |
255 | 266 | ||
256 | } | 267 | } |
@@ -127,6 +127,23 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { | @@ -127,6 +127,23 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { | ||
127 | deviceService.deleteDevice(tenantId, device.getId()); | 127 | deviceService.deleteDevice(tenantId, device.getId()); |
128 | } | 128 | } |
129 | } | 129 | } |
130 | + | ||
131 | + @Test(expected = DataValidationException.class) | ||
132 | + public void testSaveSameDeviceWithDifferentDeviceProfileId() { | ||
133 | + Device device = new Device(); | ||
134 | + device.setName("My device"); | ||
135 | + device.setType("default"); | ||
136 | + device.setTenantId(tenantId); | ||
137 | + device = deviceService.saveDevice(device); | ||
138 | + DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId,"Device Profile 2"); | ||
139 | + DeviceProfile savedDeviceProfile2 = deviceProfileService.saveDeviceProfile(deviceProfile2); | ||
140 | + device.setDeviceProfileId(savedDeviceProfile2.getId()); | ||
141 | + try { | ||
142 | + deviceService.saveDevice(device); | ||
143 | + } finally { | ||
144 | + deviceService.deleteDevice(tenantId, device.getId()); | ||
145 | + } | ||
146 | + } | ||
130 | 147 | ||
131 | @Test(expected = DataValidationException.class) | 148 | @Test(expected = DataValidationException.class) |
132 | public void testAssignDeviceToCustomerFromDifferentTenant() { | 149 | public void testAssignDeviceToCustomerFromDifferentTenant() { |
@@ -19,7 +19,9 @@ import org.junit.After; | @@ -19,7 +19,9 @@ import org.junit.After; | ||
19 | import org.junit.Assert; | 19 | import org.junit.Assert; |
20 | import org.junit.Test; | 20 | import org.junit.Test; |
21 | import org.thingsboard.server.common.data.EntityInfo; | 21 | import org.thingsboard.server.common.data.EntityInfo; |
22 | +import org.thingsboard.server.common.data.Tenant; | ||
22 | import org.thingsboard.server.common.data.TenantProfile; | 23 | import org.thingsboard.server.common.data.TenantProfile; |
24 | +import org.thingsboard.server.common.data.TenantProfileData; | ||
23 | import org.thingsboard.server.common.data.id.TenantId; | 25 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.common.data.id.TenantProfileId; | 26 | import org.thingsboard.server.common.data.id.TenantProfileId; |
25 | import org.thingsboard.server.common.data.page.PageData; | 27 | import org.thingsboard.server.common.data.page.PageData; |
@@ -136,6 +138,37 @@ public class BaseTenantProfileServiceTest extends AbstractServiceTest { | @@ -136,6 +138,37 @@ public class BaseTenantProfileServiceTest extends AbstractServiceTest { | ||
136 | tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile2); | 138 | tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile2); |
137 | } | 139 | } |
138 | 140 | ||
141 | + @Test(expected = DataValidationException.class) | ||
142 | + public void testSaveSameTenantProfileWithDifferentIsolatedTbRuleEngine() { | ||
143 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
144 | + TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
145 | + savedTenantProfile.setIsolatedTbRuleEngine(true); | ||
146 | + tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile); | ||
147 | + } | ||
148 | + | ||
149 | + @Test(expected = DataValidationException.class) | ||
150 | + public void testSaveSameTenantProfileWithDifferentIsolatedTbCore() { | ||
151 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
152 | + TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
153 | + savedTenantProfile.setIsolatedTbCore(true); | ||
154 | + tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile); | ||
155 | + } | ||
156 | + | ||
157 | + @Test(expected = DataValidationException.class) | ||
158 | + public void testDeleteTenantProfileWithExistingTenant() { | ||
159 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
160 | + TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
161 | + Tenant tenant = new Tenant(); | ||
162 | + tenant.setTitle("Test tenant"); | ||
163 | + tenant.setTenantProfileId(savedTenantProfile.getId()); | ||
164 | + tenant = tenantService.saveTenant(tenant); | ||
165 | + try { | ||
166 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
167 | + } finally { | ||
168 | + tenantService.deleteTenant(tenant.getId()); | ||
169 | + } | ||
170 | + } | ||
171 | + | ||
139 | @Test | 172 | @Test |
140 | public void testDeleteTenantProfile() { | 173 | public void testDeleteTenantProfile() { |
141 | TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | 174 | TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); |
@@ -230,7 +263,7 @@ public class BaseTenantProfileServiceTest extends AbstractServiceTest { | @@ -230,7 +263,7 @@ public class BaseTenantProfileServiceTest extends AbstractServiceTest { | ||
230 | TenantProfile tenantProfile = new TenantProfile(); | 263 | TenantProfile tenantProfile = new TenantProfile(); |
231 | tenantProfile.setName(name); | 264 | tenantProfile.setName(name); |
232 | tenantProfile.setDescription(name + " Test"); | 265 | tenantProfile.setDescription(name + " Test"); |
233 | - tenantProfile.setProfileData(JacksonUtil.OBJECT_MAPPER.createObjectNode()); | 266 | + tenantProfile.setProfileData(new TenantProfileData()); |
234 | tenantProfile.setDefault(false); | 267 | tenantProfile.setDefault(false); |
235 | tenantProfile.setIsolatedTbCore(false); | 268 | tenantProfile.setIsolatedTbCore(false); |
236 | tenantProfile.setIsolatedTbRuleEngine(false); | 269 | tenantProfile.setIsolatedTbRuleEngine(false); |