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 62 import org.thingsboard.server.common.data.Customer;
63 63 import org.thingsboard.server.common.data.DeviceProfile;
64 64 import org.thingsboard.server.common.data.DeviceProfileType;
  65 +import org.thingsboard.server.common.data.DeviceTransportType;
65 66 import org.thingsboard.server.common.data.Tenant;
66 67 import org.thingsboard.server.common.data.User;
67 68 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
  69 +import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration;
68 70 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
69 71 import org.thingsboard.server.common.data.id.HasId;
70 72 import org.thingsboard.server.common.data.id.RuleChainId;
... ... @@ -315,10 +317,13 @@ public abstract class AbstractWebTest {
315 317 DeviceProfile deviceProfile = new DeviceProfile();
316 318 deviceProfile.setName(name);
317 319 deviceProfile.setType(DeviceProfileType.DEFAULT);
  320 + deviceProfile.setTransportType(DeviceTransportType.DEFAULT);
318 321 deviceProfile.setDescription(name + " Test");
319 322 DeviceProfileData deviceProfileData = new DeviceProfileData();
320 323 DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration();
  324 + DefaultDeviceProfileTransportConfiguration transportConfiguration = new DefaultDeviceProfileTransportConfiguration();
321 325 deviceProfileData.setConfiguration(configuration);
  326 + deviceProfileData.setTransportConfiguration(transportConfiguration);
322 327 deviceProfile.setProfileData(deviceProfileData);
323 328 deviceProfile.setDefault(false);
324 329 deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased()));
... ...
... ... @@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.Device;
25 25 import org.thingsboard.server.common.data.DeviceProfile;
26 26 import org.thingsboard.server.common.data.DeviceProfileInfo;
27 27 import org.thingsboard.server.common.data.DeviceProfileType;
  28 +import org.thingsboard.server.common.data.DeviceTransportType;
28 29 import org.thingsboard.server.common.data.Tenant;
29 30 import org.thingsboard.server.common.data.User;
30 31 import org.thingsboard.server.common.data.page.PageData;
... ... @@ -154,13 +155,32 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
154 155
155 156 @Ignore
156 157 @Test
157   - public void testSaveSameDeviceProfileWithDifferentType() throws Exception {
  158 + public void testChangeDeviceProfileTypeWithExistingDevices() throws Exception {
158 159 DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile");
159 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 166 //TODO uncomment once we have other device types;
161 167 //savedDeviceProfile.setType(DeviceProfileType.LWM2M);
162 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 186 @Test
... ...
... ... @@ -183,4 +183,5 @@ public interface DeviceDao extends Dao<Device> {
183 183 */
184 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 59 private DeviceProfileDao deviceProfileDao;
60 60
61 61 @Autowired
  62 + private DeviceDao deviceDao;
  63 +
  64 + @Autowired
62 65 private TenantDao tenantDao;
63 66
64 67 @Autowired
... ... @@ -241,6 +244,12 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
241 244 if (StringUtils.isEmpty(deviceProfile.getName())) {
242 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 253 if (deviceProfile.getTenantId() == null) {
245 254 throw new DataValidationException("Device profile should be assigned to tenant!");
246 255 } else {
... ... @@ -262,8 +271,20 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
262 271 DeviceProfile old = deviceProfileDao.findById(deviceProfile.getTenantId(), deviceProfile.getId().getId());
263 272 if (old == null) {
264 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 133
134 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 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 191 private List<EntitySubtype> convertTenantDeviceTypesToDto(UUID tenantId, List<String> types) {
187 192 List<EntitySubtype> list = Collections.emptyList();
188 193 if (types != null && !types.isEmpty()) {
... ...
... ... @@ -30,9 +30,11 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader;
30 30 import org.thingsboard.server.common.data.BaseData;
31 31 import org.thingsboard.server.common.data.DeviceProfile;
32 32 import org.thingsboard.server.common.data.DeviceProfileType;
  33 +import org.thingsboard.server.common.data.DeviceTransportType;
33 34 import org.thingsboard.server.common.data.EntityType;
34 35 import org.thingsboard.server.common.data.Event;
35 36 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
  37 +import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration;
36 38 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
37 39 import org.thingsboard.server.common.data.id.EntityId;
38 40 import org.thingsboard.server.common.data.id.HasId;
... ... @@ -197,10 +199,13 @@ public abstract class AbstractServiceTest {
197 199 deviceProfile.setTenantId(tenantId);
198 200 deviceProfile.setName(name);
199 201 deviceProfile.setType(DeviceProfileType.DEFAULT);
  202 + deviceProfile.setTransportType(DeviceTransportType.DEFAULT);
200 203 deviceProfile.setDescription(name + " Test");
201 204 DeviceProfileData deviceProfileData = new DeviceProfileData();
202 205 DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration();
  206 + DefaultDeviceProfileTransportConfiguration transportConfiguration = new DefaultDeviceProfileTransportConfiguration();
203 207 deviceProfileData.setConfiguration(configuration);
  208 + deviceProfileData.setTransportConfiguration(transportConfiguration);
204 209 deviceProfile.setProfileData(deviceProfileData);
205 210 deviceProfile.setDefault(false);
206 211 deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased()));
... ...
... ... @@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.Device;
24 24 import org.thingsboard.server.common.data.DeviceProfile;
25 25 import org.thingsboard.server.common.data.DeviceProfileInfo;
26 26 import org.thingsboard.server.common.data.DeviceProfileType;
  27 +import org.thingsboard.server.common.data.DeviceTransportType;
27 28 import org.thingsboard.server.common.data.Tenant;
28 29 import org.thingsboard.server.common.data.id.TenantId;
29 30 import org.thingsboard.server.common.data.page.PageData;
... ... @@ -148,15 +149,35 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
148 149
149 150 @Ignore
150 151 @Test(expected = DataValidationException.class)
151   - public void testSaveSameDeviceProfileWithDifferentType() {
  152 + public void testChangeDeviceProfileTypeWithExistingDevices() {
152 153 DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile");
153 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 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 162 // savedDeviceProfile.setType(DeviceProfileType.LWM2M);
156 163 deviceProfileService.saveDeviceProfile(savedDeviceProfile);
157 164 }
158 165
159 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 181 public void testDeleteDeviceProfileWithExistingDevice() {
161 182 DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile");
162 183 DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile);
... ...