Commit 73a1a79821665486408306b4455810ae72e0dc7d

Authored by Andrii Shvaika
1 parent 6af45d03

Device Profile updates

... ... @@ -355,10 +355,12 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
355 355 pageData = tenantService.findTenants(pageLink);
356 356 for (Tenant tenant : pageData.getData()) {
357 357 List<EntitySubtype> deviceTypes = deviceService.findDeviceTypesByTenantId(tenant.getId()).get();
358   - deviceProfileService.findOrCreateDefaultDeviceProfile(tenant.getId());
  358 + try {
  359 + deviceProfileService.createDefaultDeviceProfile(tenant.getId());
  360 + } catch (Exception e){}
359 361 for (EntitySubtype deviceType : deviceTypes) {
360 362 try {
361   - deviceProfileService.createDeviceProfile(tenant.getId(), deviceType.getType());
  363 + deviceProfileService.findOrCreateDeviceProfile(tenant.getId(), deviceType.getType());
362 364 } catch (Exception e) {
363 365 }
364 366 }
... ...
... ... @@ -27,6 +27,8 @@ public interface DeviceProfileService {
27 27
28 28 DeviceProfile findDeviceProfileById(TenantId tenantId, DeviceProfileId deviceProfileId);
29 29
  30 + DeviceProfile findDeviceProfileByName(TenantId tenantId, String profileName);
  31 +
30 32 DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId);
31 33
32 34 DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile);
... ... @@ -37,12 +39,10 @@ public interface DeviceProfileService {
37 39
38 40 PageData<DeviceProfileInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink);
39 41
40   - DeviceProfile findOrCreateDefaultDeviceProfile(TenantId tenantId);
  42 + DeviceProfile findOrCreateDeviceProfile(TenantId tenantId, String profileName);
41 43
42 44 DeviceProfile createDefaultDeviceProfile(TenantId tenantId);
43 45
44   - DeviceProfile createDeviceProfile(TenantId tenantId, String profileName);
45   -
46 46 DeviceProfile findDefaultDeviceProfile(TenantId tenantId);
47 47
48 48 DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId);
... ...
... ... @@ -39,6 +39,7 @@ import io.netty.util.concurrent.Future;
39 39 import io.netty.util.concurrent.GenericFutureListener;
40 40 import lombok.extern.slf4j.Slf4j;
41 41 import org.springframework.util.StringUtils;
  42 +import org.thingsboard.server.common.data.DeviceProfile;
42 43 import org.thingsboard.server.common.data.DeviceTransportType;
43 44 import org.thingsboard.server.common.data.device.profile.MqttTopics;
44 45 import org.thingsboard.server.common.msg.EncryptionUtil;
... ... @@ -574,7 +575,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
574 575 try {
575 576 adaptor.convertToPublish(deviceSessionCtx, rpcResponse).ifPresent(deviceSessionCtx.getChannel()::writeAndFlush);
576 577 } catch (Exception e) {
577   - log.trace("[{}] Failed to convert device RPC commandto MQTT msg", sessionId, e);
  578 + log.trace("[{}] Failed to convert device RPC command to MQTT msg", sessionId, e);
578 579 }
579 580 }
  581 +
  582 + @Override
  583 + public void onProfileUpdate(DeviceProfile deviceProfile) {
  584 + deviceSessionCtx.getDeviceInfo().setDeviceType(deviceProfile.getName());
  585 + sessionInfo = SessionInfoProto.newBuilder().mergeFrom(sessionInfo).setDeviceType(deviceProfile.getName()).build();
  586 + }
580 587 }
... ...
... ... @@ -184,4 +184,15 @@ public interface DeviceDao extends Dao<Device> {
184 184 ListenableFuture<Device> findDeviceByTenantIdAndIdAsync(TenantId tenantId, UUID id);
185 185
186 186 Long countDevicesByDeviceProfileId(TenantId tenantId, UUID deviceProfileId);
  187 +
  188 + /**
  189 + * Find devices by tenantId, profileId and page link.
  190 + *
  191 + * @param tenantId the tenantId
  192 + * @param profileId the profileId
  193 + * @param pageLink the page link
  194 + * @return the list of device objects
  195 + */
  196 + PageData<Device> findDevicesByTenantIdAndProfileId(UUID tenantId, UUID profileId, PageLink pageLink);
  197 +
187 198 }
... ...
... ... @@ -37,4 +37,6 @@ public interface DeviceProfileDao extends Dao<DeviceProfile> {
37 37 DeviceProfile findDefaultDeviceProfile(TenantId tenantId);
38 38
39 39 DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId);
  40 +
  41 + DeviceProfile findByName(TenantId tenantId, String profileName);
40 42 }
... ...
... ... @@ -23,10 +23,12 @@ import org.springframework.cache.Cache;
23 23 import org.springframework.cache.CacheManager;
24 24 import org.springframework.cache.annotation.Cacheable;
25 25 import org.springframework.stereotype.Service;
  26 +import org.thingsboard.server.common.data.Device;
26 27 import org.thingsboard.server.common.data.DeviceProfile;
27 28 import org.thingsboard.server.common.data.DeviceProfileInfo;
28 29 import org.thingsboard.server.common.data.DeviceProfileType;
29 30 import org.thingsboard.server.common.data.DeviceTransportType;
  31 +import org.thingsboard.server.common.data.EntitySubtype;
30 32 import org.thingsboard.server.common.data.Tenant;
31 33 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
32 34 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration;
... ... @@ -44,6 +46,7 @@ import org.thingsboard.server.dao.tenant.TenantDao;
44 46
45 47 import java.util.Arrays;
46 48 import java.util.Collections;
  49 +import java.util.List;
47 50
48 51 import static org.thingsboard.server.common.data.CacheConstants.DEVICE_PROFILE_CACHE;
49 52 import static org.thingsboard.server.dao.service.Validator.validateId;
... ... @@ -54,6 +57,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
54 57
55 58 private static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
56 59 private static final String INCORRECT_DEVICE_PROFILE_ID = "Incorrect deviceProfileId ";
  60 + private static final String INCORRECT_DEVICE_PROFILE_NAME = "Incorrect deviceProfileName ";
57 61
58 62 @Autowired
59 63 private DeviceProfileDao deviceProfileDao;
... ... @@ -62,6 +66,9 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
62 66 private DeviceDao deviceDao;
63 67
64 68 @Autowired
  69 + private DeviceService deviceService;
  70 +
  71 + @Autowired
65 72 private TenantDao tenantDao;
66 73
67 74 @Autowired
... ... @@ -75,6 +82,13 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
75 82 return deviceProfileDao.findById(tenantId, deviceProfileId.getId());
76 83 }
77 84
  85 + @Override
  86 + public DeviceProfile findDeviceProfileByName(TenantId tenantId, String profileName) {
  87 + log.trace("Executing findDeviceProfileByName [{}][{}]", tenantId, profileName);
  88 + Validator.validateString(profileName, INCORRECT_DEVICE_PROFILE_NAME + profileName);
  89 + return deviceProfileDao.findByName(tenantId, profileName);
  90 + }
  91 +
78 92 @Cacheable(cacheNames = DEVICE_PROFILE_CACHE, key = "{'info', #deviceProfileId.id}")
79 93 @Override
80 94 public DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId) {
... ... @@ -87,6 +101,10 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
87 101 public DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile) {
88 102 log.trace("Executing saveDeviceProfile [{}]", deviceProfile);
89 103 deviceProfileValidator.validate(deviceProfile, DeviceProfile::getTenantId);
  104 + DeviceProfile oldDeviceProfile = null;
  105 + if (deviceProfile.getId() != null) {
  106 + oldDeviceProfile = deviceProfileDao.findById(deviceProfile.getTenantId(), deviceProfile.getId().getId());
  107 + }
90 108 DeviceProfile savedDeviceProfile;
91 109 try {
92 110 savedDeviceProfile = deviceProfileDao.save(deviceProfile.getTenantId(), deviceProfile);
... ... @@ -101,10 +119,23 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
101 119 Cache cache = cacheManager.getCache(DEVICE_PROFILE_CACHE);
102 120 cache.evict(Collections.singletonList(savedDeviceProfile.getId().getId()));
103 121 cache.evict(Arrays.asList("info", savedDeviceProfile.getId().getId()));
  122 + cache.evict(Arrays.asList(deviceProfile.getTenantId().getId(), deviceProfile.getName()));
104 123 if (savedDeviceProfile.isDefault()) {
105 124 cache.evict(Arrays.asList("default", savedDeviceProfile.getTenantId().getId()));
106 125 cache.evict(Arrays.asList("default", "info", savedDeviceProfile.getTenantId().getId()));
107 126 }
  127 + if (oldDeviceProfile != null && !oldDeviceProfile.getName().equals(deviceProfile.getName())) {
  128 + PageLink pageLink = new PageLink(100);
  129 + PageData<Device> pageData;
  130 + do {
  131 + pageData = deviceDao.findDevicesByTenantIdAndProfileId(deviceProfile.getTenantId().getId(), deviceProfile.getUuidId(), pageLink);
  132 + for (Device device : pageData.getData()) {
  133 + device.setType(deviceProfile.getName());
  134 + deviceService.saveDevice(device);
  135 + }
  136 + pageLink = pageLink.nextPageLink();
  137 + } while (pageData.hasNext());
  138 + }
108 139 return savedDeviceProfile;
109 140 }
110 141
... ... @@ -116,10 +147,11 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
116 147 if (deviceProfile != null && deviceProfile.isDefault()) {
117 148 throw new DataValidationException("Deletion of Default Device Profile is prohibited!");
118 149 }
119   - this.removeDeviceProfile(tenantId, deviceProfileId);
  150 + this.removeDeviceProfile(tenantId, deviceProfile);
120 151 }
121 152
122   - private void removeDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId) {
  153 + private void removeDeviceProfile(TenantId tenantId, DeviceProfile deviceProfile) {
  154 + DeviceProfileId deviceProfileId = deviceProfile.getId();
123 155 try {
124 156 deviceProfileDao.removeById(tenantId, deviceProfileId.getId());
125 157 } catch (Exception t) {
... ... @@ -134,6 +166,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
134 166 Cache cache = cacheManager.getCache(DEVICE_PROFILE_CACHE);
135 167 cache.evict(Collections.singletonList(deviceProfileId.getId()));
136 168 cache.evict(Arrays.asList("info", deviceProfileId.getId()));
  169 + cache.evict(Arrays.asList(tenantId.getId(), deviceProfile.getName()));
137 170 }
138 171
139 172 @Override
... ... @@ -152,12 +185,13 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
152 185 return deviceProfileDao.findDeviceProfileInfos(tenantId, pageLink);
153 186 }
154 187
  188 + @Cacheable(cacheNames = DEVICE_PROFILE_CACHE, key = "{#tenantId.id, #name}")
155 189 @Override
156   - public DeviceProfile findOrCreateDefaultDeviceProfile(TenantId tenantId) {
  190 + public DeviceProfile findOrCreateDeviceProfile(TenantId tenantId, String name) {
157 191 log.trace("Executing findOrCreateDefaultDeviceProfile");
158   - DeviceProfile deviceProfile = findDefaultDeviceProfile(tenantId);
  192 + DeviceProfile deviceProfile = findDeviceProfileByName(tenantId, name);
159 193 if (deviceProfile == null) {
160   - deviceProfile = this.createDefaultDeviceProfile(tenantId);
  194 + deviceProfile = this.doCreateDefaultDeviceProfile(tenantId, name, name.equals("default"));
161 195 }
162 196 return deviceProfile;
163 197 }
... ... @@ -168,12 +202,6 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
168 202 return doCreateDefaultDeviceProfile(tenantId, "default", true);
169 203 }
170 204
171   - @Override
172   - public DeviceProfile createDeviceProfile(TenantId tenantId, String profileName) {
173   - log.trace("Executing createDefaultDeviceProfile tenantId [{}], profileName [{}]", tenantId, profileName);
174   - return doCreateDefaultDeviceProfile(tenantId, profileName, false);
175   - }
176   -
177 205 private DeviceProfile doCreateDefaultDeviceProfile(TenantId tenantId, String profileName, boolean defaultProfile) {
178 206 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
179 207 DeviceProfile deviceProfile = new DeviceProfile();
... ... @@ -227,6 +255,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
227 255 deviceProfileDao.save(tenantId, deviceProfile);
228 256 cache.evict(Collections.singletonList(previousDefaultDeviceProfile.getId().getId()));
229 257 cache.evict(Arrays.asList("info", previousDefaultDeviceProfile.getId().getId()));
  258 + cache.evict(Arrays.asList(tenantId.getId(), previousDefaultDeviceProfile.getName()));
230 259 changed = true;
231 260 }
232 261 if (changed) {
... ... @@ -234,6 +263,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
234 263 cache.evict(Arrays.asList("info", deviceProfile.getId().getId()));
235 264 cache.evict(Arrays.asList("default", tenantId.getId()));
236 265 cache.evict(Arrays.asList("default", "info", tenantId.getId()));
  266 + cache.evict(Arrays.asList(tenantId.getId(), deviceProfile.getName()));
237 267 }
238 268 return changed;
239 269 }
... ... @@ -309,7 +339,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
309 339
310 340 @Override
311 341 protected void removeEntity(TenantId tenantId, DeviceProfile entity) {
312   - removeDeviceProfile(tenantId, entity.getId());
  342 + removeDeviceProfile(tenantId, entity);
313 343 }
314 344 };
315 345
... ...
... ... @@ -169,8 +169,14 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
169 169 deviceValidator.validate(device, Device::getTenantId);
170 170 Device savedDevice;
171 171 try {
  172 + DeviceProfile deviceProfile;
172 173 if (device.getDeviceProfileId() == null) {
173   - DeviceProfile deviceProfile = this.deviceProfileService.findOrCreateDefaultDeviceProfile(device.getTenantId());
  174 + if (!StringUtils.isEmpty(device.getType())) {
  175 + deviceProfile = this.deviceProfileService.findOrCreateDeviceProfile(device.getTenantId(), device.getType());
  176 + } else {
  177 + deviceProfile = this.deviceProfileService.findDefaultDeviceProfile(device.getTenantId());
  178 + device.setType(deviceProfile.getName());
  179 + }
174 180 device.setDeviceProfileId(new DeviceProfileId(deviceProfile.getId().getId()));
175 181 DeviceData deviceData = new DeviceData();
176 182 switch (deviceProfile.getType()) {
... ... @@ -178,7 +184,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
178 184 deviceData.setConfiguration(new DefaultDeviceConfiguration());
179 185 break;
180 186 }
181   - switch (deviceProfile.getTransportType()){
  187 + switch (deviceProfile.getTransportType()) {
182 188 case DEFAULT:
183 189 deviceData.setTransportConfiguration(new DefaultDeviceTransportConfiguration());
184 190 break;
... ... @@ -190,7 +196,14 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
190 196 break;
191 197 }
192 198 device.setDeviceData(deviceData);
  199 + } else {
  200 + deviceProfile = this.deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId());
  201 + if (deviceProfile == null) {
  202 + throw new DataValidationException("Device is referencing non existing device profile!");
  203 + }
193 204 }
  205 + device.setType(deviceProfile.getName());
  206 +
194 207 savedDevice = deviceDao.save(device.getTenantId(), device);
195 208 } catch (Exception t) {
196 209 ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
... ... @@ -441,9 +454,6 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
441 454
442 455 @Override
443 456 protected void validateDataImpl(TenantId tenantId, Device device) {
444   - if (StringUtils.isEmpty(device.getType())) {
445   - throw new DataValidationException("Device type should be specified!");
446   - }
447 457 if (StringUtils.isEmpty(device.getName())) {
448 458 throw new DataValidationException("Device name should be specified!");
449 459 }
... ...
... ... @@ -20,6 +20,7 @@ import org.springframework.data.domain.Pageable;
20 20 import org.springframework.data.jpa.repository.Query;
21 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
  23 +import org.thingsboard.server.common.data.DeviceProfile;
23 24 import org.thingsboard.server.common.data.DeviceProfileInfo;
24 25 import org.thingsboard.server.dao.model.sql.DeviceProfileEntity;
25 26
... ... @@ -53,4 +54,7 @@ public interface DeviceProfileRepository extends PagingAndSortingRepository<Devi
53 54 "FROM DeviceProfileEntity d " +
54 55 "WHERE d.tenantId = :tenantId AND d.isDefault = true")
55 56 DeviceProfileInfo findDefaultDeviceProfileInfo(@Param("tenantId") UUID tenantId);
  57 +
  58 + DeviceProfile findByTenantIdAndName(UUID id, String profileName);
  59 +
56 60 }
... ...
... ... @@ -46,6 +46,14 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
46 46 @Param("searchText") String searchText,
47 47 Pageable pageable);
48 48
  49 + @Query("SELECT d FROM DeviceEntity d WHERE d.tenantId = :tenantId " +
  50 + "AND d.deviceProfileId = :profileId " +
  51 + "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
  52 + Page<DeviceEntity> findByTenantIdAndProfileId(@Param("tenantId") UUID tenantId,
  53 + @Param("profileId") UUID profileId,
  54 + @Param("searchText") String searchText,
  55 + Pageable pageable);
  56 +
49 57 @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
50 58 "FROM DeviceEntity d " +
51 59 "LEFT JOIN CustomerEntity c on c.id = d.customerId " +
... ...
... ... @@ -105,6 +105,16 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device>
105 105 }
106 106
107 107 @Override
  108 + public PageData<Device> findDevicesByTenantIdAndProfileId(UUID tenantId, UUID profileId, PageLink pageLink) {
  109 + return DaoUtil.toPageData(
  110 + deviceRepository.findByTenantIdAndProfileId(
  111 + tenantId,
  112 + profileId,
  113 + Objects.toString(pageLink.getTextSearch(), ""),
  114 + DaoUtil.toPageable(pageLink)));
  115 + }
  116 +
  117 + @Override
108 118 public PageData<DeviceInfo> findDeviceInfosByTenantIdAndCustomerId(UUID tenantId, UUID customerId, PageLink pageLink) {
109 119 return DaoUtil.toPageData(
110 120 deviceRepository.findDeviceInfosByTenantIdAndCustomerId(
... ...
... ... @@ -80,4 +80,8 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileE
80 80 return deviceProfileRepository.findDefaultDeviceProfileInfo(tenantId.getId());
81 81 }
82 82
  83 + @Override
  84 + public DeviceProfile findByName(TenantId tenantId, String profileName) {
  85 + return deviceProfileRepository.findByTenantIdAndName(tenantId.getId(), profileName);
  86 + }
83 87 }
... ...