Commit 51966f0094f66d86078e20922a78eb49e6cd6bda

Authored by Andrii Shvaika
2 parents b9b82446 f5f531e7

Merge branch 'develop/3.2' of github.com:thingsboard/thingsboard into develop/3.2

@@ -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);