firmware tests and validation improvements

This commit is contained in:
YevhenBondarenko 2021-04-29 17:00:05 +03:00 committed by Andrew Shvayka
parent fd8dee0a9d
commit 4d4ca9b723
12 changed files with 145 additions and 33 deletions

View File

@ -63,6 +63,7 @@ CREATE TABLE IF NOT EXISTS firmware (
id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY,
created_time bigint NOT NULL,
tenant_id uuid NOT NULL,
device_profile_id uuid,
type varchar(32) NOT NULL,
title varchar(255) NOT NULL,
version varchar(255) NOT NULL,
@ -78,10 +79,12 @@ CREATE TABLE IF NOT EXISTS firmware (
);
ALTER TABLE device_profile
ADD COLUMN IF NOT EXISTS firmware_id uuid;
ADD COLUMN IF NOT EXISTS firmware_id uuid,
ADD COLUMN IF NOT EXISTS software_id uuid;
ALTER TABLE device
ADD COLUMN IF NOT EXISTS firmware_id uuid;
ADD COLUMN IF NOT EXISTS firmware_id uuid,
ADD COLUMN IF NOT EXISTS software_id uuid;
DO $$
BEGIN
@ -91,11 +94,23 @@ DO $$
FOREIGN KEY (firmware_id) REFERENCES firmware(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device_profile') THEN
ALTER TABLE device_profile
ADD CONSTRAINT fk_software_device_profile
FOREIGN KEY (firmware_id) REFERENCES firmware(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device') THEN
ALTER TABLE device
ADD CONSTRAINT fk_firmware_device
FOREIGN KEY (firmware_id) REFERENCES firmware(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device') THEN
ALTER TABLE device
ADD CONSTRAINT fk_software_device
FOREIGN KEY (firmware_id) REFERENCES firmware(id);
END IF;
END;
$$;

View File

@ -56,6 +56,7 @@ import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfilePr
import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
import org.thingsboard.server.common.data.firmware.FirmwareType;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
@ -405,9 +406,15 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
if (firmware == null) {
throw new DataValidationException("Can't assign non-existent firmware!");
}
if (!firmware.getType().equals(FirmwareType.FIRMWARE)) {
throw new DataValidationException("Can't assign firmware with type: " + firmware.getType());
}
if (firmware.getData() == null) {
throw new DataValidationException("Can't assign firmware with empty data!");
}
if (!firmware.getDeviceProfileId().equals(deviceProfile.getId())) {
throw new DataValidationException("Can't assign firmware with different deviceProfile!");
}
}
if (deviceProfile.getSoftwareId() != null) {
@ -415,9 +422,15 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
if (software == null) {
throw new DataValidationException("Can't assign non-existent software!");
}
if (!software.getType().equals(FirmwareType.SOFTWARE)) {
throw new DataValidationException("Can't assign software with type: " + software.getType());
}
if (software.getData() == null) {
throw new DataValidationException("Can't assign software with empty data!");
}
if (!software.getDeviceProfileId().equals(deviceProfile.getId())) {
throw new DataValidationException("Can't assign firmware with different deviceProfile!");
}
}
}

View File

@ -51,6 +51,7 @@ import org.thingsboard.server.common.data.device.data.DeviceData;
import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration;
import org.thingsboard.server.common.data.device.data.MqttDeviceTransportConfiguration;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.firmware.FirmwareType;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
@ -683,6 +684,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
if (firmware == null) {
throw new DataValidationException("Can't assign non-existent firmware!");
}
if (!firmware.getType().equals(FirmwareType.FIRMWARE)) {
throw new DataValidationException("Can't assign firmware with type: " + firmware.getType());
}
if (firmware.getData() == null) {
throw new DataValidationException("Can't assign firmware with empty data!");
}
@ -696,6 +700,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
if (software == null) {
throw new DataValidationException("Can't assign non-existent software!");
}
if (!software.getType().equals(FirmwareType.SOFTWARE)) {
throw new DataValidationException("Can't assign software with type: " + software.getType());
}
if (software.getData() == null) {
throw new DataValidationException("Can't assign software with empty data!");
}

View File

@ -191,6 +191,7 @@ public class BaseFirmwareService implements FirmwareService {
protected void validateUpdate(TenantId tenantId, FirmwareInfo firmware) {
FirmwareInfo firmwareOld = firmwareInfoDao.findById(tenantId, firmware.getUuidId());
validateUpdateDeviceProfile(firmware, firmwareOld);
BaseFirmwareService.validateUpdate(firmware, firmwareOld);
}
};
@ -247,6 +248,7 @@ public class BaseFirmwareService implements FirmwareService {
protected void validateUpdate(TenantId tenantId, Firmware firmware) {
Firmware firmwareOld = firmwareDao.findById(tenantId, firmware.getUuidId());
validateUpdateDeviceProfile(firmware, firmwareOld);
BaseFirmwareService.validateUpdate(firmware, firmwareOld);
if (firmwareOld.getData() != null && !firmwareOld.getData().equals(firmware.getData())) {
@ -255,11 +257,15 @@ public class BaseFirmwareService implements FirmwareService {
}
};
private static void validateUpdate(FirmwareInfo firmware, FirmwareInfo firmwareOld) {
if (!firmwareOld.getDeviceProfileId().equals(firmware.getDeviceProfileId())) {
throw new DataValidationException("Updating firmware deviceProfile is prohibited!");
private void validateUpdateDeviceProfile(FirmwareInfo firmware, FirmwareInfo firmwareOld) {
if (firmwareOld.getDeviceProfileId() != null && !firmwareOld.getDeviceProfileId().equals(firmware.getDeviceProfileId())) {
if (firmwareInfoDao.isFirmwareUsed(firmwareOld.getId(), firmware.getType(), firmwareOld.getDeviceProfileId())) {
throw new DataValidationException("Can`t update deviceProfileId because firmware is already in use!");
}
}
}
private static void validateUpdate(FirmwareInfo firmware, FirmwareInfo firmwareOld) {
if (!firmwareOld.getType().equals(firmware.getType())) {
throw new DataValidationException("Updating type is prohibited!");
}
@ -303,9 +309,7 @@ public class BaseFirmwareService implements FirmwareService {
}
}
if (firmwareInfo.getDeviceProfileId() == null) {
throw new DataValidationException("Firmware should be assigned to deviceProfile!");
} else {
if (firmwareInfo.getDeviceProfileId() != null) {
DeviceProfile deviceProfile = deviceProfileDao.findById(firmwareInfo.getTenantId(), firmwareInfo.getDeviceProfileId().getId());
if (deviceProfile == null) {
throw new DataValidationException("Firmware is referencing to non-existent device profile!");

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.dao.firmware;
import org.thingsboard.server.common.data.FirmwareInfo;
import org.thingsboard.server.common.data.firmware.FirmwareType;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.FirmwareId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
@ -31,4 +32,6 @@ public interface FirmwareInfoDao extends Dao<FirmwareInfo> {
PageData<FirmwareInfo> findFirmwareInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink);
boolean isFirmwareUsed(FirmwareId firmwareId, FirmwareType type, DeviceProfileId deviceProfileId);
}

View File

@ -32,9 +32,9 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Lob;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Lob;
import javax.persistence.Table;
import java.nio.ByteBuffer;
import java.util.UUID;
@ -110,7 +110,9 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex
this.createdTime = firmware.getCreatedTime();
this.setUuid(firmware.getUuidId());
this.tenantId = firmware.getTenantId().getId();
this.deviceProfileId = firmware.getDeviceProfileId().getId();
if (firmware.getDeviceProfileId() != null) {
this.deviceProfileId = firmware.getDeviceProfileId().getId();
}
this.type = firmware.getType();
this.title = firmware.getTitle();
this.version = firmware.getVersion();
@ -138,7 +140,9 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex
Firmware firmware = new Firmware(new FirmwareId(id));
firmware.setCreatedTime(createdTime);
firmware.setTenantId(new TenantId(tenantId));
firmware.setDeviceProfileId(new DeviceProfileId(deviceProfileId));
if (deviceProfileId != null) {
firmware.setDeviceProfileId(new DeviceProfileId(deviceProfileId));
}
firmware.setType(type);
firmware.setTitle(title);
firmware.setVersion(version);

View File

@ -109,7 +109,9 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
this.setUuid(firmware.getUuidId());
this.tenantId = firmware.getTenantId().getId();
this.type = firmware.getType();
this.deviceProfileId = firmware.getDeviceProfileId().getId();
if (firmware.getDeviceProfileId() != null) {
this.deviceProfileId = firmware.getDeviceProfileId().getId();
}
this.title = firmware.getTitle();
this.version = firmware.getVersion();
this.fileName = firmware.getFileName();
@ -154,7 +156,9 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
FirmwareInfo firmware = new FirmwareInfo(new FirmwareId(id));
firmware.setCreatedTime(createdTime);
firmware.setTenantId(new TenantId(tenantId));
firmware.setDeviceProfileId(new DeviceProfileId(deviceProfileId));
if (deviceProfileId != null) {
firmware.setDeviceProfileId(new DeviceProfileId(deviceProfileId));
}
firmware.setType(type);
firmware.setTitle(title);
firmware.setVersion(version);

View File

@ -48,4 +48,13 @@ public interface FirmwareInfoRepository extends CrudRepository<FirmwareInfoEntit
@Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.deviceProfileId, f.type, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE f.id = :id")
FirmwareInfoEntity findFirmwareInfoById(@Param("id") UUID id);
@Query(value = "SELECT exists(SELECT * " +
"FROM device_profile AS dp " +
"LEFT JOIN device AS d ON dp.id = d.device_profile_id " +
"WHERE dp.id = :deviceProfileId AND " +
"(('FIRMWARE' = :type AND (dp.firmware_id = :firmwareId OR d.firmware_id = :firmwareId)) " +
"OR ('SOFTWARE' = :type AND (dp.software_id = :firmwareId or d.software_id = :firmwareId))))", nativeQuery = true)
boolean isFirmwareUsed(@Param("firmwareId") UUID firmwareId, @Param("deviceProfileId") UUID deviceProfileId, @Param("type") String type);
}

View File

@ -22,6 +22,7 @@ import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.FirmwareInfo;
import org.thingsboard.server.common.data.firmware.FirmwareType;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.FirmwareId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
@ -85,4 +86,9 @@ public class JpaFirmwareInfoDao extends JpaAbstractSearchTextDao<FirmwareInfoEnt
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
}
@Override
public boolean isFirmwareUsed(FirmwareId firmwareId, FirmwareType type, DeviceProfileId deviceProfileId) {
return firmwareInfoRepository.isFirmwareUsed(firmwareId.getId(), deviceProfileId.getId(), type.name());
}
}

View File

@ -162,7 +162,7 @@ CREATE TABLE IF NOT EXISTS firmware (
id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY,
created_time bigint NOT NULL,
tenant_id uuid NOT NULL,
device_profile_id uuid NOT NULL,
device_profile_id uuid ,
type varchar(32) NOT NULL,
title varchar(255) NOT NULL,
version varchar(255) NOT NULL,

View File

@ -180,7 +180,7 @@ CREATE TABLE IF NOT EXISTS firmware (
id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY,
created_time bigint NOT NULL,
tenant_id uuid NOT NULL,
device_profile_id uuid NOT NULL,
device_profile_id uuid ,
type varchar(32) NOT NULL,
title varchar(255) NOT NULL,
version varchar(255) NOT NULL,

View File

@ -174,24 +174,6 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest {
firmwareService.saveFirmware(firmware);
}
@Test
public void testSaveFirmwareWithEmptyDeviceProfile() {
Firmware firmware = new Firmware();
firmware.setTenantId(tenantId);
firmware.setType(FIRMWARE);
firmware.setTitle(TITLE);
firmware.setVersion(VERSION);
firmware.setFileName(FILE_NAME);
firmware.setContentType(CONTENT_TYPE);
firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM);
firmware.setChecksum(CHECKSUM);
firmware.setData(DATA);
thrown.expect(DataValidationException.class);
thrown.expectMessage("Firmware should be assigned to deviceProfile!");
firmwareService.saveFirmware(firmware);
}
@Test
public void testSaveFirmwareWithEmptyType() {
Firmware firmware = new Firmware();
@ -424,6 +406,39 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest {
}
}
@Test
public void testUpdateDeviceProfileIdWithReferenceByDevice() {
Firmware firmware = new Firmware();
firmware.setTenantId(tenantId);
firmware.setDeviceProfileId(deviceProfileId);
firmware.setType(FIRMWARE);
firmware.setTitle(TITLE);
firmware.setVersion(VERSION);
firmware.setFileName(FILE_NAME);
firmware.setContentType(CONTENT_TYPE);
firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM);
firmware.setChecksum(CHECKSUM);
firmware.setData(DATA);
Firmware savedFirmware = firmwareService.saveFirmware(firmware);
Device device = new Device();
device.setTenantId(tenantId);
device.setName("My device");
device.setDeviceProfileId(deviceProfileId);
device.setFirmwareId(savedFirmware.getId());
Device savedDevice = deviceService.saveDevice(device);
try {
thrown.expect(DataValidationException.class);
thrown.expectMessage("Can`t update deviceProfileId because firmware is already in use!");
savedFirmware.setDeviceProfileId(null);
firmwareService.saveFirmware(savedFirmware);
} finally {
deviceService.deleteDevice(tenantId, savedDevice.getId());
firmwareService.deleteFirmware(tenantId, savedFirmware.getId());
}
}
@Test
public void testDeleteFirmwareWithReferenceByDeviceProfile() {
DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Test Device Profile");
@ -455,6 +470,38 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest {
}
}
@Test
public void testUpdateDeviceProfileIdWithReferenceByDeviceProfile() {
DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Test Device Profile");
DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile);
Firmware firmware = new Firmware();
firmware.setTenantId(tenantId);
firmware.setDeviceProfileId(savedDeviceProfile.getId());
firmware.setType(FIRMWARE);
firmware.setTitle(TITLE);
firmware.setVersion(VERSION);
firmware.setFileName(FILE_NAME);
firmware.setContentType(CONTENT_TYPE);
firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM);
firmware.setChecksum(CHECKSUM);
firmware.setData(DATA);
Firmware savedFirmware = firmwareService.saveFirmware(firmware);
savedDeviceProfile.setFirmwareId(savedFirmware.getId());
deviceProfileService.saveDeviceProfile(savedDeviceProfile);
try {
thrown.expect(DataValidationException.class);
thrown.expectMessage("Can`t update deviceProfileId because firmware is already in use!");
savedFirmware.setDeviceProfileId(null);
firmwareService.saveFirmware(savedFirmware);
} finally {
deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId());
firmwareService.deleteFirmware(tenantId, savedFirmware.getId());
}
}
@Test
public void testFindFirmwareById() {
Firmware firmware = new Firmware();