diff --git a/application/src/main/data/upgrade/3.2.2/schema_update.sql b/application/src/main/data/upgrade/3.2.2/schema_update.sql index 450160b104..d724ab6152 100644 --- a/application/src/main/data/upgrade/3.2.2/schema_update.sql +++ b/application/src/main/data/upgrade/3.2.2/schema_update.sql @@ -32,10 +32,15 @@ CREATE TABLE IF NOT EXISTS firmware ( created_time bigint NOT NULL, tenant_id uuid NOT NULL, title varchar(255) NOT NULL, + version varchar(255) NOT NULL, + file_name varchar(255), + content_type varchar(255), + checksum_algorithm varchar(32), + checksum varchar(1020), + data binary, + additional_info varchar, search_text varchar(255), - file_name varchar(255) NOT NULL, - content_type varchar(255) NOT NULL, - data bytea + CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) ); ALTER TABLE device_profile diff --git a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java b/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java index 7736abba11..4d53be8c07 100644 --- a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java +++ b/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java @@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; +import org.thingsboard.server.service.security.permission.Resource; import java.nio.ByteBuffer; @@ -97,14 +98,36 @@ public class FirmwareController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/firmware", method = RequestMethod.POST) @ResponseBody - public Firmware saveFirmware(@RequestParam("title") String title, - @RequestBody MultipartFile firmwareFile) throws ThingsboardException { - checkParameter("title", title); + public FirmwareInfo saveFirmwareInfo(@RequestParam("title") FirmwareInfo firmwareInfo) throws ThingsboardException { + checkEntity(firmwareInfo.getId(), firmwareInfo, Resource.FIRMWARE); try { - checkNotNull(firmwareFile); - Firmware firmware = new Firmware(); + return firmwareService.saveFirmwareInfo(firmwareInfo); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.POST) + @ResponseBody + public Firmware saveFirmwareData(@PathVariable(FIRMWARE_ID) String strFirmwareId, + @RequestParam String checksum, + @RequestParam String checksumAlgorithm, + @RequestBody MultipartFile firmwareFile) throws ThingsboardException { + checkParameter(FIRMWARE_ID, strFirmwareId); + checkParameter("checksum", checksum); + try { + FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId)); + FirmwareInfo info = checkFirmwareInfoId(firmwareId, Operation.READ); + + Firmware firmware = new Firmware(firmwareId); + firmware.setCreatedTime(info.getCreatedTime()); firmware.setTenantId(getTenantId()); - firmware.setTitle(title); + firmware.setVersion(info.getVersion()); + firmware.setAdditionalInfo(info.getAdditionalInfo()); + + firmware.setChecksumAlgorithm(checksumAlgorithm); + firmware.setChecksum(checksum); firmware.setFileName(firmwareFile.getOriginalFilename()); firmware.setContentType(firmwareFile.getContentType()); firmware.setData(ByteBuffer.wrap(firmwareFile.getBytes())); diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 4a9a110fab..a22a22d240 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -230,7 +230,6 @@ public class ThingsboardInstallService { systemDataLoaderService.createAdminSettings(); systemDataLoaderService.loadSystemWidgets(); systemDataLoaderService.createOAuth2Templates(); - systemDataLoaderService.loadSystemLwm2mResources(); // systemDataLoaderService.loadSystemPlugins(); // systemDataLoaderService.loadSystemRules(); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java index bff1a6f806..140cb14f1a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java @@ -22,9 +22,10 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; - public interface FirmwareService { + FirmwareInfo saveFirmwareInfo(FirmwareInfo firmwareInfo); + Firmware saveFirmware(Firmware firmware); Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java b/common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java index b4155a578a..6b8f48c5e8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java @@ -27,6 +27,14 @@ public class Firmware extends FirmwareInfo { private static final long serialVersionUID = 3091601761339422546L; + private String fileName; + + private String contentType; + + private String checksumAlgorithm; + + private String checksum; + private transient ByteBuffer data; public Firmware() { @@ -39,6 +47,10 @@ public class Firmware extends FirmwareInfo { public Firmware(Firmware firmware) { super(firmware); + this.fileName = firmware.getFileName(); + this.contentType = firmware.getContentType(); this.data = firmware.getData(); + this.checksumAlgorithm = firmware.getChecksumAlgorithm(); + this.checksum = firmware.getChecksum(); } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java index b950268649..d2fa921d19 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java @@ -24,14 +24,13 @@ import org.thingsboard.server.common.data.id.TenantId; @Slf4j @Data @EqualsAndHashCode(callSuper = true) -public class FirmwareInfo extends SearchTextBased implements HasTenantId { +public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo implements HasTenantId { private static final long serialVersionUID = 3168391583570815419L; private TenantId tenantId; private String title; - private String fileName; - private String contentType; + private String version; public FirmwareInfo() { super(); @@ -45,8 +44,7 @@ public class FirmwareInfo extends SearchTextBased implements HasTena super(firmwareInfo); this.tenantId = firmwareInfo.getTenantId(); this.title = firmwareInfo.getTitle(); - this.fileName = firmwareInfo.getFileName(); - this.contentType = firmwareInfo.getContentType(); + this.version = firmwareInfo.getVersion(); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index bff523d956..9f85dd1cb5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.DeviceProfileInfo; import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; +import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.CoapDeviceTypeConfiguration; @@ -59,6 +60,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.exception.DataValidationException; +import org.thingsboard.server.dao.firmware.FirmwareService; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.service.Validator; @@ -107,6 +109,9 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D @Autowired private CacheManager cacheManager; + @Autowired + private FirmwareService firmwareService; + private final Lock findOrCreateLock = new ReentrantLock(); @Cacheable(cacheNames = DEVICE_PROFILE_CACHE, key = "{#deviceProfileId.id}") @@ -389,6 +394,15 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D } } + if (deviceProfile.getFirmwareId() != null) { + Firmware firmware = firmwareService.findFirmwareById(tenantId, deviceProfile.getFirmwareId()); + if (firmware == null) { + throw new DataValidationException("Can't assign non-existent firmware!"); + } + if (firmware.getData() == null) { + throw new DataValidationException("Can't assign firmware with empty data!"); + } + } } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index 7ce2e650d2..d1d76b1e95 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -39,6 +39,7 @@ import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.device.DeviceSearchQuery; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; @@ -68,6 +69,7 @@ import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.dao.exception.DataValidationException; +import org.thingsboard.server.dao.firmware.FirmwareService; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; @@ -128,6 +130,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Lazy private TbTenantProfileCache tenantProfileCache; + @Autowired + private FirmwareService firmwareService; + @Override public DeviceInfo findDeviceInfoById(TenantId tenantId, DeviceId deviceId) { log.trace("Executing findDeviceInfoById [{}]", deviceId); @@ -598,6 +603,16 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe throw new DataValidationException("Can't assign device to customer from different tenant!"); } } + + if (device.getFirmwareId() != null) { + Firmware firmware = firmwareService.findFirmwareById(tenantId, device.getFirmwareId()); + if (firmware == null) { + throw new DataValidationException("Can't assign non-existent firmware!"); + } + if (firmware.getData() == null) { + throw new DataValidationException("Can't assign firmware with empty data!"); + } + } } }; diff --git a/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java b/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java index bf1c4f10e6..35d4a3c39c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.dao.firmware; +import com.google.common.hash.HashFunction; +import com.google.common.hash.Hashing; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.hibernate.exception.ConstraintViolationException; @@ -53,11 +55,36 @@ public class BaseFirmwareService implements FirmwareService { this.firmwareInfoDao = firmwareInfoDao; } + @Override + public FirmwareInfo saveFirmwareInfo(FirmwareInfo firmwareInfo) { + log.trace("Executing saveFirmwareInfo [{}]", firmwareInfo); + firmwareInfoValidator.validate(firmwareInfo, FirmwareInfo::getTenantId); + try { + return firmwareInfoDao.save(firmwareInfo.getTenantId(), firmwareInfo); + } catch (Exception t) { + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("firmware_tenant_title_version_unq_key")) { + throw new DataValidationException("Firmware with such title and version already exists!"); + } else { + throw t; + } + } + } + @Override public Firmware saveFirmware(Firmware firmware) { log.trace("Executing saveFirmware [{}]", firmware); - firmwareValidator.validate(firmware, Firmware::getTenantId); - return firmwareDao.save(firmware.getTenantId(), firmware); + firmwareValidator.validate(firmware, FirmwareInfo::getTenantId); + try { + return firmwareDao.save(firmware.getTenantId(), firmware); + } catch (Exception t) { + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("firmware_tenant_title_version_unq_key")) { + throw new DataValidationException("Firmware with such title and version already exists!"); + } else { + throw t; + } + } } @Override @@ -107,6 +134,42 @@ public class BaseFirmwareService implements FirmwareService { tenantFirmwareRemover.removeEntities(tenantId, tenantId); } + private DataValidator firmwareInfoValidator = new DataValidator<>() { + + @Override + protected void validateDataImpl(TenantId tenantId, FirmwareInfo firmware) { + if (firmware.getTenantId() == null) { + throw new DataValidationException("Firmware should be assigned to tenant!"); + } else { + Tenant tenant = tenantDao.findById(firmware.getTenantId(), firmware.getTenantId().getId()); + if (tenant == null) { + throw new DataValidationException("Firmware is referencing to non-existent tenant!"); + } + } + + if (StringUtils.isEmpty(firmware.getTitle())) { + throw new DataValidationException("Firmware title should be specified!"); + } + + if (StringUtils.isEmpty(firmware.getVersion())) { + throw new DataValidationException("Firmware version should be specified!"); + } + } + + @Override + protected void validateUpdate(TenantId tenantId, FirmwareInfo firmware) { + FirmwareInfo firmwareOld = firmwareInfoDao.findById(tenantId, firmware.getUuidId()); + + if (!firmwareOld.getTitle().equals(firmware.getTitle())) { + throw new DataValidationException("Updating firmware title is prohibited!"); + } + + if (!firmwareOld.getVersion().equals(firmware.getVersion())) { + throw new DataValidationException("Updating firmware version is prohibited!"); + } + } + }; + private DataValidator firmwareValidator = new DataValidator<>() { @Override @@ -123,22 +186,91 @@ public class BaseFirmwareService implements FirmwareService { if (StringUtils.isEmpty(firmware.getTitle())) { throw new DataValidationException("Firmware title should be specified!"); } + + if (StringUtils.isEmpty(firmware.getVersion())) { + throw new DataValidationException("Firmware version should be specified!"); + } + if (StringUtils.isEmpty(firmware.getFileName())) { throw new DataValidationException("Firmware file name should be specified!"); } + if (StringUtils.isEmpty(firmware.getContentType())) { throw new DataValidationException("Firmware content type should be specified!"); } + + if (StringUtils.isEmpty(firmware.getChecksum())) { + throw new DataValidationException("Firmware checksum should be specified!"); + } + ByteBuffer data = firmware.getData(); if (data == null || !data.hasArray() || data.array().length == 0) { throw new DataValidationException("Firmware data should be specified!"); } + + if (firmware.getChecksumAlgorithm() != null) { + HashFunction hashFunction; + switch (firmware.getChecksumAlgorithm()) { + case "sha256": + hashFunction = Hashing.sha256(); + break; + case "md5": + hashFunction = Hashing.md5(); + break; + case "crc32": + hashFunction = Hashing.crc32(); + break; + default: + throw new DataValidationException("Unknown checksum algorithm!"); + } + + String currentChecksum = hashFunction.hashBytes(data.array()).toString(); + ; + + if (!currentChecksum.equals(firmware.getChecksum())) { + throw new DataValidationException("Wrong firmware file!"); + } + } + } + + @Override + protected void validateUpdate(TenantId tenantId, Firmware firmware) { + Firmware firmwareOld = firmwareDao.findById(tenantId, firmware.getUuidId()); + + if (!firmwareOld.getTitle().equals(firmware.getTitle())) { + throw new DataValidationException("Updating firmware title is prohibited!"); + } + + if (!firmwareOld.getVersion().equals(firmware.getVersion())) { + throw new DataValidationException("Updating firmware version is prohibited!"); + } + + if (firmwareOld.getFileName() != null && !firmwareOld.getFileName().equals(firmware.getFileName())) { + throw new DataValidationException("Updating firmware file name is prohibited!"); + } + + if (firmwareOld.getContentType() != null && !firmwareOld.getContentType().equals(firmware.getContentType())) { + throw new DataValidationException("Updating firmware content type is prohibited!"); + } + + if (firmwareOld.getChecksumAlgorithm() != null && !firmwareOld.getChecksumAlgorithm().equals(firmware.getChecksumAlgorithm())) { + throw new DataValidationException("Updating firmware content type is prohibited!"); + } + + if (firmwareOld.getChecksum() != null && !firmwareOld.getChecksum().equals(firmware.getChecksum())) { + throw new DataValidationException("Updating firmware content type is prohibited!"); + } + + if (firmwareOld.getData() != null && !firmwareOld.getData().equals(firmware.getData())) { + throw new DataValidationException("Updating firmware data is prohibited!"); + } } }; private PaginatedRemover tenantFirmwareRemover = new PaginatedRemover<>() { + @Override protected PageData findEntities(TenantId tenantId, TenantId id, PageLink pageLink) { return firmwareInfoDao.findFirmwareInfoByTenantId(id, pageLink); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 05af88eeb9..67a4ec9f77 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -475,9 +475,14 @@ public class ModelConstants { public static final String FIRMWARE_TABLE_NAME = "firmware"; public static final String FIRMWARE_TENANT_ID_COLUMN = TENANT_ID_COLUMN; public static final String FIRMWARE_TITLE_COLUMN = TITLE_PROPERTY; + public static final String FIRMWARE_VERSION_COLUMN = "version"; public static final String FIRMWARE_FILE_NAME_COLUMN = "file_name"; public static final String FIRMWARE_CONTENT_TYPE_COLUMN = "content_type"; + public static final String FIRMWARE_CHECKSUM_ALGORITHM_COLUMN = "checksum_algorithm"; + public static final String FIRMWARE_CHECKSUM_COLUMN = "checksum"; public static final String FIRMWARE_DATA_COLUMN = "data"; + public static final String FIRMWARE_ADDITIONAL_INFO_COLUMN = ADDITIONAL_INFO_PROPERTY; + /** * Cassandra attributes and timeseries constants. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java index 1823c5eae5..20d1115c52 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java @@ -15,13 +15,18 @@ */ package org.thingsboard.server.dao.model.sql; +import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; import lombok.EqualsAndHashCode; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.id.FirmwareId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; +import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; +import org.thingsboard.server.dao.util.mapping.JsonStringType; import javax.persistence.Column; import javax.persistence.Entity; @@ -29,17 +34,21 @@ import javax.persistence.Table; import java.nio.ByteBuffer; import java.util.UUID; +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ALGORITHM_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; @Data @EqualsAndHashCode(callSuper = true) @Entity +@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = FIRMWARE_TABLE_NAME) public class FirmwareEntity extends BaseSqlEntity implements SearchTextEntity { @@ -49,15 +58,28 @@ public class FirmwareEntity extends BaseSqlEntity implements SearchTex @Column(name = FIRMWARE_TITLE_COLUMN) private String title; + @Column(name = FIRMWARE_VERSION_COLUMN) + private String version; + @Column(name = FIRMWARE_FILE_NAME_COLUMN) private String fileName; @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN) private String contentType; + @Column(name = FIRMWARE_CHECKSUM_ALGORITHM_COLUMN) + private String checksumAlgorithm; + + @Column(name = FIRMWARE_CHECKSUM_COLUMN) + private String checksum; + @Column(name = FIRMWARE_DATA_COLUMN, columnDefinition = "BINARY") private byte[] data; + @Type(type = "json") + @Column(name = ModelConstants.FIRMWARE_ADDITIONAL_INFO_COLUMN) + private JsonNode additionalInfo; + @Column(name = SEARCH_TEXT_PROPERTY) private String searchText; @@ -70,9 +92,13 @@ public class FirmwareEntity extends BaseSqlEntity implements SearchTex this.setUuid(firmware.getUuidId()); this.tenantId = firmware.getTenantId().getId(); this.title = firmware.getTitle(); + this.version = firmware.getVersion(); this.fileName = firmware.getFileName(); this.contentType = firmware.getContentType(); + this.checksumAlgorithm = firmware.getChecksumAlgorithm(); + this.checksum = firmware.getChecksum(); this.data = firmware.getData().array(); + this.additionalInfo = firmware.getAdditionalInfo(); } @Override @@ -91,9 +117,15 @@ public class FirmwareEntity extends BaseSqlEntity implements SearchTex firmware.setCreatedTime(createdTime); firmware.setTenantId(new TenantId(tenantId)); firmware.setTitle(title); + firmware.setVersion(version); firmware.setFileName(fileName); firmware.setContentType(contentType); - firmware.setData(ByteBuffer.wrap(data)); + firmware.setChecksumAlgorithm(checksumAlgorithm); + firmware.setChecksum(checksum); + if (data != null) { + firmware.setData(ByteBuffer.wrap(data)); + } + firmware.setAdditionalInfo(additionalInfo); return firmware; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java index ec7ee7206f..f0c19c38c8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java @@ -15,29 +15,34 @@ */ package org.thingsboard.server.dao.model.sql; +import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; import lombok.EqualsAndHashCode; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.FirmwareInfo; import org.thingsboard.server.common.data.id.FirmwareId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; +import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; +import org.thingsboard.server.dao.util.mapping.JsonStringType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; import java.util.UUID; -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN; -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; @Data @EqualsAndHashCode(callSuper = true) @Entity +@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = FIRMWARE_TABLE_NAME) public class FirmwareInfoEntity extends BaseSqlEntity implements SearchTextEntity { @@ -47,11 +52,12 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S @Column(name = FIRMWARE_TITLE_COLUMN) private String title; - @Column(name = FIRMWARE_FILE_NAME_COLUMN) - private String fileName; + @Column(name = FIRMWARE_VERSION_COLUMN) + private String version; - @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN) - private String contentType; + @Type(type = "json") + @Column(name = ModelConstants.FIRMWARE_ADDITIONAL_INFO_COLUMN) + private JsonNode additionalInfo; @Column(name = SEARCH_TEXT_PROPERTY) private String searchText; @@ -65,8 +71,8 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S this.setUuid(firmware.getUuidId()); this.tenantId = firmware.getTenantId().getId(); this.title = firmware.getTitle(); - this.fileName = firmware.getFileName(); - this.contentType = firmware.getContentType(); + this.version = firmware.getVersion(); + this.additionalInfo = firmware.getAdditionalInfo(); } @Override @@ -85,8 +91,8 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S firmware.setCreatedTime(createdTime); firmware.setTenantId(new TenantId(tenantId)); firmware.setTitle(title); - firmware.setFileName(fileName); - firmware.setContentType(contentType); + firmware.setVersion(version); + firmware.setAdditionalInfo(additionalInfo); return firmware; } } diff --git a/dao/src/main/resources/sql/schema-entities-hsql.sql b/dao/src/main/resources/sql/schema-entities-hsql.sql index 2bac2f9b99..faaf91a94f 100644 --- a/dao/src/main/resources/sql/schema-entities-hsql.sql +++ b/dao/src/main/resources/sql/schema-entities-hsql.sql @@ -162,10 +162,15 @@ CREATE TABLE IF NOT EXISTS firmware ( created_time bigint NOT NULL, tenant_id uuid NOT NULL, title varchar(255) NOT NULL, + version varchar(255) NOT NULL, + file_name varchar(255), + content_type varchar(255), + checksum_algorithm varchar(32), + checksum varchar(1020), + data binary, + additional_info varchar, search_text varchar(255), - file_name varchar(255) NOT NULL, - content_type varchar(255) NOT NULL, - data binary + CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) ); CREATE TABLE IF NOT EXISTS device_profile ( diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 431eaef9ff..cf3ef0f6a6 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -180,10 +180,15 @@ CREATE TABLE IF NOT EXISTS firmware ( created_time bigint NOT NULL, tenant_id uuid NOT NULL, title varchar(255) NOT NULL, + version varchar(255) NOT NULL, + file_name varchar(255), + content_type varchar(255), + checksum_algorithm varchar(32), + checksum varchar(1020), + data bytea, + additional_info varchar, search_text varchar(255), - file_name varchar(255) NOT NULL, - content_type varchar(255) NOT NULL, - data bytea + CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) ); CREATE TABLE IF NOT EXISTS device_profile ( diff --git a/dao/src/test/java/org/thingsboard/server/dao/SqlDaoServiceTestSuite.java b/dao/src/test/java/org/thingsboard/server/dao/SqlDaoServiceTestSuite.java index 0d9d8689fe..0d0f7f056b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/SqlDaoServiceTestSuite.java +++ b/dao/src/test/java/org/thingsboard/server/dao/SqlDaoServiceTestSuite.java @@ -24,7 +24,7 @@ import java.util.Arrays; @RunWith(ClasspathSuite.class) @ClassnameFilters({ - "org.thingsboard.server.dao.service.sql.FirmwareServiceSqlTest" + "org.thingsboard.server.dao.service.sql.*Test" }) public class SqlDaoServiceTestSuite { diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceProfileServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceProfileServiceTest.java index 0fd8925fc9..e377baa2cb 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceProfileServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceProfileServiceTest.java @@ -27,19 +27,19 @@ import org.junit.Test; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileInfo; -import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; +import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.exception.DataValidationException; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; @@ -82,18 +82,49 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfile.getName()); } + @Test + public void testSaveDeviceProfileWithFirmware() { + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); + Assert.assertNotNull(savedDeviceProfile); + Assert.assertNotNull(savedDeviceProfile.getId()); + Assert.assertTrue(savedDeviceProfile.getCreatedTime() > 0); + Assert.assertEquals(deviceProfile.getName(), savedDeviceProfile.getName()); + Assert.assertEquals(deviceProfile.getDescription(), savedDeviceProfile.getDescription()); + Assert.assertEquals(deviceProfile.getProfileData(), savedDeviceProfile.getProfileData()); + Assert.assertEquals(deviceProfile.isDefault(), savedDeviceProfile.isDefault()); + Assert.assertEquals(deviceProfile.getDefaultRuleChainId(), savedDeviceProfile.getDefaultRuleChainId()); + + Firmware firmware = new Firmware(); + firmware.setTenantId(tenantId); + firmware.setTitle("my firmware"); + firmware.setVersion("v1.0"); + firmware.setFileName("test.txt"); + firmware.setContentType("text/plain"); + firmware.setChecksumAlgorithm("sha256"); + firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); + firmware.setData(ByteBuffer.wrap(new byte[]{1})); + Firmware savedFirmware = firmwareService.saveFirmware(firmware); + + deviceProfile.setFirmwareId(savedFirmware.getId()); + + deviceProfileService.saveDeviceProfile(savedDeviceProfile); + DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); + Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfile.getName()); + } + @Test public void testFindDeviceProfileById() { - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); Assert.assertNotNull(foundDeviceProfile); Assert.assertEquals(savedDeviceProfile, foundDeviceProfile); - } + } @Test public void testFindDeviceProfileInfoById() { - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); DeviceProfileInfo foundDeviceProfileInfo = deviceProfileService.findDeviceProfileInfoById(tenantId, savedDeviceProfile.getId()); Assert.assertNotNull(foundDeviceProfileInfo); @@ -124,7 +155,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { ListeningExecutorService testExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(100)); try { List> futures = new ArrayList<>(); - for (int i = 0; i < 50; i ++) { + for (int i = 0; i < 50; i++) { futures.add(testExecutor.submit(() -> deviceProfileService.findOrCreateDeviceProfile(tenantId, "Device Profile 1"))); futures.add(testExecutor.submit(() -> deviceProfileService.findOrCreateDeviceProfile(tenantId, "Device Profile 2"))); } @@ -138,8 +169,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { @Test public void testSetDefaultDeviceProfile() { - DeviceProfile deviceProfile1 = this.createDeviceProfile(tenantId,"Device Profile 1"); - DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId,"Device Profile 2"); + DeviceProfile deviceProfile1 = this.createDeviceProfile(tenantId, "Device Profile 1"); + DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId, "Device Profile 2"); DeviceProfile savedDeviceProfile1 = deviceProfileService.saveDeviceProfile(deviceProfile1); DeviceProfile savedDeviceProfile2 = deviceProfileService.saveDeviceProfile(deviceProfile2); @@ -165,16 +196,16 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { @Test(expected = DataValidationException.class) public void testSaveDeviceProfileWithSameName() { - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); deviceProfileService.saveDeviceProfile(deviceProfile); - DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId,"Device Profile"); + DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId, "Device Profile"); deviceProfileService.saveDeviceProfile(deviceProfile2); } @Ignore @Test(expected = DataValidationException.class) public void testChangeDeviceProfileTypeWithExistingDevices() { - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); Device device = new Device(); device.setTenantId(tenantId); @@ -189,7 +220,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { @Test(expected = DataValidationException.class) public void testChangeDeviceProfileTransportTypeWithExistingDevices() { - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); Device device = new Device(); device.setTenantId(tenantId); @@ -203,7 +234,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { @Test(expected = DataValidationException.class) public void testDeleteDeviceProfileWithExistingDevice() { - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); Device device = new Device(); device.setTenantId(tenantId); @@ -216,7 +247,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { @Test public void testDeleteDeviceProfile() { - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); @@ -233,8 +264,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { Assert.assertEquals(1, pageData.getTotalElements()); deviceProfiles.addAll(pageData.getData()); - for (int i=0;i<28;i++) { - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"+i); + for (int i = 0; i < 28; i++) { + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile" + i); deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile)); } @@ -275,8 +306,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { Assert.assertEquals(1, deviceProfilePageData.getTotalElements()); deviceProfiles.addAll(deviceProfilePageData.getData()); - for (int i=0;i<28;i++) { - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"+i); + for (int i = 0; i < 28; i++) { + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile" + i); deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile)); } @@ -297,7 +328,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { List deviceProfileInfos = deviceProfiles.stream() .map(deviceProfile -> new DeviceProfileInfo(deviceProfile.getId(), - deviceProfile.getName(), deviceProfile.getType(), deviceProfile.getTransportType())).collect(Collectors.toList()); + deviceProfile.getName(), deviceProfile.getType(), deviceProfile.getTransportType())).collect(Collectors.toList()); Assert.assertEquals(deviceProfileInfos, loadedDeviceProfileInfos); @@ -312,4 +343,5 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(1, pageData.getTotalElements()); } + } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java index b323d0088c..d9ca69632b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java @@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.dao.exception.DataValidationException; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -88,6 +89,49 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { deviceService.deleteDevice(tenantId, savedDevice.getId()); } + + @Test + public void testSaveDeviceWithFirmware() { + Device device = new Device(); + device.setTenantId(tenantId); + device.setName("My device"); + device.setType("default"); + Device savedDevice = deviceService.saveDevice(device); + + Assert.assertNotNull(savedDevice); + Assert.assertNotNull(savedDevice.getId()); + Assert.assertTrue(savedDevice.getCreatedTime() > 0); + Assert.assertEquals(device.getTenantId(), savedDevice.getTenantId()); + Assert.assertNotNull(savedDevice.getCustomerId()); + Assert.assertEquals(NULL_UUID, savedDevice.getCustomerId().getId()); + Assert.assertEquals(device.getName(), savedDevice.getName()); + + DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, savedDevice.getId()); + Assert.assertNotNull(deviceCredentials); + Assert.assertNotNull(deviceCredentials.getId()); + Assert.assertEquals(savedDevice.getId(), deviceCredentials.getDeviceId()); + Assert.assertEquals(DeviceCredentialsType.ACCESS_TOKEN, deviceCredentials.getCredentialsType()); + Assert.assertNotNull(deviceCredentials.getCredentialsId()); + Assert.assertEquals(20, deviceCredentials.getCredentialsId().length()); + + + Firmware firmware = new Firmware(); + firmware.setTenantId(tenantId); + firmware.setTitle("my firmware"); + firmware.setVersion("v1.0"); + firmware.setFileName("test.txt"); + firmware.setContentType("text/plain"); + firmware.setChecksumAlgorithm("sha256"); + firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); + firmware.setData(ByteBuffer.wrap(new byte[]{1})); + Firmware savedFirmware = firmwareService.saveFirmware(firmware); + + savedDevice.setFirmwareId(savedFirmware.getId()); + + deviceService.saveDevice(savedDevice); + Device foundDevice = deviceService.findDeviceById(tenantId, savedDevice.getId()); + Assert.assertEquals(foundDevice.getName(), savedDevice.getName()); + } @Test(expected = DataValidationException.class) public void testSaveDeviceWithEmptyName() { diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java index b5383a1809..3abb97875b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java @@ -20,6 +20,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.Firmware; @@ -39,8 +40,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { public static final String TITLE = "My firmware"; private static final String FILE_NAME = "filename.txt"; + private static final String VERSION = "v1.0"; private static final String CONTENT_TYPE = "text/plain"; - private static final ByteBuffer DATA = ByteBuffer.wrap(new byte[]{0}); + private static final String CHECKSUM_ALGORITHM = "sha256"; + private static final String CHECKSUM = "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"; + private static final ByteBuffer DATA = ByteBuffer.wrap(new byte[]{1}); private IdComparator idComparator = new IdComparator<>(); @@ -65,8 +69,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); 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); @@ -79,7 +86,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Assert.assertEquals(firmware.getContentType(), savedFirmware.getContentType()); Assert.assertEquals(firmware.getData(), savedFirmware.getData()); - savedFirmware.setTitle("My new firmware"); + savedFirmware.setAdditionalInfo(JacksonUtil.newObjectNode()); firmwareService.saveFirmware(savedFirmware); Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, savedFirmware.getId()); @@ -88,12 +95,52 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); } + @Test + public void testSaveFirmwareInfoAndUpdateWithData() { + FirmwareInfo firmwareInfo = new FirmwareInfo(); + firmwareInfo.setTenantId(tenantId); + firmwareInfo.setTitle(TITLE); + firmwareInfo.setVersion(VERSION); + FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo); + + Assert.assertNotNull(savedFirmwareInfo); + Assert.assertNotNull(savedFirmwareInfo.getId()); + Assert.assertTrue(savedFirmwareInfo.getCreatedTime() > 0); + Assert.assertEquals(firmwareInfo.getTenantId(), savedFirmwareInfo.getTenantId()); + Assert.assertEquals(firmwareInfo.getTitle(), savedFirmwareInfo.getTitle()); + + Firmware firmware = new Firmware(savedFirmwareInfo.getId()); + firmware.setCreatedTime(firmwareInfo.getCreatedTime()); + firmware.setTenantId(tenantId); + firmware.setTitle(TITLE); + firmware.setVersion(VERSION); + firmware.setFileName(FILE_NAME); + firmware.setContentType(CONTENT_TYPE); + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); + firmware.setChecksum(CHECKSUM); + firmware.setData(DATA); + + firmwareService.saveFirmware(firmware); + + savedFirmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode()); + firmwareService.saveFirmwareInfo(savedFirmwareInfo); + + Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, firmware.getId()); + firmware.setAdditionalInfo(JacksonUtil.newObjectNode()); + Assert.assertEquals(foundFirmware.getTitle(), firmware.getTitle()); + + firmwareService.deleteFirmware(tenantId, savedFirmwareInfo.getId()); + } + @Test(expected = DataValidationException.class) public void testSaveFirmwareWithEmptyTenant() { Firmware firmware = new 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); firmwareService.saveFirmware(firmware); } @@ -102,8 +149,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { public void testSaveFirmwareWithEmptyTitle() { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); firmware.setContentType(CONTENT_TYPE); + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); + firmware.setChecksum(CHECKSUM); firmware.setData(DATA); firmwareService.saveFirmware(firmware); } @@ -113,7 +163,10 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); firmware.setTitle(TITLE); + firmware.setVersion(VERSION); firmware.setContentType(CONTENT_TYPE); + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); + firmware.setChecksum(CHECKSUM); firmware.setData(DATA); firmwareService.saveFirmware(firmware); } @@ -123,7 +176,10 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); firmware.setTitle(TITLE); + firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); + firmware.setChecksum(CHECKSUM); firmware.setData(DATA); firmwareService.saveFirmware(firmware); } @@ -133,8 +189,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); firmware.setTitle(TITLE); + firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); firmware.setContentType(CONTENT_TYPE); + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); + firmware.setChecksum(CHECKSUM); firmwareService.saveFirmware(firmware); } @@ -143,21 +202,76 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(new TenantId(Uuids.timeBased())); firmware.setTitle(TITLE); + firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); firmware.setContentType(CONTENT_TYPE); + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); + firmware.setChecksum(CHECKSUM); firmware.setData(DATA); firmwareService.saveFirmware(firmware); } + @Test(expected = DataValidationException.class) + public void testSaveFirmwareWithEmptyChecksum() { + Firmware firmware = new Firmware(); + firmware.setTenantId(new TenantId(Uuids.timeBased())); + firmware.setTitle(TITLE); + firmware.setVersion(VERSION); + firmware.setFileName(FILE_NAME); + firmware.setContentType(CONTENT_TYPE); + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); + firmware.setData(DATA); + firmwareService.saveFirmware(firmware); + } + @Test(expected = DataValidationException.class) + public void testSaveFirmwareInfoWithExistingTitleAndVersion() { + FirmwareInfo firmwareInfo = new FirmwareInfo(); + firmwareInfo.setTenantId(tenantId); + firmwareInfo.setTitle(TITLE); + firmwareInfo.setVersion(VERSION); + firmwareService.saveFirmwareInfo(firmwareInfo); + + FirmwareInfo newFirmwareInfo = new FirmwareInfo(); + newFirmwareInfo.setTenantId(tenantId); + newFirmwareInfo.setTitle(TITLE); + newFirmwareInfo.setVersion(VERSION); + firmwareService.saveFirmwareInfo(newFirmwareInfo); + } + + @Test(expected = DataValidationException.class) + public void testSaveFirmwareWithExistingTitleAndVersion() { + Firmware firmware = new Firmware(); + firmware.setTenantId(tenantId); + firmware.setTitle(TITLE); + firmware.setVersion(VERSION); + firmware.setFileName(FILE_NAME); + firmware.setContentType(CONTENT_TYPE); + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); + firmware.setChecksum(CHECKSUM); + firmware.setData(DATA); + firmwareService.saveFirmware(firmware); + + Firmware newFirmware = new Firmware(); + newFirmware.setTenantId(tenantId); + newFirmware.setTitle(TITLE); + newFirmware.setVersion(VERSION); + newFirmware.setFileName(FILE_NAME); + newFirmware.setContentType(CONTENT_TYPE); + newFirmware.setData(DATA); + firmwareService.saveFirmware(newFirmware); + } @Test(expected = DataValidationException.class) public void testDeleteFirmwareWithReferenceByDevice() { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); 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); @@ -181,8 +295,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); 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); @@ -203,8 +320,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); 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); @@ -219,8 +339,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); 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); @@ -238,8 +361,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); firmware.setTitle(TITLE); + firmware.setVersion(VERSION + i); firmware.setFileName(FILE_NAME); firmware.setContentType(CONTENT_TYPE); + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); + firmware.setChecksum(CHECKSUM); firmware.setData(DATA); firmwares.add(new FirmwareInfo(firmwareService.saveFirmware(firmware))); }