Browse Source

Bulk import device credentials handling refactoring

pull/5023/head
Viacheslav Klimov 5 years ago
parent
commit
3505810280
  1. 19
      application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java
  2. 4
      application/src/main/java/org/thingsboard/server/service/importing/AbstractBulkImportService.java
  3. 1
      application/src/main/java/org/thingsboard/server/service/importing/ImportedEntityInfo.java
  4. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
  5. 1
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java
  6. 25
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsServiceImpl.java
  7. 15
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
  8. 22
      dao/src/main/java/org/thingsboard/server/dao/exception/DeviceCredentialsValidationException.java

19
application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java

@ -18,8 +18,6 @@ package org.thingsboard.server.service.device;
import com.fasterxml.jackson.databind.node.BooleanNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import lombok.SneakyThrows;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
@ -39,10 +37,10 @@ import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTrans
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
import org.thingsboard.server.dao.device.DeviceCredentialsService;
import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.action.EntityActionService;
@ -63,8 +61,6 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.thingsboard.server.dao.service.Validator.validateId;
@Service
@TbCoreComponent
public class DeviceBulkImportService extends AbstractBulkImportService<Device> {
@ -104,7 +100,18 @@ public class DeviceBulkImportService extends AbstractBulkImportService<Device> {
if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.LWM2M_CREDENTIALS) {
setUpLwM2mDeviceProfile(user.getTenantId(), device);
}
device = deviceService.saveDeviceWithCredentials(device, deviceCredentials);
try {
device = deviceService.saveDeviceWithCredentials(device, deviceCredentials);
} catch (DeviceCredentialsValidationException e) {
if (deviceCredentials.getId() == null) {
device.setId(deviceCredentials.getDeviceId());
importedEntityInfo.setRelatedError("Failed to create " + deviceCredentials.getCredentialsType() + " credentials: "
+ e.getMessage() + ". Falling back to access token creds");
deviceService.createAccessTokenCredentials(device, null);
} else {
importedEntityInfo.setRelatedError("Failed to update credentials: " + e.getMessage());
}
}
} else {
device = deviceService.saveDevice(device);
}

4
application/src/main/java/org/thingsboard/server/service/importing/AbstractBulkImportService.java

@ -80,6 +80,10 @@ public abstract class AbstractBulkImportService<E extends BaseData<? extends Ent
saveKvs(user, entity, entityData);
if (importedEntityInfo.getRelatedError() != null) {
throw new RuntimeException(importedEntityInfo.getRelatedError());
}
if (importedEntityInfo.isUpdated()) {
result.setUpdated(result.getUpdated() + 1);
} else {

1
application/src/main/java/org/thingsboard/server/service/importing/ImportedEntityInfo.java

@ -22,4 +22,5 @@ public class ImportedEntityInfo<E> {
private E entity;
private boolean isUpdated;
private E oldEntity;
private String relatedError;
}

2
common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java

@ -54,6 +54,8 @@ public interface DeviceService {
Device saveDeviceWithCredentials(Device device, DeviceCredentials deviceCredentials);
void createAccessTokenCredentials(Device device, String accessToken);
Device assignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, CustomerId customerId);
Device unassignDeviceFromCustomer(TenantId tenantId, DeviceId deviceId);

1
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.common.transport.adaptor;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;

25
dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsServiceImpl.java

@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.msg.EncryptionUtil;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException;
import org.thingsboard.server.dao.service.DataValidator;
import static org.thingsboard.server.common.data.CacheConstants.DEVICE_CREDENTIALS_CACHE;
@ -117,10 +118,10 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
throw new IllegalArgumentException();
}
} catch (IllegalArgumentException e) {
throw new DataValidationException("Invalid credentials body for simple mqtt credentials!");
throw new DeviceCredentialsValidationException("Invalid credentials body for simple mqtt credentials!");
}
if (StringUtils.isEmpty(mqttCredentials.getClientId()) && StringUtils.isEmpty(mqttCredentials.getUserName())) {
throw new DataValidationException("Both mqtt client id and user name are empty!");
throw new DeviceCredentialsValidationException("Both mqtt client id and user name are empty!");
}
if (StringUtils.isEmpty(mqttCredentials.getClientId())) {
deviceCredentials.setCredentialsId(mqttCredentials.getUserName());
@ -155,7 +156,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
throw new IllegalArgumentException();
}
} catch (IllegalArgumentException e) {
throw new DataValidationException("Invalid credentials body for LwM2M credentials!");
throw new DeviceCredentialsValidationException("Invalid credentials body for LwM2M credentials!");
}
String credentialsId = null;
@ -183,7 +184,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
break;
}
if (credentialsId == null) {
throw new DataValidationException("Invalid credentials body for LwM2M credentials!");
throw new DeviceCredentialsValidationException("Invalid credentials body for LwM2M credentials!");
}
deviceCredentials.setCredentialsId(credentialsId);
}
@ -201,38 +202,38 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
@Override
protected void validateCreate(TenantId tenantId, DeviceCredentials deviceCredentials) {
if (deviceCredentialsDao.findByDeviceId(tenantId, deviceCredentials.getDeviceId().getId()) != null) {
throw new DataValidationException("Credentials for this device are already specified!");
throw new DeviceCredentialsValidationException("Credentials for this device are already specified!");
}
if (deviceCredentialsDao.findByCredentialsId(tenantId, deviceCredentials.getCredentialsId()) != null) {
throw new DataValidationException("Device credentials are already assigned to another device!");
throw new DeviceCredentialsValidationException("Device credentials are already assigned to another device!");
}
}
@Override
protected void validateUpdate(TenantId tenantId, DeviceCredentials deviceCredentials) {
if (deviceCredentialsDao.findById(tenantId, deviceCredentials.getUuidId()) == null) {
throw new DataValidationException("Unable to update non-existent device credentials!");
throw new DeviceCredentialsValidationException("Unable to update non-existent device credentials!");
}
DeviceCredentials existingCredentials = deviceCredentialsDao.findByCredentialsId(tenantId, deviceCredentials.getCredentialsId());
if (existingCredentials != null && !existingCredentials.getId().equals(deviceCredentials.getId())) {
throw new DataValidationException("Device credentials are already assigned to another device!");
throw new DeviceCredentialsValidationException("Device credentials are already assigned to another device!");
}
}
@Override
protected void validateDataImpl(TenantId tenantId, DeviceCredentials deviceCredentials) {
if (deviceCredentials.getDeviceId() == null) {
throw new DataValidationException("Device credentials should be assigned to device!");
throw new DeviceCredentialsValidationException("Device credentials should be assigned to device!");
}
if (deviceCredentials.getCredentialsType() == null) {
throw new DataValidationException("Device credentials type should be specified!");
throw new DeviceCredentialsValidationException("Device credentials type should be specified!");
}
if (StringUtils.isEmpty(deviceCredentials.getCredentialsId())) {
throw new DataValidationException("Device credentials id should be specified!");
throw new DeviceCredentialsValidationException("Device credentials id should be specified!");
}
Device device = deviceService.findDeviceById(tenantId, deviceCredentials.getDeviceId());
if (device == null) {
throw new DataValidationException("Can't assign device credentials to non-existent device!");
throw new DeviceCredentialsValidationException("Can't assign device credentials to non-existent device!");
}
}
};

15
dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java

@ -230,15 +230,20 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
private Device doSaveDevice(Device device, String accessToken, boolean doValidate) {
Device savedDevice = this.saveDeviceWithoutCredentials(device, doValidate);
if (device.getId() == null) {
DeviceCredentials deviceCredentials = new DeviceCredentials();
deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId()));
deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN);
deviceCredentials.setCredentialsId(!StringUtils.isEmpty(accessToken) ? accessToken : RandomStringUtils.randomAlphanumeric(20));
deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials);
createAccessTokenCredentials(savedDevice, accessToken);
}
return savedDevice;
}
@Override
public void createAccessTokenCredentials(Device device, String accessToken) {
DeviceCredentials deviceCredentials = new DeviceCredentials();
deviceCredentials.setDeviceId(new DeviceId(device.getUuidId()));
deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN);
deviceCredentials.setCredentialsId(!StringUtils.isEmpty(accessToken) ? accessToken : RandomStringUtils.randomAlphanumeric(20));
deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials);
}
private Device saveDeviceWithoutCredentials(Device device, boolean doValidate) {
log.trace("Executing saveDevice [{}]", device);
if (doValidate) {

22
dao/src/main/java/org/thingsboard/server/dao/exception/DeviceCredentialsValidationException.java

@ -0,0 +1,22 @@
/**
* Copyright © 2016-2021 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.exception;
public class DeviceCredentialsValidationException extends DataValidationException {
public DeviceCredentialsValidationException(String message) {
super(message);
}
}
Loading…
Cancel
Save