Commit 51966f0094f66d86078e20922a78eb49e6cd6bda
Merge branch 'develop/3.2' of github.com:thingsboard/thingsboard into develop/3.2
Showing
8 changed files
with
85 additions
and
5 deletions
@@ -62,9 +62,11 @@ import org.thingsboard.server.common.data.BaseData; | @@ -62,9 +62,11 @@ import org.thingsboard.server.common.data.BaseData; | ||
62 | import org.thingsboard.server.common.data.Customer; | 62 | import org.thingsboard.server.common.data.Customer; |
63 | import org.thingsboard.server.common.data.DeviceProfile; | 63 | import org.thingsboard.server.common.data.DeviceProfile; |
64 | import org.thingsboard.server.common.data.DeviceProfileType; | 64 | import org.thingsboard.server.common.data.DeviceProfileType; |
65 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
65 | import org.thingsboard.server.common.data.Tenant; | 66 | import org.thingsboard.server.common.data.Tenant; |
66 | import org.thingsboard.server.common.data.User; | 67 | 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.DefaultDeviceProfileConfiguration; |
69 | +import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; | ||
68 | import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | 70 | import org.thingsboard.server.common.data.device.profile.DeviceProfileData; |
69 | import org.thingsboard.server.common.data.id.HasId; | 71 | import org.thingsboard.server.common.data.id.HasId; |
70 | import org.thingsboard.server.common.data.id.RuleChainId; | 72 | import org.thingsboard.server.common.data.id.RuleChainId; |
@@ -315,10 +317,13 @@ public abstract class AbstractWebTest { | @@ -315,10 +317,13 @@ public abstract class AbstractWebTest { | ||
315 | DeviceProfile deviceProfile = new DeviceProfile(); | 317 | DeviceProfile deviceProfile = new DeviceProfile(); |
316 | deviceProfile.setName(name); | 318 | deviceProfile.setName(name); |
317 | deviceProfile.setType(DeviceProfileType.DEFAULT); | 319 | deviceProfile.setType(DeviceProfileType.DEFAULT); |
320 | + deviceProfile.setTransportType(DeviceTransportType.DEFAULT); | ||
318 | deviceProfile.setDescription(name + " Test"); | 321 | deviceProfile.setDescription(name + " Test"); |
319 | DeviceProfileData deviceProfileData = new DeviceProfileData(); | 322 | DeviceProfileData deviceProfileData = new DeviceProfileData(); |
320 | DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration(); | 323 | DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration(); |
324 | + DefaultDeviceProfileTransportConfiguration transportConfiguration = new DefaultDeviceProfileTransportConfiguration(); | ||
321 | deviceProfileData.setConfiguration(configuration); | 325 | deviceProfileData.setConfiguration(configuration); |
326 | + deviceProfileData.setTransportConfiguration(transportConfiguration); | ||
322 | deviceProfile.setProfileData(deviceProfileData); | 327 | deviceProfile.setProfileData(deviceProfileData); |
323 | deviceProfile.setDefault(false); | 328 | deviceProfile.setDefault(false); |
324 | deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased())); | 329 | deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased())); |
@@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.Device; | @@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.Device; | ||
25 | import org.thingsboard.server.common.data.DeviceProfile; | 25 | import org.thingsboard.server.common.data.DeviceProfile; |
26 | import org.thingsboard.server.common.data.DeviceProfileInfo; | 26 | import org.thingsboard.server.common.data.DeviceProfileInfo; |
27 | import org.thingsboard.server.common.data.DeviceProfileType; | 27 | import org.thingsboard.server.common.data.DeviceProfileType; |
28 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
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; |
30 | import org.thingsboard.server.common.data.page.PageData; | 31 | import org.thingsboard.server.common.data.page.PageData; |
@@ -154,13 +155,32 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController | @@ -154,13 +155,32 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController | ||
154 | 155 | ||
155 | @Ignore | 156 | @Ignore |
156 | @Test | 157 | @Test |
157 | - public void testSaveSameDeviceProfileWithDifferentType() throws Exception { | 158 | + public void testChangeDeviceProfileTypeWithExistingDevices() throws Exception { |
158 | DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | 159 | DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); |
159 | DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); | 160 | DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); |
161 | + Device device = new Device(); | ||
162 | + device.setName("Test device"); | ||
163 | + device.setType("default"); | ||
164 | + device.setDeviceProfileId(savedDeviceProfile.getId()); | ||
165 | + doPost("/api/device", device, Device.class); | ||
160 | //TODO uncomment once we have other device types; | 166 | //TODO uncomment once we have other device types; |
161 | //savedDeviceProfile.setType(DeviceProfileType.LWM2M); | 167 | //savedDeviceProfile.setType(DeviceProfileType.LWM2M); |
162 | doPost("/api/deviceProfile", savedDeviceProfile).andExpect(status().isBadRequest()) | 168 | doPost("/api/deviceProfile", savedDeviceProfile).andExpect(status().isBadRequest()) |
163 | - .andExpect(statusReason(containsString("Changing type of device profile is prohibited"))); | 169 | + .andExpect(statusReason(containsString("Can't change device profile type because devices referenced it"))); |
170 | + } | ||
171 | + | ||
172 | + @Test | ||
173 | + public void testChangeDeviceProfileTransportTypeWithExistingDevices() throws Exception { | ||
174 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | ||
175 | + DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); | ||
176 | + Device device = new Device(); | ||
177 | + device.setName("Test device"); | ||
178 | + device.setType("default"); | ||
179 | + device.setDeviceProfileId(savedDeviceProfile.getId()); | ||
180 | + doPost("/api/device", device, Device.class); | ||
181 | + savedDeviceProfile.setTransportType(DeviceTransportType.MQTT); | ||
182 | + doPost("/api/deviceProfile", savedDeviceProfile).andExpect(status().isBadRequest()) | ||
183 | + .andExpect(statusReason(containsString("Can't change device profile transport type because devices referenced it"))); | ||
164 | } | 184 | } |
165 | 185 | ||
166 | @Test | 186 | @Test |
@@ -183,4 +183,5 @@ public interface DeviceDao extends Dao<Device> { | @@ -183,4 +183,5 @@ public interface DeviceDao extends Dao<Device> { | ||
183 | */ | 183 | */ |
184 | ListenableFuture<Device> findDeviceByTenantIdAndIdAsync(TenantId tenantId, UUID id); | 184 | ListenableFuture<Device> findDeviceByTenantIdAndIdAsync(TenantId tenantId, UUID id); |
185 | 185 | ||
186 | + Long countDevicesByDeviceProfileId(TenantId tenantId, UUID deviceProfileId); | ||
186 | } | 187 | } |
@@ -59,6 +59,9 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | @@ -59,6 +59,9 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | ||
59 | private DeviceProfileDao deviceProfileDao; | 59 | private DeviceProfileDao deviceProfileDao; |
60 | 60 | ||
61 | @Autowired | 61 | @Autowired |
62 | + private DeviceDao deviceDao; | ||
63 | + | ||
64 | + @Autowired | ||
62 | private TenantDao tenantDao; | 65 | private TenantDao tenantDao; |
63 | 66 | ||
64 | @Autowired | 67 | @Autowired |
@@ -241,6 +244,12 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | @@ -241,6 +244,12 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | ||
241 | if (StringUtils.isEmpty(deviceProfile.getName())) { | 244 | if (StringUtils.isEmpty(deviceProfile.getName())) { |
242 | throw new DataValidationException("Device profile name should be specified!"); | 245 | throw new DataValidationException("Device profile name should be specified!"); |
243 | } | 246 | } |
247 | + if (deviceProfile.getType() == null) { | ||
248 | + throw new DataValidationException("Device profile type should be specified!"); | ||
249 | + } | ||
250 | + if (deviceProfile.getTransportType() == null) { | ||
251 | + throw new DataValidationException("Device profile transport type should be specified!"); | ||
252 | + } | ||
244 | if (deviceProfile.getTenantId() == null) { | 253 | if (deviceProfile.getTenantId() == null) { |
245 | throw new DataValidationException("Device profile should be assigned to tenant!"); | 254 | throw new DataValidationException("Device profile should be assigned to tenant!"); |
246 | } else { | 255 | } else { |
@@ -262,8 +271,20 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | @@ -262,8 +271,20 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | ||
262 | DeviceProfile old = deviceProfileDao.findById(deviceProfile.getTenantId(), deviceProfile.getId().getId()); | 271 | DeviceProfile old = deviceProfileDao.findById(deviceProfile.getTenantId(), deviceProfile.getId().getId()); |
263 | if (old == null) { | 272 | if (old == null) { |
264 | throw new DataValidationException("Can't update non existing device profile!"); | 273 | throw new DataValidationException("Can't update non existing device profile!"); |
265 | - } else if (!old.getType().equals(deviceProfile.getType())) { | ||
266 | - throw new DataValidationException("Changing type of device profile is prohibited!"); | 274 | + } |
275 | + boolean profileTypeChanged = !old.getType().equals(deviceProfile.getType()); | ||
276 | + boolean transportTypeChanged = !old.getTransportType().equals(deviceProfile.getTransportType()); | ||
277 | + if (profileTypeChanged || transportTypeChanged) { | ||
278 | + Long profileDeviceCount = deviceDao.countDevicesByDeviceProfileId(deviceProfile.getTenantId(), deviceProfile.getId().getId()); | ||
279 | + if (profileDeviceCount > 0) { | ||
280 | + String message = null; | ||
281 | + if (profileTypeChanged) { | ||
282 | + message = "Can't change device profile type because devices referenced it!"; | ||
283 | + } else if (transportTypeChanged) { | ||
284 | + message = "Can't change device profile transport type because devices referenced it!"; | ||
285 | + } | ||
286 | + throw new DataValidationException(message); | ||
287 | + } | ||
267 | } | 288 | } |
268 | } | 289 | } |
269 | }; | 290 | }; |
@@ -133,4 +133,6 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit | @@ -133,4 +133,6 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit | ||
133 | 133 | ||
134 | DeviceEntity findByTenantIdAndId(UUID tenantId, UUID id); | 134 | DeviceEntity findByTenantIdAndId(UUID tenantId, UUID id); |
135 | 135 | ||
136 | + Long countByDeviceProfileId(UUID deviceProfileId); | ||
137 | + | ||
136 | } | 138 | } |
@@ -183,6 +183,11 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> | @@ -183,6 +183,11 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> | ||
183 | return service.submit(() -> DaoUtil.getData(deviceRepository.findByTenantIdAndId(tenantId.getId(), id))); | 183 | return service.submit(() -> DaoUtil.getData(deviceRepository.findByTenantIdAndId(tenantId.getId(), id))); |
184 | } | 184 | } |
185 | 185 | ||
186 | + @Override | ||
187 | + public Long countDevicesByDeviceProfileId(TenantId tenantId, UUID deviceProfileId) { | ||
188 | + return deviceRepository.countByDeviceProfileId(deviceProfileId); | ||
189 | + } | ||
190 | + | ||
186 | private List<EntitySubtype> convertTenantDeviceTypesToDto(UUID tenantId, List<String> types) { | 191 | private List<EntitySubtype> convertTenantDeviceTypesToDto(UUID tenantId, List<String> types) { |
187 | List<EntitySubtype> list = Collections.emptyList(); | 192 | List<EntitySubtype> list = Collections.emptyList(); |
188 | if (types != null && !types.isEmpty()) { | 193 | if (types != null && !types.isEmpty()) { |
@@ -30,9 +30,11 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; | @@ -30,9 +30,11 @@ 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; | 31 | import org.thingsboard.server.common.data.DeviceProfile; |
32 | import org.thingsboard.server.common.data.DeviceProfileType; | 32 | import org.thingsboard.server.common.data.DeviceProfileType; |
33 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
33 | import org.thingsboard.server.common.data.EntityType; | 34 | import org.thingsboard.server.common.data.EntityType; |
34 | import org.thingsboard.server.common.data.Event; | 35 | 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.DefaultDeviceProfileConfiguration; |
37 | +import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; | ||
36 | import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | 38 | import org.thingsboard.server.common.data.device.profile.DeviceProfileData; |
37 | import org.thingsboard.server.common.data.id.EntityId; | 39 | import org.thingsboard.server.common.data.id.EntityId; |
38 | import org.thingsboard.server.common.data.id.HasId; | 40 | import org.thingsboard.server.common.data.id.HasId; |
@@ -197,10 +199,13 @@ public abstract class AbstractServiceTest { | @@ -197,10 +199,13 @@ public abstract class AbstractServiceTest { | ||
197 | deviceProfile.setTenantId(tenantId); | 199 | deviceProfile.setTenantId(tenantId); |
198 | deviceProfile.setName(name); | 200 | deviceProfile.setName(name); |
199 | deviceProfile.setType(DeviceProfileType.DEFAULT); | 201 | deviceProfile.setType(DeviceProfileType.DEFAULT); |
202 | + deviceProfile.setTransportType(DeviceTransportType.DEFAULT); | ||
200 | deviceProfile.setDescription(name + " Test"); | 203 | deviceProfile.setDescription(name + " Test"); |
201 | DeviceProfileData deviceProfileData = new DeviceProfileData(); | 204 | DeviceProfileData deviceProfileData = new DeviceProfileData(); |
202 | DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration(); | 205 | DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration(); |
206 | + DefaultDeviceProfileTransportConfiguration transportConfiguration = new DefaultDeviceProfileTransportConfiguration(); | ||
203 | deviceProfileData.setConfiguration(configuration); | 207 | deviceProfileData.setConfiguration(configuration); |
208 | + deviceProfileData.setTransportConfiguration(transportConfiguration); | ||
204 | deviceProfile.setProfileData(deviceProfileData); | 209 | deviceProfile.setProfileData(deviceProfileData); |
205 | deviceProfile.setDefault(false); | 210 | deviceProfile.setDefault(false); |
206 | deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased())); | 211 | deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased())); |
@@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.Device; | @@ -24,6 +24,7 @@ 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.DeviceProfileInfo; | 25 | import org.thingsboard.server.common.data.DeviceProfileInfo; |
26 | import org.thingsboard.server.common.data.DeviceProfileType; | 26 | import org.thingsboard.server.common.data.DeviceProfileType; |
27 | +import org.thingsboard.server.common.data.DeviceTransportType; | ||
27 | import org.thingsboard.server.common.data.Tenant; | 28 | import org.thingsboard.server.common.data.Tenant; |
28 | import org.thingsboard.server.common.data.id.TenantId; | 29 | import org.thingsboard.server.common.data.id.TenantId; |
29 | import org.thingsboard.server.common.data.page.PageData; | 30 | import org.thingsboard.server.common.data.page.PageData; |
@@ -148,15 +149,35 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | @@ -148,15 +149,35 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
148 | 149 | ||
149 | @Ignore | 150 | @Ignore |
150 | @Test(expected = DataValidationException.class) | 151 | @Test(expected = DataValidationException.class) |
151 | - public void testSaveSameDeviceProfileWithDifferentType() { | 152 | + public void testChangeDeviceProfileTypeWithExistingDevices() { |
152 | DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | 153 | DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); |
153 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | 154 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
155 | + Device device = new Device(); | ||
156 | + device.setTenantId(tenantId); | ||
157 | + device.setName("Test device"); | ||
158 | + device.setType("default"); | ||
159 | + device.setDeviceProfileId(savedDeviceProfile.getId()); | ||
160 | + deviceService.saveDevice(device); | ||
154 | //TODO: once we have more profile types, we should test that we can not change profile type in runtime and uncomment the @Ignore. | 161 | //TODO: once we have more profile types, we should test that we can not change profile type in runtime and uncomment the @Ignore. |
155 | // savedDeviceProfile.setType(DeviceProfileType.LWM2M); | 162 | // savedDeviceProfile.setType(DeviceProfileType.LWM2M); |
156 | deviceProfileService.saveDeviceProfile(savedDeviceProfile); | 163 | deviceProfileService.saveDeviceProfile(savedDeviceProfile); |
157 | } | 164 | } |
158 | 165 | ||
159 | @Test(expected = DataValidationException.class) | 166 | @Test(expected = DataValidationException.class) |
167 | + public void testChangeDeviceProfileTransportTypeWithExistingDevices() { | ||
168 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | ||
169 | + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | ||
170 | + Device device = new Device(); | ||
171 | + device.setTenantId(tenantId); | ||
172 | + device.setName("Test device"); | ||
173 | + device.setType("default"); | ||
174 | + device.setDeviceProfileId(savedDeviceProfile.getId()); | ||
175 | + deviceService.saveDevice(device); | ||
176 | + savedDeviceProfile.setTransportType(DeviceTransportType.MQTT); | ||
177 | + deviceProfileService.saveDeviceProfile(savedDeviceProfile); | ||
178 | + } | ||
179 | + | ||
180 | + @Test(expected = DataValidationException.class) | ||
160 | public void testDeleteDeviceProfileWithExistingDevice() { | 181 | public void testDeleteDeviceProfileWithExistingDevice() { |
161 | DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | 182 | DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); |
162 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | 183 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |