From f264aa43302dd70f9dfd39cd8475939889a117de Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 29 Apr 2021 10:02:51 +0300 Subject: [PATCH] fixed firmware tests and validation --- .../server/controller/FirmwareController.java | 15 +- .../firmware/DefaultFirmwareStateService.java | 16 +- .../transport/DefaultTransportApiService.java | 1 + .../BaseFirmwareControllerTest.java | 30 ++- .../controller/ControllerSqlTestSuite.java | 2 +- .../server/dao/firmware/FirmwareService.java | 4 +- .../server/common/data/Device.java | 12 ++ .../server/common/data/DeviceProfile.java | 4 + .../server/common/data/FirmwareInfo.java | 3 + .../dao/device/DeviceProfileServiceImpl.java | 10 + .../server/dao/device/DeviceServiceImpl.java | 16 ++ .../dao/firmware/BaseFirmwareService.java | 92 +++++---- .../server/dao/firmware/FirmwareInfoDao.java | 4 +- .../server/dao/model/ModelConstants.java | 3 + .../dao/model/sql/AbstractDeviceEntity.java | 16 +- .../dao/model/sql/DeviceProfileEntity.java | 18 +- .../server/dao/model/sql/FirmwareEntity.java | 7 + .../dao/model/sql/FirmwareInfoEntity.java | 13 +- .../sql/firmware/FirmwareInfoRepository.java | 19 +- .../dao/sql/firmware/JpaFirmwareInfoDao.java | 8 +- .../resources/sql/schema-entities-hsql.sql | 9 +- .../main/resources/sql/schema-entities.sql | 10 +- .../service/BaseDeviceProfileServiceTest.java | 5 + .../dao/service/BaseDeviceServiceTest.java | 43 ++++ .../dao/service/BaseFirmwareServiceTest.java | 185 ++++++++++++++++-- 25 files changed, 456 insertions(+), 89 deletions(-) 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 9c08967c8e..9b3caf7a79 100644 --- a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java +++ b/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java @@ -35,6 +35,8 @@ import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.FirmwareInfo; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; +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.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -133,6 +135,8 @@ public class FirmwareController extends BaseController { Firmware firmware = new Firmware(firmwareId); firmware.setCreatedTime(info.getCreatedTime()); firmware.setTenantId(getTenantId()); + firmware.setDeviceProfileId(info.getDeviceProfileId()); + firmware.setType(info.getType()); firmware.setTitle(info.getTitle()); firmware.setVersion(info.getVersion()); firmware.setAdditionalInfo(info.getAdditionalInfo()); @@ -175,17 +179,22 @@ public class FirmwareController extends BaseController { } @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/firmwares/{hasData}", method = RequestMethod.GET) + @RequestMapping(value = "/firmwares/{deviceProfileId}/{type}/{hasData}", method = RequestMethod.GET) @ResponseBody - public PageData getFirmwares(@PathVariable("hasData") boolean hasData, + public PageData getFirmwares(@PathVariable("deviceProfileId") String strDeviceProfileId, + @PathVariable("type") String strType, + @PathVariable("hasData") boolean hasData, @RequestParam int pageSize, @RequestParam int page, @RequestParam(required = false) String textSearch, @RequestParam(required = false) String sortProperty, @RequestParam(required = false) String sortOrder) throws ThingsboardException { + checkParameter("deviceProfileId", strDeviceProfileId); + checkParameter("type", strType); try { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); - return checkNotNull(firmwareService.findTenantFirmwaresByTenantIdAndHasData(getTenantId(), hasData, pageLink)); + return checkNotNull(firmwareService.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(getTenantId(), + new DeviceProfileId(toUUID(strDeviceProfileId)), FirmwareType.valueOf(strType), hasData, pageLink)); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java b/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java index 8638805d81..c4ad9feceb 100644 --- a/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java @@ -16,7 +16,6 @@ package org.thingsboard.server.service.firmware; import com.google.common.util.concurrent.FutureCallback; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; @@ -45,6 +44,7 @@ import org.thingsboard.server.dao.firmware.FirmwareService; import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.common.TbProtoQueueMsg; +import org.thingsboard.server.queue.provider.TbCoreQueueFactory; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.queue.TbClusterService; @@ -71,7 +71,6 @@ import static org.thingsboard.server.common.data.firmware.FirmwareKeyUtil.getTel @Slf4j @Service @TbCoreComponent -@RequiredArgsConstructor public class DefaultFirmwareStateService implements FirmwareStateService { private final TbClusterService tbClusterService; @@ -81,6 +80,19 @@ public class DefaultFirmwareStateService implements FirmwareStateService { private final RuleEngineTelemetryService telemetryService; private final TbQueueProducer> fwStateMsgProducer; + public DefaultFirmwareStateService(TbClusterService tbClusterService, FirmwareService firmwareService, + DeviceService deviceService, + DeviceProfileService deviceProfileService, + RuleEngineTelemetryService telemetryService, + TbCoreQueueFactory coreQueueFactory) { + this.tbClusterService = tbClusterService; + this.firmwareService = firmwareService; + this.deviceService = deviceService; + this.deviceProfileService = deviceProfileService; + this.telemetryService = telemetryService; + this.fwStateMsgProducer = coreQueueFactory.createToFirmwareStateServiceMsgProducer(); + } + @Override public void update(Device device, Device oldDevice) { FirmwareId newFirmwareId = device.getFirmwareId(); diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index 025122a01b..463af51862 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java @@ -480,6 +480,7 @@ public class DefaultTransportApiService implements TransportApiService { builder.setResponseStatus(TransportProtos.ResponseStatus.SUCCESS); builder.setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits()); builder.setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits()); + builder.setType(firmwareInfo.getType().name()); builder.setTitle(firmwareInfo.getTitle()); builder.setVersion(firmwareInfo.getVersion()); builder.setFileName(firmwareInfo.getFileName()); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java index 425a21e1a2..ec36be13a5 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java @@ -24,10 +24,13 @@ import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.FirmwareInfo; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; @@ -38,6 +41,7 @@ import java.util.Collections; import java.util.List; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; public abstract class BaseFirmwareControllerTest extends AbstractControllerTest { @@ -53,6 +57,7 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest private Tenant savedTenant; private User tenantAdmin; + private DeviceProfileId deviceProfileId; @Before public void beforeTest() throws Exception { @@ -71,6 +76,11 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest tenantAdmin.setLastName("Downs"); tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); + + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile", null); + DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); + Assert.assertNotNull(savedDeviceProfile); + deviceProfileId = savedDeviceProfile.getId(); } @After @@ -84,6 +94,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @Test public void testSaveFirmware() throws Exception { FirmwareInfo firmwareInfo = new FirmwareInfo(); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); @@ -107,6 +119,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @Test public void testSaveFirmwareData() throws Exception { FirmwareInfo firmwareInfo = new FirmwareInfo(); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); @@ -137,6 +151,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @Test public void testUpdateFirmwareFromDifferentTenant() throws Exception { FirmwareInfo firmwareInfo = new FirmwareInfo(); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); @@ -150,6 +166,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @Test public void testFindFirmwareInfoById() throws Exception { FirmwareInfo firmwareInfo = new FirmwareInfo(); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); @@ -163,6 +181,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @Test public void testFindFirmwareById() throws Exception { FirmwareInfo firmwareInfo = new FirmwareInfo(); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); @@ -180,6 +200,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @Test public void testDeleteFirmware() throws Exception { FirmwareInfo firmwareInfo = new FirmwareInfo(); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); @@ -197,6 +219,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest List firmwares = new ArrayList<>(); for (int i = 0; i < 165; i++) { FirmwareInfo firmwareInfo = new FirmwareInfo(); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION + i); @@ -238,6 +262,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest for (int i = 0; i < 165; i++) { FirmwareInfo firmwareInfo = new FirmwareInfo(); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION + i); @@ -257,7 +283,7 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest PageLink pageLink = new PageLink(24); PageData pageData; do { - pageData = doGetTypedWithPageLink("/api/firmwares/true?", + pageData = doGetTypedWithPageLink("/api/firmwares/" + deviceProfileId.toString() + "/FIRMWARE/true?", new TypeReference<>() { }, pageLink); loadedFirmwaresWithData.addAll(pageData.getData()); @@ -269,7 +295,7 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest List loadedFirmwaresWithoutData = new ArrayList<>(); pageLink = new PageLink(24); do { - pageData = doGetTypedWithPageLink("/api/firmwares/false?", + pageData = doGetTypedWithPageLink("/api/firmwares/" + deviceProfileId.toString() + "/FIRMWARE/false?", new TypeReference<>() { }, pageLink); loadedFirmwaresWithoutData.addAll(pageData.getData()); diff --git a/application/src/test/java/org/thingsboard/server/controller/ControllerSqlTestSuite.java b/application/src/test/java/org/thingsboard/server/controller/ControllerSqlTestSuite.java index 653f6978f6..85b058f597 100644 --- a/application/src/test/java/org/thingsboard/server/controller/ControllerSqlTestSuite.java +++ b/application/src/test/java/org/thingsboard/server/controller/ControllerSqlTestSuite.java @@ -29,7 +29,7 @@ import java.util.Arrays; // "org.thingsboard.server.controller.sql.WebsocketApiSqlTest", // "org.thingsboard.server.controller.sql.EntityQueryControllerSqlTest", // "org.thingsboard.server.controller.sql.TbResourceControllerSqlTest", - "org.thingsboard.server.controller.sql.*Test", + "org.thingsboard.server.controller.sql.FirmwareControllerSqlTest", }) public class ControllerSqlTestSuite { 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 907638eabb..980f8303f2 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 @@ -18,6 +18,8 @@ package org.thingsboard.server.dao.firmware; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.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; @@ -37,7 +39,7 @@ public interface FirmwareService { PageData findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink); - PageData findTenantFirmwaresByTenantIdAndHasData(TenantId tenantId, boolean hasData, PageLink pageLink); + PageData findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink); void deleteFirmware(TenantId tenantId, FirmwareId firmwareId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java index 5282435c0a..b48fc114cb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java @@ -50,6 +50,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo implemen private byte[] deviceDataBytes; private FirmwareId firmwareId; + private FirmwareId softwareId; public Device() { super(); @@ -69,6 +70,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo implemen this.deviceProfileId = device.getDeviceProfileId(); this.setDeviceData(device.getDeviceData()); this.firmwareId = device.getFirmwareId(); + this.softwareId = device.getSoftwareId(); } public Device updateDevice(Device device) { @@ -79,6 +81,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo implemen this.label = device.getLabel(); this.deviceProfileId = device.getDeviceProfileId(); this.setDeviceData(device.getDeviceData()); + this.setFirmwareId(device.getFirmwareId()); + this.setSoftwareId(device.getSoftwareId()); return this; } @@ -171,6 +175,14 @@ public class Device extends SearchTextBasedWithAdditionalInfo implemen this.firmwareId = firmwareId; } + public FirmwareId getSoftwareId() { + return softwareId; + } + + public void setSoftwareId(FirmwareId softwareId) { + this.softwareId = softwareId; + } + @Override public String toString() { StringBuilder builder = new StringBuilder(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java index 660d9dec93..c3a2e5ecee 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java @@ -59,6 +59,8 @@ public class DeviceProfile extends SearchTextBased implements H private FirmwareId firmwareId; + private FirmwareId softwareId; + public DeviceProfile() { super(); } @@ -77,6 +79,8 @@ public class DeviceProfile extends SearchTextBased implements H this.defaultQueueName = deviceProfile.getDefaultQueueName(); this.setProfileData(deviceProfile.getProfileData()); this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey(); + this.firmwareId = deviceProfile.getFirmwareId(); + this.softwareId = deviceProfile.getSoftwareId(); } @Override 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 aee81bcde8..9b00e9b256 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 @@ -20,6 +20,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; 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; @@ -31,6 +32,7 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo private static final long serialVersionUID = 3168391583570815419L; private TenantId tenantId; + private DeviceProfileId deviceProfileId; private FirmwareType type; private String title; private String version; @@ -53,6 +55,7 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo public FirmwareInfo(FirmwareInfo firmwareInfo) { super(firmwareInfo); this.tenantId = firmwareInfo.getTenantId(); + this.deviceProfileId = firmwareInfo.getDeviceProfileId(); this.type = firmwareInfo.getType(); this.title = firmwareInfo.getTitle(); this.version = firmwareInfo.getVersion(); 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 7833c80ed5..020fd7c524 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 @@ -409,6 +409,16 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D throw new DataValidationException("Can't assign firmware with empty data!"); } } + + if (deviceProfile.getSoftwareId() != null) { + Firmware software = firmwareService.findFirmwareById(tenantId, deviceProfile.getSoftwareId()); + if (software == null) { + throw new DataValidationException("Can't assign non-existent software!"); + } + if (software.getData() == null) { + throw new DataValidationException("Can't assign software 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 73dadef589..dd9b46b62f 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 @@ -686,6 +686,22 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe if (firmware.getData() == null) { throw new DataValidationException("Can't assign firmware with empty data!"); } + if (!firmware.getDeviceProfileId().equals(device.getDeviceProfileId())) { + throw new DataValidationException("Can't assign firmware with different deviceProfile!"); + } + } + + if (device.getSoftwareId() != null) { + Firmware software = firmwareService.findFirmwareById(tenantId, device.getSoftwareId()); + if (software == null) { + throw new DataValidationException("Can't assign non-existent software!"); + } + if (software.getData() == null) { + throw new DataValidationException("Can't assign software with empty data!"); + } + if (!software.getDeviceProfileId().equals(device.getDeviceProfileId())) { + throw new DataValidationException("Can't assign firmware with different deviceProfile!"); + } } } }; 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 5876947440..207d629bbe 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 @@ -27,13 +27,17 @@ import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.thingsboard.server.cache.firmware.FirmwareDataCache; +import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.FirmwareInfo; import org.thingsboard.server.common.data.Tenant; +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; +import org.thingsboard.server.dao.device.DeviceProfileDao; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -56,6 +60,7 @@ public class BaseFirmwareService implements FirmwareService { public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; private final TenantDao tenantDao; + private final DeviceProfileDao deviceProfileDao; private final FirmwareDao firmwareDao; private final FirmwareInfoDao firmwareInfoDao; private final CacheManager cacheManager; @@ -124,7 +129,8 @@ public class BaseFirmwareService implements FirmwareService { public ListenableFuture findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId) { log.trace("Executing findFirmwareInfoByIdAsync [{}]", firmwareId); validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId); - return firmwareInfoDao.findByIdAsync(tenantId, firmwareId.getId()); } + return firmwareInfoDao.findByIdAsync(tenantId, firmwareId.getId()); + } @Override public PageData findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink) { @@ -135,11 +141,11 @@ public class BaseFirmwareService implements FirmwareService { } @Override - public PageData findTenantFirmwaresByTenantIdAndHasData(TenantId tenantId, boolean hasData, PageLink pageLink) { + public PageData findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink) { log.trace("Executing findTenantFirmwaresByTenantIdAndHasData, tenantId [{}], hasData [{}] pageLink [{}]", tenantId, hasData, pageLink); validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validatePageLink(pageLink); - return firmwareInfoDao.findFirmwareInfoByTenantIdAndHasData(tenantId, hasData, pageLink); + return firmwareInfoDao.findFirmwareInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, firmwareType, hasData, pageLink); } @Override @@ -157,6 +163,10 @@ public class BaseFirmwareService implements FirmwareService { throw new DataValidationException("The firmware referenced by the devices cannot be deleted!"); } else if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_firmware_device_profile")) { throw new DataValidationException("The firmware referenced by the device profile cannot be deleted!"); + } else if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_software_device")) { + throw new DataValidationException("The software referenced by the devices cannot be deleted!"); + } else if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_software_device_profile")) { + throw new DataValidationException("The software referenced by the device profile cannot be deleted!"); } else { throw t; } @@ -173,23 +183,8 @@ public class BaseFirmwareService implements FirmwareService { 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!"); - } + protected void validateDataImpl(TenantId tenantId, FirmwareInfo firmwareInfo) { + validateImpl(firmwareInfo); } @Override @@ -204,22 +199,7 @@ public class BaseFirmwareService implements FirmwareService { @Override protected void validateDataImpl(TenantId tenantId, Firmware 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!"); - } + validateImpl(firmware); if (StringUtils.isEmpty(firmware.getFileName())) { throw new DataValidationException("Firmware file name should be specified!"); @@ -276,6 +256,14 @@ 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!"); + } + + if (!firmwareOld.getType().equals(firmware.getType())) { + throw new DataValidationException("Updating type is prohibited!"); + } + if (!firmwareOld.getTitle().equals(firmware.getTitle())) { throw new DataValidationException("Updating firmware title is prohibited!"); } @@ -305,6 +293,38 @@ public class BaseFirmwareService implements FirmwareService { } } + private void validateImpl(FirmwareInfo firmwareInfo) { + if (firmwareInfo.getTenantId() == null) { + throw new DataValidationException("Firmware should be assigned to tenant!"); + } else { + Tenant tenant = tenantDao.findById(firmwareInfo.getTenantId(), firmwareInfo.getTenantId().getId()); + if (tenant == null) { + throw new DataValidationException("Firmware is referencing to non-existent tenant!"); + } + } + + if (firmwareInfo.getDeviceProfileId() == null) { + throw new DataValidationException("Firmware should be assigned to deviceProfile!"); + } else { + DeviceProfile deviceProfile = deviceProfileDao.findById(firmwareInfo.getTenantId(), firmwareInfo.getDeviceProfileId().getId()); + if (deviceProfile == null) { + throw new DataValidationException("Firmware is referencing to non-existent device profile!"); + } + } + + if (firmwareInfo.getType() == null) { + throw new DataValidationException("Type should be specified!"); + } + + if (StringUtils.isEmpty(firmwareInfo.getTitle())) { + throw new DataValidationException("Firmware title should be specified!"); + } + + if (StringUtils.isEmpty(firmwareInfo.getVersion())) { + throw new DataValidationException("Firmware version should be specified!"); + } + } + private PaginatedRemover tenantFirmwareRemover = new PaginatedRemover<>() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/firmware/FirmwareInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/firmware/FirmwareInfoDao.java index a2af06ad9a..32ca8dc528 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/firmware/FirmwareInfoDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/firmware/FirmwareInfoDao.java @@ -16,6 +16,8 @@ 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.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -27,6 +29,6 @@ public interface FirmwareInfoDao extends Dao { PageData findFirmwareInfoByTenantId(TenantId tenantId, PageLink pageLink); - PageData findFirmwareInfoByTenantIdAndHasData(TenantId tenantId, boolean hasData, PageLink pageLink); + PageData findFirmwareInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink 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 260c8aa743..bc0afe630d 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 @@ -154,6 +154,7 @@ public class ModelConstants { public static final String DEVICE_DEVICE_PROFILE_ID_PROPERTY = "device_profile_id"; public static final String DEVICE_DEVICE_DATA_PROPERTY = "device_data"; public static final String DEVICE_FIRMWARE_ID_PROPERTY = "firmware_id"; + public static final String DEVICE_SOFTWARE_ID_PROPERTY = "software_id"; public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text"; public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text"; @@ -178,6 +179,7 @@ public class ModelConstants { public static final String DEVICE_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY = "default_queue_name"; public static final String DEVICE_PROFILE_PROVISION_DEVICE_KEY = "provision_device_key"; public static final String DEVICE_PROFILE_FIRMWARE_ID_PROPERTY = "firmware_id"; + public static final String DEVICE_PROFILE_SOFTWARE_ID_PROPERTY = "software_id"; /** * Cassandra entityView constants. @@ -476,6 +478,7 @@ 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_DEVICE_PROFILE_ID_COLUMN = "device_profile_id"; public static final String FIRMWARE_TYPE_COLUMN = "type"; public static final String FIRMWARE_TITLE_COLUMN = TITLE_PROPERTY; public static final String FIRMWARE_VERSION_COLUMN = "version"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractDeviceEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractDeviceEntity.java index 8dee576611..5b9d49a036 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractDeviceEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractDeviceEntity.java @@ -22,6 +22,7 @@ import lombok.EqualsAndHashCode; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDefs; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.device.data.DeviceData; import org.thingsboard.server.common.data.id.CustomerId; @@ -32,7 +33,6 @@ 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.common.util.JacksonUtil; import org.thingsboard.server.dao.util.mapping.JsonBinaryType; import org.thingsboard.server.dao.util.mapping.JsonStringType; @@ -43,8 +43,8 @@ import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @TypeDefs({ - @TypeDef(name = "json", typeClass = JsonStringType.class), - @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) + @TypeDef(name = "json", typeClass = JsonStringType.class), + @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) }) @MappedSuperclass public abstract class AbstractDeviceEntity extends BaseSqlEntity implements SearchTextEntity { @@ -77,6 +77,9 @@ public abstract class AbstractDeviceEntity extends BaseSqlEnti @Column(name = ModelConstants.DEVICE_FIRMWARE_ID_PROPERTY, columnDefinition = "uuid") private UUID firmwareId; + @Column(name = ModelConstants.DEVICE_SOFTWARE_ID_PROPERTY, columnDefinition = "uuid") + private UUID softwareId; + @Type(type = "jsonb") @Column(name = ModelConstants.DEVICE_DEVICE_DATA_PROPERTY, columnDefinition = "jsonb") private JsonNode deviceData; @@ -102,6 +105,9 @@ public abstract class AbstractDeviceEntity extends BaseSqlEnti if (device.getFirmwareId() != null) { this.firmwareId = device.getFirmwareId().getId(); } + if (device.getSoftwareId() != null) { + this.firmwareId = device.getSoftwareId().getId(); + } this.deviceData = JacksonUtil.convertValue(device.getDeviceData(), ObjectNode.class); this.name = device.getName(); this.type = device.getType(); @@ -122,6 +128,7 @@ public abstract class AbstractDeviceEntity extends BaseSqlEnti this.searchText = deviceEntity.getSearchText(); this.additionalInfo = deviceEntity.getAdditionalInfo(); this.firmwareId = deviceEntity.getFirmwareId(); + this.softwareId = deviceEntity.getSoftwareId(); } @Override @@ -149,6 +156,9 @@ public abstract class AbstractDeviceEntity extends BaseSqlEnti if (firmwareId != null) { device.setFirmwareId(new FirmwareId(firmwareId)); } + if (softwareId != null) { + device.setSoftwareId(new FirmwareId(softwareId)); + } device.setDeviceData(JacksonUtil.convertValue(deviceData, DeviceData.class)); device.setName(name); device.setType(type); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java index e437c87fdd..e4c32a44f0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java @@ -21,9 +21,10 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; +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.DeviceProfileProvisionType; +import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -33,7 +34,6 @@ 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.common.util.JacksonUtil; import org.thingsboard.server.dao.util.mapping.JsonBinaryType; import javax.persistence.Column; @@ -87,12 +87,15 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl @Column(name = ModelConstants.DEVICE_PROFILE_PROFILE_DATA_PROPERTY, columnDefinition = "jsonb") private JsonNode profileData; - @Column(name=ModelConstants.DEVICE_PROFILE_PROVISION_DEVICE_KEY) + @Column(name = ModelConstants.DEVICE_PROFILE_PROVISION_DEVICE_KEY) private String provisionDeviceKey; - @Column(name=ModelConstants.DEVICE_PROFILE_FIRMWARE_ID_PROPERTY) + @Column(name = ModelConstants.DEVICE_PROFILE_FIRMWARE_ID_PROPERTY) private UUID firmwareId; + @Column(name = ModelConstants.DEVICE_PROFILE_SOFTWARE_ID_PROPERTY) + private UUID softwareId; + public DeviceProfileEntity() { super(); } @@ -120,6 +123,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl if (deviceProfile.getFirmwareId() != null) { this.firmwareId = deviceProfile.getFirmwareId().getId(); } + if (deviceProfile.getSoftwareId() != null) { + this.firmwareId = deviceProfile.getSoftwareId().getId(); + } } @Override @@ -160,6 +166,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl deviceProfile.setFirmwareId(new FirmwareId(firmwareId)); } + if (softwareId != null) { + deviceProfile.setSoftwareId(new FirmwareId(softwareId)); + } + return deviceProfile; } } 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 6dfa2e893e..a10ec8f7ed 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 @@ -22,6 +22,7 @@ import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.Firmware; 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.dao.model.BaseSqlEntity; @@ -43,6 +44,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ 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_DATA_SIZE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DEVICE_PROFILE_ID_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; @@ -61,6 +63,9 @@ public class FirmwareEntity extends BaseSqlEntity implements SearchTex @Column(name = FIRMWARE_TENANT_ID_COLUMN) private UUID tenantId; + @Column(name = FIRMWARE_DEVICE_PROFILE_ID_COLUMN) + private UUID deviceProfileId; + @Enumerated(EnumType.STRING) @Column(name = FIRMWARE_TYPE_COLUMN) private FirmwareType type; @@ -105,6 +110,7 @@ public class FirmwareEntity extends BaseSqlEntity implements SearchTex this.createdTime = firmware.getCreatedTime(); this.setUuid(firmware.getUuidId()); this.tenantId = firmware.getTenantId().getId(); + this.deviceProfileId = firmware.getDeviceProfileId().getId(); this.type = firmware.getType(); this.title = firmware.getTitle(); this.version = firmware.getVersion(); @@ -132,6 +138,7 @@ public class FirmwareEntity extends BaseSqlEntity implements SearchTex Firmware firmware = new Firmware(new FirmwareId(id)); firmware.setCreatedTime(createdTime); firmware.setTenantId(new TenantId(tenantId)); + firmware.setDeviceProfileId(new DeviceProfileId(deviceProfileId)); firmware.setType(type); firmware.setTitle(title); firmware.setVersion(version); 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 067b061396..b1e058a012 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 @@ -23,6 +23,7 @@ import org.hibernate.annotations.TypeDef; import org.thingsboard.common.util.JacksonUtil; 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.dao.model.BaseSqlEntity; @@ -42,6 +43,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ 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_SIZE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DEVICE_PROFILE_ID_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; @@ -60,6 +62,9 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S @Column(name = FIRMWARE_TENANT_ID_COLUMN) private UUID tenantId; + @Column(name = FIRMWARE_DEVICE_PROFILE_ID_COLUMN) + private UUID deviceProfileId; + @Enumerated(EnumType.STRING) @Column(name = FIRMWARE_TYPE_COLUMN) private FirmwareType type; @@ -103,6 +108,8 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S this.createdTime = firmware.getCreatedTime(); this.setUuid(firmware.getUuidId()); this.tenantId = firmware.getTenantId().getId(); + this.type = firmware.getType(); + this.deviceProfileId = firmware.getDeviceProfileId().getId(); this.title = firmware.getTitle(); this.version = firmware.getVersion(); this.fileName = firmware.getFileName(); @@ -113,13 +120,14 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S this.additionalInfo = firmware.getAdditionalInfo(); } - public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, String type, String title, String version, + public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, UUID deviceProfileId, FirmwareType type, String title, String version, String fileName, String contentType, String checksumAlgorithm, String checksum, Long dataSize, Object additionalInfo, boolean hasData) { this.id = id; this.createdTime = createdTime; this.tenantId = tenantId; - this.type = FirmwareType.valueOf(type); + this.deviceProfileId = deviceProfileId; + this.type = type; this.title = title; this.version = version; this.fileName = fileName; @@ -146,6 +154,7 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S FirmwareInfo firmware = new FirmwareInfo(new FirmwareId(id)); firmware.setCreatedTime(createdTime); firmware.setTenantId(new TenantId(tenantId)); + firmware.setDeviceProfileId(new DeviceProfileId(deviceProfileId)); firmware.setType(type); firmware.setTitle(title); firmware.setVersion(version); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareInfoRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareInfoRepository.java index 458cecf63d..5a7af9997b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareInfoRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareInfoRepository.java @@ -20,27 +20,32 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; +import org.thingsboard.server.common.data.firmware.FirmwareType; import org.thingsboard.server.dao.model.sql.FirmwareInfoEntity; import java.util.UUID; public interface FirmwareInfoRepository extends CrudRepository { - @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, 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 " + + @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.tenantId = :tenantId " + "AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))") Page findAllByTenantId(@Param("tenantId") UUID tenantId, @Param("searchText") String searchText, Pageable pageable); - @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, 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 " + + @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.tenantId = :tenantId " + + "AND f.deviceProfileId = :deviceProfileId " + + "AND f.type = :type " + "AND ((f.data IS NOT NULL AND :hasData = true) OR (f.data IS NULL AND :hasData = false ))" + "AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))") - Page findAllByTenantIdAndHasData(@Param("tenantId") UUID tenantId, - @Param("hasData") boolean hasData, - @Param("searchText") String searchText, - Pageable pageable); + Page findAllByTenantIdAndTypeAndDeviceProfileIdAndHasData(@Param("tenantId") UUID tenantId, + @Param("deviceProfileId") UUID deviceProfileId, + @Param("type") FirmwareType type, + @Param("hasData") boolean hasData, + @Param("searchText") String searchText, + Pageable pageable); - @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, 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") + @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); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/JpaFirmwareInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/JpaFirmwareInfoDao.java index 3b80c1c7e5..db7fb37ffe 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/JpaFirmwareInfoDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/JpaFirmwareInfoDao.java @@ -20,6 +20,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.CrudRepository; 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.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -73,10 +75,12 @@ public class JpaFirmwareInfoDao extends JpaAbstractSearchTextDao findFirmwareInfoByTenantIdAndHasData(TenantId tenantId, boolean hasData, PageLink pageLink) { + public PageData findFirmwareInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink) { return DaoUtil.toPageData(firmwareInfoRepository - .findAllByTenantIdAndHasData( + .findAllByTenantIdAndTypeAndDeviceProfileIdAndHasData( tenantId.getId(), + deviceProfileId.getId(), + firmwareType, hasData, Objects.toString(pageLink.getTextSearch(), ""), DaoUtil.toPageable(pageLink))); diff --git a/dao/src/main/resources/sql/schema-entities-hsql.sql b/dao/src/main/resources/sql/schema-entities-hsql.sql index d9bc1003dc..89dcf44f35 100644 --- a/dao/src/main/resources/sql/schema-entities-hsql.sql +++ b/dao/src/main/resources/sql/schema-entities-hsql.sql @@ -162,6 +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, type varchar(32) NOT NULL, title varchar(255) NOT NULL, version varchar(255) NOT NULL, @@ -189,13 +190,15 @@ CREATE TABLE IF NOT EXISTS device_profile ( is_default boolean, tenant_id uuid, firmware_id uuid, + software_id uuid, default_rule_chain_id uuid, default_queue_name varchar(255), provision_device_key varchar, CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key), CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id), - CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id) + CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id), + CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES firmware(id) ); CREATE TABLE IF NOT EXISTS device ( @@ -211,9 +214,11 @@ CREATE TABLE IF NOT EXISTS device ( search_text varchar(255), tenant_id uuid, firmware_id uuid, + software_id uuid, CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name), CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id), - CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id) + CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id), + CONSTRAINT fk_software_device FOREIGN KEY (software_id) REFERENCES firmware(id) ); CREATE TABLE IF NOT EXISTS device_credentials ( diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index a5373fbaaf..245759cd22 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -192,8 +192,8 @@ CREATE TABLE IF NOT EXISTS firmware ( data_size bigint, additional_info varchar, search_text varchar(255), - CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version), - CONSTRAINT fk_firmware_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id) ON DELETE CASCADE + CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) +-- CONSTRAINT fk_device_profile_firmware FOREIGN KEY (device_profile_id) REFERENCES device_profile(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS device_profile ( @@ -216,8 +216,8 @@ CREATE TABLE IF NOT EXISTS device_profile ( CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key), CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id), - CONSTRAINT fk_device_profile_firmware FOREIGN KEY (firmware_id) REFERENCES firmware(id) - CONSTRAINT fk_device_profile_software FOREIGN KEY (software_id) REFERENCES firmware(id) + CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id), + CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES firmware(id) ); -- We will use one-to-many relation in the first release and extend this feature in case of user requests @@ -245,7 +245,7 @@ CREATE TABLE IF NOT EXISTS device ( software_id uuid, CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name), CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id), - CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id) + CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id), CONSTRAINT fk_software_device FOREIGN KEY (software_id) REFERENCES firmware(id) ); 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 e377baa2cb..618135fdd3 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 @@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.DeviceProfileInfo; 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.firmware.FirmwareType; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -43,6 +44,8 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.stream.Collectors; +import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; + public class BaseDeviceProfileServiceTest extends AbstractServiceTest { private IdComparator idComparator = new IdComparator<>(); @@ -97,6 +100,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(savedDeviceProfile.getId()); + firmware.setType(FIRMWARE); firmware.setTitle("my firmware"); firmware.setVersion("v1.0"); firmware.setFileName("test.txt"); 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 6d7b695ef1..4fcdd93bce 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 @@ -20,10 +20,13 @@ import org.apache.commons.lang3.RandomStringUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceInfo; +import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.Tenant; @@ -42,6 +45,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; public abstract class BaseDeviceServiceTest extends AbstractServiceTest { @@ -66,6 +70,9 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { tenantProfileService.deleteTenantProfiles(anotherTenantId); } + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test public void testSaveDevicesWithoutMaxDeviceLimit() { Device device = this.saveDevice(tenantId, "My device"); @@ -183,6 +190,8 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(device.getDeviceProfileId()); + firmware.setType(FIRMWARE); firmware.setTitle("my firmware"); firmware.setVersion("v1.0"); firmware.setFileName("test.txt"); @@ -198,6 +207,40 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { Device foundDevice = deviceService.findDeviceById(tenantId, savedDevice.getId()); Assert.assertEquals(foundDevice.getName(), savedDevice.getName()); } + + @Test + public void testAssignFirmwareToDeviceWithDifferentDeviceProfile() { + Device device = new Device(); + device.setTenantId(tenantId); + device.setName("My device"); + device.setType("default"); + Device savedDevice = deviceService.saveDevice(device); + + Assert.assertNotNull(savedDevice); + + DeviceProfile deviceProfile = createDeviceProfile(tenantId, "New device Profile"); + DeviceProfile savedProfile = deviceProfileService.saveDeviceProfile(deviceProfile); + Assert.assertNotNull(savedProfile); + + Firmware firmware = new Firmware(); + firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(savedProfile.getId()); + firmware.setType(FIRMWARE); + 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()); + + thrown.expect(DataValidationException.class); + thrown.expectMessage("Can't assign firmware with different deviceProfile!"); + deviceService.saveDevice(savedDevice); + } @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 bf96d09922..816b59fb64 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 @@ -19,13 +19,16 @@ import com.datastax.oss.driver.api.core.uuid.Uuids; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; 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; import org.thingsboard.server.common.data.FirmwareInfo; import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -36,6 +39,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; + public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { public static final String TITLE = "My firmware"; @@ -50,6 +55,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { private TenantId tenantId; + private DeviceProfileId deviceProfileId; + @Before public void before() { Tenant tenant = new Tenant(); @@ -57,8 +64,16 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Tenant savedTenant = tenantService.saveTenant(tenant); Assert.assertNotNull(savedTenant); tenantId = savedTenant.getId(); + + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); + Assert.assertNotNull(savedDeviceProfile); + deviceProfileId = savedDeviceProfile.getId(); } + @Rule + public ExpectedException thrown = ExpectedException.none(); + @After public void after() { tenantService.deleteTenant(tenantId); @@ -68,6 +83,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { public void testSaveFirmware() { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); @@ -99,6 +116,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { public void testSaveFirmwareInfoAndUpdateWithData() { FirmwareInfo firmwareInfo = new FirmwareInfo(); firmwareInfo.setTenantId(tenantId); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo); @@ -112,6 +131,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(savedFirmwareInfo.getId()); firmware.setCreatedTime(firmwareInfo.getCreatedTime()); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); @@ -135,9 +156,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmwareService.deleteFirmware(tenantId, savedFirmwareInfo.getId()); } - @Test(expected = DataValidationException.class) + @Test public void testSaveFirmwareWithEmptyTenant() { Firmware firmware = new Firmware(); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); @@ -145,65 +168,126 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); + + thrown.expect(DataValidationException.class); + thrown.expectMessage("Firmware should be assigned to tenant!"); firmwareService.saveFirmware(firmware); } - @Test(expected = DataValidationException.class) + @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(); + firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + 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("Type should be specified!"); + firmwareService.saveFirmware(firmware); + } + + @Test public void testSaveFirmwareWithEmptyTitle() { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); 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 title should be specified!"); firmwareService.saveFirmware(firmware); } - @Test(expected = DataValidationException.class) + @Test public void testSaveFirmwareWithEmptyFileName() { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); firmware.setContentType(CONTENT_TYPE); firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); + + thrown.expect(DataValidationException.class); + thrown.expectMessage("Firmware file name should be specified!"); firmwareService.saveFirmware(firmware); } - @Test(expected = DataValidationException.class) + @Test public void testSaveFirmwareWithEmptyContentType() { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); + + thrown.expect(DataValidationException.class); + thrown.expectMessage("Firmware content type should be specified!"); firmwareService.saveFirmware(firmware); } - @Test(expected = DataValidationException.class) + @Test public void testSaveFirmwareWithEmptyData() { 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); + + thrown.expect(DataValidationException.class); + thrown.expectMessage("Firmware data should be specified!"); firmwareService.saveFirmware(firmware); } - @Test(expected = DataValidationException.class) + @Test public void testSaveFirmwareWithInvalidTenant() { Firmware firmware = new Firmware(); firmware.setTenantId(new TenantId(Uuids.timeBased())); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); @@ -211,41 +295,77 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); + + thrown.expect(DataValidationException.class); + thrown.expectMessage("Firmware is referencing to non-existent tenant!"); firmwareService.saveFirmware(firmware); } - @Test(expected = DataValidationException.class) + @Test + public void testSaveFirmwareWithInvalidDeviceProfileId() { + Firmware firmware = new Firmware(); + firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(new DeviceProfileId(Uuids.timeBased())); + 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 is referencing to non-existent device profile!"); + firmwareService.saveFirmware(firmware); + } + + @Test public void testSaveFirmwareWithEmptyChecksum() { Firmware firmware = new Firmware(); - firmware.setTenantId(new TenantId(Uuids.timeBased())); + 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.setData(DATA); + + thrown.expect(DataValidationException.class); + thrown.expectMessage("Firmware checksum should be specified!"); firmwareService.saveFirmware(firmware); } - @Test(expected = DataValidationException.class) + @Test public void testSaveFirmwareInfoWithExistingTitleAndVersion() { FirmwareInfo firmwareInfo = new FirmwareInfo(); firmwareInfo.setTenantId(tenantId); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); firmwareService.saveFirmwareInfo(firmwareInfo); FirmwareInfo newFirmwareInfo = new FirmwareInfo(); newFirmwareInfo.setTenantId(tenantId); + newFirmwareInfo.setDeviceProfileId(deviceProfileId); + newFirmwareInfo.setType(FIRMWARE); newFirmwareInfo.setTitle(TITLE); newFirmwareInfo.setVersion(VERSION); + + thrown.expect(DataValidationException.class); + thrown.expectMessage("Firmware with such title and version already exists!"); firmwareService.saveFirmwareInfo(newFirmwareInfo); } - @Test(expected = DataValidationException.class) + @Test public void testSaveFirmwareWithExistingTitleAndVersion() { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); @@ -257,18 +377,27 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware newFirmware = new Firmware(); newFirmware.setTenantId(tenantId); + newFirmware.setDeviceProfileId(deviceProfileId); + newFirmware.setType(FIRMWARE); newFirmware.setTitle(TITLE); newFirmware.setVersion(VERSION); newFirmware.setFileName(FILE_NAME); newFirmware.setContentType(CONTENT_TYPE); + newFirmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); + newFirmware.setChecksum(CHECKSUM); newFirmware.setData(DATA); + + thrown.expect(DataValidationException.class); + thrown.expectMessage("Firmware with such title and version already exists!"); firmwareService.saveFirmware(newFirmware); } - @Test(expected = DataValidationException.class) + @Test public void testDeleteFirmwareWithReferenceByDevice() { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); @@ -281,11 +410,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Device device = new Device(); device.setTenantId(tenantId); device.setName("My device"); - device.setType("default"); + device.setDeviceProfileId(deviceProfileId); device.setFirmwareId(savedFirmware.getId()); Device savedDevice = deviceService.saveDevice(device); try { + thrown.expect(DataValidationException.class); + thrown.expectMessage("The firmware referenced by the devices cannot be deleted!"); firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); } finally { deviceService.deleteDevice(tenantId, savedDevice.getId()); @@ -293,10 +424,15 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { } } - @Test(expected = DataValidationException.class) + @Test public void testDeleteFirmwareWithReferenceByDeviceProfile() { + 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); @@ -306,11 +442,12 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setData(DATA); Firmware savedFirmware = firmwareService.saveFirmware(firmware); - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); - deviceProfile.setFirmwareId(savedFirmware.getId()); - DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); + savedDeviceProfile.setFirmwareId(savedFirmware.getId()); + deviceProfileService.saveDeviceProfile(savedDeviceProfile); try { + thrown.expect(DataValidationException.class); + thrown.expectMessage("The firmware referenced by the device profile cannot be deleted!"); firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); } finally { deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); @@ -322,6 +459,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { public void testFindFirmwareById() { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); @@ -341,6 +480,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { public void testFindFirmwareInfoById() { FirmwareInfo firmware = new FirmwareInfo(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); FirmwareInfo savedFirmware = firmwareService.saveFirmwareInfo(firmware); @@ -355,6 +496,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { public void testDeleteFirmware() { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); firmware.setFileName(FILE_NAME); @@ -377,6 +520,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { for (int i = 0; i < 165; i++) { Firmware firmware = new Firmware(); firmware.setTenantId(tenantId); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION + i); firmware.setFileName(FILE_NAME); @@ -420,6 +565,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { for (int i = 0; i < 165; i++) { FirmwareInfo firmwareInfo = new FirmwareInfo(); firmwareInfo.setTenantId(tenantId); + firmwareInfo.setDeviceProfileId(deviceProfileId); + firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION + i); firmwareInfo.setFileName(FILE_NAME); @@ -434,7 +581,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { PageLink pageLink = new PageLink(16); PageData pageData; do { - pageData = firmwareService.findTenantFirmwaresByTenantIdAndHasData(tenantId, false, pageLink); + pageData = firmwareService.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, FIRMWARE, false, pageLink); loadedFirmwares.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageLink.nextPageLink(); @@ -450,6 +597,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Firmware firmware = new Firmware(f.getId()); firmware.setCreatedTime(f.getCreatedTime()); firmware.setTenantId(f.getTenantId()); + firmware.setDeviceProfileId(deviceProfileId); + firmware.setType(FIRMWARE); firmware.setTitle(f.getTitle()); firmware.setVersion(f.getVersion()); firmware.setFileName(FILE_NAME); @@ -465,7 +614,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { loadedFirmwares = new ArrayList<>(); pageLink = new PageLink(16); do { - pageData = firmwareService.findTenantFirmwaresByTenantIdAndHasData(tenantId, true, pageLink); + pageData = firmwareService.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, FIRMWARE, true, pageLink); loadedFirmwares.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageLink.nextPageLink();