diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java index 3095de6bb9..2d2c7bf21c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java @@ -327,12 +327,20 @@ public class DeviceProfileDataValidator extends AbstractHasOtaPackageValidator 65534)) { - throw new DeviceCredentialsValidationException("LwM2M Server ShortServerId must not be less than 1 and more than 65534!"); - } - if (serverConfig.isBootstrapServerIs() && (serverConfig.getShortServerId() < 0 || serverConfig.getShortServerId() > 65535)) { - throw new DeviceCredentialsValidationException("Bootstrap Server ShortServerId must not be less than 0 and more than 65535!"); + if (serverConfig.getShortServerId() != null) { + if (serverConfig.isBootstrapServerIs()){ + if(serverConfig.getShortServerId() < 0 || serverConfig.getShortServerId() > 65535){ + throw new DeviceCredentialsValidationException("Bootstrap Server ShortServerId must be in range [0 - 65535]!"); + } + } else { + if (serverConfig.getShortServerId() < 1 || serverConfig.getShortServerId() > 65534) { + throw new DeviceCredentialsValidationException("LwM2M Server ShortServerId must be in range [1 - 65534]!"); + } + } + } else { + String serverName = serverConfig.isBootstrapServerIs() ? "Bootstrap Server" : "LwM2M Server"; + throw new DeviceCredentialsValidationException(serverName + " ShortServerId must not be null!"); } String server = serverConfig.isBootstrapServerIs() ? "Bootstrap Server" : "LwM2M Server"; diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java index ac0fa2cfe1..2da8a7ff45 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java @@ -20,11 +20,18 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.OtherConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryMappingConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.AbstractLwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.NoSecLwM2MBootstrapServerCredential; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.DeviceDao; @@ -34,6 +41,8 @@ import org.thingsboard.server.dao.queue.QueueService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.tenant.TenantService; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import static org.mockito.BDDMockito.willReturn; @@ -42,6 +51,34 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = DeviceProfileDataValidator.class) class DeviceProfileDataValidatorTest { + private static final String OBSERVE_ATTRIBUTES_WITHOUT_PARAMS = + " {\n" + + " \"keyName\": {},\n" + + " \"observe\": [],\n" + + " \"attribute\": [],\n" + + " \"telemetry\": [],\n" + + " \"attributeLwm2m\": {}\n" + + " }"; + + public static final String CLIENT_LWM2M_SETTINGS = + " {\n" + + " \"edrxCycle\": null,\n" + + " \"powerMode\": \"DRX\",\n" + + " \"fwUpdateResource\": null,\n" + + " \"fwUpdateStrategy\": 1,\n" + + " \"psmActivityTimer\": null,\n" + + " \"swUpdateResource\": null,\n" + + " \"swUpdateStrategy\": 1,\n" + + " \"pagingTransmissionWindow\": null,\n" + + " \"clientOnlyObserveAfterConnect\": 1\n" + + " }"; + + private static final String host = "localhost"; + private static final String hostBs = "localhost"; + + private static final int port = 5685; + private static final int portBs = 5687; + @MockBean DeviceProfileDao deviceProfileDao; @MockBean @@ -79,5 +116,56 @@ class DeviceProfileDataValidatorTest { validator.validateDataImpl(tenantId, deviceProfile); verify(validator).validateString("Device profile name", deviceProfile.getName()); } + @Test + void testValidateDeviceProfile_Lwm2mBootstrap_ShortServerId_Ok() { + Integer shortServerId = 123; + Integer shortServerIdBs = 0; + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = + getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsNoSec(shortServerId, shortServerIdBs)); + DeviceProfile deviceProfile = getDeviceProfile(transportConfiguration); + + validator.validateDataImpl(tenantId, deviceProfile); + verify(validator).validateString("Device profile name", deviceProfile.getName()); + } + + private DeviceProfile getDeviceProfile(Lwm2mDeviceProfileTransportConfiguration transportConfiguration) { + DeviceProfile deviceProfile = new DeviceProfile(); + deviceProfile.setName("default"); + deviceProfile.setType(DeviceProfileType.DEFAULT); + deviceProfile.setTransportType(DeviceTransportType.LWM2M); + DeviceProfileData data = new DeviceProfileData(); + data.setTransportConfiguration(transportConfiguration); + deviceProfile.setProfileData(data); + deviceProfile.setTenantId(tenantId); + return deviceProfile; + } + + private Lwm2mDeviceProfileTransportConfiguration getTransportConfiguration(String observeAttr, List bootstrapServerCredentials) { + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = new Lwm2mDeviceProfileTransportConfiguration(); + TelemetryMappingConfiguration observeAttrConfiguration = JacksonUtil.fromString(observeAttr, TelemetryMappingConfiguration.class); + OtherConfiguration clientLwM2mSettings = JacksonUtil.fromString(CLIENT_LWM2M_SETTINGS, OtherConfiguration.class); + transportConfiguration.setBootstrapServerUpdateEnable(true); + transportConfiguration.setObserveAttr(observeAttrConfiguration); + transportConfiguration.setClientLwM2mSettings(clientLwM2mSettings); + transportConfiguration.setBootstrap(bootstrapServerCredentials); + return transportConfiguration; + } + + private List getBootstrapServerCredentialsNoSec(Integer shortServerId, Integer shortServerIdBs){ + List bootstrap = new ArrayList<>(); + bootstrap.add(getBootstrapServerCredentialNoSec(false, shortServerId, shortServerIdBs)); + bootstrap.add(getBootstrapServerCredentialNoSec(true, shortServerId, shortServerIdBs)); + return bootstrap; + } + + private AbstractLwM2MBootstrapServerCredential getBootstrapServerCredentialNoSec(boolean isBootstrap, Integer shortServerId, Integer shortServerIdBs) { + AbstractLwM2MBootstrapServerCredential bootstrapServerCredential = new NoSecLwM2MBootstrapServerCredential(); + bootstrapServerCredential.setServerPublicKey(""); + bootstrapServerCredential.setShortServerId(isBootstrap ? shortServerIdBs : shortServerId); + bootstrapServerCredential.setBootstrapServerIs(isBootstrap); + bootstrapServerCredential.setHost(isBootstrap ? hostBs : host); + bootstrapServerCredential.setPort(isBootstrap ? portBs : port); + return bootstrapServerCredential; + } }