Commit 350581028021897cf1a51ad6f5bcc2b81f5cc71d
1 parent
41e57249
Bulk import device credentials handling refactoring
Showing
8 changed files
with
65 additions
and
24 deletions
... | ... | @@ -18,8 +18,6 @@ package org.thingsboard.server.service.device; |
18 | 18 | import com.fasterxml.jackson.databind.node.BooleanNode; |
19 | 19 | import com.fasterxml.jackson.databind.node.ObjectNode; |
20 | 20 | import com.fasterxml.jackson.databind.node.TextNode; |
21 | -import com.google.gson.JsonObject; | |
22 | -import com.google.gson.JsonPrimitive; | |
23 | 21 | import lombok.SneakyThrows; |
24 | 22 | import org.apache.commons.collections.CollectionUtils; |
25 | 23 | import org.springframework.stereotype.Service; |
... | ... | @@ -39,10 +37,10 @@ import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTrans |
39 | 37 | import org.thingsboard.server.common.data.id.TenantId; |
40 | 38 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
41 | 39 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
42 | -import org.thingsboard.server.common.transport.adaptor.JsonConverter; | |
43 | 40 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
44 | 41 | import org.thingsboard.server.dao.device.DeviceProfileService; |
45 | 42 | import org.thingsboard.server.dao.device.DeviceService; |
43 | +import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; | |
46 | 44 | import org.thingsboard.server.dao.tenant.TbTenantProfileCache; |
47 | 45 | import org.thingsboard.server.queue.util.TbCoreComponent; |
48 | 46 | import org.thingsboard.server.service.action.EntityActionService; |
... | ... | @@ -63,8 +61,6 @@ import java.util.Set; |
63 | 61 | import java.util.stream.Collectors; |
64 | 62 | import java.util.stream.Stream; |
65 | 63 | |
66 | -import static org.thingsboard.server.dao.service.Validator.validateId; | |
67 | - | |
68 | 64 | @Service |
69 | 65 | @TbCoreComponent |
70 | 66 | public class DeviceBulkImportService extends AbstractBulkImportService<Device> { |
... | ... | @@ -104,7 +100,18 @@ public class DeviceBulkImportService extends AbstractBulkImportService<Device> { |
104 | 100 | if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.LWM2M_CREDENTIALS) { |
105 | 101 | setUpLwM2mDeviceProfile(user.getTenantId(), device); |
106 | 102 | } |
107 | - device = deviceService.saveDeviceWithCredentials(device, deviceCredentials); | |
103 | + try { | |
104 | + device = deviceService.saveDeviceWithCredentials(device, deviceCredentials); | |
105 | + } catch (DeviceCredentialsValidationException e) { | |
106 | + if (deviceCredentials.getId() == null) { | |
107 | + device.setId(deviceCredentials.getDeviceId()); | |
108 | + importedEntityInfo.setRelatedError("Failed to create " + deviceCredentials.getCredentialsType() + " credentials: " | |
109 | + + e.getMessage() + ". Falling back to access token creds"); | |
110 | + deviceService.createAccessTokenCredentials(device, null); | |
111 | + } else { | |
112 | + importedEntityInfo.setRelatedError("Failed to update credentials: " + e.getMessage()); | |
113 | + } | |
114 | + } | |
108 | 115 | } else { |
109 | 116 | device = deviceService.saveDevice(device); |
110 | 117 | } | ... | ... |
... | ... | @@ -80,6 +80,10 @@ public abstract class AbstractBulkImportService<E extends BaseData<? extends Ent |
80 | 80 | |
81 | 81 | saveKvs(user, entity, entityData); |
82 | 82 | |
83 | + if (importedEntityInfo.getRelatedError() != null) { | |
84 | + throw new RuntimeException(importedEntityInfo.getRelatedError()); | |
85 | + } | |
86 | + | |
83 | 87 | if (importedEntityInfo.isUpdated()) { |
84 | 88 | result.setUpdated(result.getUpdated() + 1); |
85 | 89 | } else { | ... | ... |
... | ... | @@ -54,6 +54,8 @@ public interface DeviceService { |
54 | 54 | |
55 | 55 | Device saveDeviceWithCredentials(Device device, DeviceCredentials deviceCredentials); |
56 | 56 | |
57 | + void createAccessTokenCredentials(Device device, String accessToken); | |
58 | + | |
57 | 59 | Device assignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, CustomerId customerId); |
58 | 60 | |
59 | 61 | Device unassignDeviceFromCustomer(TenantId tenantId, DeviceId deviceId); | ... | ... |
... | ... | @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials; |
37 | 37 | import org.thingsboard.server.common.msg.EncryptionUtil; |
38 | 38 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
39 | 39 | import org.thingsboard.server.dao.exception.DataValidationException; |
40 | +import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; | |
40 | 41 | import org.thingsboard.server.dao.service.DataValidator; |
41 | 42 | |
42 | 43 | import static org.thingsboard.server.common.data.CacheConstants.DEVICE_CREDENTIALS_CACHE; |
... | ... | @@ -117,10 +118,10 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen |
117 | 118 | throw new IllegalArgumentException(); |
118 | 119 | } |
119 | 120 | } catch (IllegalArgumentException e) { |
120 | - throw new DataValidationException("Invalid credentials body for simple mqtt credentials!"); | |
121 | + throw new DeviceCredentialsValidationException("Invalid credentials body for simple mqtt credentials!"); | |
121 | 122 | } |
122 | 123 | if (StringUtils.isEmpty(mqttCredentials.getClientId()) && StringUtils.isEmpty(mqttCredentials.getUserName())) { |
123 | - throw new DataValidationException("Both mqtt client id and user name are empty!"); | |
124 | + throw new DeviceCredentialsValidationException("Both mqtt client id and user name are empty!"); | |
124 | 125 | } |
125 | 126 | if (StringUtils.isEmpty(mqttCredentials.getClientId())) { |
126 | 127 | deviceCredentials.setCredentialsId(mqttCredentials.getUserName()); |
... | ... | @@ -155,7 +156,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen |
155 | 156 | throw new IllegalArgumentException(); |
156 | 157 | } |
157 | 158 | } catch (IllegalArgumentException e) { |
158 | - throw new DataValidationException("Invalid credentials body for LwM2M credentials!"); | |
159 | + throw new DeviceCredentialsValidationException("Invalid credentials body for LwM2M credentials!"); | |
159 | 160 | } |
160 | 161 | |
161 | 162 | String credentialsId = null; |
... | ... | @@ -183,7 +184,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen |
183 | 184 | break; |
184 | 185 | } |
185 | 186 | if (credentialsId == null) { |
186 | - throw new DataValidationException("Invalid credentials body for LwM2M credentials!"); | |
187 | + throw new DeviceCredentialsValidationException("Invalid credentials body for LwM2M credentials!"); | |
187 | 188 | } |
188 | 189 | deviceCredentials.setCredentialsId(credentialsId); |
189 | 190 | } |
... | ... | @@ -201,38 +202,38 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen |
201 | 202 | @Override |
202 | 203 | protected void validateCreate(TenantId tenantId, DeviceCredentials deviceCredentials) { |
203 | 204 | if (deviceCredentialsDao.findByDeviceId(tenantId, deviceCredentials.getDeviceId().getId()) != null) { |
204 | - throw new DataValidationException("Credentials for this device are already specified!"); | |
205 | + throw new DeviceCredentialsValidationException("Credentials for this device are already specified!"); | |
205 | 206 | } |
206 | 207 | if (deviceCredentialsDao.findByCredentialsId(tenantId, deviceCredentials.getCredentialsId()) != null) { |
207 | - throw new DataValidationException("Device credentials are already assigned to another device!"); | |
208 | + throw new DeviceCredentialsValidationException("Device credentials are already assigned to another device!"); | |
208 | 209 | } |
209 | 210 | } |
210 | 211 | |
211 | 212 | @Override |
212 | 213 | protected void validateUpdate(TenantId tenantId, DeviceCredentials deviceCredentials) { |
213 | 214 | if (deviceCredentialsDao.findById(tenantId, deviceCredentials.getUuidId()) == null) { |
214 | - throw new DataValidationException("Unable to update non-existent device credentials!"); | |
215 | + throw new DeviceCredentialsValidationException("Unable to update non-existent device credentials!"); | |
215 | 216 | } |
216 | 217 | DeviceCredentials existingCredentials = deviceCredentialsDao.findByCredentialsId(tenantId, deviceCredentials.getCredentialsId()); |
217 | 218 | if (existingCredentials != null && !existingCredentials.getId().equals(deviceCredentials.getId())) { |
218 | - throw new DataValidationException("Device credentials are already assigned to another device!"); | |
219 | + throw new DeviceCredentialsValidationException("Device credentials are already assigned to another device!"); | |
219 | 220 | } |
220 | 221 | } |
221 | 222 | |
222 | 223 | @Override |
223 | 224 | protected void validateDataImpl(TenantId tenantId, DeviceCredentials deviceCredentials) { |
224 | 225 | if (deviceCredentials.getDeviceId() == null) { |
225 | - throw new DataValidationException("Device credentials should be assigned to device!"); | |
226 | + throw new DeviceCredentialsValidationException("Device credentials should be assigned to device!"); | |
226 | 227 | } |
227 | 228 | if (deviceCredentials.getCredentialsType() == null) { |
228 | - throw new DataValidationException("Device credentials type should be specified!"); | |
229 | + throw new DeviceCredentialsValidationException("Device credentials type should be specified!"); | |
229 | 230 | } |
230 | 231 | if (StringUtils.isEmpty(deviceCredentials.getCredentialsId())) { |
231 | - throw new DataValidationException("Device credentials id should be specified!"); | |
232 | + throw new DeviceCredentialsValidationException("Device credentials id should be specified!"); | |
232 | 233 | } |
233 | 234 | Device device = deviceService.findDeviceById(tenantId, deviceCredentials.getDeviceId()); |
234 | 235 | if (device == null) { |
235 | - throw new DataValidationException("Can't assign device credentials to non-existent device!"); | |
236 | + throw new DeviceCredentialsValidationException("Can't assign device credentials to non-existent device!"); | |
236 | 237 | } |
237 | 238 | } |
238 | 239 | }; | ... | ... |
... | ... | @@ -230,15 +230,20 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe |
230 | 230 | private Device doSaveDevice(Device device, String accessToken, boolean doValidate) { |
231 | 231 | Device savedDevice = this.saveDeviceWithoutCredentials(device, doValidate); |
232 | 232 | if (device.getId() == null) { |
233 | - DeviceCredentials deviceCredentials = new DeviceCredentials(); | |
234 | - deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId())); | |
235 | - deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); | |
236 | - deviceCredentials.setCredentialsId(!StringUtils.isEmpty(accessToken) ? accessToken : RandomStringUtils.randomAlphanumeric(20)); | |
237 | - deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials); | |
233 | + createAccessTokenCredentials(savedDevice, accessToken); | |
238 | 234 | } |
239 | 235 | return savedDevice; |
240 | 236 | } |
241 | 237 | |
238 | + @Override | |
239 | + public void createAccessTokenCredentials(Device device, String accessToken) { | |
240 | + DeviceCredentials deviceCredentials = new DeviceCredentials(); | |
241 | + deviceCredentials.setDeviceId(new DeviceId(device.getUuidId())); | |
242 | + deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); | |
243 | + deviceCredentials.setCredentialsId(!StringUtils.isEmpty(accessToken) ? accessToken : RandomStringUtils.randomAlphanumeric(20)); | |
244 | + deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials); | |
245 | + } | |
246 | + | |
242 | 247 | private Device saveDeviceWithoutCredentials(Device device, boolean doValidate) { |
243 | 248 | log.trace("Executing saveDevice [{}]", device); |
244 | 249 | if (doValidate) { | ... | ... |
dao/src/main/java/org/thingsboard/server/dao/exception/DeviceCredentialsValidationException.java
0 → 100644
1 | +/** | |
2 | + * Copyright © 2016-2021 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.dao.exception; | |
17 | + | |
18 | +public class DeviceCredentialsValidationException extends DataValidationException { | |
19 | + public DeviceCredentialsValidationException(String message) { | |
20 | + super(message); | |
21 | + } | |
22 | +} | ... | ... |