From 139af45fd38a395d473ccc7532a4d0d3a281f6b6 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 31 May 2021 16:43:33 +0300 Subject: [PATCH 01/19] Renamed Firmware to OtaPackage --- .../main/data/upgrade/3.2.2/schema_update.sql | 14 +- .../server/controller/BaseController.java | 42 +- .../server/controller/DeviceController.java | 19 +- .../controller/DeviceProfileController.java | 2 +- .../server/controller/FirmwareController.java | 222 ---------- .../controller/OtaPackageController.java | 222 ++++++++++ .../DefaultOtaPackageStateService.java} | 136 +++---- .../OtaPackageStateService.java} | 8 +- .../queue/DefaultTbCoreConsumerService.java | 31 +- .../service/security/AccessValidator.java | 24 +- .../service/security/permission/Resource.java | 2 +- .../permission/TenantAdminPermissions.java | 2 +- .../transport/DefaultTransportApiService.java | 68 ++-- .../src/main/resources/thingsboard.yml | 16 +- ...java => BaseOtaPackageControllerTest.java} | 115 +++--- ....java => OtaPackageControllerSqlTest.java} | 4 +- .../CaffeineOtaPackageCache.java} | 12 +- .../OtaPackageDataCache.java} | 8 +- .../RedisOtaPackageDataCache.java} | 18 +- .../server/dao/device/DeviceService.java | 5 +- .../server/dao/firmware/FirmwareService.java | 52 --- .../server/dao/ota/OtaPackageService.java | 52 +++ .../server/common/data/CacheConstants.java | 2 +- .../server/common/data/Device.java | 16 +- .../server/common/data/DeviceProfile.java | 8 +- .../server/common/data/EntityType.java | 2 +- .../{HasFirmware.java => HasOtaPackage.java} | 8 +- .../data/{Firmware.java => OtaPackage.java} | 10 +- ...{FirmwareInfo.java => OtaPackageInfo.java} | 40 +- .../common/data/id/EntityIdFactory.java | 4 +- .../id/{FirmwareId.java => OtaPackageId.java} | 10 +- .../{firmware => ota}/ChecksumAlgorithm.java | 2 +- .../OtaPackageKey.java} | 6 +- .../OtaPackageType.java} | 6 +- .../OtaPackageUpdateStatus.java} | 4 +- .../OtaPackageUtil.java} | 49 ++- .../queue/kafka/TbKafkaTopicConfigs.java | 2 +- .../provider/AwsSqsMonolithQueueFactory.java | 10 +- .../provider/AwsSqsTbCoreQueueFactory.java | 12 +- .../InMemoryMonolithQueueFactory.java | 8 +- .../provider/KafkaMonolithQueueFactory.java | 22 +- .../provider/KafkaTbCoreQueueFactory.java | 22 +- .../provider/PubSubMonolithQueueFactory.java | 12 +- .../provider/PubSubTbCoreQueueFactory.java | 12 +- .../RabbitMqMonolithQueueFactory.java | 12 +- .../provider/RabbitMqTbCoreQueueFactory.java | 12 +- .../ServiceBusMonolithQueueFactory.java | 12 +- .../ServiceBusTbCoreQueueFactory.java | 12 +- .../queue/provider/TbCoreQueueFactory.java | 6 +- .../provider/TbCoreQueueProducerProvider.java | 4 +- .../queue/settings/TbQueueCoreSettings.java | 4 +- common/queue/src/main/proto/queue.proto | 18 +- .../transport/coap/CoapTransportResource.java | 22 +- .../transport/http/DeviceApiController.java | 32 +- .../DefaultLwM2MTransportMsgHandler.java | 52 +-- .../lwm2m/server/LwM2mTransportRequest.java | 4 +- .../lwm2m/server/LwM2mTransportUtil.java | 48 +-- .../lwm2m/server/client/LwM2mClient.java | 6 +- .../lwm2m/server/client/LwM2mFwSwUpdate.java | 28 +- .../transport/mqtt/MqttTransportHandler.java | 58 +-- .../mqtt/adaptors/JsonMqttAdaptor.java | 4 +- .../mqtt/adaptors/MqttTransportAdaptor.java | 4 +- .../mqtt/adaptors/ProtoMqttAdaptor.java | 4 +- .../common/transport/TransportContext.java | 5 +- .../common/transport/TransportService.java | 6 +- .../service/DefaultTransportService.java | 6 +- .../server/dao/device/DeviceDao.java | 8 +- .../dao/device/DeviceProfileServiceImpl.java | 16 +- .../server/dao/device/DeviceServiceImpl.java | 45 ++- .../server/dao/entity/BaseEntityService.java | 12 +- .../dao/firmware/BaseFirmwareService.java | 379 ------------------ .../server/dao/model/ModelConstants.java | 31 +- .../dao/model/sql/AbstractDeviceEntity.java | 6 +- .../dao/model/sql/DeviceProfileEntity.java | 6 +- ...mwareEntity.java => OtaPackageEntity.java} | 70 ++-- ...oEntity.java => OtaPackageInfoEntity.java} | 72 ++-- .../server/dao/ota/BaseOtaPackageService.java | 373 +++++++++++++++++ .../OtaPackageDao.java} | 6 +- .../OtaPackageInfoDao.java} | 18 +- .../dao/sql/device/DeviceRepository.java | 20 +- .../server/dao/sql/device/JpaDeviceDao.java | 36 +- .../sql/firmware/FirmwareInfoRepository.java | 60 --- .../dao/sql/firmware/JpaFirmwareInfoDao.java | 94 ----- .../JpaOtaPackageDao.java} | 20 +- .../dao/sql/ota/JpaOtaPackageInfoDao.java | 94 +++++ .../dao/sql/ota/OtaPackageInfoRepository.java | 60 +++ .../OtaPackageRepository.java} | 6 +- .../server/dao/tenant/TenantServiceImpl.java | 6 +- .../resources/sql/schema-entities-hsql.sql | 14 +- .../main/resources/sql/schema-entities.sql | 14 +- .../dao/service/AbstractServiceTest.java | 4 +- .../service/BaseDeviceProfileServiceTest.java | 11 +- .../dao/service/BaseDeviceServiceTest.java | 14 +- ...st.java => BaseOtaPackageServiceTest.java} | 214 +++++----- ...est.java => OtaPackageServiceSqlTest.java} | 4 +- .../resources/application-test.properties | 4 +- .../resources/sql/hsql/drop-all-tables.sql | 2 +- 97 files changed, 1722 insertions(+), 1697 deletions(-) delete mode 100644 application/src/main/java/org/thingsboard/server/controller/FirmwareController.java create mode 100644 application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java rename application/src/main/java/org/thingsboard/server/service/{firmware/DefaultFirmwareStateService.java => ota/DefaultOtaPackageStateService.java} (69%) rename application/src/main/java/org/thingsboard/server/service/{firmware/FirmwareStateService.java => ota/OtaPackageStateService.java} (79%) rename application/src/test/java/org/thingsboard/server/controller/{BaseFirmwareControllerTest.java => BaseOtaPackageControllerTest.java} (66%) rename application/src/test/java/org/thingsboard/server/controller/sql/{FirmwareControllerSqlTest.java => OtaPackageControllerSqlTest.java} (82%) rename common/cache/src/main/java/org/thingsboard/server/cache/{firmware/CaffeineFirmwareCache.java => ota/CaffeineOtaPackageCache.java} (84%) rename common/cache/src/main/java/org/thingsboard/server/cache/{firmware/FirmwareDataCache.java => ota/OtaPackageDataCache.java} (82%) rename common/cache/src/main/java/org/thingsboard/server/cache/{firmware/RedisFirmwareDataCache.java => ota/RedisOtaPackageDataCache.java} (78%) delete mode 100644 common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java create mode 100644 common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java rename common/data/src/main/java/org/thingsboard/server/common/data/{HasFirmware.java => HasOtaPackage.java} (80%) rename common/data/src/main/java/org/thingsboard/server/common/data/{Firmware.java => OtaPackage.java} (82%) rename common/data/src/main/java/org/thingsboard/server/common/data/{FirmwareInfo.java => OtaPackageInfo.java} (58%) rename common/data/src/main/java/org/thingsboard/server/common/data/id/{FirmwareId.java => OtaPackageId.java} (79%) rename common/data/src/main/java/org/thingsboard/server/common/data/{firmware => ota}/ChecksumAlgorithm.java (93%) rename common/data/src/main/java/org/thingsboard/server/common/data/{firmware/FirmwareKey.java => ota/OtaPackageKey.java} (88%) rename common/data/src/main/java/org/thingsboard/server/common/data/{firmware/FirmwareType.java => ota/OtaPackageType.java} (86%) rename common/data/src/main/java/org/thingsboard/server/common/data/{firmware/FirmwareUpdateStatus.java => ota/OtaPackageUpdateStatus.java} (88%) rename common/data/src/main/java/org/thingsboard/server/common/data/{firmware/FirmwareUtil.java => ota/OtaPackageUtil.java} (52%) delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java rename dao/src/main/java/org/thingsboard/server/dao/model/sql/{FirmwareEntity.java => OtaPackageEntity.java} (62%) rename dao/src/main/java/org/thingsboard/server/dao/model/sql/{FirmwareInfoEntity.java => OtaPackageInfoEntity.java} (63%) create mode 100644 dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java rename dao/src/main/java/org/thingsboard/server/dao/{firmware/FirmwareDao.java => ota/OtaPackageDao.java} (81%) rename dao/src/main/java/org/thingsboard/server/dao/{firmware/FirmwareInfoDao.java => ota/OtaPackageInfoDao.java} (55%) delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareInfoRepository.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/firmware/JpaFirmwareInfoDao.java rename dao/src/main/java/org/thingsboard/server/dao/sql/{firmware/JpaFirmwareDao.java => ota/JpaOtaPackageDao.java} (62%) create mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/ota/JpaOtaPackageInfoDao.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/ota/OtaPackageInfoRepository.java rename dao/src/main/java/org/thingsboard/server/dao/sql/{firmware/FirmwareRepository.java => ota/OtaPackageRepository.java} (78%) rename dao/src/test/java/org/thingsboard/server/dao/service/{BaseFirmwareServiceTest.java => BaseOtaPackageServiceTest.java} (74%) rename dao/src/test/java/org/thingsboard/server/dao/service/sql/{FirmwareServiceSqlTest.java => OtaPackageServiceSqlTest.java} (83%) 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 4fec49130a..2814e18c2f 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 @@ -59,8 +59,8 @@ CREATE TABLE IF NOT EXISTS resource ( CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key) ); -CREATE TABLE IF NOT EXISTS firmware ( - id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, +CREATE TABLE IF NOT EXISTS ota_package ( + id uuid NOT NULL CONSTRAINT ota_package_pkey PRIMARY KEY, created_time bigint NOT NULL, tenant_id uuid NOT NULL, device_profile_id uuid, @@ -75,7 +75,7 @@ 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 ota_package_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) ); ALTER TABLE dashboard @@ -101,13 +101,13 @@ DO $$ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device_profile') THEN ALTER TABLE device_profile ADD CONSTRAINT fk_firmware_device_profile - FOREIGN KEY (firmware_id) REFERENCES firmware(id); + FOREIGN KEY (firmware_id) REFERENCES ota_package(id); END IF; IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device_profile') THEN ALTER TABLE device_profile ADD CONSTRAINT fk_software_device_profile - FOREIGN KEY (firmware_id) REFERENCES firmware(id); + FOREIGN KEY (firmware_id) REFERENCES ota_package(id); END IF; IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_default_dashboard_device_profile') THEN @@ -119,13 +119,13 @@ DO $$ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device') THEN ALTER TABLE device ADD CONSTRAINT fk_firmware_device - FOREIGN KEY (firmware_id) REFERENCES firmware(id); + FOREIGN KEY (firmware_id) REFERENCES ota_package(id); END IF; IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device') THEN ALTER TABLE device ADD CONSTRAINT fk_software_device - FOREIGN KEY (firmware_id) REFERENCES firmware(id); + FOREIGN KEY (firmware_id) REFERENCES ota_package(id); END IF; END; $$; diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index e6384c010d..dd1d388a08 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -39,8 +39,8 @@ import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityViewInfo; -import org.thingsboard.server.common.data.Firmware; -import org.thingsboard.server.common.data.FirmwareInfo; +import org.thingsboard.server.common.data.OtaPackage; +import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.TbResourceInfo; @@ -70,7 +70,7 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; @@ -110,7 +110,7 @@ import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.IncorrectParameterException; -import org.thingsboard.server.dao.firmware.FirmwareService; +import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService; import org.thingsboard.server.dao.oauth2.OAuth2Service; @@ -128,7 +128,7 @@ import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.component.ComponentDiscoveryService; -import org.thingsboard.server.service.firmware.FirmwareStateService; +import org.thingsboard.server.service.ota.OtaPackageStateService; import org.thingsboard.server.service.edge.EdgeNotificationService; import org.thingsboard.server.service.edge.rpc.EdgeGrpcService; import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; @@ -250,10 +250,10 @@ public abstract class BaseController { protected TbResourceService resourceService; @Autowired - protected FirmwareService firmwareService; + protected OtaPackageService otaPackageService; @Autowired - protected FirmwareStateService firmwareStateService; + protected OtaPackageStateService otaPackageStateService; @Autowired protected TbQueueProducerProvider producerProvider; @@ -511,8 +511,8 @@ public abstract class BaseController { case TB_RESOURCE: checkResourceId(new TbResourceId(entityId.getId()), operation); return; - case FIRMWARE: - checkFirmwareId(new FirmwareId(entityId.getId()), operation); + case OTA_PACKAGE: + checkOtaPackageId(new OtaPackageId(entityId.getId()), operation); return; default: throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType()); @@ -769,25 +769,25 @@ public abstract class BaseController { } } - Firmware checkFirmwareId(FirmwareId firmwareId, Operation operation) throws ThingsboardException { + OtaPackage checkOtaPackageId(OtaPackageId otaPackageId, Operation operation) throws ThingsboardException { try { - validateId(firmwareId, "Incorrect firmwareId " + firmwareId); - Firmware firmware = firmwareService.findFirmwareById(getCurrentUser().getTenantId(), firmwareId); - checkNotNull(firmware); - accessControlService.checkPermission(getCurrentUser(), Resource.FIRMWARE, operation, firmwareId, firmware); - return firmware; + validateId(otaPackageId, "Incorrect otaPackageId " + otaPackageId); + OtaPackage otaPackage = otaPackageService.findOtaPackageById(getCurrentUser().getTenantId(), otaPackageId); + checkNotNull(otaPackage); + accessControlService.checkPermission(getCurrentUser(), Resource.OTA_PACKAGE, operation, otaPackageId, otaPackage); + return otaPackage; } catch (Exception e) { throw handleException(e, false); } } - FirmwareInfo checkFirmwareInfoId(FirmwareId firmwareId, Operation operation) throws ThingsboardException { + OtaPackageInfo checkOtaPackageInfoId(OtaPackageId otaPackageId, Operation operation) throws ThingsboardException { try { - validateId(firmwareId, "Incorrect firmwareId " + firmwareId); - FirmwareInfo firmwareInfo = firmwareService.findFirmwareInfoById(getCurrentUser().getTenantId(), firmwareId); - checkNotNull(firmwareInfo); - accessControlService.checkPermission(getCurrentUser(), Resource.FIRMWARE, operation, firmwareId, firmwareInfo); - return firmwareInfo; + validateId(otaPackageId, "Incorrect otaPackageId " + otaPackageId); + OtaPackageInfo otaPackageIn = otaPackageService.findOtaPackageInfoById(getCurrentUser().getTenantId(), otaPackageId); + checkNotNull(otaPackageIn); + accessControlService.checkPermission(getCurrentUser(), Resource.OTA_PACKAGE, operation, otaPackageId, otaPackageIn); + return otaPackageIn; } catch (Exception e) { throw handleException(e, false); } diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index 378083b873..90094e88c1 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -53,6 +53,7 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.TimePageLink; @@ -75,6 +76,7 @@ import javax.annotation.Nullable; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; import static org.thingsboard.server.controller.EdgeController.EDGE_ID; @@ -153,7 +155,7 @@ public class DeviceController extends BaseController { deviceStateService.onDeviceUpdated(savedDevice); } - firmwareStateService.update(savedDevice, oldDevice); + otaPackageStateService.update(savedDevice, oldDevice); return savedDevice; } catch (Exception e) { @@ -778,4 +780,19 @@ public class DeviceController extends BaseController { throw handleException(e); } } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/devices/count", method = RequestMethod.GET) + @ResponseBody + public Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(@RequestParam(required = false) String otaPackageType, + @RequestParam(required = false) String deviceProfileId) throws ThingsboardException { + checkParameter("OtaPackageType", otaPackageType); + checkParameter("DeviceProfileId", deviceProfileId); + try { + return deviceService.countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage( + getCurrentUser().getTenantId(), new DeviceProfileId(UUID.fromString(deviceProfileId)), OtaPackageType.valueOf(deviceProfileId)); + } catch (Exception e) { + throw handleException(e); + } + } } diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java index 849bcb51b9..ceee45147b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java @@ -168,7 +168,7 @@ public class DeviceProfileController extends BaseController { null, created ? ActionType.ADDED : ActionType.UPDATED, null); - firmwareStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged); + otaPackageStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged); sendEntityNotificationMsg(getTenantId(), savedDeviceProfile.getId(), deviceProfile.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); diff --git a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java b/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java deleted file mode 100644 index 6728120163..0000000000 --- a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java +++ /dev/null @@ -1,222 +0,0 @@ -/** - * Copyright © 2016-2021 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.controller; - -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.core.io.ByteArrayResource; -import org.springframework.http.HttpHeaders; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; -import org.thingsboard.server.common.data.EntityType; -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.ChecksumAlgorithm; -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; -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; - -@Slf4j -@RestController -@TbCoreComponent -@RequestMapping("/api") -public class FirmwareController extends BaseController { - - public static final String FIRMWARE_ID = "firmwareId"; - public static final String CHECKSUM_ALGORITHM = "checksumAlgorithm"; - - @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')") - @RequestMapping(value = "/firmware/{firmwareId}/download", method = RequestMethod.GET) - @ResponseBody - public ResponseEntity downloadFirmware(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException { - checkParameter(FIRMWARE_ID, strFirmwareId); - try { - FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId)); - Firmware firmware = checkFirmwareId(firmwareId, Operation.READ); - - ByteArrayResource resource = new ByteArrayResource(firmware.getData().array()); - return ResponseEntity.ok() - .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + firmware.getFileName()) - .header("x-filename", firmware.getFileName()) - .contentLength(resource.contentLength()) - .contentType(parseMediaType(firmware.getContentType())) - .body(resource); - } catch (Exception e) { - throw handleException(e); - } - } - - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/firmware/info/{firmwareId}", method = RequestMethod.GET) - @ResponseBody - public FirmwareInfo getFirmwareInfoById(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException { - checkParameter(FIRMWARE_ID, strFirmwareId); - try { - FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId)); - return checkNotNull(firmwareService.findFirmwareInfoById(getTenantId(), firmwareId)); - } catch (Exception e) { - throw handleException(e); - } - } - - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") - @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.GET) - @ResponseBody - public Firmware getFirmwareById(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException { - checkParameter(FIRMWARE_ID, strFirmwareId); - try { - FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId)); - return checkFirmwareId(firmwareId, Operation.READ); - } catch (Exception e) { - throw handleException(e); - } - } - - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") - @RequestMapping(value = "/firmware", method = RequestMethod.POST) - @ResponseBody - public FirmwareInfo saveFirmwareInfo(@RequestBody FirmwareInfo firmwareInfo) throws ThingsboardException { - boolean created = firmwareInfo.getId() == null; - try { - firmwareInfo.setTenantId(getTenantId()); - checkEntity(firmwareInfo.getId(), firmwareInfo, Resource.FIRMWARE); - FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo); - logEntityAction(savedFirmwareInfo.getId(), savedFirmwareInfo, - null, created ? ActionType.ADDED : ActionType.UPDATED, null); - return savedFirmwareInfo; - } catch (Exception e) { - logEntityAction(emptyId(EntityType.FIRMWARE), firmwareInfo, - null, created ? ActionType.ADDED : ActionType.UPDATED, 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(required = false) String checksum, - @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr, - @RequestBody MultipartFile file) throws ThingsboardException { - checkParameter(FIRMWARE_ID, strFirmwareId); - checkParameter(CHECKSUM_ALGORITHM, checksumAlgorithmStr); - 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.setDeviceProfileId(info.getDeviceProfileId()); - firmware.setType(info.getType()); - firmware.setTitle(info.getTitle()); - firmware.setVersion(info.getVersion()); - firmware.setAdditionalInfo(info.getAdditionalInfo()); - - ChecksumAlgorithm checksumAlgorithm = ChecksumAlgorithm.valueOf(checksumAlgorithmStr.toUpperCase()); - - byte[] bytes = file.getBytes(); - if (StringUtils.isEmpty(checksum)) { - checksum = firmwareService.generateChecksum(checksumAlgorithm, ByteBuffer.wrap(bytes)); - } - - firmware.setChecksumAlgorithm(checksumAlgorithm); - firmware.setChecksum(checksum); - firmware.setFileName(file.getOriginalFilename()); - firmware.setContentType(file.getContentType()); - firmware.setData(ByteBuffer.wrap(bytes)); - firmware.setDataSize((long) bytes.length); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); - logEntityAction(savedFirmware.getId(), savedFirmware, null, ActionType.UPDATED, null); - return savedFirmware; - } catch (Exception e) { - logEntityAction(emptyId(EntityType.FIRMWARE), null, null, ActionType.UPDATED, e, strFirmwareId); - throw handleException(e); - } - } - - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/firmwares", method = RequestMethod.GET) - @ResponseBody - public PageData getFirmwares(@RequestParam int pageSize, - @RequestParam int page, - @RequestParam(required = false) String textSearch, - @RequestParam(required = false) String sortProperty, - @RequestParam(required = false) String sortOrder) throws ThingsboardException { - try { - PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); - return checkNotNull(firmwareService.findTenantFirmwaresByTenantId(getTenantId(), pageLink)); - } catch (Exception e) { - throw handleException(e); - } - } - - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/firmwares/{deviceProfileId}/{type}/{hasData}", method = RequestMethod.GET) - @ResponseBody - 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.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(getTenantId(), - new DeviceProfileId(toUUID(strDeviceProfileId)), FirmwareType.valueOf(strType), hasData, pageLink)); - } catch (Exception e) { - throw handleException(e); - } - } - - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") - @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.DELETE) - @ResponseBody - public void deleteFirmware(@PathVariable("firmwareId") String strFirmwareId) throws ThingsboardException { - checkParameter(FIRMWARE_ID, strFirmwareId); - try { - FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId)); - FirmwareInfo info = checkFirmwareInfoId(firmwareId, Operation.DELETE); - firmwareService.deleteFirmware(getTenantId(), firmwareId); - logEntityAction(firmwareId, info, null, ActionType.DELETED, null, strFirmwareId); - } catch (Exception e) { - logEntityAction(emptyId(EntityType.FIRMWARE), null, null, ActionType.DELETED, e, strFirmwareId); - throw handleException(e); - } - } - -} diff --git a/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java b/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java new file mode 100644 index 0000000000..02e9d4b305 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java @@ -0,0 +1,222 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.controller; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.OtaPackage; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.id.DeviceProfileId; +import org.thingsboard.server.common.data.id.OtaPackageId; +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; + +@Slf4j +@RestController +@TbCoreComponent +@RequestMapping("/api") +public class OtaPackageController extends BaseController { + + public static final String OTA_PACKAGE_ID = "otaPackageId"; + public static final String CHECKSUM_ALGORITHM = "checksumAlgorithm"; + + @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')") + @RequestMapping(value = "/otaPackage/{otaPackageId}/download", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity downloadOtaPackage(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException { + checkParameter(OTA_PACKAGE_ID, strOtaPackageId); + try { + OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); + OtaPackage otaPackage = checkOtaPackageId(otaPackageId, Operation.READ); + + ByteArrayResource resource = new ByteArrayResource(otaPackage.getData().array()); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + otaPackage.getFileName()) + .header("x-filename", otaPackage.getFileName()) + .contentLength(resource.contentLength()) + .contentType(parseMediaType(otaPackage.getContentType())) + .body(resource); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/otaPackage/info/{otaPackageId}", method = RequestMethod.GET) + @ResponseBody + public OtaPackageInfo getOtaPackageInfoById(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException { + checkParameter(OTA_PACKAGE_ID, strOtaPackageId); + try { + OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); + return checkNotNull(otaPackageService.findOtaPackageInfoById(getTenantId(), otaPackageId)); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.GET) + @ResponseBody + public OtaPackage getOtaPackageById(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException { + checkParameter(OTA_PACKAGE_ID, strOtaPackageId); + try { + OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); + return checkOtaPackageId(otaPackageId, Operation.READ); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/otaPackage", method = RequestMethod.POST) + @ResponseBody + public OtaPackageInfo saveOtaPackageInfo(@RequestBody OtaPackageInfo otaPackageInfo) throws ThingsboardException { + boolean created = otaPackageInfo.getId() == null; + try { + otaPackageInfo.setTenantId(getTenantId()); + checkEntity(otaPackageInfo.getId(), otaPackageInfo, Resource.OTA_PACKAGE); + OtaPackageInfo savedOtaPackageInfo = otaPackageService.saveOtaPackageInfo(otaPackageInfo); + logEntityAction(savedOtaPackageInfo.getId(), savedOtaPackageInfo, + null, created ? ActionType.ADDED : ActionType.UPDATED, null); + return savedOtaPackageInfo; + } catch (Exception e) { + logEntityAction(emptyId(EntityType.OTA_PACKAGE), otaPackageInfo, + null, created ? ActionType.ADDED : ActionType.UPDATED, e); + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.POST) + @ResponseBody + public OtaPackage saveOtaPackageData(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId, + @RequestParam(required = false) String checksum, + @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr, + @RequestBody MultipartFile file) throws ThingsboardException { + checkParameter(OTA_PACKAGE_ID, strOtaPackageId); + checkParameter(CHECKSUM_ALGORITHM, checksumAlgorithmStr); + try { + OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); + OtaPackageInfo info = checkOtaPackageInfoId(otaPackageId, Operation.READ); + + OtaPackage otaPackage = new OtaPackage(otaPackageId); + otaPackage.setCreatedTime(info.getCreatedTime()); + otaPackage.setTenantId(getTenantId()); + otaPackage.setDeviceProfileId(info.getDeviceProfileId()); + otaPackage.setType(info.getType()); + otaPackage.setTitle(info.getTitle()); + otaPackage.setVersion(info.getVersion()); + otaPackage.setAdditionalInfo(info.getAdditionalInfo()); + + ChecksumAlgorithm checksumAlgorithm = ChecksumAlgorithm.valueOf(checksumAlgorithmStr.toUpperCase()); + + byte[] bytes = file.getBytes(); + if (StringUtils.isEmpty(checksum)) { + checksum = otaPackageService.generateChecksum(checksumAlgorithm, ByteBuffer.wrap(bytes)); + } + + otaPackage.setChecksumAlgorithm(checksumAlgorithm); + otaPackage.setChecksum(checksum); + otaPackage.setFileName(file.getOriginalFilename()); + otaPackage.setContentType(file.getContentType()); + otaPackage.setData(ByteBuffer.wrap(bytes)); + otaPackage.setDataSize((long) bytes.length); + OtaPackage savedOtaPackage = otaPackageService.saveOtaPackage(otaPackage); + logEntityAction(savedOtaPackage.getId(), savedOtaPackage, null, ActionType.UPDATED, null); + return savedOtaPackage; + } catch (Exception e) { + logEntityAction(emptyId(EntityType.OTA_PACKAGE), null, null, ActionType.UPDATED, e, strOtaPackageId); + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/otaPackages", method = RequestMethod.GET) + @ResponseBody + public PageData getOtaPackages(@RequestParam int pageSize, + @RequestParam int page, + @RequestParam(required = false) String textSearch, + @RequestParam(required = false) String sortProperty, + @RequestParam(required = false) String sortOrder) throws ThingsboardException { + try { + PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); + return checkNotNull(otaPackageService.findTenantOtaPackagesByTenantId(getTenantId(), pageLink)); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/otaPackages/{deviceProfileId}/{type}/{hasData}", method = RequestMethod.GET) + @ResponseBody + public PageData getOtaPackages(@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(otaPackageService.findTenantOtaPackagesByTenantIdAndDeviceProfileIdAndTypeAndHasData(getTenantId(), + new DeviceProfileId(toUUID(strDeviceProfileId)), OtaPackageType.valueOf(strType), hasData, pageLink)); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.DELETE) + @ResponseBody + public void deleteOtaPackage(@PathVariable("otaPackageId") String strOtaPackageId) throws ThingsboardException { + checkParameter(OTA_PACKAGE_ID, strOtaPackageId); + try { + OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); + OtaPackageInfo info = checkOtaPackageInfoId(otaPackageId, Operation.DELETE); + otaPackageService.deleteOtaPackage(getTenantId(), otaPackageId); + logEntityAction(otaPackageId, info, null, ActionType.DELETED, null, strOtaPackageId); + } catch (Exception e) { + logEntityAction(emptyId(EntityType.OTA_PACKAGE), null, null, ActionType.DELETED, e, strOtaPackageId); + 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/ota/DefaultOtaPackageStateService.java similarity index 69% rename from application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java rename to application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java index 9720cd2097..c5d0c0472f 100644 --- a/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.service.firmware; +package org.thingsboard.server.service.ota; import com.google.common.util.concurrent.FutureCallback; import lombok.extern.slf4j.Slf4j; @@ -23,12 +23,9 @@ import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.FirmwareInfo; -import org.thingsboard.server.common.data.firmware.FirmwareType; -import org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus; -import org.thingsboard.server.common.data.firmware.FirmwareUtil; +import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.AttributeKey; import org.thingsboard.server.common.data.kv.AttributeKvEntry; @@ -37,13 +34,16 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus; +import org.thingsboard.server.common.data.ota.OtaPackageUtil; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.device.DeviceService; -import org.thingsboard.server.dao.firmware.FirmwareService; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.dao.ota.OtaPackageService; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.provider.TbCoreQueueFactory; @@ -58,44 +58,43 @@ import java.util.List; import java.util.Set; import java.util.UUID; import java.util.function.Consumer; -import java.util.function.Function; - -import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM; -import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM_ALGORITHM; -import static org.thingsboard.server.common.data.firmware.FirmwareKey.SIZE; -import static org.thingsboard.server.common.data.firmware.FirmwareKey.STATE; -import static org.thingsboard.server.common.data.firmware.FirmwareKey.TITLE; -import static org.thingsboard.server.common.data.firmware.FirmwareKey.TS; -import static org.thingsboard.server.common.data.firmware.FirmwareKey.VERSION; -import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; -import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE; -import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getAttributeKey; -import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getTargetTelemetryKey; -import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getTelemetryKey; + +import static org.thingsboard.server.common.data.ota.OtaPackageKey.CHECKSUM; +import static org.thingsboard.server.common.data.ota.OtaPackageKey.CHECKSUM_ALGORITHM; +import static org.thingsboard.server.common.data.ota.OtaPackageKey.SIZE; +import static org.thingsboard.server.common.data.ota.OtaPackageKey.STATE; +import static org.thingsboard.server.common.data.ota.OtaPackageKey.TITLE; +import static org.thingsboard.server.common.data.ota.OtaPackageKey.TS; +import static org.thingsboard.server.common.data.ota.OtaPackageKey.VERSION; +import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; +import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE; +import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey; +import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getTargetTelemetryKey; +import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getTelemetryKey; @Slf4j @Service @TbCoreComponent -public class DefaultFirmwareStateService implements FirmwareStateService { +public class DefaultOtaPackageStateService implements OtaPackageStateService { private final TbClusterService tbClusterService; - private final FirmwareService firmwareService; + private final OtaPackageService otaPackageService; private final DeviceService deviceService; private final DeviceProfileService deviceProfileService; private final RuleEngineTelemetryService telemetryService; - private final TbQueueProducer> fwStateMsgProducer; + private final TbQueueProducer> otaPackageStateMsgProducer; - public DefaultFirmwareStateService(TbClusterService tbClusterService, FirmwareService firmwareService, - DeviceService deviceService, - DeviceProfileService deviceProfileService, - RuleEngineTelemetryService telemetryService, - TbCoreQueueFactory coreQueueFactory) { + public DefaultOtaPackageStateService(TbClusterService tbClusterService, OtaPackageService otaPackageService, + DeviceService deviceService, + DeviceProfileService deviceProfileService, + RuleEngineTelemetryService telemetryService, + TbCoreQueueFactory coreQueueFactory) { this.tbClusterService = tbClusterService; - this.firmwareService = firmwareService; + this.otaPackageService = otaPackageService; this.deviceService = deviceService; this.deviceProfileService = deviceProfileService; this.telemetryService = telemetryService; - this.fwStateMsgProducer = coreQueueFactory.createToFirmwareStateServiceMsgProducer(); + this.otaPackageStateMsgProducer = coreQueueFactory.createToOtaPackageStateServiceMsgProducer(); } @Override @@ -105,14 +104,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService { } private void updateFirmware(Device device, Device oldDevice) { - FirmwareId newFirmwareId = device.getFirmwareId(); + OtaPackageId newFirmwareId = device.getFirmwareId(); if (newFirmwareId == null) { DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId()); newFirmwareId = newDeviceProfile.getFirmwareId(); } if (oldDevice != null) { if (newFirmwareId != null) { - FirmwareId oldFirmwareId = oldDevice.getFirmwareId(); + OtaPackageId oldFirmwareId = oldDevice.getFirmwareId(); if (oldFirmwareId == null) { DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(oldDevice.getTenantId(), oldDevice.getDeviceProfileId()); oldFirmwareId = oldDeviceProfile.getFirmwareId(); @@ -132,14 +131,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService { } private void updateSoftware(Device device, Device oldDevice) { - FirmwareId newSoftwareId = device.getSoftwareId(); + OtaPackageId newSoftwareId = device.getSoftwareId(); if (newSoftwareId == null) { DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId()); newSoftwareId = newDeviceProfile.getSoftwareId(); } if (oldDevice != null) { if (newSoftwareId != null) { - FirmwareId oldSoftwareId = oldDevice.getSoftwareId(); + OtaPackageId oldSoftwareId = oldDevice.getSoftwareId(); if (oldSoftwareId == null) { DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(oldDevice.getTenantId(), oldDevice.getDeviceProfileId()); oldSoftwareId = oldDeviceProfile.getSoftwareId(); @@ -170,33 +169,20 @@ public class DefaultFirmwareStateService implements FirmwareStateService { } } - private void update(TenantId tenantId, DeviceProfile deviceProfile, FirmwareType firmwareType) { - Function> getDevicesFunction; + private void update(TenantId tenantId, DeviceProfile deviceProfile, OtaPackageType otaPackageType) { Consumer updateConsumer; - switch (firmwareType) { - case FIRMWARE: - getDevicesFunction = pl -> deviceService.findDevicesByTenantIdAndTypeAndEmptyFirmware(tenantId, deviceProfile.getName(), pl); - break; - case SOFTWARE: - getDevicesFunction = pl -> deviceService.findDevicesByTenantIdAndTypeAndEmptySoftware(tenantId, deviceProfile.getName(), pl); - break; - default: - log.warn("Unsupported firmware type: [{}]", firmwareType); - return; - } - if (deviceProfile.getFirmwareId() != null) { long ts = System.currentTimeMillis(); - updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts, firmwareType); + updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts, otaPackageType); } else { - updateConsumer = d -> remove(d, firmwareType); + updateConsumer = d -> remove(d, otaPackageType); } PageLink pageLink = new PageLink(100); PageData pageData; do { - pageData = getDevicesFunction.apply(pageLink); + pageData = deviceService.findDevicesByTenantIdAndTypeAndEmptyOtaPackage(tenantId, deviceProfile.getId(), otaPackageType, pageLink); pageData.getData().forEach(updateConsumer); if (pageData.hasNext()) { @@ -206,60 +192,60 @@ public class DefaultFirmwareStateService implements FirmwareStateService { } @Override - public boolean process(ToFirmwareStateServiceMsg msg) { + public boolean process(ToOtaPackageStateServiceMsg msg) { boolean isSuccess = false; - FirmwareId targetFirmwareId = new FirmwareId(new UUID(msg.getFirmwareIdMSB(), msg.getFirmwareIdLSB())); + OtaPackageId targetOtaPackageId = new OtaPackageId(new UUID(msg.getOtaPackageIdMSB(), msg.getOtaPackageIdLSB())); DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB())); TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB())); - FirmwareType firmwareType = FirmwareType.valueOf(msg.getType()); + OtaPackageType firmwareType = OtaPackageType.valueOf(msg.getType()); long ts = msg.getTs(); Device device = deviceService.findDeviceById(tenantId, deviceId); if (device == null) { log.warn("[{}] [{}] Device was removed during firmware update msg was queued!", tenantId, deviceId); } else { - FirmwareId currentFirmwareId = FirmwareUtil.getFirmwareId(device, firmwareType); - if (currentFirmwareId == null) { + OtaPackageId currentOtaPackageId = OtaPackageUtil.getOtaPackageId(device, firmwareType); + if (currentOtaPackageId == null) { DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(tenantId, device.getDeviceProfileId()); - currentFirmwareId = FirmwareUtil.getFirmwareId(deviceProfile, firmwareType); + currentOtaPackageId = OtaPackageUtil.getOtaPackageId(deviceProfile, firmwareType); } - if (targetFirmwareId.equals(currentFirmwareId)) { - update(device, firmwareService.findFirmwareInfoById(device.getTenantId(), targetFirmwareId), ts); + if (targetOtaPackageId.equals(currentOtaPackageId)) { + update(device, otaPackageService.findOtaPackageInfoById(device.getTenantId(), targetOtaPackageId), ts); isSuccess = true; } else { - log.warn("[{}] [{}] Can`t update firmware for the device, target firmwareId: [{}], current firmwareId: [{}]!", tenantId, deviceId, targetFirmwareId, currentFirmwareId); + log.warn("[{}] [{}] Can`t update firmware for the device, target firmwareId: [{}], current firmwareId: [{}]!", tenantId, deviceId, targetOtaPackageId, currentOtaPackageId); } } return isSuccess; } - private void send(TenantId tenantId, DeviceId deviceId, FirmwareId firmwareId, long ts, FirmwareType firmwareType) { - ToFirmwareStateServiceMsg msg = ToFirmwareStateServiceMsg.newBuilder() + private void send(TenantId tenantId, DeviceId deviceId, OtaPackageId firmwareId, long ts, OtaPackageType firmwareType) { + ToOtaPackageStateServiceMsg msg = ToOtaPackageStateServiceMsg.newBuilder() .setTenantIdMSB(tenantId.getId().getMostSignificantBits()) .setTenantIdLSB(tenantId.getId().getLeastSignificantBits()) .setDeviceIdMSB(deviceId.getId().getMostSignificantBits()) .setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()) - .setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits()) - .setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits()) + .setOtaPackageIdMSB(firmwareId.getId().getMostSignificantBits()) + .setOtaPackageIdLSB(firmwareId.getId().getLeastSignificantBits()) .setType(firmwareType.name()) .setTs(ts) .build(); - FirmwareInfo firmware = firmwareService.findFirmwareInfoById(tenantId, firmwareId); + OtaPackageInfo firmware = otaPackageService.findOtaPackageInfoById(tenantId, firmwareId); if (firmware == null) { log.warn("[{}] Failed to send firmware update because firmware was already deleted", firmwareId); return; } - TopicPartitionInfo tpi = new TopicPartitionInfo(fwStateMsgProducer.getDefaultTopic(), null, null, false); - fwStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null); + TopicPartitionInfo tpi = new TopicPartitionInfo(otaPackageStateMsgProducer.getDefaultTopic(), null, null, false); + otaPackageStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null); List telemetry = new ArrayList<>(); telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), TITLE), firmware.getTitle()))); telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), VERSION), firmware.getVersion()))); telemetry.add(new BasicTsKvEntry(ts, new LongDataEntry(getTargetTelemetryKey(firmware.getType(), TS), ts))); - telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), FirmwareUpdateStatus.QUEUED.name()))); + telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), OtaPackageUpdateStatus.QUEUED.name()))); telemetryService.saveAndNotify(tenantId, deviceId, telemetry, new FutureCallback<>() { @Override @@ -275,11 +261,11 @@ public class DefaultFirmwareStateService implements FirmwareStateService { } - private void update(Device device, FirmwareInfo firmware, long ts) { + private void update(Device device, OtaPackageInfo firmware, long ts) { TenantId tenantId = device.getTenantId(); DeviceId deviceId = device.getId(); - BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), FirmwareUpdateStatus.INITIATED.name())); + BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), OtaPackageUpdateStatus.INITIATED.name())); telemetryService.saveAndNotify(tenantId, deviceId, Collections.singletonList(status), new FutureCallback<>() { @Override @@ -313,14 +299,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService { }); } - private void remove(Device device, FirmwareType firmwareType) { - telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, FirmwareUtil.getAttributeKeys(firmwareType), + private void remove(Device device, OtaPackageType firmwareType) { + telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, OtaPackageUtil.getAttributeKeys(firmwareType), new FutureCallback<>() { @Override public void onSuccess(@Nullable Void tmp) { log.trace("[{}] Success remove target firmware attributes!", device.getId()); Set keysToNotify = new HashSet<>(); - FirmwareUtil.ALL_FW_ATTRIBUTE_KEYS.forEach(key -> keysToNotify.add(new AttributeKey(DataConstants.SHARED_SCOPE, key))); + OtaPackageUtil.ALL_FW_ATTRIBUTE_KEYS.forEach(key -> keysToNotify.add(new AttributeKey(DataConstants.SHARED_SCOPE, key))); tbClusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onDelete(device.getTenantId(), device.getId(), keysToNotify), null); } diff --git a/application/src/main/java/org/thingsboard/server/service/firmware/FirmwareStateService.java b/application/src/main/java/org/thingsboard/server/service/ota/OtaPackageStateService.java similarity index 79% rename from application/src/main/java/org/thingsboard/server/service/firmware/FirmwareStateService.java rename to application/src/main/java/org/thingsboard/server/service/ota/OtaPackageStateService.java index 8562f096c9..9392d1c888 100644 --- a/application/src/main/java/org/thingsboard/server/service/firmware/FirmwareStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/ota/OtaPackageStateService.java @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.service.firmware; +package org.thingsboard.server.service.ota; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; -public interface FirmwareStateService { +public interface OtaPackageStateService { void update(Device device, Device oldDevice); void update(DeviceProfile deviceProfile, boolean isFirmwareChanged, boolean isSoftwareChanged); - boolean process(ToFirmwareStateServiceMsg msg); + boolean process(ToOtaPackageStateServiceMsg msg); } diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java index b8c8698d52..ceb364f921 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java @@ -50,7 +50,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionCloseP import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesUpdateProto; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; import org.thingsboard.server.queue.TbQueueConsumer; @@ -60,7 +60,7 @@ import org.thingsboard.server.queue.provider.TbCoreQueueFactory; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import org.thingsboard.server.service.edge.EdgeNotificationService; -import org.thingsboard.server.service.firmware.FirmwareStateService; +import org.thingsboard.server.service.ota.OtaPackageStateService; import org.thingsboard.server.service.profile.TbDeviceProfileCache; import org.thingsboard.server.service.queue.processing.AbstractConsumerService; import org.thingsboard.server.service.queue.processing.IdMsgPair; @@ -75,7 +75,6 @@ import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWra import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; -import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -101,9 +100,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService> mainConsumer; @@ -113,10 +112,10 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService> usageStatsConsumer; - private final TbQueueConsumer> firmwareStatesConsumer; + private final TbQueueConsumer> firmwareStatesConsumer; protected volatile ExecutorService usageStatsExecutor; @@ -135,11 +134,11 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService { while (!stopped) { try { - List> msgs = firmwareStatesConsumer.poll(getNotificationPollDuration()); + List> msgs = firmwareStatesConsumer.poll(getNotificationPollDuration()); if (msgs.isEmpty()) { continue; } long timeToSleep = maxProcessingTimeoutPerRecord; - for (TbProtoQueueMsg msg : msgs) { + for (TbProtoQueueMsg msg : msgs) { try { long startTime = System.currentTimeMillis(); - boolean isSuccessUpdate = handleFirmwareUpdates(msg); + boolean isSuccessUpdate = handleOtaPackageUpdates(msg); long endTime = System.currentTimeMillis(); long spentTime = endTime - startTime; timeToSleep = timeToSleep - spentTime; @@ -402,7 +401,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService msg) { + private boolean handleOtaPackageUpdates(TbProtoQueueMsg msg) { return firmwareStateService.process(msg.getValue()); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java b/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java index 914b9ce7fa..540a47e8b0 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java +++ b/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java @@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.EntityView; -import org.thingsboard.server.common.data.FirmwareInfo; +import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; @@ -46,7 +46,7 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TbResourceId; @@ -63,7 +63,7 @@ import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.exception.IncorrectParameterException; -import org.thingsboard.server.dao.firmware.FirmwareService; +import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.resource.ResourceService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.tenant.TenantService; @@ -135,7 +135,7 @@ public class AccessValidator { protected ResourceService resourceService; @Autowired - protected FirmwareService firmwareService; + protected OtaPackageService otaPackageService; private ExecutorService executor; @@ -232,8 +232,8 @@ public class AccessValidator { case TB_RESOURCE: validateResource(currentUser, operation, entityId, callback); return; - case FIRMWARE: - validateFirmware(currentUser, operation, entityId, callback); + case OTA_PACKAGE: + validateOtaPackage(currentUser, operation, entityId, callback); return; default: //TODO: add support of other entities @@ -300,20 +300,20 @@ public class AccessValidator { } } - private void validateFirmware(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback callback) { + private void validateOtaPackage(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback callback) { if (currentUser.isSystemAdmin()) { callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); } else { - FirmwareInfo firmware = firmwareService.findFirmwareInfoById(currentUser.getTenantId(), new FirmwareId(entityId.getId())); - if (firmware == null) { - callback.onSuccess(ValidationResult.entityNotFound("Firmware with requested id wasn't found!")); + OtaPackageInfo otaPackage = otaPackageService.findOtaPackageInfoById(currentUser.getTenantId(), new OtaPackageId(entityId.getId())); + if (otaPackage == null) { + callback.onSuccess(ValidationResult.entityNotFound("OtaPackage with requested id wasn't found!")); } else { try { - accessControlService.checkPermission(currentUser, Resource.FIRMWARE, operation, entityId, firmware); + accessControlService.checkPermission(currentUser, Resource.OTA_PACKAGE, operation, entityId, otaPackage); } catch (ThingsboardException e) { callback.onSuccess(ValidationResult.accessDenied(e.getMessage())); } - callback.onSuccess(ValidationResult.ok(firmware)); + callback.onSuccess(ValidationResult.ok(otaPackage)); } } } diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java b/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java index 75119c402d..43c420a94a 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java @@ -38,7 +38,7 @@ public enum Resource { DEVICE_PROFILE(EntityType.DEVICE_PROFILE), API_USAGE_STATE(EntityType.API_USAGE_STATE), TB_RESOURCE(EntityType.TB_RESOURCE), - FIRMWARE(EntityType.FIRMWARE), + OTA_PACKAGE(EntityType.OTA_PACKAGE), EDGE(EntityType.EDGE); private final EntityType entityType; diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java index af08e38087..8b4d44e938 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java @@ -42,7 +42,7 @@ public class TenantAdminPermissions extends AbstractPermissions { put(Resource.DEVICE_PROFILE, tenantEntityPermissionChecker); put(Resource.API_USAGE_STATE, tenantEntityPermissionChecker); put(Resource.TB_RESOURCE, tbResourcePermissionChecker); - put(Resource.FIRMWARE, tenantEntityPermissionChecker); + put(Resource.OTA_PACKAGE, tenantEntityPermissionChecker); put(Resource.EDGE, tenantEntityPermissionChecker); } 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 bd2df29617..76bbe1f518 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 @@ -26,27 +26,27 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.cache.firmware.FirmwareDataCache; +import org.thingsboard.server.cache.ota.OtaPackageDataCache; import org.thingsboard.server.common.data.ApiUsageState; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.Firmware; -import org.thingsboard.server.common.data.FirmwareInfo; +import org.thingsboard.server.common.data.OtaPackage; +import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData; import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; -import org.thingsboard.server.common.data.firmware.FirmwareType; -import org.thingsboard.server.common.data.firmware.FirmwareUtil; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.ota.OtaPackageUtil; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -64,7 +64,7 @@ import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.device.provision.ProvisionFailedException; import org.thingsboard.server.dao.device.provision.ProvisionRequest; import org.thingsboard.server.dao.device.provision.ProvisionResponse; -import org.thingsboard.server.dao.firmware.FirmwareService; +import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.gen.transport.TransportProtos; @@ -124,8 +124,8 @@ public class DefaultTransportApiService implements TransportApiService { private final DataDecodingEncodingService dataDecodingEncodingService; private final DeviceProvisionService deviceProvisionService; private final TbResourceService resourceService; - private final FirmwareService firmwareService; - private final FirmwareDataCache firmwareDataCache; + private final OtaPackageService otaPackageService; + private final OtaPackageDataCache otaPackageDataCache; private final ConcurrentMap deviceCreationLocks = new ConcurrentHashMap<>(); @@ -134,7 +134,7 @@ public class DefaultTransportApiService implements TransportApiService { RelationService relationService, DeviceCredentialsService deviceCredentialsService, DeviceStateService deviceStateService, DbCallbackExecutorService dbCallbackExecutorService, TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService, - DeviceProvisionService deviceProvisionService, TbResourceService resourceService, FirmwareService firmwareService, FirmwareDataCache firmwareDataCache) { + DeviceProvisionService deviceProvisionService, TbResourceService resourceService, OtaPackageService otaPackageService, OtaPackageDataCache otaPackageDataCache) { this.deviceProfileCache = deviceProfileCache; this.tenantProfileCache = tenantProfileCache; this.apiUsageStateService = apiUsageStateService; @@ -147,8 +147,8 @@ public class DefaultTransportApiService implements TransportApiService { this.dataDecodingEncodingService = dataDecodingEncodingService; this.deviceProvisionService = deviceProvisionService; this.resourceService = resourceService; - this.firmwareService = firmwareService; - this.firmwareDataCache = firmwareDataCache; + this.otaPackageService = otaPackageService; + this.otaPackageDataCache = otaPackageDataCache; } @Override @@ -184,8 +184,8 @@ public class DefaultTransportApiService implements TransportApiService { result = handle(transportApiRequestMsg.getDeviceRequestMsg()); } else if (transportApiRequestMsg.hasDeviceCredentialsRequestMsg()) { result = handle(transportApiRequestMsg.getDeviceCredentialsRequestMsg()); - } else if (transportApiRequestMsg.hasFirmwareRequestMsg()) { - result = handle(transportApiRequestMsg.getFirmwareRequestMsg()); + } else if (transportApiRequestMsg.hasOtaPackageRequestMsg()) { + result = handle(transportApiRequestMsg.getOtaPackageRequestMsg()); } return Futures.transform(Optional.ofNullable(result).orElseGet(this::getEmptyTransportApiResponseFuture), @@ -511,50 +511,50 @@ public class DefaultTransportApiService implements TransportApiService { } } - private ListenableFuture handle(TransportProtos.GetFirmwareRequestMsg requestMsg) { + private ListenableFuture handle(TransportProtos.GetOtaPackageRequestMsg requestMsg) { TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); - FirmwareType firmwareType = FirmwareType.valueOf(requestMsg.getType()); + OtaPackageType otaPackageType = OtaPackageType.valueOf(requestMsg.getType()); Device device = deviceService.findDeviceById(tenantId, deviceId); if (device == null) { return getEmptyTransportApiResponseFuture(); } - FirmwareId firmwareId = FirmwareUtil.getFirmwareId(device, firmwareType); - if (firmwareId == null) { + OtaPackageId otaPackageId = OtaPackageUtil.getOtaPackageId(device, otaPackageType); + if (otaPackageId == null) { DeviceProfile deviceProfile = deviceProfileCache.find(device.getDeviceProfileId()); - firmwareId = FirmwareUtil.getFirmwareId(deviceProfile, firmwareType); + otaPackageId = OtaPackageUtil.getOtaPackageId(deviceProfile, otaPackageType); } - TransportProtos.GetFirmwareResponseMsg.Builder builder = TransportProtos.GetFirmwareResponseMsg.newBuilder(); + TransportProtos.GetOtaPackageResponseMsg.Builder builder = TransportProtos.GetOtaPackageResponseMsg.newBuilder(); - if (firmwareId == null) { + if (otaPackageId == null) { builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND); } else { - FirmwareInfo firmwareInfo = firmwareService.findFirmwareInfoById(tenantId, firmwareId); + OtaPackageInfo otaPackageInfo = otaPackageService.findOtaPackageInfoById(tenantId, otaPackageId); - if (firmwareInfo == null) { + if (otaPackageInfo == null) { builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND); } else { 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()); - builder.setContentType(firmwareInfo.getContentType()); - if (!firmwareDataCache.has(firmwareId.toString())) { - Firmware firmware = firmwareService.findFirmwareById(tenantId, firmwareId); - firmwareDataCache.put(firmwareId.toString(), firmware.getData().array()); + builder.setOtaPackageIdMSB(otaPackageId.getId().getMostSignificantBits()); + builder.setOtaPackageIdLSB(otaPackageId.getId().getLeastSignificantBits()); + builder.setType(otaPackageInfo.getType().name()); + builder.setTitle(otaPackageInfo.getTitle()); + builder.setVersion(otaPackageInfo.getVersion()); + builder.setFileName(otaPackageInfo.getFileName()); + builder.setContentType(otaPackageInfo.getContentType()); + if (!otaPackageDataCache.has(otaPackageId.toString())) { + OtaPackage otaPackage = otaPackageService.findOtaPackageById(tenantId, otaPackageId); + otaPackageDataCache.put(otaPackageId.toString(), otaPackage.getData().array()); } } } return Futures.immediateFuture( TransportApiResponseMsg.newBuilder() - .setFirmwareResponseMsg(builder.build()) + .setOtaPackageResponseMsg(builder.build()) .build()); } diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 7fde122cf6..ae628bf9f6 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -371,7 +371,7 @@ caffeine: tokensOutdatageTime: timeToLiveInMinutes: 20000 maxSize: 10000 - firmwares: + otaPackages: timeToLiveInMinutes: 60 maxSize: 10 edges: @@ -497,7 +497,7 @@ audit-log: "device_profile": "${AUDIT_LOG_MASK_DEVICE_PROFILE:W}" "edge": "${AUDIT_LOG_MASK_EDGE:W}" "tb_resource": "${AUDIT_LOG_MASK_RESOURCE:W}" - "firmware": "${AUDIT_LOG_MASK_FIRMWARE:W}" + "ota_package": "${AUDIT_LOG_MASK_OTA_PACKAGE:W}" sink: # Type of external sink. possible options: none, elasticsearch type: "${AUDIT_LOG_SINK_TYPE:none}" @@ -749,7 +749,7 @@ queue: sasl.config: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_JAAS_CONFIG:org.apache.kafka.common.security.plain.PlainLoginModule required username=\"CLUSTER_API_KEY\" password=\"CLUSTER_API_SECRET\";}" security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" consumer-properties-per-topic: - tb_firmware: + tb_ota_package: - key: max.poll.records value: 10 other: @@ -759,7 +759,7 @@ queue: transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}" notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}" js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100;min.insync.replicas:1}" - fw-updates: "${TB_QUEUE_KAFKA_FW_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:10;min.insync.replicas:1}" + ota-updates: "${TB_QUEUE_KAFKA_OTA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:10;min.insync.replicas:1}" consumer-stats: enabled: "${TB_QUEUE_KAFKA_CONSUMER_STATS_ENABLED:true}" print-interval-ms: "${TB_QUEUE_KAFKA_CONSUMER_STATS_MIN_PRINT_INTERVAL_MS:60000}" @@ -830,10 +830,10 @@ queue: poll-interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}" partitions: "${TB_QUEUE_CORE_PARTITIONS:10}" pack-processing-timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:2000}" - firmware: - topic: "${TB_QUEUE_CORE_FW_TOPIC:tb_firmware}" - pack-interval-ms: "${TB_QUEUE_CORE_FW_PACK_INTERVAL_MS:60000}" - pack-size: "${TB_QUEUE_CORE_FW_PACK_SIZE:100}" + ota: + topic: "${TB_QUEUE_CORE_OTA_TOPIC:tb_ota_package}" + pack-interval-ms: "${TB_QUEUE_CORE_OTA_PACK_INTERVAL_MS:60000}" + pack-size: "${TB_QUEUE_CORE_OTA_PACK_SIZE:100}" usage-stats-topic: "${TB_QUEUE_US_TOPIC:tb_usage_stats}" stats: enabled: "${TB_QUEUE_CORE_STATS_ENABLED:true}" diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java similarity index 66% rename from application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java index ec36be13a5..9b73053831 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java @@ -25,11 +25,10 @@ import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequ 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.OtaPackage; +import org.thingsboard.server.common.data.OtaPackageInfo; 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; @@ -41,11 +40,11 @@ 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; +import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; -public abstract class BaseFirmwareControllerTest extends AbstractControllerTest { +public abstract class BaseOtaPackageControllerTest extends AbstractControllerTest { - private IdComparator idComparator = new IdComparator<>(); + private IdComparator idComparator = new IdComparator<>(); public static final String TITLE = "My firmware"; private static final String FILE_NAME = "filename.txt"; @@ -93,13 +92,13 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @Test public void testSaveFirmware() throws Exception { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo); Assert.assertNotNull(savedFirmwareInfo); Assert.assertNotNull(savedFirmwareInfo.getId()); @@ -112,19 +111,19 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest save(savedFirmwareInfo); - FirmwareInfo foundFirmwareInfo = doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString(), FirmwareInfo.class); + OtaPackageInfo foundFirmwareInfo = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class); Assert.assertEquals(foundFirmwareInfo.getTitle(), savedFirmwareInfo.getTitle()); } @Test public void testSaveFirmwareData() throws Exception { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo); Assert.assertNotNull(savedFirmwareInfo); Assert.assertNotNull(savedFirmwareInfo.getId()); @@ -137,12 +136,12 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest save(savedFirmwareInfo); - FirmwareInfo foundFirmwareInfo = doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString(), FirmwareInfo.class); + OtaPackageInfo foundFirmwareInfo = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class); Assert.assertEquals(foundFirmwareInfo.getTitle(), savedFirmwareInfo.getTitle()); MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array()); - Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM); + OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM); Assert.assertEquals(FILE_NAME, savedFirmware.getFileName()); Assert.assertEquals(CONTENT_TYPE, savedFirmware.getContentType()); @@ -150,97 +149,97 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @Test public void testUpdateFirmwareFromDifferentTenant() throws Exception { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo); loginDifferentTenant(); - doPost("/api/firmware", savedFirmwareInfo, FirmwareInfo.class, status().isForbidden()); + doPost("/api/otaPackage", savedFirmwareInfo, OtaPackageInfo.class, status().isForbidden()); deleteDifferentTenant(); } @Test public void testFindFirmwareInfoById() throws Exception { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo); - FirmwareInfo foundFirmware = doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString(), FirmwareInfo.class); + OtaPackageInfo foundFirmware = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class); Assert.assertNotNull(foundFirmware); Assert.assertEquals(savedFirmwareInfo, foundFirmware); } @Test public void testFindFirmwareById() throws Exception { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo); MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array()); - Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM); + OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM); - Firmware foundFirmware = doGet("/api/firmware/" + savedFirmwareInfo.getId().getId().toString(), Firmware.class); + OtaPackage foundFirmware = doGet("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString(), OtaPackage.class); Assert.assertNotNull(foundFirmware); Assert.assertEquals(savedFirmware, foundFirmware); } @Test public void testDeleteFirmware() throws Exception { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo); - doDelete("/api/firmware/" + savedFirmwareInfo.getId().getId().toString()) + doDelete("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString()) .andExpect(status().isOk()); - doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString()) + doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString()) .andExpect(status().isNotFound()); } @Test public void testFindTenantFirmwares() throws Exception { - List firmwares = new ArrayList<>(); + List otaPackages = new ArrayList<>(); for (int i = 0; i < 165; i++) { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION + i); - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo); if (i > 100) { MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array()); - Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM); - firmwares.add(new FirmwareInfo(savedFirmware)); + OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM); + otaPackages.add(new OtaPackageInfo(savedFirmware)); } else { - firmwares.add(savedFirmwareInfo); + otaPackages.add(savedFirmwareInfo); } } - List loadedFirmwares = new ArrayList<>(); + List loadedFirmwares = new ArrayList<>(); PageLink pageLink = new PageLink(24); - PageData pageData; + PageData pageData; do { - pageData = doGetTypedWithPageLink("/api/firmwares?", + pageData = doGetTypedWithPageLink("/api/otaPackages?", new TypeReference<>() { }, pageLink); loadedFirmwares.addAll(pageData.getData()); @@ -249,41 +248,41 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest } } while (pageData.hasNext()); - Collections.sort(firmwares, idComparator); + Collections.sort(otaPackages, idComparator); Collections.sort(loadedFirmwares, idComparator); - Assert.assertEquals(firmwares, loadedFirmwares); + Assert.assertEquals(otaPackages, loadedFirmwares); } @Test public void testFindTenantFirmwaresByHasData() throws Exception { - List firmwaresWithData = new ArrayList<>(); - List firmwaresWithoutData = new ArrayList<>(); + List otaPackagesWithData = new ArrayList<>(); + List otaPackagesWithoutData = new ArrayList<>(); for (int i = 0; i < 165; i++) { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION + i); - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo); if (i > 100) { MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array()); - Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM); - firmwaresWithData.add(new FirmwareInfo(savedFirmware)); + OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM); + otaPackagesWithData.add(new OtaPackageInfo(savedFirmware)); } else { - firmwaresWithoutData.add(savedFirmwareInfo); + otaPackagesWithoutData.add(savedFirmwareInfo); } } - List loadedFirmwaresWithData = new ArrayList<>(); + List loadedFirmwaresWithData = new ArrayList<>(); PageLink pageLink = new PageLink(24); - PageData pageData; + PageData pageData; do { - pageData = doGetTypedWithPageLink("/api/firmwares/" + deviceProfileId.toString() + "/FIRMWARE/true?", + pageData = doGetTypedWithPageLink("/api/otaPackages/" + deviceProfileId.toString() + "/FIRMWARE/true?", new TypeReference<>() { }, pageLink); loadedFirmwaresWithData.addAll(pageData.getData()); @@ -292,10 +291,10 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest } } while (pageData.hasNext()); - List loadedFirmwaresWithoutData = new ArrayList<>(); + List loadedFirmwaresWithoutData = new ArrayList<>(); pageLink = new PageLink(24); do { - pageData = doGetTypedWithPageLink("/api/firmwares/" + deviceProfileId.toString() + "/FIRMWARE/false?", + pageData = doGetTypedWithPageLink("/api/otaPackages/" + deviceProfileId.toString() + "/FIRMWARE/false?", new TypeReference<>() { }, pageLink); loadedFirmwaresWithoutData.addAll(pageData.getData()); @@ -304,25 +303,25 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest } } while (pageData.hasNext()); - Collections.sort(firmwaresWithData, idComparator); - Collections.sort(firmwaresWithoutData, idComparator); + Collections.sort(otaPackagesWithData, idComparator); + Collections.sort(otaPackagesWithoutData, idComparator); Collections.sort(loadedFirmwaresWithData, idComparator); Collections.sort(loadedFirmwaresWithoutData, idComparator); - Assert.assertEquals(firmwaresWithData, loadedFirmwaresWithData); - Assert.assertEquals(firmwaresWithoutData, loadedFirmwaresWithoutData); + Assert.assertEquals(otaPackagesWithData, loadedFirmwaresWithData); + Assert.assertEquals(otaPackagesWithoutData, loadedFirmwaresWithoutData); } - private FirmwareInfo save(FirmwareInfo firmwareInfo) throws Exception { - return doPost("/api/firmware", firmwareInfo, FirmwareInfo.class); + private OtaPackageInfo save(OtaPackageInfo firmwareInfo) throws Exception { + return doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class); } - protected Firmware savaData(String urlTemplate, MockMultipartFile content, String... params) throws Exception { + protected OtaPackage savaData(String urlTemplate, MockMultipartFile content, String... params) throws Exception { MockMultipartHttpServletRequestBuilder postRequest = MockMvcRequestBuilders.multipart(urlTemplate, params); postRequest.file(content); setJwtToken(postRequest); - return readResponse(mockMvc.perform(postRequest).andExpect(status().isOk()), Firmware.class); + return readResponse(mockMvc.perform(postRequest).andExpect(status().isOk()), OtaPackage.class); } } diff --git a/application/src/test/java/org/thingsboard/server/controller/sql/FirmwareControllerSqlTest.java b/application/src/test/java/org/thingsboard/server/controller/sql/OtaPackageControllerSqlTest.java similarity index 82% rename from application/src/test/java/org/thingsboard/server/controller/sql/FirmwareControllerSqlTest.java rename to application/src/test/java/org/thingsboard/server/controller/sql/OtaPackageControllerSqlTest.java index a0e4a838ca..92bd9ba9c6 100644 --- a/application/src/test/java/org/thingsboard/server/controller/sql/FirmwareControllerSqlTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/sql/OtaPackageControllerSqlTest.java @@ -15,9 +15,9 @@ */ package org.thingsboard.server.controller.sql; -import org.thingsboard.server.controller.BaseFirmwareControllerTest; +import org.thingsboard.server.controller.BaseOtaPackageControllerTest; import org.thingsboard.server.dao.service.DaoSqlTest; @DaoSqlTest -public class FirmwareControllerSqlTest extends BaseFirmwareControllerTest { +public class OtaPackageControllerSqlTest extends BaseOtaPackageControllerTest { } diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java similarity index 84% rename from common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCache.java rename to common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java index 1acb09b28e..a864fc6dba 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java @@ -13,19 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.cache.firmware; +package org.thingsboard.server.cache.ota; import lombok.RequiredArgsConstructor; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cache.CacheManager; import org.springframework.stereotype.Service; -import static org.thingsboard.server.common.data.CacheConstants.FIRMWARE_CACHE; +import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_CACHE; @Service @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "caffeine", matchIfMissing = true) @RequiredArgsConstructor -public class CaffeineFirmwareCache implements FirmwareDataCache { +public class CaffeineOtaPackageCache implements OtaPackageDataCache { private final CacheManager cacheManager; @@ -36,7 +36,7 @@ public class CaffeineFirmwareCache implements FirmwareDataCache { @Override public byte[] get(String key, int chunkSize, int chunk) { - byte[] data = cacheManager.getCache(FIRMWARE_CACHE).get(key, byte[].class); + byte[] data = cacheManager.getCache(OTA_PACKAGE_CACHE).get(key, byte[].class); if (chunkSize < 1) { return data; @@ -58,11 +58,11 @@ public class CaffeineFirmwareCache implements FirmwareDataCache { @Override public void put(String key, byte[] value) { - cacheManager.getCache(FIRMWARE_CACHE).putIfAbsent(key, value); + cacheManager.getCache(OTA_PACKAGE_CACHE).putIfAbsent(key, value); } @Override public void evict(String key) { - cacheManager.getCache(FIRMWARE_CACHE).evict(key); + cacheManager.getCache(OTA_PACKAGE_CACHE).evict(key); } } diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/FirmwareDataCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/ota/OtaPackageDataCache.java similarity index 82% rename from common/cache/src/main/java/org/thingsboard/server/cache/firmware/FirmwareDataCache.java rename to common/cache/src/main/java/org/thingsboard/server/cache/ota/OtaPackageDataCache.java index 99f2f0d521..77057406c2 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/FirmwareDataCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/ota/OtaPackageDataCache.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.cache.firmware; +package org.thingsboard.server.cache.ota; -public interface FirmwareDataCache { +public interface OtaPackageDataCache { byte[] get(String key); @@ -25,8 +25,8 @@ public interface FirmwareDataCache { void evict(String key); - default boolean has(String firmwareId) { - byte[] data = get(firmwareId, 1, 0); + default boolean has(String otaPackageId) { + byte[] data = get(otaPackageId, 1, 0); return data != null && data.length > 0; } } diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/RedisFirmwareDataCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java similarity index 78% rename from common/cache/src/main/java/org/thingsboard/server/cache/firmware/RedisFirmwareDataCache.java rename to common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java index 08dd6facc2..1e4ae53829 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/RedisFirmwareDataCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.cache.firmware; +package org.thingsboard.server.cache.ota; import lombok.RequiredArgsConstructor; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -21,12 +21,12 @@ import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.stereotype.Service; -import static org.thingsboard.server.common.data.CacheConstants.FIRMWARE_CACHE; +import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_CACHE; @Service @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") @RequiredArgsConstructor -public class RedisFirmwareDataCache implements FirmwareDataCache { +public class RedisOtaPackageDataCache implements OtaPackageDataCache { private final RedisConnectionFactory redisConnectionFactory; @@ -39,30 +39,30 @@ public class RedisFirmwareDataCache implements FirmwareDataCache { public byte[] get(String key, int chunkSize, int chunk) { try (RedisConnection connection = redisConnectionFactory.getConnection()) { if (chunkSize == 0) { - return connection.get(toFirmwareCacheKey(key)); + return connection.get(toOtaPackageCacheKey(key)); } int startIndex = chunkSize * chunk; int endIndex = startIndex + chunkSize - 1; - return connection.getRange(toFirmwareCacheKey(key), startIndex, endIndex); + return connection.getRange(toOtaPackageCacheKey(key), startIndex, endIndex); } } @Override public void put(String key, byte[] value) { try (RedisConnection connection = redisConnectionFactory.getConnection()) { - connection.set(toFirmwareCacheKey(key), value); + connection.set(toOtaPackageCacheKey(key), value); } } @Override public void evict(String key) { try (RedisConnection connection = redisConnectionFactory.getConnection()) { - connection.del(toFirmwareCacheKey(key)); + connection.del(toOtaPackageCacheKey(key)); } } - private byte[] toFirmwareCacheKey(String key) { - return String.format("%s::%s", FIRMWARE_CACHE, key).getBytes(); + private byte[] toOtaPackageCacheKey(String key) { + return String.format("%s::%s", OTA_PACKAGE_CACHE, key).getBytes(); } } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java index b4692ec5bf..761211f32c 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java @@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.DeviceCredentials; @@ -63,9 +64,9 @@ public interface DeviceService { PageData findDevicesByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink); - PageData findDevicesByTenantIdAndTypeAndEmptyFirmware(TenantId tenantId, String type, PageLink pageLink); + PageData findDevicesByTenantIdAndTypeAndEmptyOtaPackage(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType type, PageLink pageLink); - PageData findDevicesByTenantIdAndTypeAndEmptySoftware(TenantId tenantId, String type, PageLink pageLink); + Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType otaPackageType); PageData findDeviceInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink); 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 deleted file mode 100644 index eeaafbd777..0000000000 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright © 2016-2021 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.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.ChecksumAlgorithm; -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 java.nio.ByteBuffer; - -public interface FirmwareService { - - FirmwareInfo saveFirmwareInfo(FirmwareInfo firmwareInfo); - - Firmware saveFirmware(Firmware firmware); - - String generateChecksum(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data); - - Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId); - - FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId); - - ListenableFuture findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId); - - PageData findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink); - - PageData findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink); - - void deleteFirmware(TenantId tenantId, FirmwareId firmwareId); - - void deleteFirmwaresByTenantId(TenantId tenantId); -} diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java new file mode 100644 index 0000000000..589bdf14b6 --- /dev/null +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java @@ -0,0 +1,52 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.ota; + +import com.google.common.util.concurrent.ListenableFuture; +import org.thingsboard.server.common.data.OtaPackage; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.id.DeviceProfileId; +import org.thingsboard.server.common.data.id.OtaPackageId; +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 java.nio.ByteBuffer; + +public interface OtaPackageService { + + OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo); + + OtaPackage saveOtaPackage(OtaPackage otaPackage); + + String generateChecksum(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data); + + OtaPackage findOtaPackageById(TenantId tenantId, OtaPackageId otaPackageId); + + OtaPackageInfo findOtaPackageInfoById(TenantId tenantId, OtaPackageId otaPackageId); + + ListenableFuture findOtaPackageInfoByIdAsync(TenantId tenantId, OtaPackageId otaPackageId); + + PageData findTenantOtaPackagesByTenantId(TenantId tenantId, PageLink pageLink); + + PageData findTenantOtaPackagesByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType otaPackageType, boolean hasData, PageLink pageLink); + + void deleteOtaPackage(TenantId tenantId, OtaPackageId otaPackageId); + + void deleteOtaPackagesByTenantId(TenantId tenantId); +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java index ce4576705b..3cc3f56737 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java @@ -29,5 +29,5 @@ public class CacheConstants { public static final String DEVICE_PROFILE_CACHE = "deviceProfiles"; public static final String ATTRIBUTES_CACHE = "attributes"; public static final String TOKEN_OUTDATAGE_TIME_CACHE = "tokensOutdatageTime"; - public static final String FIRMWARE_CACHE = "firmwares"; + public static final String OTA_PACKAGE_CACHE = "otaPackages"; } 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 bce3ba703f..9abc619b48 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 @@ -23,7 +23,7 @@ import org.thingsboard.server.common.data.device.data.DeviceData; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.NoXss; @@ -32,7 +32,7 @@ import java.io.IOException; @EqualsAndHashCode(callSuper = true) @Slf4j -public class Device extends SearchTextBasedWithAdditionalInfo implements HasName, HasTenantId, HasCustomerId, HasFirmware { +public class Device extends SearchTextBasedWithAdditionalInfo implements HasName, HasTenantId, HasCustomerId, HasOtaPackage { private static final long serialVersionUID = 2807343040519543363L; @@ -49,8 +49,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo implemen @JsonIgnore private byte[] deviceDataBytes; - private FirmwareId firmwareId; - private FirmwareId softwareId; + private OtaPackageId firmwareId; + private OtaPackageId softwareId; public Device() { super(); @@ -167,19 +167,19 @@ public class Device extends SearchTextBasedWithAdditionalInfo implemen return getName(); } - public FirmwareId getFirmwareId() { + public OtaPackageId getFirmwareId() { return firmwareId; } - public void setFirmwareId(FirmwareId firmwareId) { + public void setFirmwareId(OtaPackageId firmwareId) { this.firmwareId = firmwareId; } - public FirmwareId getSoftwareId() { + public OtaPackageId getSoftwareId() { return softwareId; } - public void setSoftwareId(FirmwareId softwareId) { + public void setSoftwareId(OtaPackageId softwareId) { this.softwareId = softwareId; } 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 e35fbb84a0..13c4692976 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 @@ -23,7 +23,7 @@ import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.NoXss; @@ -37,7 +37,7 @@ import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalIn @Data @EqualsAndHashCode(callSuper = true) @Slf4j -public class DeviceProfile extends SearchTextBased implements HasName, HasTenantId, HasFirmware { +public class DeviceProfile extends SearchTextBased implements HasName, HasTenantId, HasOtaPackage { private TenantId tenantId; @NoXss @@ -60,9 +60,9 @@ public class DeviceProfile extends SearchTextBased implements H @NoXss private String provisionDeviceKey; - private FirmwareId firmwareId; + private OtaPackageId firmwareId; - private FirmwareId softwareId; + private OtaPackageId softwareId; public DeviceProfile() { super(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java index d3508d42dd..cf6c6fd9a7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java @@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; * @author Andrew Shvayka */ public enum EntityType { - TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, API_USAGE_STATE, TB_RESOURCE, FIRMWARE, EDGE; + TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, API_USAGE_STATE, TB_RESOURCE, OTA_PACKAGE, EDGE; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HasFirmware.java b/common/data/src/main/java/org/thingsboard/server/common/data/HasOtaPackage.java similarity index 80% rename from common/data/src/main/java/org/thingsboard/server/common/data/HasFirmware.java rename to common/data/src/main/java/org/thingsboard/server/common/data/HasOtaPackage.java index ae05829092..09320e13d0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HasFirmware.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HasOtaPackage.java @@ -15,11 +15,11 @@ */ package org.thingsboard.server.common.data; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; -public interface HasFirmware { +public interface HasOtaPackage { - FirmwareId getFirmwareId(); + OtaPackageId getFirmwareId(); - FirmwareId getSoftwareId(); + OtaPackageId getSoftwareId(); } 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/OtaPackage.java similarity index 82% rename from common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java rename to common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java index b4155a578a..6110310cd3 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/OtaPackage.java @@ -17,27 +17,27 @@ package org.thingsboard.server.common.data; import lombok.Data; import lombok.EqualsAndHashCode; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import java.nio.ByteBuffer; @Data @EqualsAndHashCode(callSuper = true) -public class Firmware extends FirmwareInfo { +public class OtaPackage extends OtaPackageInfo { private static final long serialVersionUID = 3091601761339422546L; private transient ByteBuffer data; - public Firmware() { + public OtaPackage() { super(); } - public Firmware(FirmwareId id) { + public OtaPackage(OtaPackageId id) { super(id); } - public Firmware(Firmware firmware) { + public OtaPackage(OtaPackage firmware) { super(firmware); this.data = firmware.getData(); } 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/OtaPackageInfo.java similarity index 58% rename from common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java rename to common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java index 33b529e303..5a33a95215 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/OtaPackageInfo.java @@ -19,22 +19,22 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; -import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.TenantId; @Slf4j @Data @EqualsAndHashCode(callSuper = true) -public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo implements HasName, HasTenantId { +public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo implements HasName, HasTenantId { private static final long serialVersionUID = 3168391583570815419L; private TenantId tenantId; private DeviceProfileId deviceProfileId; - private FirmwareType type; + private OtaPackageType type; private String title; private String version; private boolean hasData; @@ -45,27 +45,27 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo private Long dataSize; - public FirmwareInfo() { + public OtaPackageInfo() { super(); } - public FirmwareInfo(FirmwareId id) { + public OtaPackageInfo(OtaPackageId id) { super(id); } - 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(); - this.hasData = firmwareInfo.isHasData(); - this.fileName = firmwareInfo.getFileName(); - this.contentType = firmwareInfo.getContentType(); - this.checksumAlgorithm = firmwareInfo.getChecksumAlgorithm(); - this.checksum = firmwareInfo.getChecksum(); - this.dataSize = firmwareInfo.getDataSize(); + public OtaPackageInfo(OtaPackageInfo otaPackageInfo) { + super(otaPackageInfo); + this.tenantId = otaPackageInfo.getTenantId(); + this.deviceProfileId = otaPackageInfo.getDeviceProfileId(); + this.type = otaPackageInfo.getType(); + this.title = otaPackageInfo.getTitle(); + this.version = otaPackageInfo.getVersion(); + this.hasData = otaPackageInfo.isHasData(); + this.fileName = otaPackageInfo.getFileName(); + this.contentType = otaPackageInfo.getContentType(); + this.checksumAlgorithm = otaPackageInfo.getChecksumAlgorithm(); + this.checksum = otaPackageInfo.getChecksum(); + this.dataSize = otaPackageInfo.getDataSize(); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java index df2846eead..a4b2327c75 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java @@ -71,8 +71,8 @@ public class EntityIdFactory { return new ApiUsageStateId(uuid); case TB_RESOURCE: return new TbResourceId(uuid); - case FIRMWARE: - return new FirmwareId(uuid); + case OTA_PACKAGE: + return new OtaPackageId(uuid); case EDGE: return new EdgeId(uuid); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/FirmwareId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java similarity index 79% rename from common/data/src/main/java/org/thingsboard/server/common/data/id/FirmwareId.java rename to common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java index 3cdee53f58..0442792238 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/FirmwareId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java @@ -22,23 +22,23 @@ import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -public class FirmwareId extends UUIDBased implements EntityId { +public class OtaPackageId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @JsonCreator - public FirmwareId(@JsonProperty("id") UUID id) { + public OtaPackageId(@JsonProperty("id") UUID id) { super(id); } - public static FirmwareId fromString(String firmwareId) { - return new FirmwareId(UUID.fromString(firmwareId)); + public static OtaPackageId fromString(String firmwareId) { + return new OtaPackageId(UUID.fromString(firmwareId)); } @JsonIgnore @Override public EntityType getEntityType() { - return EntityType.FIRMWARE; + return EntityType.OTA_PACKAGE; } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/ChecksumAlgorithm.java b/common/data/src/main/java/org/thingsboard/server/common/data/ota/ChecksumAlgorithm.java similarity index 93% rename from common/data/src/main/java/org/thingsboard/server/common/data/firmware/ChecksumAlgorithm.java rename to common/data/src/main/java/org/thingsboard/server/common/data/ota/ChecksumAlgorithm.java index 3998482e35..ce33463054 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/ChecksumAlgorithm.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ota/ChecksumAlgorithm.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.firmware; +package org.thingsboard.server.common.data.ota; public enum ChecksumAlgorithm { MD5, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareKey.java b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageKey.java similarity index 88% rename from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareKey.java rename to common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageKey.java index cb38b6724c..0528b9dfe3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareKey.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageKey.java @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.firmware; +package org.thingsboard.server.common.data.ota; import lombok.Getter; -public enum FirmwareKey { +public enum OtaPackageKey { TITLE("title"), VERSION("version"), TS("ts"), STATE("state"), SIZE("size"), CHECKSUM("checksum"), CHECKSUM_ALGORITHM("checksum_algorithm"); @Getter private final String value; - FirmwareKey(String value) { + OtaPackageKey(String value) { this.value = value; } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareType.java b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageType.java similarity index 86% rename from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareType.java rename to common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageType.java index 5f6aa0d925..cab8cf1847 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageType.java @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.firmware; +package org.thingsboard.server.common.data.ota; import lombok.Getter; -public enum FirmwareType { +public enum OtaPackageType { FIRMWARE("fw"), SOFTWARE("sw"); @Getter private final String keyPrefix; - FirmwareType(String keyPrefix) { + OtaPackageType(String keyPrefix) { this.keyPrefix = keyPrefix; } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUpdateStatus.java b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUpdateStatus.java similarity index 88% rename from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUpdateStatus.java rename to common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUpdateStatus.java index 3e46174792..caa043c595 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUpdateStatus.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUpdateStatus.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.firmware; +package org.thingsboard.server.common.data.ota; -public enum FirmwareUpdateStatus { +public enum OtaPackageUpdateStatus { QUEUED, INITIATED, DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUtil.java b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUtil.java similarity index 52% rename from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUtil.java rename to common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUtil.java index 646ad24173..f2b29ec1f2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUtil.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUtil.java @@ -13,21 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.firmware; +package org.thingsboard.server.common.data.ota; import lombok.extern.slf4j.Slf4j; -import org.thingsboard.server.common.data.HasFirmware; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.HasOtaPackage; +import org.thingsboard.server.common.data.id.OtaPackageId; 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.common.data.firmware.FirmwareType.SOFTWARE; +import java.util.function.Supplier; @Slf4j -public class FirmwareUtil { +public class OtaPackageUtil { public static final List ALL_FW_ATTRIBUTE_KEYS; @@ -35,19 +33,19 @@ public class FirmwareUtil { static { ALL_FW_ATTRIBUTE_KEYS = new ArrayList<>(); - for (FirmwareKey key : FirmwareKey.values()) { - ALL_FW_ATTRIBUTE_KEYS.add(getAttributeKey(FIRMWARE, key)); + for (OtaPackageKey key : OtaPackageKey.values()) { + ALL_FW_ATTRIBUTE_KEYS.add(getAttributeKey(OtaPackageType.FIRMWARE, key)); } ALL_SW_ATTRIBUTE_KEYS = new ArrayList<>(); - for (FirmwareKey key : FirmwareKey.values()) { - ALL_SW_ATTRIBUTE_KEYS.add(getAttributeKey(SOFTWARE, key)); + for (OtaPackageKey key : OtaPackageKey.values()) { + ALL_SW_ATTRIBUTE_KEYS.add(getAttributeKey(OtaPackageType.SOFTWARE, key)); } } - public static List getAttributeKeys(FirmwareType firmwareType) { + public static List getAttributeKeys(OtaPackageType firmwareType) { switch (firmwareType) { case FIRMWARE: return ALL_FW_ATTRIBUTE_KEYS; @@ -57,35 +55,46 @@ public class FirmwareUtil { return Collections.emptyList(); } - public static String getAttributeKey(FirmwareType type, FirmwareKey key) { + public static String getAttributeKey(OtaPackageType type, OtaPackageKey key) { return type.getKeyPrefix() + "_" + key.getValue(); } - public static String getTargetTelemetryKey(FirmwareType type, FirmwareKey key) { + public static String getTargetTelemetryKey(OtaPackageType type, OtaPackageKey key) { return getTelemetryKey("target_", type, key); } - public static String getCurrentTelemetryKey(FirmwareType type, FirmwareKey key) { + public static String getCurrentTelemetryKey(OtaPackageType type, OtaPackageKey key) { return getTelemetryKey("current_", type, key); } - private static String getTelemetryKey(String prefix, FirmwareType type, FirmwareKey key) { + private static String getTelemetryKey(String prefix, OtaPackageType type, OtaPackageKey key) { return prefix + type.getKeyPrefix() + "_" + key.getValue(); } - public static String getTelemetryKey(FirmwareType type, FirmwareKey key) { + public static String getTelemetryKey(OtaPackageType type, OtaPackageKey key) { return type.getKeyPrefix() + "_" + key.getValue(); } - public static FirmwareId getFirmwareId(HasFirmware entity, FirmwareType firmwareType) { - switch (firmwareType) { + public static OtaPackageId getOtaPackageId(HasOtaPackage entity, OtaPackageType type) { + switch (type) { case FIRMWARE: return entity.getFirmwareId(); case SOFTWARE: return entity.getSoftwareId(); default: - log.warn("Unsupported firmware type: [{}]", firmwareType); + log.warn("Unsupported ota package type: [{}]", type); return null; } } + + public static T getByOtaPackageType(Supplier firmwareSupplier, Supplier softwareSupplier, OtaPackageType type) { + switch (type) { + case FIRMWARE: + return firmwareSupplier.get(); + case SOFTWARE: + return softwareSupplier.get(); + default: + throw new RuntimeException("Unsupported OtaPackage type: " + type); + } + } } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java index 1a6a1a56e4..624918c8dd 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java @@ -38,7 +38,7 @@ public class TbKafkaTopicConfigs { private String notificationsProperties; @Value("${queue.kafka.topic-properties.js-executor}") private String jsExecutorProperties; - @Value("${queue.kafka.topic-properties.fw-updates:}") + @Value("${queue.kafka.topic-properties.ota-updates:}") private String fwUpdatesProperties; @Getter diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java index c2f4f4f750..d89b03c744 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java @@ -187,14 +187,14 @@ public class AwsSqsMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEng } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getFirmwareTopic(), - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getOtaPackageTopic(), + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getFirmwareTopic()); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getOtaPackageTopic()); } @PreDestroy diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java index 0267cdecb8..eaa73bc108 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.gen.js.JsInvokeProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; @@ -177,14 +177,14 @@ public class AwsSqsTbCoreQueueFactory implements TbCoreQueueFactory { } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getFirmwareTopic(), - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getOtaPackageTopic(), + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getFirmwareTopic()); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getOtaPackageTopic()); } @PreDestroy diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java index 8806176f9f..cd1c34b612 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java @@ -131,13 +131,13 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - return new InMemoryTbQueueConsumer<>(coreSettings.getFirmwareTopic()); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + return new InMemoryTbQueueConsumer<>(coreSettings.getOtaPackageTopic()); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - return new InMemoryTbQueueProducer<>(coreSettings.getFirmwareTopic()); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + return new InMemoryTbQueueProducer<>(coreSettings.getOtaPackageTopic()); } @Override diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java index a526331116..c57260bef8 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.gen.js.JsInvokeProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; @@ -277,24 +277,24 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> consumerBuilder = TbKafkaConsumerTemplate.builder(); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> consumerBuilder = TbKafkaConsumerTemplate.builder(); consumerBuilder.settings(kafkaSettings); - consumerBuilder.topic(coreSettings.getFirmwareTopic()); - consumerBuilder.clientId("monolith-fw-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("monolith-fw-consumer"); - consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); + consumerBuilder.topic(coreSettings.getOtaPackageTopic()); + consumerBuilder.clientId("monolith-ota-consumer-" + serviceInfoProvider.getServiceId()); + consumerBuilder.groupId("monolith-ota-consumer"); + consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(fwUpdatesAdmin); consumerBuilder.statsService(consumerStatsService); return consumerBuilder.build(); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder> requestBuilder = TbKafkaProducerTemplate.builder(); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder> requestBuilder = TbKafkaProducerTemplate.builder(); requestBuilder.settings(kafkaSettings); - requestBuilder.clientId("monolith-fw-producer-" + serviceInfoProvider.getServiceId()); - requestBuilder.defaultTopic(coreSettings.getFirmwareTopic()); + requestBuilder.clientId("monolith-ota-producer-" + serviceInfoProvider.getServiceId()); + requestBuilder.defaultTopic(coreSettings.getOtaPackageTopic()); requestBuilder.admin(fwUpdatesAdmin); return requestBuilder.build(); } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java index 5f64e42ffd..bec01c7201 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.gen.js.JsInvokeProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; @@ -245,24 +245,24 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory { } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> consumerBuilder = TbKafkaConsumerTemplate.builder(); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> consumerBuilder = TbKafkaConsumerTemplate.builder(); consumerBuilder.settings(kafkaSettings); - consumerBuilder.topic(coreSettings.getFirmwareTopic()); - consumerBuilder.clientId("tb-core-fw-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("tb-core-fw-consumer"); - consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); + consumerBuilder.topic(coreSettings.getOtaPackageTopic()); + consumerBuilder.clientId("tb-core-ota-consumer-" + serviceInfoProvider.getServiceId()); + consumerBuilder.groupId("tb-core-ota-consumer"); + consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(fwUpdatesAdmin); consumerBuilder.statsService(consumerStatsService); return consumerBuilder.build(); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder> requestBuilder = TbKafkaProducerTemplate.builder(); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder> requestBuilder = TbKafkaProducerTemplate.builder(); requestBuilder.settings(kafkaSettings); - requestBuilder.clientId("tb-core-fw-producer-" + serviceInfoProvider.getServiceId()); - requestBuilder.defaultTopic(coreSettings.getFirmwareTopic()); + requestBuilder.clientId("tb-core-ota-producer-" + serviceInfoProvider.getServiceId()); + requestBuilder.defaultTopic(coreSettings.getOtaPackageTopic()); requestBuilder.admin(fwUpdatesAdmin); return requestBuilder.build(); } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java index 3504c6aef2..3f014f578c 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java @@ -22,9 +22,9 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsRequest; import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsResponse; -import org.thingsboard.server.gen.transport.TransportProtos.*; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; @@ -192,14 +192,14 @@ public class PubSubMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEng } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic(), - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic(), + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic()); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic()); } @Override diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java index a9ebf5a4de..65ea183d66 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.gen.js.JsInvokeProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; @@ -166,14 +166,14 @@ public class PubSubTbCoreQueueFactory implements TbCoreQueueFactory { } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic(), - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic(), + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic()); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic()); } @Override diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java index cd6043cdde..7730f8f5dd 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java @@ -24,7 +24,7 @@ import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsRequest; import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsResponse; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; @@ -190,14 +190,14 @@ public class RabbitMqMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic(), - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic(), + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic()); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic()); } @Override diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java index 8b5ad00de4..c0abeab162 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.gen.js.JsInvokeProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; @@ -172,14 +172,14 @@ public class RabbitMqTbCoreQueueFactory implements TbCoreQueueFactory { } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic(), - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic(), + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic()); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic()); } @Override diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java index b569d13742..2443093cf0 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.gen.js.JsInvokeProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; @@ -189,14 +189,14 @@ public class ServiceBusMonolithQueueFactory implements TbCoreQueueFactory, TbRul } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic(), - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic(), + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic()); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic()); } @Override diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java index 17e6eb9a27..7a9da236ed 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.gen.js.JsInvokeProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; @@ -172,14 +172,14 @@ public class ServiceBusTbCoreQueueFactory implements TbCoreQueueFactory { } @Override - public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() { - return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic(), - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); + public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() { + return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic(), + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); } @Override - public TbQueueProducer> createToFirmwareStateServiceMsgProducer() { - return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic()); + public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() { + return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic()); } @Override diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueFactory.java index be5ca967bf..584a6e389b 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueFactory.java @@ -16,7 +16,7 @@ package org.thingsboard.server.queue.provider; import org.thingsboard.server.gen.js.JsInvokeProtos; -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; @@ -91,14 +91,14 @@ public interface TbCoreQueueFactory extends TbUsageStatsClientQueueFactory { * * @return */ - TbQueueConsumer> createToFirmwareStateServiceMsgConsumer(); + TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer(); /** * Used to consume messages about firmware update notifications by TB Core Service * * @return */ - TbQueueProducer> createToFirmwareStateServiceMsgProducer(); + TbQueueProducer> createToOtaPackageStateServiceMsgProducer(); /** * Used to consume high priority messages by TB Core Service diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java index b7e7a155ed..6c8ab4455b 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.queue.provider; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Service; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; @@ -25,11 +24,12 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.common.TbProtoQueueMsg; +import org.thingsboard.server.queue.util.TbCoreComponent; import javax.annotation.PostConstruct; @Service -@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'") +@TbCoreComponent public class TbCoreQueueProducerProvider implements TbQueueProducerProvider { private final TbCoreQueueFactory tbQueueProvider; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java b/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java index d194fdb4ea..3c9ff5813e 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java @@ -26,8 +26,8 @@ public class TbQueueCoreSettings { @Value("${queue.core.topic}") private String topic; - @Value("${queue.core.firmware.topic:tb_firmware}") - private String firmwareTopic; + @Value("${queue.core.ota.topic:tb_ota_package}") + private String otaPackageTopic; @Value("${queue.core.usage-stats-topic:tb_usage_stats}") private String usageStatsTopic; diff --git a/common/queue/src/main/proto/queue.proto b/common/queue/src/main/proto/queue.proto index b4d929f60c..faf88c5620 100644 --- a/common/queue/src/main/proto/queue.proto +++ b/common/queue/src/main/proto/queue.proto @@ -388,7 +388,7 @@ enum ResponseStatus { FAILURE = 3; } -message GetFirmwareRequestMsg { +message GetOtaPackageRequestMsg { int64 deviceIdMSB = 1; int64 deviceIdLSB = 2; int64 tenantIdMSB = 3; @@ -396,10 +396,10 @@ message GetFirmwareRequestMsg { string type = 5; } -message GetFirmwareResponseMsg { +message GetOtaPackageResponseMsg { ResponseStatus responseStatus = 1; - int64 firmwareIdMSB = 2; - int64 firmwareIdLSB = 3; + int64 otaPackageIdMSB = 2; + int64 otaPackageIdLSB = 3; string type = 4; string title = 5; string version = 6; @@ -627,7 +627,7 @@ message TransportApiRequestMsg { ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7; ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8; GetResourceRequestMsg resourceRequestMsg = 9; - GetFirmwareRequestMsg firmwareRequestMsg = 10; + GetOtaPackageRequestMsg otaPackageRequestMsg = 10; GetSnmpDevicesRequestMsg snmpDevicesRequestMsg = 11; GetDeviceRequestMsg deviceRequestMsg = 12; GetDeviceCredentialsRequestMsg deviceCredentialsRequestMsg = 13; @@ -642,7 +642,7 @@ message TransportApiResponseMsg { GetSnmpDevicesResponseMsg snmpDevicesResponseMsg = 5; LwM2MResponseMsg lwM2MResponseMsg = 6; GetResourceResponseMsg resourceResponseMsg = 7; - GetFirmwareResponseMsg firmwareResponseMsg = 8; + GetOtaPackageResponseMsg otaPackageResponseMsg = 8; GetDeviceResponseMsg deviceResponseMsg = 9; GetDeviceCredentialsResponseMsg deviceCredentialsResponseMsg = 10; } @@ -710,13 +710,13 @@ message ToUsageStatsServiceMsg { int64 customerIdLSB = 7; } -message ToFirmwareStateServiceMsg { +message ToOtaPackageStateServiceMsg { int64 ts = 1; int64 tenantIdMSB = 2; int64 tenantIdLSB = 3; int64 deviceIdMSB = 4; int64 deviceIdLSB = 5; - int64 firmwareIdMSB = 6; - int64 firmwareIdLSB = 7; + int64 otaPackageIdMSB = 6; + int64 otaPackageIdLSB = 7; string type = 8; } diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java index 47cf44f6fa..cd80aa42df 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java @@ -44,7 +44,7 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.security.DeviceTokenCredentials; import org.thingsboard.server.common.msg.session.FeatureType; import org.thingsboard.server.common.msg.session.SessionMsgType; @@ -350,10 +350,10 @@ public class CoapTransportResource extends AbstractCoapTransportResource { new CoapNoOpCallback(exchange)); break; case GET_FIRMWARE_REQUEST: - getFirmwareCallback(sessionInfo, exchange, FirmwareType.FIRMWARE); + getOtaPackageCallback(sessionInfo, exchange, OtaPackageType.FIRMWARE); break; case GET_SOFTWARE_REQUEST: - getFirmwareCallback(sessionInfo, exchange, FirmwareType.SOFTWARE); + getOtaPackageCallback(sessionInfo, exchange, OtaPackageType.SOFTWARE); break; } } catch (AdaptorException e) { @@ -366,14 +366,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource { return new UUID(sessionInfoProto.getSessionIdMSB(), sessionInfoProto.getSessionIdLSB()); } - private void getFirmwareCallback(TransportProtos.SessionInfoProto sessionInfo, CoapExchange exchange, FirmwareType firmwareType) { - TransportProtos.GetFirmwareRequestMsg requestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() + private void getOtaPackageCallback(TransportProtos.SessionInfoProto sessionInfo, CoapExchange exchange, OtaPackageType firmwareType) { + TransportProtos.GetOtaPackageRequestMsg requestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder() .setTenantIdMSB(sessionInfo.getTenantIdMSB()) .setTenantIdLSB(sessionInfo.getTenantIdLSB()) .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) .setType(firmwareType.name()).build(); - transportContext.getTransportService().process(sessionInfo, requestMsg, new FirmwareCallback(exchange)); + transportContext.getTransportService().process(sessionInfo, requestMsg, new OtaPackageCallback(exchange)); } private TransportProtos.SessionInfoProto lookupAsyncSessionInfo(String token) { @@ -470,25 +470,25 @@ public class CoapTransportResource extends AbstractCoapTransportResource { } } - private class FirmwareCallback implements TransportServiceCallback { + private class OtaPackageCallback implements TransportServiceCallback { private final CoapExchange exchange; - FirmwareCallback(CoapExchange exchange) { + OtaPackageCallback(CoapExchange exchange) { this.exchange = exchange; } @Override - public void onSuccess(TransportProtos.GetFirmwareResponseMsg msg) { + public void onSuccess(TransportProtos.GetOtaPackageResponseMsg msg) { String title = exchange.getQueryParameter("title"); String version = exchange.getQueryParameter("version"); if (msg.getResponseStatus().equals(TransportProtos.ResponseStatus.SUCCESS)) { if (msg.getTitle().equals(title) && msg.getVersion().equals(version)) { - String firmwareId = new UUID(msg.getFirmwareIdMSB(), msg.getFirmwareIdLSB()).toString(); + String firmwareId = new UUID(msg.getOtaPackageIdMSB(), msg.getOtaPackageIdLSB()).toString(); String strChunkSize = exchange.getQueryParameter("size"); String strChunk = exchange.getQueryParameter("chunk"); int chunkSize = StringUtils.isEmpty(strChunkSize) ? 0 : Integer.parseInt(strChunkSize); int chunk = StringUtils.isEmpty(strChunk) ? 0 : Integer.parseInt(strChunk); - exchange.respond(CoAP.ResponseCode.CONTENT, transportContext.getFirmwareDataCache().get(firmwareId, chunkSize, chunk)); + exchange.respond(CoAP.ResponseCode.CONTENT, transportContext.getOtaPackageDataCache().get(firmwareId, chunkSize, chunk)); } else { exchange.respond(CoAP.ResponseCode.BAD_REQUEST); } diff --git a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java index 31180b478d..f4a3f705af 100644 --- a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java +++ b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java @@ -34,7 +34,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.server.common.data.DeviceTransportType; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.TbTransportService; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.transport.SessionMsgListener; @@ -213,7 +213,7 @@ public class DeviceApiController implements TbTransportService { @RequestParam(value = "version") String version, @RequestParam(value = "size", required = false, defaultValue = "0") int size, @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) { - return getFirmwareCallback(deviceToken, title, version, size, chunk, FirmwareType.FIRMWARE); + return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.FIRMWARE); } @RequestMapping(value = "/{deviceToken}/software", method = RequestMethod.GET) @@ -222,7 +222,7 @@ public class DeviceApiController implements TbTransportService { @RequestParam(value = "version") String version, @RequestParam(value = "size", required = false, defaultValue = "0") int size, @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) { - return getFirmwareCallback(deviceToken, title, version, size, chunk, FirmwareType.SOFTWARE); + return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.SOFTWARE); } @RequestMapping(value = "/provision", method = RequestMethod.POST) @@ -233,17 +233,17 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - private DeferredResult getFirmwareCallback(String deviceToken, String title, String version, int size, int chunk, FirmwareType firmwareType) { + private DeferredResult getOtaPackageCallback(String deviceToken, String title, String version, int size, int chunk, OtaPackageType firmwareType) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> { - TransportProtos.GetFirmwareRequestMsg requestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() + TransportProtos.GetOtaPackageRequestMsg requestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder() .setTenantIdMSB(sessionInfo.getTenantIdMSB()) .setTenantIdLSB(sessionInfo.getTenantIdLSB()) .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) .setType(firmwareType.name()).build(); - transportContext.getTransportService().process(sessionInfo, requestMsg, new GetFirmwareCallback(responseWriter, title, version, size, chunk)); + transportContext.getTransportService().process(sessionInfo, requestMsg, new GetOtaPackageCallback(responseWriter, title, version, size, chunk)); })); return responseWriter; } @@ -294,14 +294,14 @@ public class DeviceApiController implements TbTransportService { } } - private class GetFirmwareCallback implements TransportServiceCallback { + private class GetOtaPackageCallback implements TransportServiceCallback { private final DeferredResult responseWriter; private final String title; private final String version; private final int chuckSize; private final int chuck; - GetFirmwareCallback(DeferredResult responseWriter, String title, String version, int chuckSize, int chuck) { + GetOtaPackageCallback(DeferredResult responseWriter, String title, String version, int chuckSize, int chuck) { this.responseWriter = responseWriter; this.title = title; this.version = version; @@ -310,17 +310,17 @@ public class DeviceApiController implements TbTransportService { } @Override - public void onSuccess(TransportProtos.GetFirmwareResponseMsg firmwareResponseMsg) { - if (!TransportProtos.ResponseStatus.SUCCESS.equals(firmwareResponseMsg.getResponseStatus())) { + public void onSuccess(TransportProtos.GetOtaPackageResponseMsg otaPackageResponseMsg) { + if (!TransportProtos.ResponseStatus.SUCCESS.equals(otaPackageResponseMsg.getResponseStatus())) { responseWriter.setResult(new ResponseEntity<>(HttpStatus.NOT_FOUND)); - } else if (title.equals(firmwareResponseMsg.getTitle()) && version.equals(firmwareResponseMsg.getVersion())) { - String firmwareId = new UUID(firmwareResponseMsg.getFirmwareIdMSB(), firmwareResponseMsg.getFirmwareIdLSB()).toString(); - ByteArrayResource resource = new ByteArrayResource(transportContext.getFirmwareDataCache().get(firmwareId, chuckSize, chuck)); + } else if (title.equals(otaPackageResponseMsg.getTitle()) && version.equals(otaPackageResponseMsg.getVersion())) { + String otaPackageId = new UUID(otaPackageResponseMsg.getOtaPackageIdMSB(), otaPackageResponseMsg.getOtaPackageIdLSB()).toString(); + ByteArrayResource resource = new ByteArrayResource(transportContext.getOtaPackageDataCache().get(otaPackageId, chuckSize, chuck)); ResponseEntity response = ResponseEntity.ok() - .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + firmwareResponseMsg.getFileName()) - .header("x-filename", firmwareResponseMsg.getFileName()) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + otaPackageResponseMsg.getFileName()) + .header("x-filename", otaPackageResponseMsg.getFileName()) .contentLength(resource.contentLength()) - .contentType(parseMediaType(firmwareResponseMsg.getContentType())) + .contentType(parseMediaType(otaPackageResponseMsg.getContentType())) .body(resource); responseWriter.setResult(response); } else { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index 9092f8abeb..abe2a50855 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -39,13 +39,13 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardExecutors; -import org.thingsboard.server.cache.firmware.FirmwareDataCache; +import org.thingsboard.server.cache.ota.OtaPackageDataCache; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.firmware.FirmwareKey; -import org.thingsboard.server.common.data.firmware.FirmwareType; -import org.thingsboard.server.common.data.firmware.FirmwareUtil; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.ota.OtaPackageKey; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.ota.OtaPackageUtil; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.adaptor.AdaptorException; @@ -87,8 +87,8 @@ import java.util.stream.Collectors; import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.DOWNLOADED; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.UPDATING; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED; @@ -132,7 +132,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler private final TransportService transportService; private final LwM2mTransportContext context; public final LwM2MTransportServerConfig config; - public final FirmwareDataCache firmwareDataCache; + public final OtaPackageDataCache otaPackageDataCache; public final LwM2mTransportServerHelper helper; private final LwM2MJsonAdaptor adaptor; private final TbLwM2MDtlsSessionStore sessionStore; @@ -143,14 +143,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public DefaultLwM2MTransportMsgHandler(TransportService transportService, LwM2MTransportServerConfig config, LwM2mTransportServerHelper helper, LwM2mClientContext clientContext, @Lazy LwM2mTransportRequest lwM2mTransportRequest, - FirmwareDataCache firmwareDataCache, + OtaPackageDataCache otaPackageDataCache, LwM2mTransportContext context, LwM2MJsonAdaptor adaptor, TbLwM2MDtlsSessionStore sessionStore) { this.transportService = transportService; this.config = config; this.helper = helper; this.clientContext = clientContext; this.lwM2mTransportRequest = lwM2mTransportRequest; - this.firmwareDataCache = firmwareDataCache; + this.otaPackageDataCache = otaPackageDataCache; this.context = context; this.adaptor = adaptor; this.rpcSubscriptions = new ConcurrentHashMap<>(); @@ -357,14 +357,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler String pathName = tsKvProto.getKv().getKey(); String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); Object valueNew = getValueFromKvProto(tsKvProto.getKv()); - if ((FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) + if ((OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.VERSION).equals(pathName) && (!valueNew.equals(lwM2MClient.getFwUpdate().getCurrentVersion()))) - || (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.TITLE).equals(pathName) + || (OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.TITLE).equals(pathName) && (!valueNew.equals(lwM2MClient.getFwUpdate().getCurrentTitle())))) { this.getInfoFirmwareUpdate(lwM2MClient); - } else if ((FirmwareUtil.getAttributeKey(FirmwareType.SOFTWARE, FirmwareKey.VERSION).equals(pathName) + } else if ((OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.VERSION).equals(pathName) && (!valueNew.equals(lwM2MClient.getSwUpdate().getCurrentVersion()))) - || (FirmwareUtil.getAttributeKey(FirmwareType.SOFTWARE, FirmwareKey.TITLE).equals(pathName) + || (OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.TITLE).equals(pathName) && (!valueNew.equals(lwM2MClient.getSwUpdate().getCurrentTitle())))) { this.getInfoSoftwareUpdate(lwM2MClient); } @@ -391,7 +391,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler msg.getSharedUpdatedList().forEach(tsKvProto -> { String pathName = tsKvProto.getKv().getKey(); Object valueNew = getValueFromKvProto(tsKvProto.getKv()); - if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFwUpdate().getCurrentVersion())) { + if (OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFwUpdate().getCurrentVersion())) { lwM2MClient.getFwUpdate().setCurrentVersion((String) valueNew); } }); @@ -1344,18 +1344,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler if (lwM2MClient.getRegistration().getSupportedVersion(FW_ID) != null) { SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); if (sessionInfo != null) { - transportService.process(sessionInfo, createFirmwareRequestMsg(sessionInfo, FirmwareType.FIRMWARE.name()), + transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.FIRMWARE.name()), new TransportServiceCallback<>() { @Override - public void onSuccess(TransportProtos.GetFirmwareResponseMsg response) { + public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) - && response.getType().equals(FirmwareType.FIRMWARE.name())) { + && response.getType().equals(OtaPackageType.FIRMWARE.name())) { lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion()); lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle()); - lwM2MClient.getFwUpdate().setCurrentId(new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB())).getId()); + lwM2MClient.getFwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId()); lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest); } else { - log.trace("Firmware [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); + log.trace("OtaPackage [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); } } @@ -1373,15 +1373,15 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); if (sessionInfo != null) { DefaultLwM2MTransportMsgHandler serviceImpl = this; - transportService.process(sessionInfo, createFirmwareRequestMsg(sessionInfo, FirmwareType.SOFTWARE.name()), + transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.SOFTWARE.name()), new TransportServiceCallback<>() { @Override - public void onSuccess(TransportProtos.GetFirmwareResponseMsg response) { + public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) - && response.getType().equals(FirmwareType.SOFTWARE.name())) { + && response.getType().equals(OtaPackageType.SOFTWARE.name())) { lwM2MClient.getSwUpdate().setCurrentVersion(response.getVersion()); lwM2MClient.getSwUpdate().setCurrentTitle(response.getTitle()); - lwM2MClient.getSwUpdate().setCurrentId(new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB())).getId()); + lwM2MClient.getSwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId()); lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest); } else { log.trace("Software [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); @@ -1397,8 +1397,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } } - private TransportProtos.GetFirmwareRequestMsg createFirmwareRequestMsg(SessionInfoProto sessionInfo, String nameFwSW) { - return TransportProtos.GetFirmwareRequestMsg.newBuilder() + private TransportProtos.GetOtaPackageRequestMsg createOtaPackageRequestMsg(SessionInfoProto sessionInfo, String nameFwSW) { + return TransportProtos.GetOtaPackageRequestMsg.newBuilder() .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) .setTenantIdMSB(sessionInfo.getTenantIdMSB()) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java index e5cd289758..87e72c2873 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java @@ -71,8 +71,8 @@ import java.util.stream.Collectors; import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; import static org.eclipse.leshan.core.ResponseCode.BAD_REQUEST; import static org.eclipse.leshan.core.ResponseCode.NOT_FOUND; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.DOWNLOADED; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.FAILED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getContentFormatByResourceModelType; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEFAULT_TIMEOUT; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_ID; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java index 320059b0a7..a013f75c1b 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java @@ -43,10 +43,10 @@ import org.eclipse.leshan.server.registration.Registration; import org.nustaq.serialization.FSTConfiguration; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; -import org.thingsboard.server.common.data.firmware.FirmwareKey; -import org.thingsboard.server.common.data.firmware.FirmwareType; -import org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus; -import org.thingsboard.server.common.data.firmware.FirmwareUtil; +import org.thingsboard.server.common.data.ota.OtaPackageKey; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus; +import org.thingsboard.server.common.data.ota.OtaPackageUtil; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; @@ -77,12 +77,12 @@ import static org.eclipse.leshan.core.model.ResourceModel.Type.OBJLNK; import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE; import static org.eclipse.leshan.core.model.ResourceModel.Type.STRING; import static org.eclipse.leshan.core.model.ResourceModel.Type.TIME; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.DOWNLOADED; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.DOWNLOADING; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.FAILED; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.UPDATED; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.UPDATING; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.VERIFIED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADING; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.VERIFIED; import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; @@ -139,7 +139,7 @@ public class LwM2mTransportUtil { public static final String ERROR_KEY = "error"; public static final String METHOD_KEY = "methodName"; - // FirmWare + // Firmware public static final String FW_UPDATE = "Firmware update"; public static final Integer FW_ID = 5; // Package W @@ -155,7 +155,7 @@ public class LwM2mTransportUtil { // Update E public static final String FW_UPDATE_ID = "/5/0/2"; - // SoftWare + // Software public static final String SW_UPDATE = "Software update"; public static final Integer SW_ID = 9; // Package W @@ -354,7 +354,7 @@ public class LwM2mTransportUtil { * FirmwareUpdateStatus { * DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED */ - public static FirmwareUpdateStatus EqualsFwSateToFirmwareUpdateStatus(StateFw stateFw, UpdateResultFw updateResultFw) { + public static OtaPackageUpdateStatus EqualsFwSateToFirmwareUpdateStatus(StateFw stateFw, UpdateResultFw updateResultFw) { switch (updateResultFw) { case INITIAL: switch (stateFw) { @@ -500,7 +500,7 @@ public class LwM2mTransportUtil { * FirmwareUpdateStatus { * DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED */ - public static FirmwareUpdateStatus EqualsSwSateToFirmwareUpdateStatus(UpdateStateSw updateStateSw, UpdateResultSw updateResultSw) { + public static OtaPackageUpdateStatus EqualsSwSateToFirmwareUpdateStatus(UpdateStateSw updateStateSw, UpdateResultSw updateResultSw) { switch (updateResultSw) { case INITIAL: switch (updateStateSw) { @@ -932,15 +932,15 @@ public class LwM2mTransportUtil { } public static boolean isFwSwWords (String pathName) { - return FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) - || FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.TITLE).equals(pathName) - || FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.CHECKSUM).equals(pathName) - || FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.CHECKSUM_ALGORITHM).equals(pathName) - || FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.SIZE).equals(pathName) - || FirmwareUtil.getAttributeKey(FirmwareType.SOFTWARE, FirmwareKey.VERSION).equals(pathName) - || FirmwareUtil.getAttributeKey(FirmwareType.SOFTWARE, FirmwareKey.TITLE).equals(pathName) - || FirmwareUtil.getAttributeKey(FirmwareType.SOFTWARE, FirmwareKey.CHECKSUM).equals(pathName) - || FirmwareUtil.getAttributeKey(FirmwareType.SOFTWARE, FirmwareKey.CHECKSUM_ALGORITHM).equals(pathName) - || FirmwareUtil.getAttributeKey(FirmwareType.SOFTWARE, FirmwareKey.SIZE).equals(pathName); + return OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.VERSION).equals(pathName) + || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.TITLE).equals(pathName) + || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.CHECKSUM).equals(pathName) + || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.CHECKSUM_ALGORITHM).equals(pathName) + || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.SIZE).equals(pathName) + || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.VERSION).equals(pathName) + || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.TITLE).equals(pathName) + || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.CHECKSUM).equals(pathName) + || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.CHECKSUM_ALGORITHM).equals(pathName) + || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.SIZE).equals(pathName); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java index 9ef45c3b3b..a6a1fadbf3 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java @@ -31,7 +31,7 @@ import org.eclipse.leshan.server.registration.Registration; import org.eclipse.leshan.server.security.SecurityInfo; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; @@ -120,8 +120,8 @@ public class LwM2mClient implements Cloneable { this.init = false; this.queuedRequests = new ConcurrentLinkedQueue<>(); - this.fwUpdate = new LwM2mFwSwUpdate(this, FirmwareType.FIRMWARE); - this.swUpdate = new LwM2mFwSwUpdate(this, FirmwareType.SOFTWARE); + this.fwUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.FIRMWARE); + this.swUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.SOFTWARE); if (this.credentials != null && this.credentials.hasDeviceInfo()) { this.session = createSession(nodeId, sessionId, credentials); this.deviceId = new UUID(session.getDeviceIdMSB(), session.getDeviceIdLSB()); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java index e3e8608839..a0e5432c5a 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java @@ -20,8 +20,8 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.eclipse.leshan.core.request.ContentFormat; -import org.thingsboard.server.common.data.firmware.FirmwareType; -import org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler; import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportRequest; @@ -32,11 +32,11 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; -import static org.thingsboard.server.common.data.firmware.FirmwareKey.STATE; -import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; -import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE; -import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.UPDATING; -import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getAttributeKey; +import static org.thingsboard.server.common.data.ota.OtaPackageKey.STATE; +import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; +import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; +import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_NAME_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID; @@ -97,14 +97,14 @@ public class LwM2mFwSwUpdate { @Getter @Setter private volatile boolean infoFwSwUpdate = false; - private final FirmwareType type; + private final OtaPackageType type; @Getter LwM2mClient lwM2MClient; @Getter @Setter private final List pendingInfoRequestsStart; - public LwM2mFwSwUpdate(LwM2mClient lwM2MClient, FirmwareType type) { + public LwM2mFwSwUpdate(LwM2mClient lwM2MClient, OtaPackageType type) { this.lwM2MClient = lwM2MClient; this.pendingInfoRequestsStart = new CopyOnWriteArrayList<>(); this.type = type; @@ -139,7 +139,7 @@ public class LwM2mFwSwUpdate { } if (this.pendingInfoRequestsStart.size() == 0) { this.infoFwSwUpdate = false; - if (!FirmwareUpdateStatus.DOWNLOADING.name().equals(this.stateUpdate)) { + if (!OtaPackageUpdateStatus.DOWNLOADING.name().equals(this.stateUpdate)) { boolean conditionalStart = this.type.equals(FIRMWARE) ? this.conditionalFwUpdateStart() : this.conditionalSwUpdateStart(); if (conditionalStart) { @@ -154,12 +154,12 @@ public class LwM2mFwSwUpdate { * before operation Write: fw_state = DOWNLOADING */ private void writeFwSwWare(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) { - this.stateUpdate = FirmwareUpdateStatus.DOWNLOADING.name(); + this.stateUpdate = OtaPackageUpdateStatus.DOWNLOADING.name(); // this.observeStateUpdate(); this.sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null); int chunkSize = 0; int chunk = 0; - byte[] firmwareChunk = handler.firmwareDataCache.get(this.currentId.toString(), chunkSize, chunk); + byte[] firmwareChunk = handler.otaPackageDataCache.get(this.currentId.toString(), chunkSize, chunk); String targetIdVer = convertPathFromObjectIdToIdVer(this.pathPackageId, this.lwM2MClient.getRegistration()); request.sendAllRequest(lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, ContentFormat.OPAQUE.getName(), firmwareChunk, handler.config.getTimeout(), null); @@ -287,10 +287,10 @@ public class LwM2mFwSwUpdate { LwM2mTransportUtil.UpdateResultSw.fromUpdateResultSwByCode(updateResult.intValue()).type; String key = splitCamelCaseString((String) this.lwM2MClient.getResourceNameByRezId(null, this.pathResultId)); if (success) { - this.stateUpdate = FirmwareUpdateStatus.UPDATED.name(); + this.stateUpdate = OtaPackageUpdateStatus.UPDATED.name(); this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null); } else { - this.stateUpdate = FirmwareUpdateStatus.FAILED.name(); + this.stateUpdate = OtaPackageUpdateStatus.FAILED.name(); this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_ERROR, value); } handler.helper.sendParametersOnThingsboardTelemetry( diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index f2a6922b6d..961c20ed34 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -47,8 +47,8 @@ import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.profile.MqttTopics; -import org.thingsboard.server.common.data.firmware.FirmwareType; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.msg.EncryptionUtil; import org.thingsboard.server.common.msg.tools.TbRateLimitsException; import org.thingsboard.server.common.transport.SessionMsgListener; @@ -126,8 +126,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private volatile InetSocketAddress address; private volatile GatewaySessionHandler gatewaySessionHandler; - private final ConcurrentHashMap fwSessions; - private final ConcurrentHashMap fwChunkSizes; + private final ConcurrentHashMap otaPackSessions; + private final ConcurrentHashMap chunkSizes; MqttTransportHandler(MqttTransportContext context, SslHandler sslHandler) { this.sessionId = UUID.randomUUID(); @@ -137,8 +137,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement this.sslHandler = sslHandler; this.mqttQoSMap = new ConcurrentHashMap<>(); this.deviceSessionCtx = new DeviceSessionCtx(sessionId, mqttQoSMap, context); - this.fwSessions = new ConcurrentHashMap<>(); - this.fwChunkSizes = new ConcurrentHashMap<>(); + this.otaPackSessions = new ConcurrentHashMap<>(); + this.chunkSizes = new ConcurrentHashMap<>(); } @Override @@ -320,9 +320,9 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement TransportProtos.ClaimDeviceMsg claimDeviceMsg = payloadAdaptor.convertToClaimDevice(deviceSessionCtx, mqttMsg); transportService.process(deviceSessionCtx.getSessionInfo(), claimDeviceMsg, getPubAckCallback(ctx, msgId, claimDeviceMsg)); } else if ((fwMatcher = FW_REQUEST_PATTERN.matcher(topicName)).find()) { - getFirmwareCallback(ctx, mqttMsg, msgId, fwMatcher, FirmwareType.FIRMWARE); + getOtaPackageCallback(ctx, mqttMsg, msgId, fwMatcher, OtaPackageType.FIRMWARE); } else if ((fwMatcher = SW_REQUEST_PATTERN.matcher(topicName)).find()) { - getFirmwareCallback(ctx, mqttMsg, msgId, fwMatcher, FirmwareType.SOFTWARE); + getOtaPackageCallback(ctx, mqttMsg, msgId, fwMatcher, OtaPackageType.SOFTWARE); } else { transportService.reportActivity(deviceSessionCtx.getSessionInfo()); ack(ctx, msgId); @@ -334,38 +334,38 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } } - private void getFirmwareCallback(ChannelHandlerContext ctx, MqttPublishMessage mqttMsg, int msgId, Matcher fwMatcher, FirmwareType type) { + private void getOtaPackageCallback(ChannelHandlerContext ctx, MqttPublishMessage mqttMsg, int msgId, Matcher fwMatcher, OtaPackageType type) { String payload = mqttMsg.content().toString(UTF8); int chunkSize = StringUtils.isNotEmpty(payload) ? Integer.parseInt(payload) : 0; String requestId = fwMatcher.group("requestId"); int chunk = Integer.parseInt(fwMatcher.group("chunk")); if (chunkSize > 0) { - this.fwChunkSizes.put(requestId, chunkSize); + this.chunkSizes.put(requestId, chunkSize); } else { - chunkSize = fwChunkSizes.getOrDefault(requestId, 0); + chunkSize = chunkSizes.getOrDefault(requestId, 0); } if (chunkSize > context.getMaxPayloadSize()) { - sendFirmwareError(ctx, PAYLOAD_TOO_LARGE); + sendOtaPackageError(ctx, PAYLOAD_TOO_LARGE); return; } - String firmwareId = fwSessions.get(requestId); + String otaPackageId = otaPackSessions.get(requestId); - if (firmwareId != null) { - sendFirmware(ctx, mqttMsg.variableHeader().packetId(), firmwareId, requestId, chunkSize, chunk, type); + if (otaPackageId != null) { + sendOtaPackage(ctx, mqttMsg.variableHeader().packetId(), otaPackageId, requestId, chunkSize, chunk, type); } else { TransportProtos.SessionInfoProto sessionInfo = deviceSessionCtx.getSessionInfo(); - TransportProtos.GetFirmwareRequestMsg getFirmwareRequestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() + TransportProtos.GetOtaPackageRequestMsg getOtaPackageRequestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder() .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) .setTenantIdMSB(sessionInfo.getTenantIdMSB()) .setTenantIdLSB(sessionInfo.getTenantIdLSB()) .setType(type.name()) .build(); - transportService.process(deviceSessionCtx.getSessionInfo(), getFirmwareRequestMsg, - new FirmwareCallback(ctx, msgId, getFirmwareRequestMsg, requestId, chunkSize, chunk)); + transportService.process(deviceSessionCtx.getSessionInfo(), getOtaPackageRequestMsg, + new OtaPackageCallback(ctx, msgId, getOtaPackageRequestMsg, requestId, chunkSize, chunk)); } } @@ -425,15 +425,15 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } } - private class FirmwareCallback implements TransportServiceCallback { + private class OtaPackageCallback implements TransportServiceCallback { private final ChannelHandlerContext ctx; private final int msgId; - private final TransportProtos.GetFirmwareRequestMsg msg; + private final TransportProtos.GetOtaPackageRequestMsg msg; private final String requestId; private final int chunkSize; private final int chunk; - FirmwareCallback(ChannelHandlerContext ctx, int msgId, TransportProtos.GetFirmwareRequestMsg msg, String requestId, int chunkSize, int chunk) { + OtaPackageCallback(ChannelHandlerContext ctx, int msgId, TransportProtos.GetOtaPackageRequestMsg msg, String requestId, int chunkSize, int chunk) { this.ctx = ctx; this.msgId = msgId; this.msg = msg; @@ -443,13 +443,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } @Override - public void onSuccess(TransportProtos.GetFirmwareResponseMsg response) { + public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())) { - FirmwareId firmwareId = new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB())); - fwSessions.put(requestId, firmwareId.toString()); - sendFirmware(ctx, msgId, firmwareId.toString(), requestId, chunkSize, chunk, FirmwareType.valueOf(response.getType())); + OtaPackageId firmwareId = new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())); + otaPackSessions.put(requestId, firmwareId.toString()); + sendOtaPackage(ctx, msgId, firmwareId.toString(), requestId, chunkSize, chunk, OtaPackageType.valueOf(response.getType())); } else { - sendFirmwareError(ctx, response.getResponseStatus().toString()); + sendOtaPackageError(ctx, response.getResponseStatus().toString()); } } @@ -460,11 +460,11 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } } - private void sendFirmware(ChannelHandlerContext ctx, int msgId, String firmwareId, String requestId, int chunkSize, int chunk, FirmwareType type) { + private void sendOtaPackage(ChannelHandlerContext ctx, int msgId, String firmwareId, String requestId, int chunkSize, int chunk, OtaPackageType type) { log.trace("[{}] Send firmware [{}] to device!", sessionId, firmwareId); ack(ctx, msgId); try { - byte[] firmwareChunk = context.getFirmwareDataCache().get(firmwareId, chunkSize, chunk); + byte[] firmwareChunk = context.getOtaPackageDataCache().get(firmwareId, chunkSize, chunk); deviceSessionCtx.getPayloadAdaptor() .convertToPublish(deviceSessionCtx, firmwareChunk, requestId, chunk, type) .ifPresent(deviceSessionCtx.getChannel()::writeAndFlush); @@ -473,7 +473,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } } - private void sendFirmwareError(ChannelHandlerContext ctx, String error) { + private void sendOtaPackageError(ChannelHandlerContext ctx, String error) { log.warn("[{}] {}", sessionId, error); deviceSessionCtx.getChannel().writeAndFlush(deviceSessionCtx .getPayloadAdaptor() diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java index a9d7b3e2ea..19d2e15fc5 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java @@ -30,7 +30,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.device.profile.MqttTopics; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.transport.adaptor.AdaptorException; import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.gen.transport.TransportProtos; @@ -155,7 +155,7 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { } @Override - public Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) { + public Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, OtaPackageType firmwareType) { return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk)); } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java index d0c1f30524..62ae6ae027 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java @@ -23,7 +23,7 @@ import io.netty.handler.codec.mqtt.MqttMessage; import io.netty.handler.codec.mqtt.MqttMessageType; import io.netty.handler.codec.mqtt.MqttPublishMessage; import io.netty.handler.codec.mqtt.MqttPublishVariableHeader; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.transport.adaptor.AdaptorException; import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; @@ -78,7 +78,7 @@ public interface MqttTransportAdaptor { Optional convertToPublish(MqttDeviceAwareSessionContext ctx, ProvisionDeviceResponseMsg provisionResponse) throws AdaptorException; - Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) throws AdaptorException; + Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, OtaPackageType firmwareType) throws AdaptorException; default MqttPublishMessage createMqttPublishMsg(MqttDeviceAwareSessionContext ctx, String topic, byte[] payloadInBytes) { MqttFixedHeader mqttFixedHeader = diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java index 08a2f9abe3..a007c73a5a 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java @@ -28,7 +28,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.device.profile.MqttTopics; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.transport.adaptor.AdaptorException; import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.common.transport.adaptor.ProtoConverter; @@ -168,7 +168,7 @@ public class ProtoMqttAdaptor implements MqttTransportAdaptor { } @Override - public Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) throws AdaptorException { + public Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, OtaPackageType firmwareType) throws AdaptorException { return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk)); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java index d4798108c6..d48d3fd04e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java @@ -21,14 +21,13 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.common.util.ThingsBoardExecutors; -import org.thingsboard.server.cache.firmware.FirmwareDataCache; +import org.thingsboard.server.cache.ota.OtaPackageDataCache; import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; import org.thingsboard.server.queue.scheduler.SchedulerComponent; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; /** * Created by ashvayka on 15.10.18. @@ -53,7 +52,7 @@ public abstract class TransportContext { @Getter @Autowired - private FirmwareDataCache firmwareDataCache; + private OtaPackageDataCache otaPackageDataCache; @Autowired private TransportResourceCache transportResourceCache; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java index 2209ffc305..4a4e68f64f 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java @@ -29,8 +29,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; -import org.thingsboard.server.gen.transport.TransportProtos.GetFirmwareRequestMsg; -import org.thingsboard.server.gen.transport.TransportProtos.GetFirmwareResponseMsg; +import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageRequestMsg; +import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetResourceRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetResourceResponseMsg; @@ -115,7 +115,7 @@ public interface TransportService { void process(TransportToDeviceActorMsg msg, TransportServiceCallback callback); - void process(SessionInfoProto sessionInfoProto, GetFirmwareRequestMsg msg, TransportServiceCallback callback); + void process(SessionInfoProto sessionInfoProto, GetOtaPackageRequestMsg msg, TransportServiceCallback callback); SessionMetaData registerAsyncSession(SessionInfoProto sessionInfo, SessionMsgListener listener); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 7035c3374e..77b75dc07a 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -614,13 +614,13 @@ public class DefaultTransportService implements TransportService { } @Override - public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.GetFirmwareRequestMsg msg, TransportServiceCallback callback) { + public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.GetOtaPackageRequestMsg msg, TransportServiceCallback callback) { if (checkLimits(sessionInfo, msg, callback)) { TbProtoQueueMsg protoMsg = - new TbProtoQueueMsg<>(UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder().setFirmwareRequestMsg(msg).build()); + new TbProtoQueueMsg<>(UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder().setOtaPackageRequestMsg(msg).build()); AsyncCallbackTemplate.withCallback(transportApiRequestTemplate.send(protoMsg), response -> { - callback.onSuccess(response.getValue().getFirmwareResponseMsg()); + callback.onSuccess(response.getValue().getOtaPackageResponseMsg()); }, callback::onError, transportCallbackExecutor); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java index 34982b92b6..de13c85727 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java @@ -21,6 +21,7 @@ import org.thingsboard.server.common.data.DeviceInfo; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.Dao; @@ -81,9 +82,12 @@ public interface DeviceDao extends Dao, TenantEntityDao { */ PageData findDevicesByTenantIdAndType(UUID tenantId, String type, PageLink pageLink); - PageData findDevicesByTenantIdAndTypeAndEmptyFirmware(UUID tenantId, String type, PageLink pageLink); + PageData findDevicesByTenantIdAndTypeAndEmptyOtaPackage(UUID tenantId, + UUID deviceProfileId, + OtaPackageType type, + PageLink pageLink); - PageData findDevicesByTenantIdAndTypeAndEmptySoftware(UUID tenantId, String type, PageLink pageLink); + Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(UUID tenantId, UUID deviceProfileId, OtaPackageType otaPackageType); /** * Find device infos by tenantId, type and page link. 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 8158134925..e41289e97b 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 @@ -43,7 +43,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.OtaPackage; 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; @@ -57,7 +57,7 @@ import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfilePr import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -66,7 +66,7 @@ import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.dao.dashboard.DashboardService; 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.ota.OtaPackageService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -119,7 +119,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D private CacheManager cacheManager; @Autowired - private FirmwareService firmwareService; + private OtaPackageService otaPackageService; @Autowired private RuleChainService ruleChainService; @@ -427,11 +427,11 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D } if (deviceProfile.getFirmwareId() != null) { - Firmware firmware = firmwareService.findFirmwareById(tenantId, deviceProfile.getFirmwareId()); + OtaPackage firmware = otaPackageService.findOtaPackageById(tenantId, deviceProfile.getFirmwareId()); if (firmware == null) { throw new DataValidationException("Can't assign non-existent firmware!"); } - if (!firmware.getType().equals(FirmwareType.FIRMWARE)) { + if (!firmware.getType().equals(OtaPackageType.FIRMWARE)) { throw new DataValidationException("Can't assign firmware with type: " + firmware.getType()); } if (firmware.getData() == null) { @@ -443,11 +443,11 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D } if (deviceProfile.getSoftwareId() != null) { - Firmware software = firmwareService.findFirmwareById(tenantId, deviceProfile.getSoftwareId()); + OtaPackage software = otaPackageService.findOtaPackageById(tenantId, deviceProfile.getSoftwareId()); if (software == null) { throw new DataValidationException("Can't assign non-existent software!"); } - if (!software.getType().equals(FirmwareType.SOFTWARE)) { + if (!software.getType().equals(OtaPackageType.SOFTWARE)) { throw new DataValidationException("Can't assign software with type: " + software.getType()); } if (software.getData() == null) { 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 237d53a7f2..34aa462a6d 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 @@ -41,7 +41,7 @@ import org.thingsboard.server.common.data.DeviceTransportType; 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.OtaPackage; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.device.DeviceSearchQuery; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; @@ -54,13 +54,13 @@ import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfig import org.thingsboard.server.common.data.device.data.MqttDeviceTransportConfiguration; import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.common.data.firmware.FirmwareType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.relation.EntityRelation; @@ -76,7 +76,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus; import org.thingsboard.server.dao.entity.AbstractEntityService; 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.ota.OtaPackageService; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; @@ -138,7 +138,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe private TbTenantProfileCache tenantProfileCache; @Autowired - private FirmwareService firmwareService; + private OtaPackageService otaPackageService; @Override public DeviceInfo findDeviceInfoById(TenantId tenantId, DeviceId deviceId) { @@ -201,14 +201,12 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe deviceCredentials.setDeviceId(savedDevice.getId()); if (device.getId() == null) { deviceCredentialsService.createDeviceCredentials(savedDevice.getTenantId(), deviceCredentials); - } - else { + } else { DeviceCredentials foundDeviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getTenantId(), savedDevice.getId()); if (foundDeviceCredentials == null) { deviceCredentialsService.createDeviceCredentials(savedDevice.getTenantId(), deviceCredentials); - } - else { - deviceCredentialsService.updateDeviceCredentials(device.getTenantId(), deviceCredentials); + } else { + deviceCredentialsService.updateDeviceCredentials(device.getTenantId(), deviceCredentials); } } return savedDevice; @@ -364,21 +362,24 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe } @Override - public PageData findDevicesByTenantIdAndTypeAndEmptyFirmware(TenantId tenantId, String type, PageLink pageLink) { - log.trace("Executing findDevicesByTenantIdAndTypeAndEmptyFirmware, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink); + public PageData findDevicesByTenantIdAndTypeAndEmptyOtaPackage(TenantId tenantId, + DeviceProfileId deviceProfileId, + OtaPackageType type, + PageLink pageLink) { + log.trace("Executing findDevicesByTenantIdAndTypeAndEmptyOtaPackage, tenantId [{}], deviceProfileId [{}], type [{}], pageLink [{}]", + tenantId, deviceProfileId, type, pageLink); validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - validateString(type, "Incorrect type " + type); + validateId(tenantId, INCORRECT_DEVICE_PROFILE_ID + deviceProfileId); validatePageLink(pageLink); - return deviceDao.findDevicesByTenantIdAndTypeAndEmptyFirmware(tenantId.getId(), type, pageLink); + return deviceDao.findDevicesByTenantIdAndTypeAndEmptyOtaPackage(tenantId.getId(), deviceProfileId.getId(), type, pageLink); } @Override - public PageData findDevicesByTenantIdAndTypeAndEmptySoftware(TenantId tenantId, String type, PageLink pageLink) { - log.trace("Executing findDevicesByTenantIdAndTypeAndEmptySoftware, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink); + public Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType type) { + log.trace("Executing countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage, tenantId [{}], deviceProfileId [{}], type [{}]", tenantId, deviceProfileId, type); validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - validateString(type, "Incorrect type " + type); - validatePageLink(pageLink); - return deviceDao.findDevicesByTenantIdAndTypeAndEmptySoftware(tenantId.getId(), type, pageLink); + validateId(tenantId, INCORRECT_DEVICE_PROFILE_ID + deviceProfileId); + return deviceDao.countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(tenantId.getId(), deviceProfileId.getId(), type); } @Override @@ -708,11 +709,11 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe .ifPresent(DeviceTransportConfiguration::validate); if (device.getFirmwareId() != null) { - Firmware firmware = firmwareService.findFirmwareById(tenantId, device.getFirmwareId()); + OtaPackage firmware = otaPackageService.findOtaPackageById(tenantId, device.getFirmwareId()); if (firmware == null) { throw new DataValidationException("Can't assign non-existent firmware!"); } - if (!firmware.getType().equals(FirmwareType.FIRMWARE)) { + if (!firmware.getType().equals(OtaPackageType.FIRMWARE)) { throw new DataValidationException("Can't assign firmware with type: " + firmware.getType()); } if (firmware.getData() == null) { @@ -724,11 +725,11 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe } if (device.getSoftwareId() != null) { - Firmware software = firmwareService.findFirmwareById(tenantId, device.getSoftwareId()); + OtaPackage software = otaPackageService.findOtaPackageById(tenantId, device.getSoftwareId()); if (software == null) { throw new DataValidationException("Can't assign non-existent software!"); } - if (!software.getType().equals(FirmwareType.SOFTWARE)) { + if (!software.getType().equals(OtaPackageType.SOFTWARE)) { throw new DataValidationException("Can't assign software with type: " + software.getType()); } if (software.getData() == null) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java index 73cebc0797..7686d9ec21 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java @@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.TenantId; @@ -49,7 +49,7 @@ import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.exception.IncorrectParameterException; -import org.thingsboard.server.dao.firmware.FirmwareService; +import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.resource.ResourceService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.tenant.TenantService; @@ -102,7 +102,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe private ResourceService resourceService; @Autowired - private FirmwareService firmwareService; + private OtaPackageService otaPackageService; @Override public void deleteEntityRelations(TenantId tenantId, EntityId entityId) { @@ -167,8 +167,8 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe case TB_RESOURCE: hasName = resourceService.findResourceInfoByIdAsync(tenantId, new TbResourceId(entityId.getId())); break; - case FIRMWARE: - hasName = firmwareService.findFirmwareInfoByIdAsync(tenantId, new FirmwareId(entityId.getId())); + case OTA_PACKAGE: + hasName = otaPackageService.findOtaPackageInfoByIdAsync(tenantId, new OtaPackageId(entityId.getId())); break; default: throw new IllegalStateException("Not Implemented!"); @@ -192,7 +192,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe case DEVICE_PROFILE: case API_USAGE_STATE: case TB_RESOURCE: - case FIRMWARE: + case OTA_PACKAGE: break; case CUSTOMER: hasCustomerId = () -> new CustomerId(entityId.getId()); 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 deleted file mode 100644 index 2e0d5c03b6..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java +++ /dev/null @@ -1,379 +0,0 @@ -/** - * Copyright © 2016-2021 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.firmware; - -import com.google.common.hash.HashFunction; -import com.google.common.hash.Hashing; -import com.google.common.util.concurrent.ListenableFuture; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.hibernate.exception.ConstraintViolationException; -import org.springframework.cache.Cache; -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.exception.ThingsboardErrorCode; -import org.thingsboard.server.common.data.exception.ThingsboardException; -import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm; -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; -import org.thingsboard.server.dao.tenant.TenantDao; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import static org.thingsboard.server.common.data.CacheConstants.FIRMWARE_CACHE; -import static org.thingsboard.server.dao.service.Validator.validateId; -import static org.thingsboard.server.dao.service.Validator.validatePageLink; - -@Service -@Slf4j -@RequiredArgsConstructor -public class BaseFirmwareService implements FirmwareService { - public static final String INCORRECT_FIRMWARE_ID = "Incorrect firmwareId "; - 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; - private final FirmwareDataCache firmwareDataCache; - - @Override - public FirmwareInfo saveFirmwareInfo(FirmwareInfo firmwareInfo) { - log.trace("Executing saveFirmwareInfo [{}]", firmwareInfo); - firmwareInfoValidator.validate(firmwareInfo, FirmwareInfo::getTenantId); - try { - FirmwareId firmwareId = firmwareInfo.getId(); - if (firmwareId != null) { - Cache cache = cacheManager.getCache(FIRMWARE_CACHE); - cache.evict(toFirmwareInfoKey(firmwareId)); - firmwareDataCache.evict(firmwareId.toString()); - } - 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, FirmwareInfo::getTenantId); - try { - FirmwareId firmwareId = firmware.getId(); - if (firmwareId != null) { - Cache cache = cacheManager.getCache(FIRMWARE_CACHE); - cache.evict(toFirmwareInfoKey(firmwareId)); - firmwareDataCache.evict(firmwareId.toString()); - } - 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 - public String generateChecksum(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data) { - if (data == null || !data.hasArray() || data.array().length == 0) { - throw new DataValidationException("Firmware data should be specified!"); - } - - return getHashFunction(checksumAlgorithm).hashBytes(data.array()).toString(); - } - - private HashFunction getHashFunction(ChecksumAlgorithm checksumAlgorithm) { - switch (checksumAlgorithm) { - case MD5: - return Hashing.md5(); - case SHA256: - return Hashing.sha256(); - case SHA384: - return Hashing.sha384(); - case SHA512: - return Hashing.sha512(); - case CRC32: - return Hashing.crc32(); - case MURMUR3_32: - return Hashing.murmur3_32(); - case MURMUR3_128: - return Hashing.murmur3_128(); - default: - throw new DataValidationException("Unknown checksum algorithm!"); - } - } - - @Override - public Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId) { - log.trace("Executing findFirmwareById [{}]", firmwareId); - validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId); - return firmwareDao.findById(tenantId, firmwareId.getId()); - } - - @Override - @Cacheable(cacheNames = FIRMWARE_CACHE, key = "{#firmwareId}") - public FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId) { - log.trace("Executing findFirmwareInfoById [{}]", firmwareId); - validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId); - return firmwareInfoDao.findById(tenantId, firmwareId.getId()); - } - - @Override - public ListenableFuture findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId) { - log.trace("Executing findFirmwareInfoByIdAsync [{}]", firmwareId); - validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId); - return firmwareInfoDao.findByIdAsync(tenantId, firmwareId.getId()); - } - - @Override - public PageData findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink) { - log.trace("Executing findTenantFirmwaresByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink); - validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - validatePageLink(pageLink); - return firmwareInfoDao.findFirmwareInfoByTenantId(tenantId, pageLink); - } - - @Override - 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.findFirmwareInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, firmwareType, hasData, pageLink); - } - - @Override - public void deleteFirmware(TenantId tenantId, FirmwareId firmwareId) { - log.trace("Executing deleteFirmware [{}]", firmwareId); - validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId); - try { - Cache cache = cacheManager.getCache(FIRMWARE_CACHE); - cache.evict(toFirmwareInfoKey(firmwareId)); - firmwareDataCache.evict(firmwareId.toString()); - firmwareDao.removeById(tenantId, firmwareId.getId()); - } catch (Exception t) { - ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); - if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_firmware_device")) { - 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; - } - } - } - - @Override - public void deleteFirmwaresByTenantId(TenantId tenantId) { - log.trace("Executing deleteFirmwaresByTenantId, tenantId [{}]", tenantId); - validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - tenantFirmwareRemover.removeEntities(tenantId, tenantId); - } - - private DataValidator firmwareInfoValidator = new DataValidator<>() { - - @Override - protected void validateDataImpl(TenantId tenantId, FirmwareInfo firmwareInfo) { - validateImpl(firmwareInfo); - } - - @Override - protected void validateUpdate(TenantId tenantId, FirmwareInfo firmware) { - FirmwareInfo firmwareOld = firmwareInfoDao.findById(tenantId, firmware.getUuidId()); - - validateUpdateDeviceProfile(firmware, firmwareOld); - BaseFirmwareService.validateUpdate(firmware, firmwareOld); - } - }; - - private DataValidator firmwareValidator = new DataValidator<>() { - - @Override - protected void validateDataImpl(TenantId tenantId, Firmware firmware) { - validateImpl(firmware); - - 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 (firmware.getChecksumAlgorithm() == null) { - throw new DataValidationException("Firmware checksum algorithm should be specified!"); - } - if (StringUtils.isEmpty(firmware.getChecksum())) { - throw new DataValidationException("Firmware checksum should be specified!"); - } - - String currentChecksum; - - currentChecksum = generateChecksum(firmware.getChecksumAlgorithm(), firmware.getData()); - - 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()); - - validateUpdateDeviceProfile(firmware, firmwareOld); - BaseFirmwareService.validateUpdate(firmware, firmwareOld); - - if (firmwareOld.getData() != null && !firmwareOld.getData().equals(firmware.getData())) { - throw new DataValidationException("Updating firmware data is prohibited!"); - } - } - }; - - private void validateUpdateDeviceProfile(FirmwareInfo firmware, FirmwareInfo firmwareOld) { - if (firmwareOld.getDeviceProfileId() != null && !firmwareOld.getDeviceProfileId().equals(firmware.getDeviceProfileId())) { - if (firmwareInfoDao.isFirmwareUsed(firmwareOld.getId(), firmware.getType(), firmwareOld.getDeviceProfileId())) { - throw new DataValidationException("Can`t update deviceProfileId because firmware is already in use!"); - } - } - } - - private static void validateUpdate(FirmwareInfo firmware, FirmwareInfo firmwareOld) { - if (!firmwareOld.getType().equals(firmware.getType())) { - throw new DataValidationException("Updating type is prohibited!"); - } - - 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.getDataSize() != null && !firmwareOld.getDataSize().equals(firmware.getDataSize())) { - throw new DataValidationException("Updating firmware data size is prohibited!"); - } - } - - 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) { - 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<>() { - - @Override - protected PageData findEntities(TenantId tenantId, TenantId id, PageLink pageLink) { - return firmwareInfoDao.findFirmwareInfoByTenantId(id, pageLink); - } - - @Override - protected void removeEntity(TenantId tenantId, FirmwareInfo entity) { - deleteFirmware(tenantId, entity.getId()); - } - }; - - protected Optional extractConstraintViolationException(Exception t) { - if (t instanceof ConstraintViolationException) { - return Optional.of((ConstraintViolationException) t); - } else if (t.getCause() instanceof ConstraintViolationException) { - return Optional.of((ConstraintViolationException) (t.getCause())); - } else { - return Optional.empty(); - } - } - - private static List toFirmwareInfoKey(FirmwareId firmwareId) { - return Collections.singletonList(firmwareId); - } - -} 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 0bc346e36c..34878a3810 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 @@ -479,22 +479,21 @@ public class ModelConstants { public static final String RESOURCE_DATA_COLUMN = "data"; /** - * Firmware constants. - */ - 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"; - 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_DATA_SIZE_COLUMN = "data_size"; - public static final String FIRMWARE_ADDITIONAL_INFO_COLUMN = ADDITIONAL_INFO_PROPERTY; - public static final String FIRMWARE_HAS_DATA_PROPERTY = "has_data"; + * Ota Package constants. + */ + public static final String OTA_PACKAGE_TABLE_NAME = "ota_package"; + public static final String OTA_PACKAGE_TENANT_ID_COLUMN = TENANT_ID_COLUMN; + public static final String OTA_PACKAGE_DEVICE_PROFILE_ID_COLUMN = "device_profile_id"; + public static final String OTA_PACKAGE_TYPE_COLUMN = "type"; + public static final String OTA_PACKAGE_TILE_COLUMN = TITLE_PROPERTY; + public static final String OTA_PACKAGE_VERSION_COLUMN = "version"; + public static final String OTA_PACKAGE_FILE_NAME_COLUMN = "file_name"; + public static final String OTA_PACKAGE_CONTENT_TYPE_COLUMN = "content_type"; + public static final String OTA_PACKAGE_CHECKSUM_ALGORITHM_COLUMN = "checksum_algorithm"; + public static final String OTA_PACKAGE_CHECKSUM_COLUMN = "checksum"; + public static final String OTA_PACKAGE_DATA_COLUMN = "data"; + public static final String OTA_PACKAGE_DATA_SIZE_COLUMN = "data_size"; + public static final String OTA_PACKAGE_ADDITIONAL_INFO_COLUMN = ADDITIONAL_INFO_PROPERTY; /** * Edge constants. 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 ed6a871fea..c9913565e4 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 @@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.device.data.DeviceData; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; @@ -154,10 +154,10 @@ public abstract class AbstractDeviceEntity extends BaseSqlEnti device.setDeviceProfileId(new DeviceProfileId(deviceProfileId)); } if (firmwareId != null) { - device.setFirmwareId(new FirmwareId(firmwareId)); + device.setFirmwareId(new OtaPackageId(firmwareId)); } if (softwareId != null) { - device.setSoftwareId(new FirmwareId(softwareId)); + device.setSoftwareId(new OtaPackageId(softwareId)); } device.setDeviceData(JacksonUtil.convertValue(deviceData, DeviceData.class)); device.setName(name); 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 ec440526a4..a3d6c491c0 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 @@ -29,7 +29,7 @@ import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; @@ -178,11 +178,11 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl deviceProfile.setProvisionDeviceKey(provisionDeviceKey); if (firmwareId != null) { - deviceProfile.setFirmwareId(new FirmwareId(firmwareId)); + deviceProfile.setFirmwareId(new OtaPackageId(firmwareId)); } if (softwareId != null) { - deviceProfile.setSoftwareId(new FirmwareId(softwareId)); + deviceProfile.setSoftwareId(new OtaPackageId(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/OtaPackageEntity.java similarity index 62% rename from dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java rename to dao/src/main/java/org/thingsboard/server/dao/model/sql/OtaPackageEntity.java index e16d0417e4..97e4dbebbd 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/OtaPackageEntity.java @@ -20,11 +20,11 @@ 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.firmware.ChecksumAlgorithm; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.OtaPackage; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; @@ -40,75 +40,75 @@ 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_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; -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TYPE_COLUMN; -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_CHECKSUM_ALGORITHM_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_CHECKSUM_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_CONTENT_TYPE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_DATA_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_DATA_SIZE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_DEVICE_PROFILE_ID_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_FILE_NAME_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_TABLE_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_TENANT_ID_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_TILE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_TYPE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_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 { +@Table(name = OTA_PACKAGE_TABLE_NAME) +public class OtaPackageEntity extends BaseSqlEntity implements SearchTextEntity { - @Column(name = FIRMWARE_TENANT_ID_COLUMN) + @Column(name = OTA_PACKAGE_TENANT_ID_COLUMN) private UUID tenantId; - @Column(name = FIRMWARE_DEVICE_PROFILE_ID_COLUMN) + @Column(name = OTA_PACKAGE_DEVICE_PROFILE_ID_COLUMN) private UUID deviceProfileId; @Enumerated(EnumType.STRING) - @Column(name = FIRMWARE_TYPE_COLUMN) - private FirmwareType type; + @Column(name = OTA_PACKAGE_TYPE_COLUMN) + private OtaPackageType type; - @Column(name = FIRMWARE_TITLE_COLUMN) + @Column(name = OTA_PACKAGE_TILE_COLUMN) private String title; - @Column(name = FIRMWARE_VERSION_COLUMN) + @Column(name = OTA_PACKAGE_VERSION_COLUMN) private String version; - @Column(name = FIRMWARE_FILE_NAME_COLUMN) + @Column(name = OTA_PACKAGE_FILE_NAME_COLUMN) private String fileName; - @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN) + @Column(name = OTA_PACKAGE_CONTENT_TYPE_COLUMN) private String contentType; @Enumerated(EnumType.STRING) - @Column(name = FIRMWARE_CHECKSUM_ALGORITHM_COLUMN) + @Column(name = OTA_PACKAGE_CHECKSUM_ALGORITHM_COLUMN) private ChecksumAlgorithm checksumAlgorithm; - @Column(name = FIRMWARE_CHECKSUM_COLUMN) + @Column(name = OTA_PACKAGE_CHECKSUM_COLUMN) private String checksum; @Lob - @Column(name = FIRMWARE_DATA_COLUMN, columnDefinition = "BINARY") + @Column(name = OTA_PACKAGE_DATA_COLUMN, columnDefinition = "BINARY") private byte[] data; - @Column(name = FIRMWARE_DATA_SIZE_COLUMN) + @Column(name = OTA_PACKAGE_DATA_SIZE_COLUMN) private Long dataSize; @Type(type = "json") - @Column(name = ModelConstants.FIRMWARE_ADDITIONAL_INFO_COLUMN) + @Column(name = ModelConstants.OTA_PACKAGE_ADDITIONAL_INFO_COLUMN) private JsonNode additionalInfo; @Column(name = SEARCH_TEXT_PROPERTY) private String searchText; - public FirmwareEntity() { + public OtaPackageEntity() { super(); } - public FirmwareEntity(Firmware firmware) { + public OtaPackageEntity(OtaPackage firmware) { this.createdTime = firmware.getCreatedTime(); this.setUuid(firmware.getUuidId()); this.tenantId = firmware.getTenantId().getId(); @@ -138,8 +138,8 @@ public class FirmwareEntity extends BaseSqlEntity implements SearchTex } @Override - public Firmware toData() { - Firmware firmware = new Firmware(new FirmwareId(id)); + public OtaPackage toData() { + OtaPackage firmware = new OtaPackage(new OtaPackageId(id)); firmware.setCreatedTime(createdTime); firmware.setTenantId(new TenantId(tenantId)); if (deviceProfileId != null) { 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/OtaPackageInfoEntity.java similarity index 63% rename from dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java rename to dao/src/main/java/org/thingsboard/server/dao/model/sql/OtaPackageInfoEntity.java index 93a6e83f25..30441ed098 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/OtaPackageInfoEntity.java @@ -21,11 +21,11 @@ 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.FirmwareInfo; -import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; @@ -40,60 +40,60 @@ import javax.persistence.Table; import javax.persistence.Transient; 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_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; -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TYPE_COLUMN; -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_CHECKSUM_ALGORITHM_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_CHECKSUM_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_CONTENT_TYPE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_DATA_SIZE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_DEVICE_PROFILE_ID_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_FILE_NAME_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_TABLE_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_TENANT_ID_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_TILE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_TYPE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_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 { +@Table(name = OTA_PACKAGE_TABLE_NAME) +public class OtaPackageInfoEntity extends BaseSqlEntity implements SearchTextEntity { - @Column(name = FIRMWARE_TENANT_ID_COLUMN) + @Column(name = OTA_PACKAGE_TENANT_ID_COLUMN) private UUID tenantId; - @Column(name = FIRMWARE_DEVICE_PROFILE_ID_COLUMN) + @Column(name = OTA_PACKAGE_DEVICE_PROFILE_ID_COLUMN) private UUID deviceProfileId; @Enumerated(EnumType.STRING) - @Column(name = FIRMWARE_TYPE_COLUMN) - private FirmwareType type; + @Column(name = OTA_PACKAGE_TYPE_COLUMN) + private OtaPackageType type; - @Column(name = FIRMWARE_TITLE_COLUMN) + @Column(name = OTA_PACKAGE_TILE_COLUMN) private String title; - @Column(name = FIRMWARE_VERSION_COLUMN) + @Column(name = OTA_PACKAGE_VERSION_COLUMN) private String version; - @Column(name = FIRMWARE_FILE_NAME_COLUMN) + @Column(name = OTA_PACKAGE_FILE_NAME_COLUMN) private String fileName; - @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN) + @Column(name = OTA_PACKAGE_CONTENT_TYPE_COLUMN) private String contentType; @Enumerated(EnumType.STRING) - @Column(name = FIRMWARE_CHECKSUM_ALGORITHM_COLUMN) + @Column(name = OTA_PACKAGE_CHECKSUM_ALGORITHM_COLUMN) private ChecksumAlgorithm checksumAlgorithm; - @Column(name = FIRMWARE_CHECKSUM_COLUMN) + @Column(name = OTA_PACKAGE_CHECKSUM_COLUMN) private String checksum; - @Column(name = FIRMWARE_DATA_SIZE_COLUMN) + @Column(name = OTA_PACKAGE_DATA_SIZE_COLUMN) private Long dataSize; @Type(type = "json") - @Column(name = ModelConstants.FIRMWARE_ADDITIONAL_INFO_COLUMN) + @Column(name = ModelConstants.OTA_PACKAGE_ADDITIONAL_INFO_COLUMN) private JsonNode additionalInfo; @Column(name = SEARCH_TEXT_PROPERTY) @@ -102,11 +102,11 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S @Transient private boolean hasData; - public FirmwareInfoEntity() { + public OtaPackageInfoEntity() { super(); } - public FirmwareInfoEntity(FirmwareInfo firmware) { + public OtaPackageInfoEntity(OtaPackageInfo firmware) { this.createdTime = firmware.getCreatedTime(); this.setUuid(firmware.getUuidId()); this.tenantId = firmware.getTenantId().getId(); @@ -124,9 +124,9 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S this.additionalInfo = firmware.getAdditionalInfo(); } - public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, UUID deviceProfileId, FirmwareType type, String title, String version, - String fileName, String contentType, ChecksumAlgorithm checksumAlgorithm, String checksum, Long dataSize, - Object additionalInfo, boolean hasData) { + public OtaPackageInfoEntity(UUID id, long createdTime, UUID tenantId, UUID deviceProfileId, OtaPackageType type, String title, String version, + String fileName, String contentType, ChecksumAlgorithm checksumAlgorithm, String checksum, Long dataSize, + Object additionalInfo, boolean hasData) { this.id = id; this.createdTime = createdTime; this.tenantId = tenantId; @@ -154,8 +154,8 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S } @Override - public FirmwareInfo toData() { - FirmwareInfo firmware = new FirmwareInfo(new FirmwareId(id)); + public OtaPackageInfo toData() { + OtaPackageInfo firmware = new OtaPackageInfo(new OtaPackageId(id)); firmware.setCreatedTime(createdTime); firmware.setTenantId(new TenantId(tenantId)); if (deviceProfileId != null) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java new file mode 100644 index 0000000000..ae19576861 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java @@ -0,0 +1,373 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.ota; + +import com.google.common.hash.HashFunction; +import com.google.common.hash.Hashing; +import com.google.common.util.concurrent.ListenableFuture; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.hibernate.exception.ConstraintViolationException; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.thingsboard.server.cache.ota.OtaPackageDataCache; +import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.OtaPackage; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.id.DeviceProfileId; +import org.thingsboard.server.common.data.id.OtaPackageId; +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; +import org.thingsboard.server.dao.tenant.TenantDao; + +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_CACHE; +import static org.thingsboard.server.dao.service.Validator.validateId; +import static org.thingsboard.server.dao.service.Validator.validatePageLink; + +@Service +@Slf4j +@RequiredArgsConstructor +public class BaseOtaPackageService implements OtaPackageService { + public static final String INCORRECT_OTA_PACKAGE_ID = "Incorrect otaPackageId "; + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; + + private final TenantDao tenantDao; + private final DeviceProfileDao deviceProfileDao; + private final OtaPackageDao otaPackageDao; + private final OtaPackageInfoDao otaPackageInfoDao; + private final CacheManager cacheManager; + private final OtaPackageDataCache otaPackageDataCache; + + @Override + public OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo) { + log.trace("Executing saveOtaPackageInfo [{}]", otaPackageInfo); + otaPackageInfoValidator.validate(otaPackageInfo, OtaPackageInfo::getTenantId); + try { + OtaPackageId otaPackageId = otaPackageInfo.getId(); + if (otaPackageId != null) { + Cache cache = cacheManager.getCache(OTA_PACKAGE_CACHE); + cache.evict(toOtaPackageInfoKey(otaPackageId)); + otaPackageDataCache.evict(otaPackageId.toString()); + } + return otaPackageInfoDao.save(otaPackageInfo.getTenantId(), otaPackageInfo); + } catch (Exception t) { + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("ota_package_tenant_title_version_unq_key")) { + throw new DataValidationException("OtaPackage with such title and version already exists!"); + } else { + throw t; + } + } + } + + @Override + public OtaPackage saveOtaPackage(OtaPackage otaPackage) { + log.trace("Executing saveOtaPackage [{}]", otaPackage); + otaPackageValidator.validate(otaPackage, OtaPackageInfo::getTenantId); + try { + OtaPackageId otaPackageId = otaPackage.getId(); + if (otaPackageId != null) { + Cache cache = cacheManager.getCache(OTA_PACKAGE_CACHE); + cache.evict(toOtaPackageInfoKey(otaPackageId)); + otaPackageDataCache.evict(otaPackageId.toString()); + } + return otaPackageDao.save(otaPackage.getTenantId(), otaPackage); + } catch (Exception t) { + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("ota_package_tenant_title_version_unq_key")) { + throw new DataValidationException("OtaPackage with such title and version already exists!"); + } else { + throw t; + } + } + } + + @Override + public String generateChecksum(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data) { + if (data == null || !data.hasArray() || data.array().length == 0) { + throw new DataValidationException("OtaPackage data should be specified!"); + } + + return getHashFunction(checksumAlgorithm).hashBytes(data.array()).toString(); + } + + private HashFunction getHashFunction(ChecksumAlgorithm checksumAlgorithm) { + switch (checksumAlgorithm) { + case MD5: + return Hashing.md5(); + case SHA256: + return Hashing.sha256(); + case SHA384: + return Hashing.sha384(); + case SHA512: + return Hashing.sha512(); + case CRC32: + return Hashing.crc32(); + case MURMUR3_32: + return Hashing.murmur3_32(); + case MURMUR3_128: + return Hashing.murmur3_128(); + default: + throw new DataValidationException("Unknown checksum algorithm!"); + } + } + + @Override + public OtaPackage findOtaPackageById(TenantId tenantId, OtaPackageId otaPackageId) { + log.trace("Executing findOtaPackageById [{}]", otaPackageId); + validateId(otaPackageId, INCORRECT_OTA_PACKAGE_ID + otaPackageId); + return otaPackageDao.findById(tenantId, otaPackageId.getId()); + } + + @Override + @Cacheable(cacheNames = OTA_PACKAGE_CACHE, key = "{#otaPackageId}") + public OtaPackageInfo findOtaPackageInfoById(TenantId tenantId, OtaPackageId otaPackageId) { + log.trace("Executing findOtaPackageInfoById [{}]", otaPackageId); + validateId(otaPackageId, INCORRECT_OTA_PACKAGE_ID + otaPackageId); + return otaPackageInfoDao.findById(tenantId, otaPackageId.getId()); + } + + @Override + public ListenableFuture findOtaPackageInfoByIdAsync(TenantId tenantId, OtaPackageId otaPackageId) { + log.trace("Executing findOtaPackageInfoByIdAsync [{}]", otaPackageId); + validateId(otaPackageId, INCORRECT_OTA_PACKAGE_ID + otaPackageId); + return otaPackageInfoDao.findByIdAsync(tenantId, otaPackageId.getId()); + } + + @Override + public PageData findTenantOtaPackagesByTenantId(TenantId tenantId, PageLink pageLink) { + log.trace("Executing findTenantOtaPackagesByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validatePageLink(pageLink); + return otaPackageInfoDao.findOtaPackageInfoByTenantId(tenantId, pageLink); + } + + @Override + public PageData findTenantOtaPackagesByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType otaPackageType, boolean hasData, PageLink pageLink) { + log.trace("Executing findTenantOtaPackagesByTenantIdAndHasData, tenantId [{}], hasData [{}] pageLink [{}]", tenantId, hasData, pageLink); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validatePageLink(pageLink); + return otaPackageInfoDao.findOtaPackageInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, otaPackageType, hasData, pageLink); + } + + @Override + public void deleteOtaPackage(TenantId tenantId, OtaPackageId otaPackageId) { + log.trace("Executing deleteOtaPackage [{}]", otaPackageId); + validateId(otaPackageId, INCORRECT_OTA_PACKAGE_ID + otaPackageId); + try { + Cache cache = cacheManager.getCache(OTA_PACKAGE_CACHE); + cache.evict(toOtaPackageInfoKey(otaPackageId)); + otaPackageDataCache.evict(otaPackageId.toString()); + otaPackageDao.removeById(tenantId, otaPackageId.getId()); + } catch (Exception t) { + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_firmware_device")) { + throw new DataValidationException("The otaPackage 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 otaPackage 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; + } + } + } + + @Override + public void deleteOtaPackagesByTenantId(TenantId tenantId) { + log.trace("Executing deleteOtaPackagesByTenantId, tenantId [{}]", tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + tenantOtaPackageRemover.removeEntities(tenantId, tenantId); + } + + private DataValidator otaPackageInfoValidator = new DataValidator<>() { + + @Override + protected void validateDataImpl(TenantId tenantId, OtaPackageInfo otaPackageInfo) { + validateImpl(otaPackageInfo); + } + + @Override + protected void validateUpdate(TenantId tenantId, OtaPackageInfo otaPackage) { + OtaPackageInfo otaPackageOld = otaPackageInfoDao.findById(tenantId, otaPackage.getUuidId()); + + validateUpdateDeviceProfile(otaPackage, otaPackageOld); + BaseOtaPackageService.validateUpdate(otaPackage, otaPackageOld); + } + }; + + private DataValidator otaPackageValidator = new DataValidator<>() { + + @Override + protected void validateDataImpl(TenantId tenantId, OtaPackage otaPackage) { + validateImpl(otaPackage); + + if (StringUtils.isEmpty(otaPackage.getFileName())) { + throw new DataValidationException("OtaPackage file name should be specified!"); + } + + if (StringUtils.isEmpty(otaPackage.getContentType())) { + throw new DataValidationException("OtaPackage content type should be specified!"); + } + + if (otaPackage.getChecksumAlgorithm() == null) { + throw new DataValidationException("OtaPackage checksum algorithm should be specified!"); + } + if (StringUtils.isEmpty(otaPackage.getChecksum())) { + throw new DataValidationException("OtaPackage checksum should be specified!"); + } + + String currentChecksum; + + currentChecksum = generateChecksum(otaPackage.getChecksumAlgorithm(), otaPackage.getData()); + + if (!currentChecksum.equals(otaPackage.getChecksum())) { + throw new DataValidationException("Wrong otaPackage file!"); + } + } + + @Override + protected void validateUpdate(TenantId tenantId, OtaPackage otaPackage) { + OtaPackage otaPackageOld = otaPackageDao.findById(tenantId, otaPackage.getUuidId()); + + validateUpdateDeviceProfile(otaPackage, otaPackageOld); + BaseOtaPackageService.validateUpdate(otaPackage, otaPackageOld); + + if (otaPackageOld.getData() != null && !otaPackageOld.getData().equals(otaPackage.getData())) { + throw new DataValidationException("Updating otaPackage data is prohibited!"); + } + } + }; + + private void validateUpdateDeviceProfile(OtaPackageInfo otaPackage, OtaPackageInfo otaPackageOld) { + if (otaPackageOld.getDeviceProfileId() != null && !otaPackageOld.getDeviceProfileId().equals(otaPackage.getDeviceProfileId())) { + if (otaPackageInfoDao.isOtaPackageUsed(otaPackageOld.getId(), otaPackage.getType(), otaPackageOld.getDeviceProfileId())) { + throw new DataValidationException("Can`t update deviceProfileId because otaPackage is already in use!"); + } + } + } + + private static void validateUpdate(OtaPackageInfo otaPackage, OtaPackageInfo otaPackageOld) { + if (!otaPackageOld.getType().equals(otaPackage.getType())) { + throw new DataValidationException("Updating type is prohibited!"); + } + + if (!otaPackageOld.getTitle().equals(otaPackage.getTitle())) { + throw new DataValidationException("Updating otaPackage title is prohibited!"); + } + + if (!otaPackageOld.getVersion().equals(otaPackage.getVersion())) { + throw new DataValidationException("Updating otaPackage version is prohibited!"); + } + + if (otaPackageOld.getFileName() != null && !otaPackageOld.getFileName().equals(otaPackage.getFileName())) { + throw new DataValidationException("Updating otaPackage file name is prohibited!"); + } + + if (otaPackageOld.getContentType() != null && !otaPackageOld.getContentType().equals(otaPackage.getContentType())) { + throw new DataValidationException("Updating otaPackage content type is prohibited!"); + } + + if (otaPackageOld.getChecksumAlgorithm() != null && !otaPackageOld.getChecksumAlgorithm().equals(otaPackage.getChecksumAlgorithm())) { + throw new DataValidationException("Updating otaPackage content type is prohibited!"); + } + + if (otaPackageOld.getChecksum() != null && !otaPackageOld.getChecksum().equals(otaPackage.getChecksum())) { + throw new DataValidationException("Updating otaPackage content type is prohibited!"); + } + + if (otaPackageOld.getDataSize() != null && !otaPackageOld.getDataSize().equals(otaPackage.getDataSize())) { + throw new DataValidationException("Updating otaPackage data size is prohibited!"); + } + } + + private void validateImpl(OtaPackageInfo otaPackageInfo) { + if (otaPackageInfo.getTenantId() == null) { + throw new DataValidationException("OtaPackage should be assigned to tenant!"); + } else { + Tenant tenant = tenantDao.findById(otaPackageInfo.getTenantId(), otaPackageInfo.getTenantId().getId()); + if (tenant == null) { + throw new DataValidationException("OtaPackage is referencing to non-existent tenant!"); + } + } + + if (otaPackageInfo.getDeviceProfileId() != null) { + DeviceProfile deviceProfile = deviceProfileDao.findById(otaPackageInfo.getTenantId(), otaPackageInfo.getDeviceProfileId().getId()); + if (deviceProfile == null) { + throw new DataValidationException("OtaPackage is referencing to non-existent device profile!"); + } + } + + if (otaPackageInfo.getType() == null) { + throw new DataValidationException("Type should be specified!"); + } + + if (StringUtils.isEmpty(otaPackageInfo.getTitle())) { + throw new DataValidationException("OtaPackage title should be specified!"); + } + + if (StringUtils.isEmpty(otaPackageInfo.getVersion())) { + throw new DataValidationException("OtaPackage version should be specified!"); + } + } + + private PaginatedRemover tenantOtaPackageRemover = + new PaginatedRemover<>() { + + @Override + protected PageData findEntities(TenantId tenantId, TenantId id, PageLink pageLink) { + return otaPackageInfoDao.findOtaPackageInfoByTenantId(id, pageLink); + } + + @Override + protected void removeEntity(TenantId tenantId, OtaPackageInfo entity) { + deleteOtaPackage(tenantId, entity.getId()); + } + }; + + protected Optional extractConstraintViolationException(Exception t) { + if (t instanceof ConstraintViolationException) { + return Optional.of((ConstraintViolationException) t); + } else if (t.getCause() instanceof ConstraintViolationException) { + return Optional.of((ConstraintViolationException) (t.getCause())); + } else { + return Optional.empty(); + } + } + + private static List toOtaPackageInfoKey(OtaPackageId otaPackageId) { + return Collections.singletonList(otaPackageId); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/firmware/FirmwareDao.java b/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageDao.java similarity index 81% rename from dao/src/main/java/org/thingsboard/server/dao/firmware/FirmwareDao.java rename to dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageDao.java index 0cacb47ea0..42f66663d1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/firmware/FirmwareDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageDao.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.firmware; +package org.thingsboard.server.dao.ota; -import org.thingsboard.server.common.data.Firmware; +import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.dao.Dao; -public interface FirmwareDao extends Dao { +public interface OtaPackageDao extends Dao { } diff --git a/dao/src/main/java/org/thingsboard/server/dao/firmware/FirmwareInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageInfoDao.java similarity index 55% rename from dao/src/main/java/org/thingsboard/server/dao/firmware/FirmwareInfoDao.java rename to dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageInfoDao.java index 7cb6c3a57f..d3294f0ec3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/firmware/FirmwareInfoDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageInfoDao.java @@ -13,25 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.firmware; +package org.thingsboard.server.dao.ota; -import org.thingsboard.server.common.data.FirmwareInfo; -import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.id.DeviceProfileId; -import org.thingsboard.server.common.data.id.FirmwareId; +import org.thingsboard.server.common.data.id.OtaPackageId; 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.Dao; -import java.util.UUID; +public interface OtaPackageInfoDao extends Dao { -public interface FirmwareInfoDao extends Dao { + PageData findOtaPackageInfoByTenantId(TenantId tenantId, PageLink pageLink); - PageData findFirmwareInfoByTenantId(TenantId tenantId, PageLink pageLink); + PageData findOtaPackageInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType otaPackageType, boolean hasData, PageLink pageLink); - PageData findFirmwareInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink); - - boolean isFirmwareUsed(FirmwareId firmwareId, FirmwareType type, DeviceProfileId deviceProfileId); + boolean isOtaPackageUsed(OtaPackageId otaPackageId, OtaPackageType otaPackageType, DeviceProfileId deviceProfileId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java index 3bbe18f2ab..58c05547b0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java @@ -96,23 +96,35 @@ public interface DeviceRepository extends PagingAndSortingRepository findByTenantIdAndTypeAndFirmwareIdIsNull(@Param("tenantId") UUID tenantId, - @Param("type") String type, + @Param("deviceProfileId") UUID deviceProfileId, @Param("textSearch") String textSearch, Pageable pageable); @Query("SELECT d FROM DeviceEntity d WHERE d.tenantId = :tenantId " + - "AND d.type = :type " + + "AND d.deviceProfileId = :deviceProfileId " + "AND d.softwareId = null " + "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))") Page findByTenantIdAndTypeAndSoftwareIdIsNull(@Param("tenantId") UUID tenantId, - @Param("type") String type, + @Param("deviceProfileId") UUID deviceProfileId, @Param("textSearch") String textSearch, Pageable pageable); + @Query("SELECT count(*) FROM DeviceEntity d WHERE d.tenantId = :tenantId " + + "AND d.deviceProfileId = :deviceProfileId " + + "AND d.firmwareId = null") + Long countByTenantIdAndDeviceProfileIdAndFirmwareIdIsNull(@Param("tenantId") UUID tenantId, + @Param("deviceProfileId") UUID deviceProfileId); + + @Query("SELECT count(*) FROM DeviceEntity d WHERE d.tenantId = :tenantId " + + "AND d.deviceProfileId = :deviceProfileId " + + "AND d.softwareId = null") + Long countByTenantIdAndDeviceProfileIdAndSoftwareIdIsNull(@Param("tenantId") UUID tenantId, + @Param("deviceProfileId") UUID deviceProfileId); + @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " + "FROM DeviceEntity d " + "LEFT JOIN CustomerEntity c on c.id = d.customerId " + diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java index 344286d7ac..0e3e843405 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java @@ -18,6 +18,8 @@ package org.thingsboard.server.dao.sql.device; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; @@ -27,6 +29,8 @@ import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.ota.OtaPackageUtil; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.DaoUtil; @@ -155,23 +159,27 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao } @Override - public PageData findDevicesByTenantIdAndTypeAndEmptyFirmware(UUID tenantId, String type, PageLink pageLink) { - return DaoUtil.toPageData( - deviceRepository.findByTenantIdAndTypeAndFirmwareIdIsNull( - tenantId, - type, - Objects.toString(pageLink.getTextSearch(), ""), - DaoUtil.toPageable(pageLink))); + public PageData findDevicesByTenantIdAndTypeAndEmptyOtaPackage(UUID tenantId, + UUID deviceProfileId, + OtaPackageType type, + PageLink pageLink) { + Pageable pageable = DaoUtil.toPageable(pageLink); + String searchText = Objects.toString(pageLink.getTextSearch(), ""); + Page page = OtaPackageUtil.getByOtaPackageType( + () -> deviceRepository.findByTenantIdAndTypeAndFirmwareIdIsNull(tenantId, deviceProfileId, searchText, pageable), + () -> deviceRepository.findByTenantIdAndTypeAndSoftwareIdIsNull(tenantId, deviceProfileId, searchText, pageable), + type + ); + return DaoUtil.toPageData(page); } @Override - public PageData findDevicesByTenantIdAndTypeAndEmptySoftware(UUID tenantId, String type, PageLink pageLink) { - return DaoUtil.toPageData( - deviceRepository.findByTenantIdAndTypeAndSoftwareIdIsNull( - tenantId, - type, - Objects.toString(pageLink.getTextSearch(), ""), - DaoUtil.toPageable(pageLink))); + public Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(UUID tenantId, UUID deviceProfileId, OtaPackageType type) { + return OtaPackageUtil.getByOtaPackageType( + () -> deviceRepository.countByTenantIdAndDeviceProfileIdAndFirmwareIdIsNull(tenantId, deviceProfileId), + () -> deviceRepository.countByTenantIdAndDeviceProfileIdAndSoftwareIdIsNull(tenantId, deviceProfileId), + type + ); } @Override 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 deleted file mode 100644 index dab6ce3304..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareInfoRepository.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright © 2016-2021 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.sql.firmware; - -import org.springframework.data.domain.Page; -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.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.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 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.deviceProfileId, f.type, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE f.id = :id") - FirmwareInfoEntity findFirmwareInfoById(@Param("id") UUID id); - - @Query(value = "SELECT exists(SELECT * " + - "FROM device_profile AS dp " + - "LEFT JOIN device AS d ON dp.id = d.device_profile_id " + - "WHERE dp.id = :deviceProfileId AND " + - "(('FIRMWARE' = :type AND (dp.firmware_id = :firmwareId OR d.firmware_id = :firmwareId)) " + - "OR ('SOFTWARE' = :type AND (dp.software_id = :firmwareId or d.software_id = :firmwareId))))", nativeQuery = true) - boolean isFirmwareUsed(@Param("firmwareId") UUID firmwareId, @Param("deviceProfileId") UUID deviceProfileId, @Param("type") String type); - -} 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 deleted file mode 100644 index 8cae33a057..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/JpaFirmwareInfoDao.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright © 2016-2021 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.sql.firmware; - -import lombok.extern.slf4j.Slf4j; -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.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.DaoUtil; -import org.thingsboard.server.dao.firmware.FirmwareInfoDao; -import org.thingsboard.server.dao.model.sql.FirmwareInfoEntity; -import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; - -import java.util.Objects; -import java.util.UUID; - -@Slf4j -@Component -public class JpaFirmwareInfoDao extends JpaAbstractSearchTextDao implements FirmwareInfoDao { - - @Autowired - private FirmwareInfoRepository firmwareInfoRepository; - - @Override - protected Class getEntityClass() { - return FirmwareInfoEntity.class; - } - - @Override - protected CrudRepository getCrudRepository() { - return firmwareInfoRepository; - } - - @Override - public FirmwareInfo findById(TenantId tenantId, UUID id) { - return DaoUtil.getData(firmwareInfoRepository.findFirmwareInfoById(id)); - } - - @Override - public FirmwareInfo save(TenantId tenantId, FirmwareInfo firmwareInfo) { - FirmwareInfo savedFirmware = super.save(tenantId, firmwareInfo); - if (firmwareInfo.getId() == null) { - return savedFirmware; - } else { - return findById(tenantId, savedFirmware.getId().getId()); - } - } - - @Override - public PageData findFirmwareInfoByTenantId(TenantId tenantId, PageLink pageLink) { - return DaoUtil.toPageData(firmwareInfoRepository - .findAllByTenantId( - tenantId.getId(), - Objects.toString(pageLink.getTextSearch(), ""), - DaoUtil.toPageable(pageLink))); - } - - @Override - public PageData findFirmwareInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink) { - return DaoUtil.toPageData(firmwareInfoRepository - .findAllByTenantIdAndTypeAndDeviceProfileIdAndHasData( - tenantId.getId(), - deviceProfileId.getId(), - firmwareType, - hasData, - Objects.toString(pageLink.getTextSearch(), ""), - DaoUtil.toPageable(pageLink))); - } - - @Override - public boolean isFirmwareUsed(FirmwareId firmwareId, FirmwareType type, DeviceProfileId deviceProfileId) { - return firmwareInfoRepository.isFirmwareUsed(firmwareId.getId(), deviceProfileId.getId(), type.name()); - } -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/JpaFirmwareDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/ota/JpaOtaPackageDao.java similarity index 62% rename from dao/src/main/java/org/thingsboard/server/dao/sql/firmware/JpaFirmwareDao.java rename to dao/src/main/java/org/thingsboard/server/dao/sql/ota/JpaOtaPackageDao.java index 44b956c298..95737ca48d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/JpaFirmwareDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/ota/JpaOtaPackageDao.java @@ -13,34 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.sql.firmware; +package org.thingsboard.server.dao.sql.ota; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Component; -import org.thingsboard.server.common.data.Firmware; -import org.thingsboard.server.dao.firmware.FirmwareDao; -import org.thingsboard.server.dao.model.sql.FirmwareEntity; +import org.thingsboard.server.common.data.OtaPackage; +import org.thingsboard.server.dao.ota.OtaPackageDao; +import org.thingsboard.server.dao.model.sql.OtaPackageEntity; import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; import java.util.UUID; @Slf4j @Component -public class JpaFirmwareDao extends JpaAbstractSearchTextDao implements FirmwareDao { +public class JpaOtaPackageDao extends JpaAbstractSearchTextDao implements OtaPackageDao { @Autowired - private FirmwareRepository firmwareRepository; + private OtaPackageRepository otaPackageRepository; @Override - protected Class getEntityClass() { - return FirmwareEntity.class; + protected Class getEntityClass() { + return OtaPackageEntity.class; } @Override - protected CrudRepository getCrudRepository() { - return firmwareRepository; + protected CrudRepository getCrudRepository() { + return otaPackageRepository; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/ota/JpaOtaPackageInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/ota/JpaOtaPackageInfoDao.java new file mode 100644 index 0000000000..0d35c8ee0d --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/ota/JpaOtaPackageInfoDao.java @@ -0,0 +1,94 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.sql.ota; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.common.data.id.DeviceProfileId; +import org.thingsboard.server.common.data.id.OtaPackageId; +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.DaoUtil; +import org.thingsboard.server.dao.ota.OtaPackageInfoDao; +import org.thingsboard.server.dao.model.sql.OtaPackageInfoEntity; +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; + +import java.util.Objects; +import java.util.UUID; + +@Slf4j +@Component +public class JpaOtaPackageInfoDao extends JpaAbstractSearchTextDao implements OtaPackageInfoDao { + + @Autowired + private OtaPackageInfoRepository otaPackageInfoRepository; + + @Override + protected Class getEntityClass() { + return OtaPackageInfoEntity.class; + } + + @Override + protected CrudRepository getCrudRepository() { + return otaPackageInfoRepository; + } + + @Override + public OtaPackageInfo findById(TenantId tenantId, UUID id) { + return DaoUtil.getData(otaPackageInfoRepository.findOtaPackageInfoById(id)); + } + + @Override + public OtaPackageInfo save(TenantId tenantId, OtaPackageInfo otaPackageInfo) { + OtaPackageInfo savedOtaPackage = super.save(tenantId, otaPackageInfo); + if (otaPackageInfo.getId() == null) { + return savedOtaPackage; + } else { + return findById(tenantId, savedOtaPackage.getId().getId()); + } + } + + @Override + public PageData findOtaPackageInfoByTenantId(TenantId tenantId, PageLink pageLink) { + return DaoUtil.toPageData(otaPackageInfoRepository + .findAllByTenantId( + tenantId.getId(), + Objects.toString(pageLink.getTextSearch(), ""), + DaoUtil.toPageable(pageLink))); + } + + @Override + public PageData findOtaPackageInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType otaPackageType, boolean hasData, PageLink pageLink) { + return DaoUtil.toPageData(otaPackageInfoRepository + .findAllByTenantIdAndTypeAndDeviceProfileIdAndHasData( + tenantId.getId(), + deviceProfileId.getId(), + otaPackageType, + hasData, + Objects.toString(pageLink.getTextSearch(), ""), + DaoUtil.toPageable(pageLink))); + } + + @Override + public boolean isOtaPackageUsed(OtaPackageId otaPackageId, OtaPackageType otaPackageType, DeviceProfileId deviceProfileId) { + return otaPackageInfoRepository.isOtaPackageUsed(otaPackageId.getId(), deviceProfileId.getId(), otaPackageType.name()); + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/ota/OtaPackageInfoRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/ota/OtaPackageInfoRepository.java new file mode 100644 index 0000000000..9848f83200 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/ota/OtaPackageInfoRepository.java @@ -0,0 +1,60 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.sql.ota; + +import org.springframework.data.domain.Page; +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.ota.OtaPackageType; +import org.thingsboard.server.dao.model.sql.OtaPackageInfoEntity; + +import java.util.UUID; + +public interface OtaPackageInfoRepository extends CrudRepository { + @Query("SELECT new OtaPackageInfoEntity(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 OtaPackageEntity 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 OtaPackageInfoEntity(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 OtaPackageEntity 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 findAllByTenantIdAndTypeAndDeviceProfileIdAndHasData(@Param("tenantId") UUID tenantId, + @Param("deviceProfileId") UUID deviceProfileId, + @Param("type") OtaPackageType type, + @Param("hasData") boolean hasData, + @Param("searchText") String searchText, + Pageable pageable); + + @Query("SELECT new OtaPackageInfoEntity(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 OtaPackageEntity f WHERE f.id = :id") + OtaPackageInfoEntity findOtaPackageInfoById(@Param("id") UUID id); + + @Query(value = "SELECT exists(SELECT * " + + "FROM device_profile AS dp " + + "LEFT JOIN device AS d ON dp.id = d.device_profile_id " + + "WHERE dp.id = :deviceProfileId AND " + + "(('FIRMWARE' = :type AND (dp.firmware_id = :otaPackageId OR d.firmware_id = :otaPackageId)) " + + "OR ('SOFTWARE' = :type AND (dp.software_id = :otaPackageId or d.software_id = :otaPackageId))))", nativeQuery = true) + boolean isOtaPackageUsed(@Param("otaPackageId") UUID otaPackageId, @Param("deviceProfileId") UUID deviceProfileId, @Param("type") String type); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/ota/OtaPackageRepository.java similarity index 78% rename from dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareRepository.java rename to dao/src/main/java/org/thingsboard/server/dao/sql/ota/OtaPackageRepository.java index a969507798..3699005ff2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/firmware/FirmwareRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/ota/OtaPackageRepository.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.sql.firmware; +package org.thingsboard.server.dao.sql.ota; import org.springframework.data.repository.CrudRepository; -import org.thingsboard.server.dao.model.sql.FirmwareEntity; +import org.thingsboard.server.dao.model.sql.OtaPackageEntity; import java.util.UUID; -public interface FirmwareRepository extends CrudRepository { +public interface OtaPackageRepository extends CrudRepository { } diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java index 6391ed73e7..c5050467dd 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java @@ -35,7 +35,7 @@ import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.exception.DataValidationException; -import org.thingsboard.server.dao.firmware.FirmwareService; +import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.resource.ResourceService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.service.DataValidator; @@ -94,7 +94,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe private ResourceService resourceService; @Autowired - private FirmwareService firmwareService; + private OtaPackageService otaPackageService; @Override public Tenant findTenantById(TenantId tenantId) { @@ -150,7 +150,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe ruleChainService.deleteRuleChainsByTenantId(tenantId); apiUsageStateService.deleteApiUsageStateByTenantId(tenantId); resourceService.deleteResourcesByTenantId(tenantId); - firmwareService.deleteFirmwaresByTenantId(tenantId); + otaPackageService.deleteOtaPackagesByTenantId(tenantId); tenantDao.removeById(tenantId, tenantId.getId()); deleteEntityRelations(tenantId, tenantId); } diff --git a/dao/src/main/resources/sql/schema-entities-hsql.sql b/dao/src/main/resources/sql/schema-entities-hsql.sql index fcb7f82ed0..dfc1821f66 100644 --- a/dao/src/main/resources/sql/schema-entities-hsql.sql +++ b/dao/src/main/resources/sql/schema-entities-hsql.sql @@ -160,8 +160,8 @@ CREATE TABLE IF NOT EXISTS rule_node_state ( CONSTRAINT fk_rule_node_state_node_id FOREIGN KEY (rule_node_id) REFERENCES rule_node(id) ON DELETE CASCADE ); -CREATE TABLE IF NOT EXISTS firmware ( - id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, +CREATE TABLE IF NOT EXISTS ota_package ( + id uuid NOT NULL CONSTRAINT ota_package_pkey PRIMARY KEY, created_time bigint NOT NULL, tenant_id uuid NOT NULL, device_profile_id uuid , @@ -176,7 +176,7 @@ 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 ota_package_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) ); CREATE TABLE IF NOT EXISTS device_profile ( @@ -202,8 +202,8 @@ CREATE TABLE IF NOT EXISTS device_profile ( 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_default_dashboard_device_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(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) + CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES ota_package(id), + CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES ota_package(id) ); CREATE TABLE IF NOT EXISTS device ( @@ -222,8 +222,8 @@ 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_software_device FOREIGN KEY (software_id) REFERENCES firmware(id) + CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES ota_package(id), + CONSTRAINT fk_software_device FOREIGN KEY (software_id) REFERENCES ota_package(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 30b9a3dbe7..be7e836a65 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -178,8 +178,8 @@ CREATE TABLE IF NOT EXISTS rule_node_state ( CONSTRAINT fk_rule_node_state_node_id FOREIGN KEY (rule_node_id) REFERENCES rule_node(id) ON DELETE CASCADE ); -CREATE TABLE IF NOT EXISTS firmware ( - id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, +CREATE TABLE IF NOT EXISTS ota_package ( + id uuid NOT NULL CONSTRAINT ota_package_pkey PRIMARY KEY, created_time bigint NOT NULL, tenant_id uuid NOT NULL, device_profile_id uuid , @@ -194,7 +194,7 @@ 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 ota_package_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 ); @@ -221,8 +221,8 @@ CREATE TABLE IF NOT EXISTS device_profile ( 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_default_dashboard_device_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(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) + CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES ota_package(id), + CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES ota_package(id) ); -- We will use one-to-many relation in the first release and extend this feature in case of user requests @@ -250,8 +250,8 @@ 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_software_device FOREIGN KEY (software_id) REFERENCES firmware(id) + CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES ota_package(id), + CONSTRAINT fk_software_device FOREIGN KEY (software_id) REFERENCES ota_package(id) ); CREATE TABLE IF NOT EXISTS device_credentials ( diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java index 091ab1741e..2aeb44c0be 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java @@ -54,7 +54,7 @@ import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.event.EventService; -import org.thingsboard.server.dao.firmware.FirmwareService; +import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.resource.ResourceService; import org.thingsboard.server.dao.rule.RuleChainService; @@ -160,7 +160,7 @@ public abstract class AbstractServiceTest { @Autowired - protected FirmwareService firmwareService; + protected OtaPackageService otaPackageService; public class IdComparator implements Comparator { @Override 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 5516cb6181..e53b740cbf 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 @@ -28,10 +28,9 @@ 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.DeviceTransportType; -import org.thingsboard.server.common.data.Firmware; +import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.Tenant; -import org.thingsboard.server.common.data.firmware.FirmwareType; -import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -45,7 +44,7 @@ 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; +import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; public class BaseDeviceProfileServiceTest extends AbstractServiceTest { @@ -99,7 +98,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { Assert.assertEquals(deviceProfile.isDefault(), savedDeviceProfile.isDefault()); Assert.assertEquals(deviceProfile.getDefaultRuleChainId(), savedDeviceProfile.getDefaultRuleChainId()); - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(savedDeviceProfile.getId()); firmware.setType(FIRMWARE); @@ -110,7 +109,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(ChecksumAlgorithm.SHA256); firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); firmware.setData(ByteBuffer.wrap(new byte[]{1})); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); + OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); deviceProfile.setFirmwareId(savedFirmware.getId()); 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 587fce1ed5..f335ffacd3 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 @@ -28,10 +28,10 @@ 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.OtaPackage; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantProfile; -import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -46,7 +46,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.common.data.ota.OtaPackageType.FIRMWARE; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; public abstract class BaseDeviceServiceTest extends AbstractServiceTest { @@ -189,7 +189,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { Assert.assertEquals(20, deviceCredentials.getCredentialsId().length()); - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(device.getDeviceProfileId()); firmware.setType(FIRMWARE); @@ -200,7 +200,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(ChecksumAlgorithm.SHA256); firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); firmware.setData(ByteBuffer.wrap(new byte[]{1})); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); + OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); savedDevice.setFirmwareId(savedFirmware.getId()); @@ -223,7 +223,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { DeviceProfile savedProfile = deviceProfileService.saveDeviceProfile(deviceProfile); Assert.assertNotNull(savedProfile); - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(savedProfile.getId()); firmware.setType(FIRMWARE); @@ -234,7 +234,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(ChecksumAlgorithm.SHA256); firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); firmware.setData(ByteBuffer.wrap(new byte[]{1})); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); + OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); savedDevice.setFirmwareId(savedFirmware.getId()); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseOtaPackageServiceTest.java similarity index 74% rename from dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java rename to dao/src/test/java/org/thingsboard/server/dao/service/BaseOtaPackageServiceTest.java index bd9e0ed372..e7cee8c878 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseOtaPackageServiceTest.java @@ -25,10 +25,10 @@ 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.OtaPackage; +import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.Tenant; -import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm; +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -40,9 +40,9 @@ 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.common.data.ota.OtaPackageType.FIRMWARE; -public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { +public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest { public static final String TITLE = "My firmware"; private static final String FILE_NAME = "filename.txt"; @@ -52,7 +52,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { private static final String CHECKSUM = "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"; private static final ByteBuffer DATA = ByteBuffer.wrap(new byte[]{1}); - private IdComparator idComparator = new IdComparator<>(); + private IdComparator idComparator = new IdComparator<>(); private TenantId tenantId; @@ -82,7 +82,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { @Test public void testSaveFirmware() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -93,7 +93,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); + OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); Assert.assertNotNull(savedFirmware); Assert.assertNotNull(savedFirmware.getId()); @@ -105,23 +105,23 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Assert.assertEquals(firmware.getData(), savedFirmware.getData()); savedFirmware.setAdditionalInfo(JacksonUtil.newObjectNode()); - firmwareService.saveFirmware(savedFirmware); + otaPackageService.saveOtaPackage(savedFirmware); - Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, savedFirmware.getId()); + OtaPackage foundFirmware = otaPackageService.findOtaPackageById(tenantId, savedFirmware.getId()); Assert.assertEquals(foundFirmware.getTitle(), savedFirmware.getTitle()); - firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); + otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); } @Test public void testSaveFirmwareInfoAndUpdateWithData() { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setTenantId(tenantId); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); - FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo); + OtaPackageInfo savedFirmwareInfo = otaPackageService.saveOtaPackageInfo(firmwareInfo); Assert.assertNotNull(savedFirmwareInfo); Assert.assertNotNull(savedFirmwareInfo.getId()); @@ -129,7 +129,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Assert.assertEquals(firmwareInfo.getTenantId(), savedFirmwareInfo.getTenantId()); Assert.assertEquals(firmwareInfo.getTitle(), savedFirmwareInfo.getTitle()); - Firmware firmware = new Firmware(savedFirmwareInfo.getId()); + OtaPackage firmware = new OtaPackage(savedFirmwareInfo.getId()); firmware.setCreatedTime(firmwareInfo.getCreatedTime()); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); @@ -142,24 +142,24 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksum(CHECKSUM); firmware.setData(DATA); - firmwareService.saveFirmware(firmware); + otaPackageService.saveOtaPackage(firmware); - savedFirmwareInfo = firmwareService.findFirmwareInfoById(tenantId, savedFirmwareInfo.getId()); + savedFirmwareInfo = otaPackageService.findOtaPackageInfoById(tenantId, savedFirmwareInfo.getId()); savedFirmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode()); - firmwareService.saveFirmwareInfo(savedFirmwareInfo); + otaPackageService.saveOtaPackageInfo(savedFirmwareInfo); - Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, firmware.getId()); + OtaPackage foundFirmware = otaPackageService.findOtaPackageById(tenantId, firmware.getId()); firmware.setAdditionalInfo(JacksonUtil.newObjectNode()); Assert.assertEquals(foundFirmware.getTitle(), firmware.getTitle()); Assert.assertTrue(foundFirmware.isHasData()); - firmwareService.deleteFirmware(tenantId, savedFirmwareInfo.getId()); + otaPackageService.deleteOtaPackage(tenantId, savedFirmwareInfo.getId()); } @Test public void testSaveFirmwareWithEmptyTenant() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); firmware.setTitle(TITLE); @@ -171,13 +171,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setData(DATA); thrown.expect(DataValidationException.class); - thrown.expectMessage("Firmware should be assigned to tenant!"); - firmwareService.saveFirmware(firmware); + thrown.expectMessage("OtaPackage should be assigned to tenant!"); + otaPackageService.saveOtaPackage(firmware); } @Test public void testSaveFirmwareWithEmptyType() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setTitle(TITLE); @@ -190,12 +190,12 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { thrown.expect(DataValidationException.class); thrown.expectMessage("Type should be specified!"); - firmwareService.saveFirmware(firmware); + otaPackageService.saveOtaPackage(firmware); } @Test public void testSaveFirmwareWithEmptyTitle() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -207,13 +207,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setData(DATA); thrown.expect(DataValidationException.class); - thrown.expectMessage("Firmware title should be specified!"); - firmwareService.saveFirmware(firmware); + thrown.expectMessage("OtaPackage title should be specified!"); + otaPackageService.saveOtaPackage(firmware); } @Test public void testSaveFirmwareWithEmptyFileName() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -225,13 +225,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setData(DATA); thrown.expect(DataValidationException.class); - thrown.expectMessage("Firmware file name should be specified!"); - firmwareService.saveFirmware(firmware); + thrown.expectMessage("OtaPackage file name should be specified!"); + otaPackageService.saveOtaPackage(firmware); } @Test public void testSaveFirmwareWithEmptyContentType() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -243,13 +243,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setData(DATA); thrown.expect(DataValidationException.class); - thrown.expectMessage("Firmware content type should be specified!"); - firmwareService.saveFirmware(firmware); + thrown.expectMessage("OtaPackage content type should be specified!"); + otaPackageService.saveOtaPackage(firmware); } @Test public void testSaveFirmwareWithEmptyData() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -261,13 +261,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksum(CHECKSUM); thrown.expect(DataValidationException.class); - thrown.expectMessage("Firmware data should be specified!"); - firmwareService.saveFirmware(firmware); + thrown.expectMessage("OtaPackage data should be specified!"); + otaPackageService.saveOtaPackage(firmware); } @Test public void testSaveFirmwareWithInvalidTenant() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(new TenantId(Uuids.timeBased())); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -280,13 +280,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setData(DATA); thrown.expect(DataValidationException.class); - thrown.expectMessage("Firmware is referencing to non-existent tenant!"); - firmwareService.saveFirmware(firmware); + thrown.expectMessage("OtaPackage is referencing to non-existent tenant!"); + otaPackageService.saveOtaPackage(firmware); } @Test public void testSaveFirmwareWithInvalidDeviceProfileId() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(new DeviceProfileId(Uuids.timeBased())); firmware.setType(FIRMWARE); @@ -299,13 +299,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setData(DATA); thrown.expect(DataValidationException.class); - thrown.expectMessage("Firmware is referencing to non-existent device profile!"); - firmwareService.saveFirmware(firmware); + thrown.expectMessage("OtaPackage is referencing to non-existent device profile!"); + otaPackageService.saveOtaPackage(firmware); } @Test public void testSaveFirmwareWithEmptyChecksum() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -317,21 +317,21 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setData(DATA); thrown.expect(DataValidationException.class); - thrown.expectMessage("Firmware checksum should be specified!"); - firmwareService.saveFirmware(firmware); + thrown.expectMessage("OtaPackage checksum should be specified!"); + otaPackageService.saveOtaPackage(firmware); } @Test public void testSaveFirmwareInfoWithExistingTitleAndVersion() { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setTenantId(tenantId); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); firmwareInfo.setTitle(TITLE); firmwareInfo.setVersion(VERSION); - firmwareService.saveFirmwareInfo(firmwareInfo); + otaPackageService.saveOtaPackageInfo(firmwareInfo); - FirmwareInfo newFirmwareInfo = new FirmwareInfo(); + OtaPackageInfo newFirmwareInfo = new OtaPackageInfo(); newFirmwareInfo.setTenantId(tenantId); newFirmwareInfo.setDeviceProfileId(deviceProfileId); newFirmwareInfo.setType(FIRMWARE); @@ -339,13 +339,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { newFirmwareInfo.setVersion(VERSION); thrown.expect(DataValidationException.class); - thrown.expectMessage("Firmware with such title and version already exists!"); - firmwareService.saveFirmwareInfo(newFirmwareInfo); + thrown.expectMessage("OtaPackage with such title and version already exists!"); + otaPackageService.saveOtaPackageInfo(newFirmwareInfo); } @Test public void testSaveFirmwareWithExistingTitleAndVersion() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -356,9 +356,9 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); - firmwareService.saveFirmware(firmware); + otaPackageService.saveOtaPackage(firmware); - Firmware newFirmware = new Firmware(); + OtaPackage newFirmware = new OtaPackage(); newFirmware.setTenantId(tenantId); newFirmware.setDeviceProfileId(deviceProfileId); newFirmware.setType(FIRMWARE); @@ -371,13 +371,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { newFirmware.setData(DATA); thrown.expect(DataValidationException.class); - thrown.expectMessage("Firmware with such title and version already exists!"); - firmwareService.saveFirmware(newFirmware); + thrown.expectMessage("OtaPackage with such title and version already exists!"); + otaPackageService.saveOtaPackage(newFirmware); } @Test public void testDeleteFirmwareWithReferenceByDevice() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -388,7 +388,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); + OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); Device device = new Device(); device.setTenantId(tenantId); @@ -399,17 +399,17 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { try { thrown.expect(DataValidationException.class); - thrown.expectMessage("The firmware referenced by the devices cannot be deleted!"); - firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); + thrown.expectMessage("The otaPackage referenced by the devices cannot be deleted!"); + otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); } finally { deviceService.deleteDevice(tenantId, savedDevice.getId()); - firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); + otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); } } @Test public void testUpdateDeviceProfileIdWithReferenceByDevice() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -420,7 +420,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); + OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); Device device = new Device(); device.setTenantId(tenantId); @@ -431,12 +431,12 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { try { thrown.expect(DataValidationException.class); - thrown.expectMessage("Can`t update deviceProfileId because firmware is already in use!"); + thrown.expectMessage("Can`t update deviceProfileId because otaPackage is already in use!"); savedFirmware.setDeviceProfileId(null); - firmwareService.saveFirmware(savedFirmware); + otaPackageService.saveOtaPackage(savedFirmware); } finally { deviceService.deleteDevice(tenantId, savedDevice.getId()); - firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); + otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); } } @@ -445,7 +445,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Test Device Profile"); DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(savedDeviceProfile.getId()); firmware.setType(FIRMWARE); @@ -456,18 +456,18 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); + OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); 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()); + thrown.expectMessage("The otaPackage referenced by the device profile cannot be deleted!"); + otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); } finally { deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); - firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); + otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); } } @@ -476,7 +476,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Test Device Profile"); DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(savedDeviceProfile.getId()); firmware.setType(FIRMWARE); @@ -487,25 +487,25 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); + OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); savedDeviceProfile.setFirmwareId(savedFirmware.getId()); deviceProfileService.saveDeviceProfile(savedDeviceProfile); try { thrown.expect(DataValidationException.class); - thrown.expectMessage("Can`t update deviceProfileId because firmware is already in use!"); + thrown.expectMessage("Can`t update deviceProfileId because otaPackage is already in use!"); savedFirmware.setDeviceProfileId(null); - firmwareService.saveFirmware(savedFirmware); + otaPackageService.saveOtaPackage(savedFirmware); } finally { deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); - firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); + otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); } } @Test public void testFindFirmwareById() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -516,33 +516,33 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); + OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); - Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, savedFirmware.getId()); + OtaPackage foundFirmware = otaPackageService.findOtaPackageById(tenantId, savedFirmware.getId()); Assert.assertNotNull(foundFirmware); Assert.assertEquals(savedFirmware, foundFirmware); - firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); + otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); } @Test public void testFindFirmwareInfoById() { - FirmwareInfo firmware = new FirmwareInfo(); + OtaPackageInfo firmware = new OtaPackageInfo(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); firmware.setTitle(TITLE); firmware.setVersion(VERSION); - FirmwareInfo savedFirmware = firmwareService.saveFirmwareInfo(firmware); + OtaPackageInfo savedFirmware = otaPackageService.saveOtaPackageInfo(firmware); - FirmwareInfo foundFirmware = firmwareService.findFirmwareInfoById(tenantId, savedFirmware.getId()); + OtaPackageInfo foundFirmware = otaPackageService.findOtaPackageInfoById(tenantId, savedFirmware.getId()); Assert.assertNotNull(foundFirmware); Assert.assertEquals(savedFirmware, foundFirmware); - firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); + otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); } @Test public void testDeleteFirmware() { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -553,20 +553,20 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmware.setChecksum(CHECKSUM); firmware.setData(DATA); - Firmware savedFirmware = firmwareService.saveFirmware(firmware); + OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); - Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, savedFirmware.getId()); + OtaPackage foundFirmware = otaPackageService.findOtaPackageById(tenantId, savedFirmware.getId()); Assert.assertNotNull(foundFirmware); - firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); - foundFirmware = firmwareService.findFirmwareById(tenantId, savedFirmware.getId()); + otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); + foundFirmware = otaPackageService.findOtaPackageById(tenantId, savedFirmware.getId()); Assert.assertNull(foundFirmware); } @Test public void testFindTenantFirmwaresByTenantId() { - List firmwares = new ArrayList<>(); + List firmwares = new ArrayList<>(); for (int i = 0; i < 165; i++) { - Firmware firmware = new Firmware(); + OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); firmware.setType(FIRMWARE); @@ -578,16 +578,16 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksum(CHECKSUM); firmware.setData(DATA); - FirmwareInfo info = new FirmwareInfo(firmwareService.saveFirmware(firmware)); + OtaPackageInfo info = new OtaPackageInfo(otaPackageService.saveOtaPackage(firmware)); info.setHasData(true); firmwares.add(info); } - List loadedFirmwares = new ArrayList<>(); + List loadedFirmwares = new ArrayList<>(); PageLink pageLink = new PageLink(16); - PageData pageData; + PageData pageData; do { - pageData = firmwareService.findTenantFirmwaresByTenantId(tenantId, pageLink); + pageData = otaPackageService.findTenantOtaPackagesByTenantId(tenantId, pageLink); loadedFirmwares.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageLink.nextPageLink(); @@ -599,19 +599,19 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Assert.assertEquals(firmwares, loadedFirmwares); - firmwareService.deleteFirmwaresByTenantId(tenantId); + otaPackageService.deleteOtaPackagesByTenantId(tenantId); pageLink = new PageLink(31); - pageData = firmwareService.findTenantFirmwaresByTenantId(tenantId, pageLink); + pageData = otaPackageService.findTenantOtaPackagesByTenantId(tenantId, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertTrue(pageData.getData().isEmpty()); } @Test public void testFindTenantFirmwaresByTenantIdAndHasData() { - List firmwares = new ArrayList<>(); + List firmwares = new ArrayList<>(); for (int i = 0; i < 165; i++) { - FirmwareInfo firmwareInfo = new FirmwareInfo(); + OtaPackageInfo firmwareInfo = new OtaPackageInfo(); firmwareInfo.setTenantId(tenantId); firmwareInfo.setDeviceProfileId(deviceProfileId); firmwareInfo.setType(FIRMWARE); @@ -622,14 +622,14 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmwareInfo.setChecksumAlgorithm(CHECKSUM_ALGORITHM); firmwareInfo.setChecksum(CHECKSUM); firmwareInfo.setDataSize((long) DATA.array().length); - firmwares.add(firmwareService.saveFirmwareInfo(firmwareInfo)); + firmwares.add(otaPackageService.saveOtaPackageInfo(firmwareInfo)); } - List loadedFirmwares = new ArrayList<>(); + List loadedFirmwares = new ArrayList<>(); PageLink pageLink = new PageLink(16); - PageData pageData; + PageData pageData; do { - pageData = firmwareService.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, FIRMWARE, false, pageLink); + pageData = otaPackageService.findTenantOtaPackagesByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, FIRMWARE, false, pageLink); loadedFirmwares.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageLink.nextPageLink(); @@ -642,7 +642,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Assert.assertEquals(firmwares, loadedFirmwares); firmwares.forEach(f -> { - Firmware firmware = new Firmware(f.getId()); + OtaPackage firmware = new OtaPackage(f.getId()); firmware.setCreatedTime(f.getCreatedTime()); firmware.setTenantId(f.getTenantId()); firmware.setDeviceProfileId(deviceProfileId); @@ -655,14 +655,14 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { firmware.setChecksum(CHECKSUM); firmware.setData(DATA); firmware.setDataSize((long) DATA.array().length); - firmwareService.saveFirmware(firmware); + otaPackageService.saveOtaPackage(firmware); f.setHasData(true); }); loadedFirmwares = new ArrayList<>(); pageLink = new PageLink(16); do { - pageData = firmwareService.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, FIRMWARE, true, pageLink); + pageData = otaPackageService.findTenantOtaPackagesByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, FIRMWARE, true, pageLink); loadedFirmwares.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageLink.nextPageLink(); @@ -674,10 +674,10 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { Assert.assertEquals(firmwares, loadedFirmwares); - firmwareService.deleteFirmwaresByTenantId(tenantId); + otaPackageService.deleteOtaPackagesByTenantId(tenantId); pageLink = new PageLink(31); - pageData = firmwareService.findTenantFirmwaresByTenantId(tenantId, pageLink); + pageData = otaPackageService.findTenantOtaPackagesByTenantId(tenantId, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertTrue(pageData.getData().isEmpty()); } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/sql/FirmwareServiceSqlTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/sql/OtaPackageServiceSqlTest.java similarity index 83% rename from dao/src/test/java/org/thingsboard/server/dao/service/sql/FirmwareServiceSqlTest.java rename to dao/src/test/java/org/thingsboard/server/dao/service/sql/OtaPackageServiceSqlTest.java index a89414e3a2..59ac4f76bf 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/sql/FirmwareServiceSqlTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/sql/OtaPackageServiceSqlTest.java @@ -15,9 +15,9 @@ */ package org.thingsboard.server.dao.service.sql; -import org.thingsboard.server.dao.service.BaseFirmwareServiceTest; +import org.thingsboard.server.dao.service.BaseOtaPackageServiceTest; import org.thingsboard.server.dao.service.DaoSqlTest; @DaoSqlTest -public class FirmwareServiceSqlTest extends BaseFirmwareServiceTest { +public class OtaPackageServiceSqlTest extends BaseOtaPackageServiceTest { } diff --git a/dao/src/test/resources/application-test.properties b/dao/src/test/resources/application-test.properties index 2805c78fdd..74eb4f43f0 100644 --- a/dao/src/test/resources/application-test.properties +++ b/dao/src/test/resources/application-test.properties @@ -36,8 +36,8 @@ caffeine.specs.tenantProfiles.maxSize=100000 caffeine.specs.deviceProfiles.timeToLiveInMinutes=1440 caffeine.specs.deviceProfiles.maxSize=100000 -caffeine.specs.firmwares.timeToLiveInMinutes=1440 -caffeine.specs.firmwares.maxSize=100000 +caffeine.specs.otaPackages.timeToLiveInMinutes=1440 +caffeine.specs.otaPackages.maxSize=100000 caffeine.specs.edges.timeToLiveInMinutes=1440 caffeine.specs.edges.maxSize=100000 diff --git a/dao/src/test/resources/sql/hsql/drop-all-tables.sql b/dao/src/test/resources/sql/hsql/drop-all-tables.sql index f65316f2c1..726b4ba412 100644 --- a/dao/src/test/resources/sql/hsql/drop-all-tables.sql +++ b/dao/src/test/resources/sql/hsql/drop-all-tables.sql @@ -29,7 +29,7 @@ DROP TABLE IF EXISTS oauth2_client_registration_info; DROP TABLE IF EXISTS oauth2_client_registration_template; DROP TABLE IF EXISTS api_usage_state; DROP TABLE IF EXISTS resource; -DROP TABLE IF EXISTS firmware; +DROP TABLE IF EXISTS ota_package; DROP TABLE IF EXISTS edge; DROP TABLE IF EXISTS edge_event; DROP FUNCTION IF EXISTS to_uuid; From 9d93f429e81bfc57537cb6c3f80cde2c40616280 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Mon, 31 May 2021 18:15:31 +0300 Subject: [PATCH 02/19] UI: Rename firmware to OtaPackage --- ui-ngx/src/app/core/http/entity.service.ts | 20 +-- ui-ngx/src/app/core/http/firmware.service.ts | 123 ------------------ .../src/app/core/http/ota-package.service.ts | 123 ++++++++++++++++++ ui-ngx/src/app/core/services/menu.service.ts | 8 +- ...device-profile-autocomplete.component.html | 1 + .../device-profile-autocomplete.component.ts | 3 + .../profile/device-profile.component.html | 12 +- .../profile/device-profile.component.ts | 4 +- .../app/modules/home/models/services.map.ts | 4 +- .../home/pages/device/device.component.html | 12 +- .../home/pages/device/device.component.ts | 4 +- .../firmware/firmware-table-config.resolve.ts | 115 ---------------- .../modules/home/pages/home-pages.module.ts | 4 +- .../ota-update-routing.module.ts} | 14 +- .../ota-update-table-config.resolve.ts | 116 +++++++++++++++++ .../ota-update.component.html} | 80 ++++++------ .../ota-update.component.ts} | 44 ++++--- .../ota-update.module.ts} | 10 +- .../ota-package-autocomplete.component.html} | 27 ++-- .../ota-package-autocomplete.component.ts} | 110 +++++++--------- ui-ngx/src/app/shared/models/constants.ts | 1 + ui-ngx/src/app/shared/models/device.models.ts | 10 +- .../app/shared/models/entity-type.models.ts | 20 +-- .../id/{firmware-id.ts => ota-package-id.ts} | 4 +- ...rmware.models.ts => ota-package.models.ts} | 43 ++++-- ui-ngx/src/app/shared/shared.module.ts | 6 +- .../assets/locale/locale.constant-en_US.json | 96 +++++++------- 27 files changed, 521 insertions(+), 493 deletions(-) delete mode 100644 ui-ngx/src/app/core/http/firmware.service.ts create mode 100644 ui-ngx/src/app/core/http/ota-package.service.ts delete mode 100644 ui-ngx/src/app/modules/home/pages/firmware/firmware-table-config.resolve.ts rename ui-ngx/src/app/modules/home/pages/{firmware/firmware-routing.module.ts => ota-update/ota-update-routing.module.ts} (78%) create mode 100644 ui-ngx/src/app/modules/home/pages/ota-update/ota-update-table-config.resolve.ts rename ui-ngx/src/app/modules/home/pages/{firmware/firmwares.component.html => ota-update/ota-update.component.html} (60%) rename ui-ngx/src/app/modules/home/pages/{firmware/firmwares.component.ts => ota-update/ota-update.component.ts} (74%) rename ui-ngx/src/app/modules/home/pages/{firmware/firmware.module.ts => ota-update/ota-update.module.ts} (79%) rename ui-ngx/src/app/shared/components/{firmware/firmware-autocomplete.component.html => ota-package/ota-package-autocomplete.component.html} (62%) rename ui-ngx/src/app/shared/components/{firmware/firmware-autocomplete.component.ts => ota-package/ota-package-autocomplete.component.ts} (59%) rename ui-ngx/src/app/shared/models/id/{firmware-id.ts => ota-package-id.ts} (90%) rename ui-ngx/src/app/shared/models/{firmware.models.ts => ota-package.models.ts} (58%) diff --git a/ui-ngx/src/app/core/http/entity.service.ts b/ui-ngx/src/app/core/http/entity.service.ts index c5ef4b8db4..c58e5ac909 100644 --- a/ui-ngx/src/app/core/http/entity.service.ts +++ b/ui-ngx/src/app/core/http/entity.service.ts @@ -75,12 +75,12 @@ import { StringOperation } from '@shared/models/query/query.models'; import { alarmFields } from '@shared/models/alarm.models'; -import { FirmwareService } from '@core/http/firmware.service'; -import { EdgeService } from "@core/http/edge.service"; +import { OtaPackageService } from '@core/http/ota-package.service'; +import { EdgeService } from '@core/http/edge.service'; import { Edge, EdgeEventType } from '@shared/models/edge.models'; -import { RuleChainType } from "@shared/models/rule-chain.models"; -import { WidgetService } from "@core/http/widget.service"; -import { DeviceProfileService } from "@core/http/device-profile.service"; +import { RuleChainType } from '@shared/models/rule-chain.models'; +import { WidgetService } from '@core/http/widget.service'; +import { DeviceProfileService } from '@core/http/device-profile.service'; @Injectable({ providedIn: 'root' @@ -101,7 +101,7 @@ export class EntityService { private dashboardService: DashboardService, private entityRelationService: EntityRelationService, private attributeService: AttributeService, - private firmwareService: FirmwareService, + private otaPackageService: OtaPackageService, private widgetService: WidgetService, private deviceProfileService: DeviceProfileService, private utils: UtilsService @@ -142,8 +142,8 @@ export class EntityService { case EntityType.ALARM: console.error('Get Alarm Entity is not implemented!'); break; - case EntityType.FIRMWARE: - observable = this.firmwareService.getFirmwareInfo(entityId, config); + case EntityType.OTA_PACKAGE: + observable = this.otaPackageService.getOtaPackageInfo(entityId, config); break; } return observable; @@ -359,9 +359,9 @@ export class EntityService { case EntityType.ALARM: console.error('Get Alarm Entities is not implemented!'); break; - case EntityType.FIRMWARE: + case EntityType.OTA_PACKAGE: pageLink.sortOrder.property = 'title'; - entitiesObservable = this.firmwareService.getFirmwares(pageLink, config); + entitiesObservable = this.otaPackageService.getOtaPackages(pageLink, config); break; } return entitiesObservable; diff --git a/ui-ngx/src/app/core/http/firmware.service.ts b/ui-ngx/src/app/core/http/firmware.service.ts deleted file mode 100644 index 1fe51c5f68..0000000000 --- a/ui-ngx/src/app/core/http/firmware.service.ts +++ /dev/null @@ -1,123 +0,0 @@ -/// -/// Copyright © 2016-2021 The Thingsboard Authors -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { PageLink } from '@shared/models/page/page-link'; -import { defaultHttpOptionsFromConfig, defaultHttpUploadOptions, RequestConfig } from '@core/http/http-utils'; -import { Observable } from 'rxjs'; -import { PageData } from '@shared/models/page/page-data'; -import { ChecksumAlgorithm, Firmware, FirmwareInfo, FirmwareType } from '@shared/models/firmware.models'; -import { catchError, map, mergeMap } from 'rxjs/operators'; -import { deepClone } from '@core/utils'; - -@Injectable({ - providedIn: 'root' -}) -export class FirmwareService { - constructor( - private http: HttpClient - ) { - - } - - public getFirmwares(pageLink: PageLink, config?: RequestConfig): Observable> { - return this.http.get>(`/api/firmwares${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config)); - } - - public getFirmwaresInfoByDeviceProfileId(pageLink: PageLink, deviceProfileId: string, type: FirmwareType, - hasData = true, config?: RequestConfig): Observable> { - const url = `/api/firmwares/${deviceProfileId}/${type}/${hasData}${pageLink.toQuery()}`; - return this.http.get>(url, defaultHttpOptionsFromConfig(config)); - } - - public getFirmware(firmwareId: string, config?: RequestConfig): Observable { - return this.http.get(`/api/firmware/${firmwareId}`, defaultHttpOptionsFromConfig(config)); - } - - public getFirmwareInfo(firmwareId: string, config?: RequestConfig): Observable { - return this.http.get(`/api/firmware/info/${firmwareId}`, defaultHttpOptionsFromConfig(config)); - } - - public downloadFirmware(firmwareId: string): Observable { - return this.http.get(`/api/firmware/${firmwareId}/download`, { responseType: 'arraybuffer', observe: 'response' }).pipe( - map((response) => { - const headers = response.headers; - const filename = headers.get('x-filename'); - const contentType = headers.get('content-type'); - const linkElement = document.createElement('a'); - try { - const blob = new Blob([response.body], { type: contentType }); - const url = URL.createObjectURL(blob); - linkElement.setAttribute('href', url); - linkElement.setAttribute('download', filename); - const clickEvent = new MouseEvent('click', - { - view: window, - bubbles: true, - cancelable: false - } - ); - linkElement.dispatchEvent(clickEvent); - return null; - } catch (e) { - throw e; - } - }) - ); - } - - public saveFirmware(firmware: Firmware, config?: RequestConfig): Observable { - if (!firmware.file) { - return this.saveFirmwareInfo(firmware, config); - } - const firmwareInfo = deepClone(firmware); - delete firmwareInfo.file; - delete firmwareInfo.checksum; - delete firmwareInfo.checksumAlgorithm; - return this.saveFirmwareInfo(firmwareInfo, config).pipe( - mergeMap(res => { - return this.uploadFirmwareFile(res.id.id, firmware.file, firmware.checksumAlgorithm, firmware.checksum).pipe( - catchError(() => this.deleteFirmware(res.id.id)) - ); - }) - ); - } - - public saveFirmwareInfo(firmware: FirmwareInfo, config?: RequestConfig): Observable { - return this.http.post('/api/firmware', firmware, defaultHttpOptionsFromConfig(config)); - } - - public uploadFirmwareFile(firmwareId: string, file: File, checksumAlgorithm: ChecksumAlgorithm, - checksum?: string, config?: RequestConfig): Observable { - if (!config) { - config = {}; - } - const formData = new FormData(); - formData.append('file', file); - let url = `/api/firmware/${firmwareId}?checksumAlgorithm=${checksumAlgorithm}`; - if (checksum) { - url += `&checksum=${checksum}`; - } - return this.http.post(url, formData, - defaultHttpUploadOptions(config.ignoreLoading, config.ignoreErrors, config.resendRequest)); - } - - public deleteFirmware(firmwareId: string, config?: RequestConfig) { - return this.http.delete(`/api/firmware/${firmwareId}`, defaultHttpOptionsFromConfig(config)); - } - -} diff --git a/ui-ngx/src/app/core/http/ota-package.service.ts b/ui-ngx/src/app/core/http/ota-package.service.ts new file mode 100644 index 0000000000..34993e5318 --- /dev/null +++ b/ui-ngx/src/app/core/http/ota-package.service.ts @@ -0,0 +1,123 @@ +/// +/// Copyright © 2016-2021 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { PageLink } from '@shared/models/page/page-link'; +import { defaultHttpOptionsFromConfig, defaultHttpUploadOptions, RequestConfig } from '@core/http/http-utils'; +import { Observable } from 'rxjs'; +import { PageData } from '@shared/models/page/page-data'; +import { ChecksumAlgorithm, OtaPackage, OtaPackageInfo, OtaUpdateType } from '@shared/models/ota-package.models'; +import { catchError, map, mergeMap } from 'rxjs/operators'; +import { deepClone } from '@core/utils'; + +@Injectable({ + providedIn: 'root' +}) +export class OtaPackageService { + constructor( + private http: HttpClient + ) { + + } + + public getOtaPackages(pageLink: PageLink, config?: RequestConfig): Observable> { + return this.http.get>(`/api/otaPackages${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config)); + } + + public getOtaPackagesInfoByDeviceProfileId(pageLink: PageLink, deviceProfileId: string, type: OtaUpdateType, + hasData = true, config?: RequestConfig): Observable> { + const url = `/api/otaPackages/${deviceProfileId}/${type}/${hasData}${pageLink.toQuery()}`; + return this.http.get>(url, defaultHttpOptionsFromConfig(config)); + } + + public getOtaPackage(otaPackageId: string, config?: RequestConfig): Observable { + return this.http.get(`/api/otaPackages/${otaPackageId}`, defaultHttpOptionsFromConfig(config)); + } + + public getOtaPackageInfo(otaPackageId: string, config?: RequestConfig): Observable { + return this.http.get(`/api/otaPackage/info/${otaPackageId}`, defaultHttpOptionsFromConfig(config)); + } + + public downloadOtaPackage(otaPackageId: string): Observable { + return this.http.get(`/api/otaPackage/${otaPackageId}/download`, { responseType: 'arraybuffer', observe: 'response' }).pipe( + map((response) => { + const headers = response.headers; + const filename = headers.get('x-filename'); + const contentType = headers.get('content-type'); + const linkElement = document.createElement('a'); + try { + const blob = new Blob([response.body], { type: contentType }); + const url = URL.createObjectURL(blob); + linkElement.setAttribute('href', url); + linkElement.setAttribute('download', filename); + const clickEvent = new MouseEvent('click', + { + view: window, + bubbles: true, + cancelable: false + } + ); + linkElement.dispatchEvent(clickEvent); + return null; + } catch (e) { + throw e; + } + }) + ); + } + + public saveOtaPackage(otaPackage: OtaPackage, config?: RequestConfig): Observable { + if (!otaPackage.file) { + return this.saveOtaPackageInfo(otaPackage, config); + } + const otaPackageInfo = deepClone(otaPackage); + delete otaPackageInfo.file; + delete otaPackageInfo.checksum; + delete otaPackageInfo.checksumAlgorithm; + return this.saveOtaPackageInfo(otaPackageInfo, config).pipe( + mergeMap(res => { + return this.uploadOtaPackageFile(res.id.id, otaPackage.file, otaPackage.checksumAlgorithm, otaPackage.checksum).pipe( + catchError(() => this.deleteOtaPackage(res.id.id)) + ); + }) + ); + } + + public saveOtaPackageInfo(otaPackageInfo: OtaPackageInfo, config?: RequestConfig): Observable { + return this.http.post('/api/otaPackage', otaPackageInfo, defaultHttpOptionsFromConfig(config)); + } + + public uploadOtaPackageFile(otaPackageId: string, file: File, checksumAlgorithm: ChecksumAlgorithm, + checksum?: string, config?: RequestConfig): Observable { + if (!config) { + config = {}; + } + const formData = new FormData(); + formData.append('file', file); + let url = `/api/otaPackage/${otaPackageId}?checksumAlgorithm=${checksumAlgorithm}`; + if (checksum) { + url += `&checksum=${checksum}`; + } + return this.http.post(url, formData, + defaultHttpUploadOptions(config.ignoreLoading, config.ignoreErrors, config.resendRequest)); + } + + public deleteOtaPackage(otaPackageId: string, config?: RequestConfig) { + return this.http.delete(`/api/otaPackage/${otaPackageId}`, defaultHttpOptionsFromConfig(config)); + } + +} diff --git a/ui-ngx/src/app/core/services/menu.service.ts b/ui-ngx/src/app/core/services/menu.service.ts index 07a6d8f237..806447f112 100644 --- a/ui-ngx/src/app/core/services/menu.service.ts +++ b/ui-ngx/src/app/core/services/menu.service.ts @@ -276,9 +276,9 @@ export class MenuService { }, { id: guid(), - name: 'firmware.firmware', + name: 'ota-update.ota-updates', type: 'link', - path: '/firmwares', + path: '/otaUpdates', icon: 'memory' }, { @@ -423,9 +423,9 @@ export class MenuService { path: '/deviceProfiles' }, { - name: 'firmware.firmware', + name: 'ota-update.ota-updates', icon: 'memory', - path: '/firmwares' + path: '/otaUpdates' } ] }, diff --git a/ui-ngx/src/app/modules/home/components/profile/device-profile-autocomplete.component.html b/ui-ngx/src/app/modules/home/components/profile/device-profile-autocomplete.component.html index 17caf4f0d7..bd6f92b175 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device-profile-autocomplete.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/device-profile-autocomplete.component.html @@ -66,4 +66,5 @@ {{ 'device-profile.device-profile-required' | translate }} + {{ hint | translate }} diff --git a/ui-ngx/src/app/modules/home/components/profile/device-profile-autocomplete.component.ts b/ui-ngx/src/app/modules/home/components/profile/device-profile-autocomplete.component.ts index 3a0ae491da..a2fa8d1ed3 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device-profile-autocomplete.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device-profile-autocomplete.component.ts @@ -91,6 +91,9 @@ export class DeviceProfileAutocompleteComponent implements ControlValueAccessor, @Input() disabled: boolean; + @Input() + hint: string; + @Output() deviceProfileUpdated = new EventEmitter(); diff --git a/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html b/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html index 325bc20419..5fa6c1acdb 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html @@ -67,18 +67,18 @@ [queueType]="serviceType" formControlName="defaultQueueName"> - - - + - + device-profile.type diff --git a/ui-ngx/src/app/modules/home/components/profile/device-profile.component.ts b/ui-ngx/src/app/modules/home/components/profile/device-profile.component.ts index 6db89d818e..efaa234adb 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device-profile.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device-profile.component.ts @@ -40,7 +40,7 @@ import { EntityType } from '@shared/models/entity-type.models'; import { RuleChainId } from '@shared/models/id/rule-chain-id'; import { ServiceType } from '@shared/models/queue.models'; import { EntityId } from '@shared/models/id/entity-id'; -import { FirmwareType } from '@shared/models/firmware.models'; +import { OtaUpdateType } from '@shared/models/ota-package.models'; import { DashboardId } from '@shared/models/id/dashboard-id'; @Component({ @@ -71,7 +71,7 @@ export class DeviceProfileComponent extends EntityComponent { deviceProfileId: EntityId; - firmwareTypes = FirmwareType; + otaUpdateType = OtaUpdateType; constructor(protected store: Store, protected translate: TranslateService, diff --git a/ui-ngx/src/app/modules/home/models/services.map.ts b/ui-ngx/src/app/modules/home/models/services.map.ts index c518249b77..4b65083038 100644 --- a/ui-ngx/src/app/modules/home/models/services.map.ts +++ b/ui-ngx/src/app/modules/home/models/services.map.ts @@ -35,7 +35,7 @@ import { Router } from '@angular/router'; import { BroadcastService } from '@core/services/broadcast.service'; import { ImportExportService } from '@home/components/import-export/import-export.service'; import { DeviceProfileService } from '@core/http/device-profile.service'; -import { FirmwareService } from '@core/http/firmware.service'; +import { OtaPackageService } from '@core/http/ota-package.service'; export const ServicesMap = new Map>( [ @@ -59,6 +59,6 @@ export const ServicesMap = new Map>( ['router', Router], ['importExport', ImportExportService], ['deviceProfileService', DeviceProfileService], - ['firmwareService', FirmwareService] + ['otaPackageService', OtaPackageService] ] ); diff --git a/ui-ngx/src/app/modules/home/pages/device/device.component.html b/ui-ngx/src/app/modules/home/pages/device/device.component.html index f09437662a..2dd6486eeb 100644 --- a/ui-ngx/src/app/modules/home/pages/device/device.component.html +++ b/ui-ngx/src/app/modules/home/pages/device/device.component.html @@ -101,18 +101,18 @@ device.label - - - + - + diff --git a/ui-ngx/src/app/modules/home/pages/device/device.component.ts b/ui-ngx/src/app/modules/home/pages/device/device.component.ts index d7f21fb2fc..1ed9f784f1 100644 --- a/ui-ngx/src/app/modules/home/pages/device/device.component.ts +++ b/ui-ngx/src/app/modules/home/pages/device/device.component.ts @@ -34,7 +34,7 @@ import { ActionNotificationShow } from '@core/notification/notification.actions' import { TranslateService } from '@ngx-translate/core'; import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; import { Subject } from 'rxjs'; -import { FirmwareType } from '@shared/models/firmware.models'; +import { OtaUpdateType } from '@shared/models/ota-package.models'; @Component({ selector: 'tb-device', @@ -49,7 +49,7 @@ export class DeviceComponent extends EntityComponent { deviceScope: 'tenant' | 'customer' | 'customer_user' | 'edge'; - firmwareTypes = FirmwareType; + otaUpdateType = OtaUpdateType; constructor(protected store: Store, protected translate: TranslateService, diff --git a/ui-ngx/src/app/modules/home/pages/firmware/firmware-table-config.resolve.ts b/ui-ngx/src/app/modules/home/pages/firmware/firmware-table-config.resolve.ts deleted file mode 100644 index 23efe2117b..0000000000 --- a/ui-ngx/src/app/modules/home/pages/firmware/firmware-table-config.resolve.ts +++ /dev/null @@ -1,115 +0,0 @@ -/// -/// Copyright © 2016-2021 The Thingsboard Authors -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -import { Injectable } from '@angular/core'; -import { Resolve } from '@angular/router'; -import { - DateEntityTableColumn, - EntityTableColumn, - EntityTableConfig -} from '@home/models/entity/entities-table-config.models'; -import { - ChecksumAlgorithmTranslationMap, - Firmware, - FirmwareInfo, - FirmwareTypeTranslationMap -} from '@shared/models/firmware.models'; -import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models'; -import { TranslateService } from '@ngx-translate/core'; -import { DatePipe } from '@angular/common'; -import { FirmwareService } from '@core/http/firmware.service'; -import { PageLink } from '@shared/models/page/page-link'; -import { FirmwaresComponent } from '@home/pages/firmware/firmwares.component'; -import { EntityAction } from '@home/models/entity/entity-component.models'; -import { FileSizePipe } from '@shared/pipe/file-size.pipe'; - -@Injectable() -export class FirmwareTableConfigResolve implements Resolve> { - - private readonly config: EntityTableConfig = new EntityTableConfig(); - - constructor(private translate: TranslateService, - private datePipe: DatePipe, - private firmwareService: FirmwareService, - private fileSize: FileSizePipe) { - this.config.entityType = EntityType.FIRMWARE; - this.config.entityComponent = FirmwaresComponent; - this.config.entityTranslations = entityTypeTranslations.get(EntityType.FIRMWARE); - this.config.entityResources = entityTypeResources.get(EntityType.FIRMWARE); - - this.config.entityTitle = (firmware) => firmware ? firmware.title : ''; - - this.config.columns.push( - new DateEntityTableColumn('createdTime', 'common.created-time', this.datePipe, '150px'), - new EntityTableColumn('title', 'firmware.title', '25%'), - new EntityTableColumn('version', 'firmware.version', '25%'), - new EntityTableColumn('type', 'firmware.type', '25%', entity => { - return this.translate.instant(FirmwareTypeTranslationMap.get(entity.type)); - }), - new EntityTableColumn('fileName', 'firmware.file-name', '25%'), - new EntityTableColumn('dataSize', 'firmware.file-size', '70px', entity => { - return this.fileSize.transform(entity.dataSize || 0); - }), - new EntityTableColumn('checksum', 'firmware.checksum', '540px', entity => { - return `${ChecksumAlgorithmTranslationMap.get(entity.checksumAlgorithm)}: ${entity.checksum}`; - }, () => ({}), false) - ); - - this.config.cellActionDescriptors.push( - { - name: this.translate.instant('firmware.download'), - icon: 'file_download', - isEnabled: (firmware) => firmware.hasData, - onAction: ($event, entity) => this.exportFirmware($event, entity) - } - ); - - this.config.deleteEntityTitle = firmware => this.translate.instant('firmware.delete-firmware-title', - { firmwareTitle: firmware.title }); - this.config.deleteEntityContent = () => this.translate.instant('firmware.delete-firmware-text'); - this.config.deleteEntitiesTitle = count => this.translate.instant('firmware.delete-firmwares-title', {count}); - this.config.deleteEntitiesContent = () => this.translate.instant('firmware.delete-firmwares-text'); - - this.config.entitiesFetchFunction = pageLink => this.firmwareService.getFirmwares(pageLink); - this.config.loadEntity = id => this.firmwareService.getFirmwareInfo(id.id); - this.config.saveEntity = firmware => this.firmwareService.saveFirmware(firmware); - this.config.deleteEntity = id => this.firmwareService.deleteFirmware(id.id); - - this.config.onEntityAction = action => this.onFirmwareAction(action); - } - - resolve(): EntityTableConfig { - this.config.tableTitle = this.translate.instant('firmware.firmware'); - return this.config; - } - - exportFirmware($event: Event, firmware: FirmwareInfo) { - if ($event) { - $event.stopPropagation(); - } - this.firmwareService.downloadFirmware(firmware.id.id).subscribe(); - } - - onFirmwareAction(action: EntityAction): boolean { - switch (action.action) { - case 'uploadFirmware': - this.exportFirmware(action.event, action.entity); - return true; - } - return false; - } - -} diff --git a/ui-ngx/src/app/modules/home/pages/home-pages.module.ts b/ui-ngx/src/app/modules/home/pages/home-pages.module.ts index 050b71db83..834321fc49 100644 --- a/ui-ngx/src/app/modules/home/pages/home-pages.module.ts +++ b/ui-ngx/src/app/modules/home/pages/home-pages.module.ts @@ -35,7 +35,7 @@ import { modulesMap } from '../../common/modules-map'; import { DeviceProfileModule } from './device-profile/device-profile.module'; import { ApiUsageModule } from '@home/pages/api-usage/api-usage.module'; import { EdgeModule } from '@home/pages/edge/edge.module'; -import { FirmwareModule } from '@home/pages/firmware/firmware.module'; +import { OtaUpdateModule } from '@home/pages/ota-update/ota-update.module'; @NgModule({ exports: [ @@ -55,7 +55,7 @@ import { FirmwareModule } from '@home/pages/firmware/firmware.module'; DashboardModule, AuditLogModule, ApiUsageModule, - FirmwareModule, + OtaUpdateModule, UserModule ], providers: [ diff --git a/ui-ngx/src/app/modules/home/pages/firmware/firmware-routing.module.ts b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update-routing.module.ts similarity index 78% rename from ui-ngx/src/app/modules/home/pages/firmware/firmware-routing.module.ts rename to ui-ngx/src/app/modules/home/pages/ota-update/ota-update-routing.module.ts index 688f3bfc1f..6945244c47 100644 --- a/ui-ngx/src/app/modules/home/pages/firmware/firmware-routing.module.ts +++ b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update-routing.module.ts @@ -18,22 +18,22 @@ import { RouterModule, Routes } from '@angular/router'; import { EntitiesTableComponent } from '@home/components/entity/entities-table.component'; import { Authority } from '@shared/models/authority.enum'; import { NgModule } from '@angular/core'; -import { FirmwareTableConfigResolve } from '@home/pages/firmware/firmware-table-config.resolve'; +import { OtaUpdateTableConfigResolve } from '@home/pages/ota-update/ota-update-table-config.resolve'; const routes: Routes = [ { - path: 'firmwares', + path: 'otaUpdates', component: EntitiesTableComponent, data: { auth: [Authority.TENANT_ADMIN], - title: 'firmware.firmware', + title: 'ota-update.ota-updates', breadcrumb: { - label: 'firmware.firmware', + label: 'ota-update.ota-updates', icon: 'memory' } }, resolve: { - entitiesTableConfig: FirmwareTableConfigResolve + entitiesTableConfig: OtaUpdateTableConfigResolve } } ]; @@ -42,7 +42,7 @@ const routes: Routes = [ imports: [RouterModule.forChild(routes)], exports: [RouterModule], providers: [ - FirmwareTableConfigResolve + OtaUpdateTableConfigResolve ] }) -export class FirmwareRoutingModule{ } +export class OtaUpdateRoutingModule { } diff --git a/ui-ngx/src/app/modules/home/pages/ota-update/ota-update-table-config.resolve.ts b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update-table-config.resolve.ts new file mode 100644 index 0000000000..b22d43da46 --- /dev/null +++ b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update-table-config.resolve.ts @@ -0,0 +1,116 @@ +/// +/// Copyright © 2016-2021 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Injectable } from '@angular/core'; +import { Resolve } from '@angular/router'; +import { + DateEntityTableColumn, + EntityTableColumn, + EntityTableConfig +} from '@home/models/entity/entities-table-config.models'; +import { + ChecksumAlgorithmTranslationMap, + OtaPackage, + OtaPackageInfo, + OtaUpdateTypeTranslationMap +} from '@shared/models/ota-package.models'; +import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models'; +import { TranslateService } from '@ngx-translate/core'; +import { DatePipe } from '@angular/common'; +import { OtaPackageService } from '@core/http/ota-package.service'; +import { PageLink } from '@shared/models/page/page-link'; +import { OtaUpdateComponent } from '@home/pages/ota-update/ota-update.component'; +import { EntityAction } from '@home/models/entity/entity-component.models'; +import { FileSizePipe } from '@shared/pipe/file-size.pipe'; + +@Injectable() +export class OtaUpdateTableConfigResolve implements Resolve> { + + private readonly config: EntityTableConfig = + new EntityTableConfig(); + + constructor(private translate: TranslateService, + private datePipe: DatePipe, + private otaPackageService: OtaPackageService, + private fileSize: FileSizePipe) { + this.config.entityType = EntityType.OTA_PACKAGE; + this.config.entityComponent = OtaUpdateComponent; + this.config.entityTranslations = entityTypeTranslations.get(EntityType.OTA_PACKAGE); + this.config.entityResources = entityTypeResources.get(EntityType.OTA_PACKAGE); + + this.config.entityTitle = (otaPackage) => otaPackage ? otaPackage.title : ''; + + this.config.columns.push( + new DateEntityTableColumn('createdTime', 'common.created-time', this.datePipe, '150px'), + new EntityTableColumn('title', 'ota-update.title', '25%'), + new EntityTableColumn('version', 'ota-update.version', '25%'), + new EntityTableColumn('type', 'ota-update.package-type', '25%', entity => { + return this.translate.instant(OtaUpdateTypeTranslationMap.get(entity.type)); + }), + new EntityTableColumn('fileName', 'ota-update.file-name', '25%'), + new EntityTableColumn('dataSize', 'ota-update.file-size', '70px', entity => { + return this.fileSize.transform(entity.dataSize || 0); + }), + new EntityTableColumn('checksum', 'ota-update.checksum', '540px', entity => { + return `${ChecksumAlgorithmTranslationMap.get(entity.checksumAlgorithm)}: ${entity.checksum}`; + }, () => ({}), false) + ); + + this.config.cellActionDescriptors.push( + { + name: this.translate.instant('ota-update.download'), + icon: 'file_download', + isEnabled: (otaPackage) => otaPackage.hasData, + onAction: ($event, entity) => this.exportPackage($event, entity) + } + ); + + this.config.deleteEntityTitle = otaPackage => this.translate.instant('ota-update.delete-ota-update-title', + { title: otaPackage.title }); + this.config.deleteEntityContent = () => this.translate.instant('ota-update.delete-ota-update-text'); + this.config.deleteEntitiesTitle = count => this.translate.instant('ota-update.delete-ota-updates-title', {count}); + this.config.deleteEntitiesContent = () => this.translate.instant('ota-update.delete-ota-updates-text'); + + this.config.entitiesFetchFunction = pageLink => this.otaPackageService.getOtaPackages(pageLink); + this.config.loadEntity = id => this.otaPackageService.getOtaPackageInfo(id.id); + this.config.saveEntity = otaPackage => this.otaPackageService.saveOtaPackage(otaPackage); + this.config.deleteEntity = id => this.otaPackageService.deleteOtaPackage(id.id); + + this.config.onEntityAction = action => this.onPackageAction(action); + } + + resolve(): EntityTableConfig { + this.config.tableTitle = this.translate.instant('ota-update.packages-repository'); + return this.config; + } + + exportPackage($event: Event, otaPackageInfo: OtaPackageInfo) { + if ($event) { + $event.stopPropagation(); + } + this.otaPackageService.downloadOtaPackage(otaPackageInfo.id.id).subscribe(); + } + + onPackageAction(action: EntityAction): boolean { + switch (action.action) { + case 'uploadPackage': + this.exportPackage(action.event, action.entity); + return true; + } + return false; + } + +} diff --git a/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.html b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.html similarity index 60% rename from ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.html rename to ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.html index b608604d2f..77a68f72e5 100644 --- a/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.html +++ b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.html @@ -18,114 +18,112 @@
-
+
-
- firmware.warning-after-save-no-edit +
- firmware.title + ota-update.title - {{ 'firmware.title-required' | translate }} + {{ 'ota-update.title-required' | translate }} - firmware.version + ota-update.version - {{ 'firmware.version-required' | translate }} + {{ 'ota-update.version-required' | translate }}
-
- - firmware.type - - - - {{ firmwareTypeTranslationMap.get(firmwareType) | translate }} - - - - - -
+ + + + ota-update.package-type + + + {{ otaUpdateTypeTranslationMap.get(packageType) | translate }} + + + +
ota-update.warning-after-save-no-edit
- firmware.checksum-algorithm - - + ota-update.checksum-algorithm + {{ checksumAlgorithmTranslationMap.get(checksumAlgorithm) }} - firmware.checksum + ota-update.checksum
-
+
+ dropLabel="{{'ota-update.drop-file' | translate}}">
- firmware.file-name + ota-update.file-name - firmware.file-size-bytes + ota-update.file-size-bytes - firmware.content-type + ota-update.content-type
- firmware.description + ota-update.description
diff --git a/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.ts b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.ts similarity index 74% rename from ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.ts rename to ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.ts index e2283a588f..fd4cd7ae27 100644 --- a/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.ts +++ b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update.component.ts @@ -25,29 +25,29 @@ import { EntityComponent } from '@home/components/entity/entity.component'; import { ChecksumAlgorithm, ChecksumAlgorithmTranslationMap, - Firmware, - FirmwareType, - FirmwareTypeTranslationMap -} from '@shared/models/firmware.models'; + OtaPackage, + OtaUpdateType, + OtaUpdateTypeTranslationMap +} from '@shared/models/ota-package.models'; import { ActionNotificationShow } from '@core/notification/notification.actions'; @Component({ - selector: 'tb-firmware', - templateUrl: './firmwares.component.html' + selector: 'tb-ota-update', + templateUrl: './ota-update.component.html' }) -export class FirmwaresComponent extends EntityComponent implements OnInit, OnDestroy { +export class OtaUpdateComponent extends EntityComponent implements OnInit, OnDestroy { private destroy$ = new Subject(); checksumAlgorithms = Object.values(ChecksumAlgorithm); checksumAlgorithmTranslationMap = ChecksumAlgorithmTranslationMap; - firmwareTypes = Object.values(FirmwareType); - firmwareTypeTranslationMap = FirmwareTypeTranslationMap; + packageTypes = Object.values(OtaUpdateType); + otaUpdateTypeTranslationMap = OtaUpdateTypeTranslationMap; constructor(protected store: Store, protected translate: TranslateService, - @Inject('entity') protected entityValue: Firmware, - @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig, + @Inject('entity') protected entityValue: OtaPackage, + @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig, public fb: FormBuilder) { super(store, fb, entityValue, entitiesTableConfigValue); } @@ -66,12 +66,12 @@ export class FirmwaresComponent extends EntityComponent implements OnI } } - buildForm(entity: Firmware): FormGroup { + buildForm(entity: OtaPackage): FormGroup { const form = this.fb.group({ title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]], version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]], - type: [entity?.type ? entity.type : FirmwareType.FIRMWARE, [Validators.required]], - deviceProfileId: [entity ? entity.deviceProfileId : null], + type: [entity?.type ? entity.type : OtaUpdateType.FIRMWARE, Validators.required], + deviceProfileId: [entity ? entity.deviceProfileId : null, Validators.required], checksumAlgorithm: [entity && entity.checksumAlgorithm ? entity.checksumAlgorithm : ChecksumAlgorithm.SHA256], checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)], additionalInfo: this.fb.group( @@ -90,7 +90,7 @@ export class FirmwaresComponent extends EntityComponent implements OnI return form; } - updateForm(entity: Firmware) { + updateForm(entity: OtaPackage) { this.entityForm.patchValue({ title: entity.title, version: entity.version, @@ -105,12 +105,18 @@ export class FirmwaresComponent extends EntityComponent implements OnI description: entity.additionalInfo ? entity.additionalInfo.description : '' } }); + if (!this.isAdd && this.entityForm.enabled) { + this.entityForm.disable({emitEvent: false}); + this.entityForm.get('additionalInfo').enable({emitEvent: false}); + // this.entityForm.get('dataSize').disable({emitEvent: false}); + // this.entityForm.get('contentType').disable({emitEvent: false}); + } } - onFirmwareIdCopied() { + onPackageIdCopied() { this.store.dispatch(new ActionNotificationShow( { - message: this.translate.instant('firmware.idCopiedMessage'), + message: this.translate.instant('ota-update.idCopiedMessage'), type: 'success', duration: 750, verticalPosition: 'bottom', @@ -118,10 +124,10 @@ export class FirmwaresComponent extends EntityComponent implements OnI })); } - onFirmwareChecksumCopied() { + onPackageChecksumCopied() { this.store.dispatch(new ActionNotificationShow( { - message: this.translate.instant('firmware.checksum-copied-message'), + message: this.translate.instant('ota-update.checksum-copied-message'), type: 'success', duration: 750, verticalPosition: 'bottom', diff --git a/ui-ngx/src/app/modules/home/pages/firmware/firmware.module.ts b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update.module.ts similarity index 79% rename from ui-ngx/src/app/modules/home/pages/firmware/firmware.module.ts rename to ui-ngx/src/app/modules/home/pages/ota-update/ota-update.module.ts index ab1b8343b2..58beef85ec 100644 --- a/ui-ngx/src/app/modules/home/pages/firmware/firmware.module.ts +++ b/ui-ngx/src/app/modules/home/pages/ota-update/ota-update.module.ts @@ -18,18 +18,18 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SharedModule } from '@shared/shared.module'; import { HomeComponentsModule } from '@home/components/home-components.module'; -import { FirmwareRoutingModule } from '@home/pages/firmware/firmware-routing.module'; -import { FirmwaresComponent } from '@home/pages/firmware/firmwares.component'; +import { OtaUpdateRoutingModule } from '@home/pages/ota-update/ota-update-routing.module'; +import { OtaUpdateComponent } from '@home/pages/ota-update/ota-update.component'; @NgModule({ declarations: [ - FirmwaresComponent + OtaUpdateComponent ], imports: [ CommonModule, SharedModule, HomeComponentsModule, - FirmwareRoutingModule + OtaUpdateRoutingModule ] }) -export class FirmwareModule { } +export class OtaUpdateModule { } diff --git a/ui-ngx/src/app/shared/components/firmware/firmware-autocomplete.component.html b/ui-ngx/src/app/shared/components/ota-package/ota-package-autocomplete.component.html similarity index 62% rename from ui-ngx/src/app/shared/components/firmware/firmware-autocomplete.component.html rename to ui-ngx/src/app/shared/components/ota-package/ota-package-autocomplete.component.html index 7bb434e7d1..51c291006d 100644 --- a/ui-ngx/src/app/shared/components/firmware/firmware-autocomplete.component.html +++ b/ui-ngx/src/app/shared/components/ota-package/ota-package-autocomplete.component.html @@ -15,40 +15,41 @@ limitations under the License. --> - + - - - + #packageAutocomplete="matAutocomplete" + [displayWith]="displayPackageFn"> + + - +
- {{ notFoundFirmware | translate }} + {{ notFoundPackage | translate }}
- {{ translate.get(notMatchingFirmware, + {{ translate.get(notMatchingPackage, {entity: truncate.transform(searchText, true, 6, '...')}) | async }}
- + {{ requiredErrorText | translate }} + {{ hintText | translate }}
diff --git a/ui-ngx/src/app/shared/components/firmware/firmware-autocomplete.component.ts b/ui-ngx/src/app/shared/components/ota-package/ota-package-autocomplete.component.ts similarity index 59% rename from ui-ngx/src/app/shared/components/firmware/firmware-autocomplete.component.ts rename to ui-ngx/src/app/shared/components/ota-package/ota-package-autocomplete.component.ts index a3aeafbd5e..25df909a8c 100644 --- a/ui-ngx/src/app/shared/components/firmware/firmware-autocomplete.component.ts +++ b/ui-ngx/src/app/shared/components/ota-package/ota-package-autocomplete.component.ts @@ -28,29 +28,29 @@ import { BaseData } from '@shared/models/base-data'; import { EntityService } from '@core/http/entity.service'; import { TruncatePipe } from '@shared/pipe/truncate.pipe'; import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; -import { FirmwareInfo, FirmwareType } from '@shared/models/firmware.models'; -import { FirmwareService } from '@core/http/firmware.service'; +import { OtaPackageInfo, OtaUpdateTranslation, OtaUpdateType } from '@shared/models/ota-package.models'; +import { OtaPackageService } from '@core/http/ota-package.service'; import { PageLink } from '@shared/models/page/page-link'; import { Direction } from '@shared/models/page/sort-order'; @Component({ - selector: 'tb-firmware-autocomplete', - templateUrl: './firmware-autocomplete.component.html', + selector: 'tb-ota-package-autocomplete', + templateUrl: './ota-package-autocomplete.component.html', styleUrls: [], providers: [{ provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => FirmwareAutocompleteComponent), + useExisting: forwardRef(() => OtaPackageAutocompleteComponent), multi: true }] }) -export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnInit { +export class OtaPackageAutocompleteComponent implements ControlValueAccessor, OnInit { - firmwareFormGroup: FormGroup; + otaPackageFormGroup: FormGroup; modelValue: string | EntityId | null; @Input() - type = FirmwareType.FIRMWARE; + type = OtaUpdateType.FIRMWARE; @Input() deviceProfileId: string; @@ -78,42 +78,24 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn @Input() disabled: boolean; - @ViewChild('firmwareInput', {static: true}) firmwareInput: ElementRef; - @ViewChild('firmwareInput', {read: MatAutocompleteTrigger}) firmwareAutocomplete: MatAutocompleteTrigger; + @ViewChild('packageInput', {static: true}) packageInput: ElementRef; - filteredFirmwares: Observable>; + filteredPackages: Observable>; searchText = ''; private dirty = false; - private firmwareTypeTranslation = new Map( - [ - [FirmwareType.FIRMWARE, { - label: 'firmware.firmware', - required: 'firmware.firmware-required', - noFound: 'firmware.no-firmware-text', - noMatching: 'firmware.no-firmware-matching' - }], - [FirmwareType.SOFTWARE, { - label: 'firmware.software', - required: 'firmware.software-required', - noFound: 'firmware.no-software-text', - noMatching: 'firmware.no-software-matching' - }] - ] - ); - private propagateChange = (v: any) => { }; constructor(private store: Store, public translate: TranslateService, public truncate: TruncatePipe, private entityService: EntityService, - private firmwareService: FirmwareService, + private otaPackageService: OtaPackageService, private fb: FormBuilder) { - this.firmwareFormGroup = this.fb.group({ - firmwareId: [null] + this.otaPackageFormGroup = this.fb.group({ + packageId: [null] }); } @@ -125,7 +107,7 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn } ngOnInit() { - this.filteredFirmwares = this.firmwareFormGroup.get('firmwareId').valueChanges + this.filteredPackages = this.otaPackageFormGroup.get('packageId').valueChanges .pipe( tap(value => { let modelValue; @@ -140,7 +122,7 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn } }), map(value => value ? (typeof value === 'string' ? value : value.title) : ''), - mergeMap(name => this.fetchFirmware(name)), + mergeMap(name => this.fetchPackages(name)), share() ); } @@ -149,7 +131,7 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn } getCurrentEntity(): BaseData | null { - const currentRuleChain = this.firmwareFormGroup.get('firmwareId').value; + const currentRuleChain = this.otaPackageFormGroup.get('packageId').value; if (currentRuleChain && typeof currentRuleChain !== 'string') { return currentRuleChain as BaseData; } else { @@ -160,9 +142,9 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; if (this.disabled) { - this.firmwareFormGroup.disable({emitEvent: false}); + this.otaPackageFormGroup.disable({emitEvent: false}); } else { - this.firmwareFormGroup.enable({emitEvent: false}); + this.otaPackageFormGroup.enable({emitEvent: false}); } } @@ -173,21 +155,21 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn writeValue(value: string | EntityId | null): void { this.searchText = ''; if (value != null && value !== '') { - let firmwareId = ''; + let packageId = ''; if (typeof value === 'string') { - firmwareId = value; + packageId = value; } else if (value.entityType && value.id) { - firmwareId = value.id; + packageId = value.id; } - if (firmwareId !== '') { - this.entityService.getEntity(EntityType.FIRMWARE, firmwareId, {ignoreLoading: true, ignoreErrors: true}).subscribe( + if (packageId !== '') { + this.entityService.getEntity(EntityType.OTA_PACKAGE, packageId, {ignoreLoading: true, ignoreErrors: true}).subscribe( (entity) => { this.modelValue = this.useFullEntityId ? entity.id : entity.id.id; - this.firmwareFormGroup.get('firmwareId').patchValue(entity, {emitEvent: false}); + this.otaPackageFormGroup.get('packageId').patchValue(entity, {emitEvent: false}); }, () => { this.modelValue = null; - this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: false}); + this.otaPackageFormGroup.get('packageId').patchValue('', {emitEvent: false}); if (value !== null) { this.propagateChange(this.modelValue); } @@ -195,25 +177,25 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn ); } else { this.modelValue = null; - this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: false}); + this.otaPackageFormGroup.get('packageId').patchValue('', {emitEvent: false}); this.propagateChange(null); } } else { this.modelValue = null; - this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: false}); + this.otaPackageFormGroup.get('packageId').patchValue('', {emitEvent: false}); } this.dirty = true; } onFocus() { if (this.dirty) { - this.firmwareFormGroup.get('firmwareId').updateValueAndValidity({onlySelf: true, emitEvent: true}); + this.otaPackageFormGroup.get('packageId').updateValueAndValidity({onlySelf: true, emitEvent: true}); this.dirty = false; } } reset() { - this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: false}); + this.otaPackageFormGroup.get('packageId').patchValue('', {emitEvent: false}); } updateView(value: string | null) { @@ -223,47 +205,51 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn } } - displayFirmwareFn(firmware?: FirmwareInfo): string | undefined { - return firmware ? `${firmware.title} (${firmware.version})` : undefined; + displayPackageFn(packageInfo?: OtaPackageInfo): string | undefined { + return packageInfo ? `${packageInfo.title} (${packageInfo.version})` : undefined; } - fetchFirmware(searchText?: string): Observable> { + fetchPackages(searchText?: string): Observable> { this.searchText = searchText; const pageLink = new PageLink(50, 0, searchText, { property: 'title', direction: Direction.ASC }); - return this.firmwareService.getFirmwaresInfoByDeviceProfileId(pageLink, this.deviceProfileId, this.type, + return this.otaPackageService.getOtaPackagesInfoByDeviceProfileId(pageLink, this.deviceProfileId, this.type, true, {ignoreLoading: true}).pipe( map((data) => data && data.data.length ? data.data : null) ); } clear() { - this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: true}); + this.otaPackageFormGroup.get('packageId').patchValue('', {emitEvent: true}); setTimeout(() => { - this.firmwareInput.nativeElement.blur(); - this.firmwareInput.nativeElement.focus(); + this.packageInput.nativeElement.blur(); + this.packageInput.nativeElement.focus(); }, 0); } get placeholderText(): string { - return this.labelText || this.firmwareTypeTranslation.get(this.type).label; + return this.labelText || OtaUpdateTranslation.get(this.type).label; } get requiredErrorText(): string { - return this.requiredText || this.firmwareTypeTranslation.get(this.type).required; + return this.requiredText || OtaUpdateTranslation.get(this.type).required; + } + + get notFoundPackage(): string { + return OtaUpdateTranslation.get(this.type).noFound; } - get notFoundFirmware(): string { - return this.firmwareTypeTranslation.get(this.type).noFound; + get notMatchingPackage(): string { + return OtaUpdateTranslation.get(this.type).noMatching; } - get notMatchingFirmware(): string { - return this.firmwareTypeTranslation.get(this.type).noMatching; + get hintText(): string { + return OtaUpdateTranslation.get(this.type).hint; } - firmwareTitleText(firmware: FirmwareInfo): string { - return `${firmware.title} (${firmware.version})`; + packageTitleText(firpackageInfomware: OtaPackageInfo): string { + return `${firpackageInfomware.title} (${firpackageInfomware.version})`; } } diff --git a/ui-ngx/src/app/shared/models/constants.ts b/ui-ngx/src/app/shared/models/constants.ts index 44327e1c2c..b72e2b196d 100644 --- a/ui-ngx/src/app/shared/models/constants.ts +++ b/ui-ngx/src/app/shared/models/constants.ts @@ -121,6 +121,7 @@ export const HelpLinks = { entitiesImport: helpBaseUrl + '/docs/user-guide/bulk-provisioning', rulechains: helpBaseUrl + '/docs/user-guide/ui/rule-chains', dashboards: helpBaseUrl + '/docs/user-guide/ui/dashboards', + otaUpdates: helpBaseUrl + '/docs/user-guide/ui/ota-updates', widgetsBundles: helpBaseUrl + '/docs/user-guide/ui/widget-library#bundles', widgetsConfig: helpBaseUrl + '/docs/user-guide/ui/dashboards#widget-configuration', widgetsConfigTimeseries: helpBaseUrl + '/docs/user-guide/ui/dashboards#timeseries', diff --git a/ui-ngx/src/app/shared/models/device.models.ts b/ui-ngx/src/app/shared/models/device.models.ts index fe7868d584..9b13c4dc72 100644 --- a/ui-ngx/src/app/shared/models/device.models.ts +++ b/ui-ngx/src/app/shared/models/device.models.ts @@ -27,7 +27,7 @@ import { KeyFilter } from '@shared/models/query/query.models'; import { TimeUnit } from '@shared/models/time/time.models'; import * as _moment from 'moment'; import { AbstractControl, ValidationErrors } from '@angular/forms'; -import { FirmwareId } from '@shared/models/id/firmware-id'; +import { OtaPackageId } from '@shared/models/id/ota-package-id'; import { DashboardId } from '@shared/models/id/dashboard-id'; export enum DeviceProfileType { @@ -500,8 +500,8 @@ export interface DeviceProfile extends BaseData { defaultRuleChainId?: RuleChainId; defaultDashboardId?: DashboardId; defaultQueueName?: string; - firmwareId?: FirmwareId; - softwareId?: FirmwareId; + firmwareId?: OtaPackageId; + softwareId?: OtaPackageId; profileData: DeviceProfileData; } @@ -563,8 +563,8 @@ export interface Device extends BaseData { name: string; type: string; label: string; - firmwareId?: FirmwareId; - softwareId?: FirmwareId; + firmwareId?: OtaPackageId; + softwareId?: OtaPackageId; deviceProfileId?: DeviceProfileId; deviceData?: DeviceData; additionalInfo?: any; diff --git a/ui-ngx/src/app/shared/models/entity-type.models.ts b/ui-ngx/src/app/shared/models/entity-type.models.ts index ae2382e0ea..d088cbc88a 100644 --- a/ui-ngx/src/app/shared/models/entity-type.models.ts +++ b/ui-ngx/src/app/shared/models/entity-type.models.ts @@ -35,7 +35,7 @@ export enum EntityType { WIDGET_TYPE = 'WIDGET_TYPE', API_USAGE_STATE = 'API_USAGE_STATE', TB_RESOURCE = 'TB_RESOURCE', - FIRMWARE = 'FIRMWARE' + OTA_PACKAGE = 'OTA_PACKAGE' } export enum AliasEntityType { @@ -296,14 +296,14 @@ export const entityTypeTranslations = new Map( +export const OtaUpdateTypeTranslationMap = new Map( [ - [FirmwareType.FIRMWARE, 'firmware.types.firmware'], - [FirmwareType.SOFTWARE, 'firmware.types.software'] + [OtaUpdateType.FIRMWARE, 'ota-update.types.firmware'], + [OtaUpdateType.SOFTWARE, 'ota-update.types.software'] ] ); -export interface FirmwareInfo extends BaseData { +export interface OtaUpdateTranslation { + label: string; + required: string; + noFound: string; + noMatching: string; + hint: string; +} + +export const OtaUpdateTranslation = new Map( + [ + [OtaUpdateType.FIRMWARE, { + label: 'ota-update.assign-firmware', + required: 'ota-update.assign-firmware-required', + noFound: 'ota-update.no-firmware-text', + noMatching: 'ota-update.no-firmware-matching', + hint: 'ota-update.chose-firmware-distributed-device' + }], + [OtaUpdateType.SOFTWARE, { + label: 'ota-update.assign-software', + required: 'ota-update.assign-software-required', + noFound: 'ota-update.no-software-text', + noMatching: 'ota-update.no-software-matching', + hint: 'ota-update.chose-software-distributed-device' + }] + ] +); + +export interface OtaPackageInfo extends BaseData { tenantId?: TenantId; - type: FirmwareType; + type: OtaUpdateType; deviceProfileId?: DeviceProfileId; title?: string; version?: string; @@ -68,7 +95,7 @@ export interface FirmwareInfo extends BaseData { additionalInfo?: any; } -export interface Firmware extends FirmwareInfo { +export interface OtaPackage extends OtaPackageInfo { file?: File; data: string; } diff --git a/ui-ngx/src/app/shared/shared.module.ts b/ui-ngx/src/app/shared/shared.module.ts index 925b297e77..5e71d4c44a 100644 --- a/ui-ngx/src/app/shared/shared.module.ts +++ b/ui-ngx/src/app/shared/shared.module.ts @@ -141,7 +141,7 @@ import { FileSizePipe } from '@shared/pipe/file-size.pipe'; import { WidgetsBundleSearchComponent } from '@shared/components/widgets-bundle-search.component'; import { SelectableColumnsPipe } from '@shared/pipe/selectable-columns.pipe'; import { QuickTimeIntervalComponent } from '@shared/components/time/quick-time-interval.component'; -import { FirmwareAutocompleteComponent } from '@shared/components/firmware/firmware-autocomplete.component'; +import { OtaPackageAutocompleteComponent } from '@shared/components/ota-package/ota-package-autocomplete.component'; import { MAT_DATE_LOCALE } from '@angular/material/core'; @NgModule({ @@ -239,7 +239,7 @@ import { MAT_DATE_LOCALE } from '@angular/material/core'; HistorySelectorComponent, EntityGatewaySelectComponent, ContactComponent, - FirmwareAutocompleteComponent, + OtaPackageAutocompleteComponent, WidgetsBundleSearchComponent ], imports: [ @@ -411,7 +411,7 @@ import { MAT_DATE_LOCALE } from '@angular/material/core'; HistorySelectorComponent, EntityGatewaySelectComponent, ContactComponent, - FirmwareAutocompleteComponent, + OtaPackageAutocompleteComponent, WidgetsBundleSearchComponent ] }) diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index c04da7b2e7..204abf4f8c 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1516,7 +1516,7 @@ "list-of-edges": "{ count, plural, 1 {One edge} other {List of # edges} }", "edge-name-starts-with": "Edges whose names start with '{{prefix}}'", "type-tb-resource": "Resource", - "type-firmware": "Firmware" + "type-ota-package": "OTA package" }, "entity-field": { "created-time": "Created time", @@ -1927,51 +1927,6 @@ "inherit-owner": "Inherit from owner", "source-attribute-not-set": "If source attribute isn't set" }, - "firmware": { - "add": "Add firmware", - "checksum": "Checksum", - "checksum-copied-message": "Firmware checksum has been copied to clipboard", - "checksum-required": "Checksum is required.", - "checksum-algorithm": "Checksum algorithm", - "content-type": "Content type", - "copy-checksum": "Copy checksum", - "copyId": "Copy firmware Id", - "description": "Description", - "delete": "Delete firmware", - "delete-firmware-text": "Be careful, after the confirmation the firmware will become unrecoverable.", - "delete-firmware-title": "Are you sure you want to delete the firmware '{{firmwareTitle}}'?", - "delete-firmwares-action-title": "Delete { count, plural, 1 {1 firmware} other {# firmwares} }", - "delete-firmwares-text": "Be careful, after the confirmation all selected resources will be removed.", - "delete-firmwares-title": "Are you sure you want to delete { count, plural, 1 {1 firmware} other {# firmwares} }?", - "download": "Download firmware", - "drop-file": "Drop a firmware file or click to select a file to upload.", - "empty": "Firmware is empty", - "idCopiedMessage": "Firmware Id has been copied to clipboard", - "no-firmware-matching": "No firmware matching '{{entity}}' were found.", - "no-firmware-text": "No firmwares found", - "no-software-matching": "No sowtware matching '{{entity}}' were found.", - "no-software-text": "No software found", - "file-name": "File name", - "file-size": "File size", - "file-size-bytes": "File size in bytes", - "firmware": "Firmware", - "firmware-details": "Firmware details", - "firmware-required": "Firmware is required.", - "search": "Search firmwares", - "selected-firmware": "{ count, plural, 1 {1 firmware} other {# firmwares} } selected", - "software": "Software", - "software-required": "Software is required.", - "title": "Title", - "title-required": "Title is required.", - "type": "Firmware type", - "types": { - "firmware": "Firmware", - "software": "Software" - }, - "version": "Version", - "version-required": "Version is required.", - "warning-after-save-no-edit": "Once the firmware is saved, it will not be possible to change the title and version fields." - }, "fullscreen": { "expand": "Expand to fullscreen", "exit": "Exit fullscreen", @@ -2191,6 +2146,55 @@ "or": "or", "error": "Login error" }, + "ota-update": { + "add": "Add package", + "assign-firmware": "Assigned firmware", + "assign-firmware-required": "Assigned firmware is required", + "assign-software": "Assigned software", + "assign-software-required": "Assigned software is required", + "checksum": "Checksum", + "checksum-algorithm": "Checksum algorithm", + "checksum-copied-message": "Package checksum has been copied to clipboard", + "chose-compatible-device-profile": "Choose compatible device profile", + "chose-firmware-distributed-device": "Choose firmware that will be distributed to the devices", + "chose-software-distributed-device": "Choose software that will be distributed to the devices", + "content-type": "Content type", + "copy-checksum": "Copy checksum", + "copyId": "Copy package Id", + "idCopiedMessage": "Package Id has been copied to clipboard", + "description": "Description", + "delete": "Delete package", + "delete-ota-update-text": "Be careful, after the confirmation the OTA update will become unrecoverable.", + "delete-ota-update-title": "Are you sure you want to delete the OTA update '{{title}}'?", + "delete-ota-updates-text": "Be careful, after the confirmation all selected OTA updates will be removed.", + "delete-ota-updates-title": "Are you sure you want to delete { count, plural, 1 {1 OTA update} other {# OTA updates} }?", + "drop-file": "Drop a package file or click to select a file to upload.", + "download": "Download package", + "file-name": "File name", + "file-size": "File size", + "file-size-bytes": "File size in bytes", + "no-packages-text": "No packages found", + "no-firmware-text": "No compatible Firmware OTA Update packages provisioned.", + "no-firmware-matching": "No compatible Firmware OTA Update packages matching '{{entity}}' were found.", + "no-software-text": "No compatible Software OTA Update packages provisioned.", + "no-software-matching": "No compatible Software OTA Update packages matching '{{entity}}' were found.", + "search": "Search packages", + "selected-package": "{ count, plural, 1 {1 package} other {# packages} } selected", + "ota-update": "OTA update", + "ota-update-details": "OTA update details", + "ota-updates": "OTA updates", + "package-type": "Package type", + "packages-repository": "Packages repository", + "title": "Title", + "title-required": "Title is required.", + "types": { + "firmware": "Firmware", + "software": "Software" + }, + "version": "Version", + "version-required": "Version is required.", + "warning-after-save-no-edit": "Once the package is uploaded, you will not be able to modify title, version, device profile and package type." + }, "position": { "top": "Top", "bottom": "Bottom", From 078fdce491514d6fc38c18bd9b36c8f28d958e3f Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 31 May 2021 19:50:39 +0300 Subject: [PATCH 03/19] firmware dashboard improvements --- .../data/json/demo/dashboards/firmware.json | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/application/src/main/data/json/demo/dashboards/firmware.json b/application/src/main/data/json/demo/dashboards/firmware.json index 6e8d18cd98..4711e34702 100644 --- a/application/src/main/data/json/demo/dashboards/firmware.json +++ b/application/src/main/data/json/demo/dashboards/firmware.json @@ -1,5 +1,6 @@ { "title": "Firmware", + "image": null, "configuration": { "description": "", "widgets": { @@ -247,7 +248,7 @@ "name": "Edit firmware", "icon": "edit", "type": "customPretty", - "customHtml": "\n \n

Edit firmware {{entityName}}

\n \n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n", + "customHtml": "
\n \n

Edit firmware {{entityName}}

\n \n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
", "customCss": "", "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}", "customResources": [], @@ -257,7 +258,7 @@ "name": "Download firware", "icon": "file_download", "type": "custom", - "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet firmwareService = $injector.get(widgetContext.servicesMap.get('firmwareService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n firmwareService.downloadFirmware(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n firmwareService.downloadFirmware(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", "id": "12533058-42f6-e75f-620c-219c48d01ec0" }, { @@ -1021,7 +1022,7 @@ "name": "Edit firmware", "icon": "edit", "type": "customPretty", - "customHtml": "
\n \n

Edit firmware {{entityName}}

\n \n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
", + "customHtml": "
\n \n

Edit firmware {{entityName}}

\n \n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
", "customCss": "", "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}", "customResources": [], @@ -1031,7 +1032,7 @@ "name": "Download firware", "icon": "file_download", "type": "custom", - "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet firmwareService = $injector.get(widgetContext.servicesMap.get('firmwareService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n firmwareService.downloadFirmware(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n firmwareService.downloadFirmware(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", "id": "12533058-42f6-e75f-620c-219c48d01ec0" }, { @@ -1297,7 +1298,7 @@ "name": "Edit firmware", "icon": "edit", "type": "customPretty", - "customHtml": "
\n \n

Edit firmware {{entityName}}

\n \n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
", + "customHtml": "
\n \n

Edit firmware {{entityName}}

\n \n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
", "customCss": "", "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}", "customResources": [], @@ -1307,7 +1308,7 @@ "name": "Download firware", "icon": "file_download", "type": "custom", - "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet firmwareService = $injector.get(widgetContext.servicesMap.get('firmwareService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n firmwareService.downloadFirmware(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n firmwareService.downloadFirmware(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", "id": "12533058-42f6-e75f-620c-219c48d01ec0" }, { @@ -1573,7 +1574,7 @@ "name": "Edit firmware", "icon": "edit", "type": "customPretty", - "customHtml": "
\n \n

Edit firmware {{entityName}}

\n \n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
", + "customHtml": "
\n \n

Edit firmware {{entityName}}

\n \n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
", "customCss": "", "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}", "customResources": [], @@ -1583,7 +1584,7 @@ "name": "Download firware", "icon": "file_download", "type": "custom", - "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet firmwareService = $injector.get(widgetContext.servicesMap.get('firmwareService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n firmwareService.downloadFirmware(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n firmwareService.downloadFirmware(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", "id": "12533058-42f6-e75f-620c-219c48d01ec0" }, { @@ -1849,7 +1850,7 @@ "name": "Edit firmware", "icon": "edit", "type": "customPretty", - "customHtml": "
\n \n

Edit firmware {{entityName}}

\n \n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
", + "customHtml": "
\n \n

Edit firmware {{entityName}}

\n \n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
", "customCss": "", "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}", "customResources": [], @@ -1859,7 +1860,7 @@ "name": "Download firware", "icon": "file_download", "type": "custom", - "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet firmwareService = $injector.get(widgetContext.servicesMap.get('firmwareService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n firmwareService.downloadFirmware(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n firmwareService.downloadFirmware(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", "id": "12533058-42f6-e75f-620c-219c48d01ec0" }, { From 7da03c1b50d07e314a58b936574a988abb633907 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 1 Jun 2021 10:52:28 +0300 Subject: [PATCH 04/19] remove transaction from TbLwM2mRedisRegistrationStore --- .../lwm2m/server/DefaultLwM2MTransportMsgHandler.java | 1 - .../server/store/TbLwM2mRedisRegistrationStore.java | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index abe2a50855..2ae1be66f3 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -247,7 +247,6 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler * @param observations - !!! Warn: if have not finishing unReg, then this operation will be finished on next Client`s connect */ public void unReg(Registration registration, Collection observations) { - log.error("Client unRegistration -> test", new RuntimeException()); unRegistrationExecutor.submit(() -> { try { this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId()); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java index 973124b4e9..365b92bf66 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java @@ -337,23 +337,24 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto } } + //TODO: JedisCluster didn't implement Transaction, maybe should use some advanced key creation strategies private void removeAddrIndex(RedisConnection connection, Registration registration) { // Watch the key to remove. byte[] regAddrKey = toRegAddrKey(registration.getSocketAddress()); - connection.watch(regAddrKey); +// connection.watch(regAddrKey); byte[] epFromAddr = connection.get(regAddrKey); // Delete the key if needed. if (Arrays.equals(epFromAddr, registration.getEndpoint().getBytes(UTF_8))) { // Try to delete the key - connection.multi(); +// connection.multi(); connection.del(regAddrKey); - connection.exec(); +// connection.exec(); // if transaction failed this is not an issue as the socket address is probably reused and we don't neeed to // delete it anymore. } else { // the key must not be deleted. - connection.unwatch(); +// connection.unwatch(); } } From e0f04091b89d5ee2490df2ee773f331e6fee578b Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Tue, 1 Jun 2021 11:36:25 +0300 Subject: [PATCH 05/19] UI: Change order translate ota-package --- .../src/assets/locale/locale.constant-en_US.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 204abf4f8c..6966888ea3 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2161,30 +2161,30 @@ "content-type": "Content type", "copy-checksum": "Copy checksum", "copyId": "Copy package Id", - "idCopiedMessage": "Package Id has been copied to clipboard", - "description": "Description", "delete": "Delete package", "delete-ota-update-text": "Be careful, after the confirmation the OTA update will become unrecoverable.", "delete-ota-update-title": "Are you sure you want to delete the OTA update '{{title}}'?", "delete-ota-updates-text": "Be careful, after the confirmation all selected OTA updates will be removed.", "delete-ota-updates-title": "Are you sure you want to delete { count, plural, 1 {1 OTA update} other {# OTA updates} }?", - "drop-file": "Drop a package file or click to select a file to upload.", + "description": "Description", "download": "Download package", + "drop-file": "Drop a package file or click to select a file to upload.", "file-name": "File name", "file-size": "File size", "file-size-bytes": "File size in bytes", - "no-packages-text": "No packages found", - "no-firmware-text": "No compatible Firmware OTA Update packages provisioned.", + "idCopiedMessage": "Package Id has been copied to clipboard", "no-firmware-matching": "No compatible Firmware OTA Update packages matching '{{entity}}' were found.", - "no-software-text": "No compatible Software OTA Update packages provisioned.", + "no-firmware-text": "No compatible Firmware OTA Update packages provisioned.", + "no-packages-text": "No packages found", "no-software-matching": "No compatible Software OTA Update packages matching '{{entity}}' were found.", - "search": "Search packages", - "selected-package": "{ count, plural, 1 {1 package} other {# packages} } selected", + "no-software-text": "No compatible Software OTA Update packages provisioned.", "ota-update": "OTA update", "ota-update-details": "OTA update details", "ota-updates": "OTA updates", "package-type": "Package type", "packages-repository": "Packages repository", + "search": "Search packages", + "selected-package": "{ count, plural, 1 {1 package} other {# packages} } selected", "title": "Title", "title-required": "Title is required.", "types": { From 51d14efe6ac36e4c531d5b86ba82633435333d75 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Wed, 2 Jun 2021 11:40:20 +0300 Subject: [PATCH 06/19] fixed OtaPackage data cache --- .../server/controller/DeviceController.java | 8 ++-- .../src/main/resources/thingsboard.yml | 3 ++ .../cache/ota/CaffeineOtaPackageCache.java | 7 +-- .../cache/ota/RedisOtaPackageDataCache.java | 3 +- .../server/common/data/CacheConstants.java | 1 + .../server/dao/ota/BaseOtaPackageService.java | 15 ++----- .../service/BaseOtaPackageServiceTest.java | 44 +------------------ .../resources/application-test.properties | 3 ++ 8 files changed, 23 insertions(+), 61 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index 90094e88c1..b13393515c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -782,15 +782,15 @@ public class DeviceController extends BaseController { } @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/devices/count", method = RequestMethod.GET) + @RequestMapping(value = "/devices/count/{otaPackageType}", method = RequestMethod.GET) @ResponseBody - public Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(@RequestParam(required = false) String otaPackageType, - @RequestParam(required = false) String deviceProfileId) throws ThingsboardException { + public Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(@PathVariable("otaPackageType") String otaPackageType, + @RequestParam String deviceProfileId) throws ThingsboardException { checkParameter("OtaPackageType", otaPackageType); checkParameter("DeviceProfileId", deviceProfileId); try { return deviceService.countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage( - getCurrentUser().getTenantId(), new DeviceProfileId(UUID.fromString(deviceProfileId)), OtaPackageType.valueOf(deviceProfileId)); + getCurrentUser().getTenantId(), new DeviceProfileId(UUID.fromString(deviceProfileId)), OtaPackageType.valueOf(otaPackageType)); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index ae628bf9f6..de1f3cd3af 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -374,6 +374,9 @@ caffeine: otaPackages: timeToLiveInMinutes: 60 maxSize: 10 + otaPackagesData: + timeToLiveInMinutes: 60 + maxSize: 10 edges: timeToLiveInMinutes: 1440 maxSize: 0 diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java index a864fc6dba..8b1f0804f3 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java @@ -21,6 +21,7 @@ import org.springframework.cache.CacheManager; import org.springframework.stereotype.Service; import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_CACHE; +import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_DATA_CACHE; @Service @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "caffeine", matchIfMissing = true) @@ -36,7 +37,7 @@ public class CaffeineOtaPackageCache implements OtaPackageDataCache { @Override public byte[] get(String key, int chunkSize, int chunk) { - byte[] data = cacheManager.getCache(OTA_PACKAGE_CACHE).get(key, byte[].class); + byte[] data = cacheManager.getCache(OTA_PACKAGE_DATA_CACHE).get(key, byte[].class); if (chunkSize < 1) { return data; @@ -58,11 +59,11 @@ public class CaffeineOtaPackageCache implements OtaPackageDataCache { @Override public void put(String key, byte[] value) { - cacheManager.getCache(OTA_PACKAGE_CACHE).putIfAbsent(key, value); + cacheManager.getCache(OTA_PACKAGE_DATA_CACHE).putIfAbsent(key, value); } @Override public void evict(String key) { - cacheManager.getCache(OTA_PACKAGE_CACHE).evict(key); + cacheManager.getCache(OTA_PACKAGE_DATA_CACHE).evict(key); } } diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java index 1e4ae53829..c2c3bc34a8 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java @@ -22,6 +22,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.stereotype.Service; import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_CACHE; +import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_DATA_CACHE; @Service @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") @@ -63,6 +64,6 @@ public class RedisOtaPackageDataCache implements OtaPackageDataCache { } private byte[] toOtaPackageCacheKey(String key) { - return String.format("%s::%s", OTA_PACKAGE_CACHE, key).getBytes(); + return String.format("%s::%s", OTA_PACKAGE_DATA_CACHE, key).getBytes(); } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java index 3cc3f56737..ced7a64a0f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java @@ -30,4 +30,5 @@ public class CacheConstants { public static final String ATTRIBUTES_CACHE = "attributes"; public static final String TOKEN_OUTDATAGE_TIME_CACHE = "tokensOutdatageTime"; public static final String OTA_PACKAGE_CACHE = "otaPackages"; + public static final String OTA_PACKAGE_DATA_CACHE = "otaPackagesData"; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java index ae19576861..536c79843a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java @@ -221,8 +221,6 @@ public class BaseOtaPackageService implements OtaPackageService { @Override protected void validateUpdate(TenantId tenantId, OtaPackageInfo otaPackage) { OtaPackageInfo otaPackageOld = otaPackageInfoDao.findById(tenantId, otaPackage.getUuidId()); - - validateUpdateDeviceProfile(otaPackage, otaPackageOld); BaseOtaPackageService.validateUpdate(otaPackage, otaPackageOld); } }; @@ -261,7 +259,6 @@ public class BaseOtaPackageService implements OtaPackageService { protected void validateUpdate(TenantId tenantId, OtaPackage otaPackage) { OtaPackage otaPackageOld = otaPackageDao.findById(tenantId, otaPackage.getUuidId()); - validateUpdateDeviceProfile(otaPackage, otaPackageOld); BaseOtaPackageService.validateUpdate(otaPackage, otaPackageOld); if (otaPackageOld.getData() != null && !otaPackageOld.getData().equals(otaPackage.getData())) { @@ -270,14 +267,6 @@ public class BaseOtaPackageService implements OtaPackageService { } }; - private void validateUpdateDeviceProfile(OtaPackageInfo otaPackage, OtaPackageInfo otaPackageOld) { - if (otaPackageOld.getDeviceProfileId() != null && !otaPackageOld.getDeviceProfileId().equals(otaPackage.getDeviceProfileId())) { - if (otaPackageInfoDao.isOtaPackageUsed(otaPackageOld.getId(), otaPackage.getType(), otaPackageOld.getDeviceProfileId())) { - throw new DataValidationException("Can`t update deviceProfileId because otaPackage is already in use!"); - } - } - } - private static void validateUpdate(OtaPackageInfo otaPackage, OtaPackageInfo otaPackageOld) { if (!otaPackageOld.getType().equals(otaPackage.getType())) { throw new DataValidationException("Updating type is prohibited!"); @@ -291,6 +280,10 @@ public class BaseOtaPackageService implements OtaPackageService { throw new DataValidationException("Updating otaPackage version is prohibited!"); } + if (!otaPackageOld.getDeviceProfileId().equals(otaPackage.getDeviceProfileId())) { + throw new DataValidationException("Updating otaPackage deviceProfile is prohibited!"); + } + if (otaPackageOld.getFileName() != null && !otaPackageOld.getFileName().equals(otaPackage.getFileName())) { throw new DataValidationException("Updating otaPackage file name is prohibited!"); } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseOtaPackageServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseOtaPackageServiceTest.java index e7cee8c878..ab895e1052 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseOtaPackageServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseOtaPackageServiceTest.java @@ -408,7 +408,7 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest { } @Test - public void testUpdateDeviceProfileIdWithReferenceByDevice() { + public void testUpdateDeviceProfileId() { OtaPackage firmware = new OtaPackage(); firmware.setTenantId(tenantId); firmware.setDeviceProfileId(deviceProfileId); @@ -422,20 +422,12 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest { firmware.setData(DATA); OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); - Device device = new Device(); - device.setTenantId(tenantId); - device.setName("My device"); - device.setDeviceProfileId(deviceProfileId); - device.setFirmwareId(savedFirmware.getId()); - Device savedDevice = deviceService.saveDevice(device); - try { thrown.expect(DataValidationException.class); - thrown.expectMessage("Can`t update deviceProfileId because otaPackage is already in use!"); + thrown.expectMessage("Updating otaPackage deviceProfile is prohibited!"); savedFirmware.setDeviceProfileId(null); otaPackageService.saveOtaPackage(savedFirmware); } finally { - deviceService.deleteDevice(tenantId, savedDevice.getId()); otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); } } @@ -471,38 +463,6 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest { } } - @Test - public void testUpdateDeviceProfileIdWithReferenceByDeviceProfile() { - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Test Device Profile"); - DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); - - OtaPackage firmware = new OtaPackage(); - firmware.setTenantId(tenantId); - firmware.setDeviceProfileId(savedDeviceProfile.getId()); - firmware.setType(FIRMWARE); - firmware.setTitle(TITLE); - firmware.setVersion(VERSION); - firmware.setFileName(FILE_NAME); - firmware.setContentType(CONTENT_TYPE); - firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); - firmware.setChecksum(CHECKSUM); - firmware.setData(DATA); - OtaPackage savedFirmware = otaPackageService.saveOtaPackage(firmware); - - savedDeviceProfile.setFirmwareId(savedFirmware.getId()); - deviceProfileService.saveDeviceProfile(savedDeviceProfile); - - try { - thrown.expect(DataValidationException.class); - thrown.expectMessage("Can`t update deviceProfileId because otaPackage is already in use!"); - savedFirmware.setDeviceProfileId(null); - otaPackageService.saveOtaPackage(savedFirmware); - } finally { - deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); - otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId()); - } - } - @Test public void testFindFirmwareById() { OtaPackage firmware = new OtaPackage(); diff --git a/dao/src/test/resources/application-test.properties b/dao/src/test/resources/application-test.properties index 74eb4f43f0..d7a960471b 100644 --- a/dao/src/test/resources/application-test.properties +++ b/dao/src/test/resources/application-test.properties @@ -39,6 +39,9 @@ caffeine.specs.deviceProfiles.maxSize=100000 caffeine.specs.otaPackages.timeToLiveInMinutes=1440 caffeine.specs.otaPackages.maxSize=100000 +caffeine.specs.otaPackagesData.timeToLiveInMinutes=1440 +caffeine.specs.otaPackagesData.maxSize=100000 + caffeine.specs.edges.timeToLiveInMinutes=1440 caffeine.specs.edges.maxSize=100000 From 98801038fdd054f3951487035d933b26626b15a4 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 2 Jun 2021 11:42:56 +0300 Subject: [PATCH 07/19] UI: Rename 'Add credential' to 'Add credentials' --- .../home/components/wizard/device-wizard-dialog.component.html | 2 +- ui-ngx/src/assets/locale/locale.constant-cs_CZ.json | 2 +- ui-ngx/src/assets/locale/locale.constant-en_US.json | 2 +- ui-ngx/src/assets/locale/locale.constant-es_ES.json | 2 +- ui-ngx/src/assets/locale/locale.constant-ko_KR.json | 2 +- ui-ngx/src/assets/locale/locale.constant-sl_SI.json | 2 +- ui-ngx/src/assets/locale/locale.constant-zh_CN.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/wizard/device-wizard-dialog.component.html b/ui-ngx/src/app/modules/home/components/wizard/device-wizard-dialog.component.html index 245cb6503b..39be34b823 100644 --- a/ui-ngx/src/app/modules/home/components/wizard/device-wizard-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/wizard/device-wizard-dialog.component.html @@ -155,7 +155,7 @@ {{ 'device.credentials' | translate }}
- {{ 'device.wizard.add-credential' | translate }} + {{ 'device.wizard.add-credentials' | translate }} diff --git a/ui-ngx/src/assets/locale/locale.constant-cs_CZ.json b/ui-ngx/src/assets/locale/locale.constant-cs_CZ.json index 92941c9404..128e8d6d93 100644 --- a/ui-ngx/src/assets/locale/locale.constant-cs_CZ.json +++ b/ui-ngx/src/assets/locale/locale.constant-cs_CZ.json @@ -923,7 +923,7 @@ "existing-device-profile": "Vybrat existující profil zařízení", "specific-configuration": "Specifická konfigurace", "customer-to-assign-device": "Přiřadit zařízení zákazníkovi", - "add-credential": "Přidat přístupový údaj" + "add-credentials": "Přidat přístupový údaj" } }, "device-profile": { diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 6966888ea3..49a29a98b4 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1000,7 +1000,7 @@ "existing-device-profile": "Select existing device profile", "specific-configuration": "Specific configuration", "customer-to-assign-device": "Customer to assign the device", - "add-credential": "Add credential" + "add-credentials": "Add credentials" }, "unassign-devices-from-edge-title": "Are you sure you want to unassign { count, plural, 1 {1 device} other {# devices} }?", "unassign-devices-from-edge-text": "After the confirmation all selected devices will be unassigned and won't be accessible by the edge." diff --git a/ui-ngx/src/assets/locale/locale.constant-es_ES.json b/ui-ngx/src/assets/locale/locale.constant-es_ES.json index 9d18102a43..fc1049ca91 100644 --- a/ui-ngx/src/assets/locale/locale.constant-es_ES.json +++ b/ui-ngx/src/assets/locale/locale.constant-es_ES.json @@ -947,7 +947,7 @@ "existing-device-profile": "Seleccionar un perfil existente", "specific-configuration": "Configuración específica", "customer-to-assign-device": "Cliente al que asignar el dispositivo", - "add-credential": "Añadir credencial" + "add-credentials": "Añadir credencial" }, "assign-device-to-edge-text": "Seleccione los dispositivos para asignar al borde", "unassign-device-from-edge-title": "¿Está seguro de que desea desasignar el dispositivo '{{deviceName}}'?", diff --git a/ui-ngx/src/assets/locale/locale.constant-ko_KR.json b/ui-ngx/src/assets/locale/locale.constant-ko_KR.json index cbe962bc2a..f966203fbf 100644 --- a/ui-ngx/src/assets/locale/locale.constant-ko_KR.json +++ b/ui-ngx/src/assets/locale/locale.constant-ko_KR.json @@ -920,7 +920,7 @@ "existing-device-profile": "기존 장치 프로파일 선택", "specific-configuration": "특수 설정", "customer-to-assign-device": "장치에 할당할 커스터머", - "add-credential": "크리덴셜 추가" + "add-credentials": "크리덴셜 추가" } }, "device-profile": { diff --git a/ui-ngx/src/assets/locale/locale.constant-sl_SI.json b/ui-ngx/src/assets/locale/locale.constant-sl_SI.json index 7dd60aaa2f..e57ee78e87 100644 --- a/ui-ngx/src/assets/locale/locale.constant-sl_SI.json +++ b/ui-ngx/src/assets/locale/locale.constant-sl_SI.json @@ -920,7 +920,7 @@ "existing-device-profile": "Select existing device profile", "specific-configuration": "Specific configuration", "customer-to-assign-device": "Customer to assign the device", - "add-credential": "Add credential" + "add-credentials": "Add credentials" } }, "device-profile": { diff --git a/ui-ngx/src/assets/locale/locale.constant-zh_CN.json b/ui-ngx/src/assets/locale/locale.constant-zh_CN.json index b7a3078c3b..99b0864d36 100644 --- a/ui-ngx/src/assets/locale/locale.constant-zh_CN.json +++ b/ui-ngx/src/assets/locale/locale.constant-zh_CN.json @@ -1079,7 +1079,7 @@ "view-credentials": "查看凭据", "view-devices": "查看设备", "wizard": { - "add-credential": "添加凭据", + "add-credentials": "添加凭据", "customer-to-assign-device": "客户分配设备", "device-details": "设备详细信息", "device-wizard": "设备向导", From ea574aa4d867e255253650d507d23c912a1b81fb Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 2 Jun 2021 12:43:54 +0300 Subject: [PATCH 08/19] UI: Fix update validate component device-credentials after enable component --- .../home/components/device/device-credentials.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/ui-ngx/src/app/modules/home/components/device/device-credentials.component.ts b/ui-ngx/src/app/modules/home/components/device/device-credentials.component.ts index 19e9419829..21c8d40a42 100644 --- a/ui-ngx/src/app/modules/home/components/device/device-credentials.component.ts +++ b/ui-ngx/src/app/modules/home/components/device/device-credentials.component.ts @@ -148,6 +148,7 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, } else { this.deviceCredentialsFormGroup.enable({emitEvent: false}); this.updateValidators(); + this.deviceCredentialsFormGroup.updateValueAndValidity(); } } From f0f08fd0c90c03dbcb88cbcd0089afff610fe0a7 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Thu, 3 Jun 2021 08:21:23 +0300 Subject: [PATCH 09/19] LWM2M: fix bug RPC device of line --- .../device/DeviceActorMessageProcessor.java | 10 +- common/queue/src/main/proto/queue.proto | 2 + .../AbstractLwm2mTransportResource.java | 92 +++++++++++ .../DefaultLwM2MTransportMsgHandler.java | 38 +++-- .../server/DefaultLwM2mTransportService.java | 20 ++- .../server/LwM2mTransportCoapResource.java | 145 ++++++++++++++++++ .../lwm2m/server/LwM2mTransportUtil.java | 8 +- .../server/client/LwM2mClientContextImpl.java | 37 ++++- .../mqtt/session/GatewaySessionHandler.java | 6 +- .../service/DefaultTransportService.java | 1 + 10 files changed, 326 insertions(+), 33 deletions(-) create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 5af11d87f5..0c5fec537e 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -192,6 +192,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { syncSessionSet.add(key); } }); + log.warn("46) Rpc syncSessionSet [{}] subscription after sent [{}]",syncSessionSet, rpcSubscriptions); syncSessionSet.forEach(rpcSubscriptions::remove); } @@ -240,6 +241,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { log.debug("[{}] Pushing {} pending RPC messages to new async session [{}]", deviceId, toDeviceRpcPendingMap.size(), sessionId); if (sessionType == SessionType.SYNC) { log.debug("[{}] Cleanup sync rpc session [{}]", deviceId, sessionId); + log.warn("47) Rpc sessionId [{}] Cleanup sync rpc session subscription before [{}]",sessionId, rpcSubscriptions); rpcSubscriptions.remove(sessionId); } } else { @@ -454,7 +456,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { } else { SessionInfoMetaData sessionMD = sessions.get(sessionId); if (sessionMD == null) { - sessionMD = new SessionInfoMetaData(new SessionInfo(SessionType.SYNC, sessionInfo.getNodeId())); + sessionMD = new SessionInfoMetaData(new SessionInfo(subscribeCmd.getSessionType(), sessionInfo.getNodeId())); } sessionMD.setSubscribedToAttributes(true); log.debug("[{}] Registering attributes subscription for session [{}]", deviceId, sessionId); @@ -471,15 +473,17 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { UUID sessionId = getSessionId(sessionInfo); if (subscribeCmd.getUnsubscribe()) { log.debug("[{}] Canceling rpc subscription for session [{}]", deviceId, sessionId); + log.warn("48) Rpc sessionId [{}] Canceling rpc subscription for session subscription before [{}]",sessionId, rpcSubscriptions); rpcSubscriptions.remove(sessionId); } else { SessionInfoMetaData sessionMD = sessions.get(sessionId); if (sessionMD == null) { - sessionMD = new SessionInfoMetaData(new SessionInfo(SessionType.SYNC, sessionInfo.getNodeId())); + sessionMD = new SessionInfoMetaData(new SessionInfo(subscribeCmd.getSessionType(), sessionInfo.getNodeId())); } sessionMD.setSubscribedToRPC(true); log.debug("[{}] Registering rpc subscription for session [{}]", deviceId, sessionId); rpcSubscriptions.put(sessionId, sessionMD.getSessionInfo()); + log.warn("45) sessionId [{}] Registering rpc subscription for session [{}]",sessionId, rpcSubscriptions); sendPendingRequests(context, sessionId, sessionInfo); dumpSessions(); } @@ -509,6 +513,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { log.debug("[{}] Canceling subscriptions for closed session [{}]", deviceId, sessionId); sessions.remove(sessionId); attributeSubscriptions.remove(sessionId); + log.warn("49) Rpc sessionId [{}] Canceling subscriptions for closed session subscription before [{}]",sessionId, rpcSubscriptions); rpcSubscriptions.remove(sessionId); if (sessions.isEmpty()) { reportSessionClose(); @@ -764,6 +769,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { Map sessionsToRemove = sessions.entrySet().stream().filter(kv -> kv.getValue().getLastActivityTime() < expTime).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); sessionsToRemove.forEach((sessionId, sessionMD) -> { sessions.remove(sessionId); + log.warn("50) Rpc sessionId [{}] checkSessionsTimeout subscription before [{}]",sessionId, rpcSubscriptions); rpcSubscriptions.remove(sessionId); attributeSubscriptions.remove(sessionId); notifyTransportAboutClosedSession(sessionId, sessionMD, "session timeout!"); diff --git a/common/queue/src/main/proto/queue.proto b/common/queue/src/main/proto/queue.proto index faf88c5620..acea8d6382 100644 --- a/common/queue/src/main/proto/queue.proto +++ b/common/queue/src/main/proto/queue.proto @@ -310,10 +310,12 @@ message SessionCloseNotificationProto { message SubscribeToAttributeUpdatesMsg { bool unsubscribe = 1; + SessionType sessionType = 2; } message SubscribeToRPCMsg { bool unsubscribe = 1; + SessionType sessionType = 2; } message ToDeviceRpcRequestMsg { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java new file mode 100644 index 0000000000..07821abc0c --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java @@ -0,0 +1,92 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.transport.lwm2m.server; + +import lombok.extern.slf4j.Slf4j; +import org.eclipse.californium.core.coap.CoAP; +import org.eclipse.californium.core.coap.Response; +import org.eclipse.californium.core.server.resources.CoapExchange; +import org.eclipse.leshan.core.californium.LwM2mCoapResource; +import org.thingsboard.server.common.transport.TransportServiceCallback; + +@Slf4j +public abstract class AbstractLwm2mTransportResource extends LwM2mCoapResource { + protected final LwM2mTransportMsgHandler handler; + + public AbstractLwm2mTransportResource(LwM2mTransportMsgHandler handler, String name) { + super(name); + this.handler = handler; + } + + @Override + public void handleGET(CoapExchange exchange) { + processHandleGet(exchange); + } + + @Override + public void handlePOST(CoapExchange exchange) { + processHandlePost(exchange); + } + + protected abstract void processHandleGet(CoapExchange exchange); + + protected abstract void processHandlePost(CoapExchange exchange); + + public static class CoapOkCallback implements TransportServiceCallback { + private final CoapExchange exchange; + private final CoAP.ResponseCode onSuccessResponse; + private final CoAP.ResponseCode onFailureResponse; + + public CoapOkCallback(CoapExchange exchange, CoAP.ResponseCode onSuccessResponse, CoAP.ResponseCode onFailureResponse) { + this.exchange = exchange; + this.onSuccessResponse = onSuccessResponse; + this.onFailureResponse = onFailureResponse; + } + + @Override + public void onSuccess(Void msg) { + Response response = new Response(onSuccessResponse); + response.setAcknowledged(isConRequest()); + exchange.respond(response); + } + + @Override + public void onError(Throwable e) { + exchange.respond(onFailureResponse); + } + + private boolean isConRequest() { + return exchange.advanced().getRequest().isConfirmable(); + } + } + + public static class CoapNoOpCallback implements TransportServiceCallback { + private final CoapExchange exchange; + + CoapNoOpCallback(CoapExchange exchange) { + this.exchange = exchange; + } + + @Override + public void onSuccess(Void msg) { + } + + @Override + public void onError(Throwable e) { + exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR); + } + } +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index e0a85bc77d..fecd149230 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -42,10 +42,10 @@ import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.server.cache.ota.OtaPackageDataCache; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.ota.OtaPackageKey; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.ota.OtaPackageUtil; -import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.adaptor.AdaptorException; @@ -87,9 +87,9 @@ import java.util.stream.Collectors; import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; -import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST; @@ -189,13 +189,15 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); if (sessionInfo != null) { transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); - TransportProtos.TransportToDeviceActorMsg msg = TransportProtos.TransportToDeviceActorMsg.newBuilder() + log.warn("40) sessionId [{}] Registering rpc subscription after Registration client",new UUID (sessionInfo.getSessionIdMSB(),sessionInfo.getSessionIdLSB())); + transportService.process(TransportProtos.TransportToDeviceActorMsg.newBuilder() .setSessionInfo(sessionInfo) .setSessionEvent(DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN)) - .setSubscribeToAttributes(TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build()) - .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().build()) - .build(); - transportService.process(msg, null); + .setSubscribeToAttributes(TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder() + .setSessionType(TransportProtos.SessionType.ASYNC).build()) + .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder() + .setSessionType(TransportProtos.SessionType.ASYNC).build()) + .build(), null); this.getInfoFirmwareUpdate(lwM2MClient, null); this.getInfoSoftwareUpdate(lwM2MClient, null); this.initLwM2mFromClientValue(registration, lwM2MClient); @@ -250,7 +252,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler unRegistrationExecutor.submit(() -> { try { this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId()); - this.closeClientSession(registration); +// this.closeClientSession(registration); } catch (Throwable t) { log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t); this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client Unable un Registration, %s", t.getMessage()), registration.getId()); @@ -262,10 +264,11 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registration); if (sessionInfo != null) { transportService.deregisterSession(sessionInfo); + // TO DO may problem, better by registrationId sessionStore.remove(registration.getEndpoint()); this.doCloseSession(sessionInfo); clientContext.removeClientByRegistrationId(registration.getId()); - log.info("Client close session: [{}] unReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType()); + log.warn("52) Client close session [{}]: [{}] unReg [{}] name [{}] profile ", new UUID (sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()), registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType()); } else { log.error("Client close session: [{}] unReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); } @@ -446,10 +449,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRpcRequestMsg, SessionInfoProto sessionInfo) { // #1 this.checkRpcRequestTimeout(); - log.warn ("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); + UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB()); + log.warn ("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, requestUUID); String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null"; LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName()); - UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB()); if (!this.rpcSubscriptions.containsKey(requestUUID)) { this.rpcSubscriptions.put(requestUUID, toDeviceRpcRequestMsg.getExpirationTime()); Lwm2mClientRpcRequest lwm2mClientRpcRequest = null; @@ -479,8 +482,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } private void checkRpcRequestTimeout() { - Set rpcSubscriptionsToRemove = rpcSubscriptions.entrySet().stream().filter(kv -> System.currentTimeMillis() > kv.getValue()).map(Map.Entry::getKey).collect(Collectors.toSet()); - rpcSubscriptionsToRemove.forEach(rpcSubscriptions::remove); + log.warn ("4.1) before rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); + if (rpcSubscriptions.size() > 0) { + Set rpcSubscriptionsToRemove = rpcSubscriptions.entrySet().stream().filter(kv -> System.currentTimeMillis() > kv.getValue()).map(Map.Entry::getKey).collect(Collectors.toSet()); + log.warn ("4.2) System.currentTimeMillis(): [{}]", System.currentTimeMillis()); + log.warn ("4.3) rpcSubscriptionsToRemove: [{}]", rpcSubscriptionsToRemove); + rpcSubscriptionsToRemove.forEach(rpcSubscriptions::remove); + } + log.warn ("4.4) after rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); } public void sentRpcResponse(Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) { @@ -1372,7 +1381,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler lwM2MClient.getFwUpdate().setRpcRequest(rpcRequest); lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion()); lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle()); - lwM2MClient.getFwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId()); + log.warn("11) OtaPackageIdMSB: [{}] OtaPackageIdLSB: [{}]", response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB()); + lwM2MClient.getFwUpdate().setCurrentId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())); if (rpcRequest == null) { lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java index 90e3e13033..688ab88eeb 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java @@ -28,7 +28,6 @@ import org.eclipse.leshan.server.californium.registration.CaliforniumRegistratio import org.eclipse.leshan.server.model.LwM2mModelProvider; import org.eclipse.leshan.server.security.EditableSecurityStore; import org.springframework.stereotype.Component; -import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; @@ -58,14 +57,14 @@ import java.security.spec.InvalidParameterSpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Arrays; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256; import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8; import static org.thingsboard.server.transport.lwm2m.server.LwM2mNetworkConfig.getCoapConfig; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_COAP_RESOURCE; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_COAP_RESOURCE; @Slf4j @Component @@ -81,7 +80,7 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { private final LwM2mTransportContext context; private final LwM2MTransportServerConfig config; private final LwM2mTransportServerHelper helper; - private final LwM2mTransportMsgHandler handler; + private final DefaultLwM2MTransportMsgHandler handler; private final CaliforniumRegistrationStore registrationStore; private final EditableSecurityStore securityStore; private final LwM2mClientContext lwM2mClientContext; @@ -96,6 +95,19 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { new LWM2MGenerationPSkRPkECC(); } this.server = getLhServer(); + /** + * Add a resource to the server. + * CoapResource -> + * path = FW_PACKAGE or SW_PACKAGE + * nameFile = "BC68JAR01A09_TO_BC68JAR01A10.bin" + * "coap://host:port/{path}/{token}/{nameFile}" + */ + + + LwM2mTransportCoapResource fwCoapResource = new LwM2mTransportCoapResource(handler, FW_COAP_RESOURCE); + LwM2mTransportCoapResource swCoapResource = new LwM2mTransportCoapResource(handler, SW_COAP_RESOURCE); + this.server.coap().getServer().add(fwCoapResource); + this.server.coap().getServer().add(swCoapResource); this.startLhServer(); this.context.setServer(server); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java new file mode 100644 index 0000000000..c03b38451a --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java @@ -0,0 +1,145 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.transport.lwm2m.server; + +import lombok.extern.slf4j.Slf4j; +import org.eclipse.californium.core.coap.CoAP; +import org.eclipse.californium.core.coap.Request; +import org.eclipse.californium.core.coap.Response; +import org.eclipse.californium.core.network.Exchange; +import org.eclipse.californium.core.observe.ObserveRelation; +import org.eclipse.californium.core.server.resources.CoapExchange; +import org.eclipse.californium.core.server.resources.Resource; +import org.eclipse.californium.core.server.resources.ResourceObserver; + +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +@Slf4j +public class LwM2mTransportCoapResource extends AbstractLwm2mTransportResource { + private final ConcurrentMap tokenToObserveRelationMap = new ConcurrentHashMap<>(); + private final ConcurrentMap tokenToObserveNotificationSeqMap = new ConcurrentHashMap<>(); + + public LwM2mTransportCoapResource(LwM2mTransportMsgHandler handler, String name) { + super(handler, name); + this.setObservable(true); // enable observing + this.addObserver(new CoapResourceObserver()); + } + + + @Override + public void checkObserveRelation(Exchange exchange, Response response) { + String token = getTokenFromRequest(exchange.getRequest()); + final ObserveRelation relation = exchange.getRelation(); + if (relation == null || relation.isCanceled()) { + return; // because request did not try to establish a relation + } + if (CoAP.ResponseCode.isSuccess(response.getCode())) { + + if (!relation.isEstablished()) { + relation.setEstablished(); + addObserveRelation(relation); + } + AtomicInteger notificationCounter = tokenToObserveNotificationSeqMap.computeIfAbsent(token, s -> new AtomicInteger(0)); + response.getOptions().setObserve(notificationCounter.getAndIncrement()); + } // ObserveLayer takes care of the else case + } + + + @Override + protected void processHandleGet(CoapExchange exchange) { + log.warn("1) processHandleGet [{}]", exchange); +// exchange.respond(CoAP.ResponseCode.BAD_REQUEST); +// int ver = 10; + int ver = 9; + UUID currentId; + if (ver == 10) { + long mSB = 4951557297924280811L; + long lSb = -8451242882176289074L; + currentId = new UUID(mSB, lSb); + } else { + long mSB = 9085827945869414891L; + long lSb = -9086716326447629319L; + currentId = new UUID(mSB, lSb); + } + String resource = exchange.getRequestOptions().getUriPath().get(0); + String token = exchange.getRequestOptions().getUriPath().get(1); + exchange.respond(CoAP.ResponseCode.CONTENT, this.getFwData(currentId)); + + } + + @Override + protected void processHandlePost(CoapExchange exchange) { + log.warn("2) processHandleGet [{}]", exchange); + } + + /** + * Override the default behavior so that requests to sub resources (typically /{name}/{token}) are handled by + * /name resource. + */ + @Override + public Resource getChild(String name) { + return this; + } + + + private String getTokenFromRequest(Request request) { + return (request.getSourceContext() != null ? request.getSourceContext().getPeerAddress().getAddress().getHostAddress() : "null") + + ":" + (request.getSourceContext() != null ? request.getSourceContext().getPeerAddress().getPort() : -1) + ":" + request.getTokenString(); + } + + public class CoapResourceObserver implements ResourceObserver { + + @Override + public void changedName(String old) { + + } + + @Override + public void changedPath(String old) { + + } + + @Override + public void addedChild(Resource child) { + + } + + @Override + public void removedChild(Resource child) { + + } + + @Override + public void addedObserveRelation(ObserveRelation relation) { + + } + + @Override + public void removedObserveRelation(ObserveRelation relation) { + + } + } + + private byte[] getFwData(UUID currentId) { + int chunkSize = 0; + int chunk = 0; + return ((DefaultLwM2MTransportMsgHandler) handler).otaPackageDataCache.get(currentId.toString(), chunkSize, chunk); + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java index adf9e07bc4..2e7681250a 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java @@ -43,11 +43,11 @@ import org.eclipse.leshan.server.registration.Registration; import org.nustaq.serialization.FSTConfiguration; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; +import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.ota.OtaPackageKey; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus; import org.thingsboard.server.common.data.ota.OtaPackageUtil; -import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; @@ -77,14 +77,14 @@ import static org.eclipse.leshan.core.model.ResourceModel.Type.OBJLNK; import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE; import static org.eclipse.leshan.core.model.ResourceModel.Type.STRING; import static org.eclipse.leshan.core.model.ResourceModel.Type.TIME; +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADING; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATED; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.VERIFIED; -import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; -import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; @Slf4j public class LwM2mTransportUtil { @@ -140,6 +140,7 @@ public class LwM2mTransportUtil { public static final String METHOD_KEY = "methodName"; // Firmware + public static final String FW_COAP_RESOURCE = "fw"; public static final String FW_UPDATE = "Firmware update"; public static final Integer FW_ID = 5; // Package W @@ -156,6 +157,7 @@ public class LwM2mTransportUtil { public static final String FW_UPDATE_ID = "/5/0/2"; // Software + public static final String SW_COAP_RESOURCE = "sw"; public static final String SW_UPDATE = "Software update"; public static final Integer SW_ID = 9; // Package W diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java index 8674516e85..a29edf6424 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java @@ -37,6 +37,7 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; import static org.eclipse.leshan.core.SecurityMode.NO_SEC; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; @@ -68,12 +69,15 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { @Override public LwM2mClient getOrRegister(Registration registration) { + LwM2mClient client = null; if (registration == null) { - return null; + return client; + } + if (lwM2mClientsByRegistrationId.size()>0) { + client = this.lwM2mClientsByRegistrationId.get(registration.getId()); } - LwM2mClient client = lwM2mClientsByRegistrationId.get(registration.getId()); if (client == null) { - client = lwM2mClientsByEndpoint.get(registration.getEndpoint()); + client = this.lwM2mClientsByEndpoint.get(registration.getEndpoint()); if (client == null) { client = registerOrUpdate(registration); } @@ -83,12 +87,29 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { @Override public LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo) { - LwM2mClient lwM2mClient = lwM2mClientsByEndpoint.values().stream().filter(c -> + LwM2mClient lwM2mClient = null; + Predicate isClientFilter = c -> (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) - .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) - - ).findAny().get(); - if (lwM2mClient == null) { + .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))); +// if (this.lwM2mClientsByEndpoint.size()>0) { +// lwM2mClient = this.lwM2mClientsByEndpoint.values().stream().filter(c -> +// (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) +// .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) +// ).findAny().get(); +// } + if (this.lwM2mClientsByEndpoint.size()>0) { + lwM2mClient = this.lwM2mClientsByEndpoint.values().stream().filter(isClientFilter).findAny().get(); + } +// if (lwM2mClient == null && this.lwM2mClientsByRegistrationId.size() > 0) { +// lwM2mClient = this.lwM2mClientsByRegistrationId.values().stream().filter(c -> +// (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) +// .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) +// ).findAny().get(); +// } + if (lwM2mClient == null && this.lwM2mClientsByRegistrationId.size() > 0) { + lwM2mClient = this.lwM2mClientsByRegistrationId.values().stream().filter(isClientFilter).findAny().get(); + } + if (lwM2mClient == null){ log.warn("Device TimeOut? lwM2mClient is null."); log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}]", sessionInfo, lwM2mClientsByEndpoint.values().size()); log.error("", new RuntimeException()); diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java index 7882ad2410..891c466151 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java @@ -259,8 +259,10 @@ public class GatewaySessionHandler { transportService.process(TransportProtos.TransportToDeviceActorMsg.newBuilder() .setSessionInfo(deviceSessionInfo) .setSessionEvent(DefaultTransportService.getSessionEventMsg(TransportProtos.SessionEvent.OPEN)) - .setSubscribeToAttributes(TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build()) - .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().build()) + .setSubscribeToAttributes(TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder() + .setSessionType(TransportProtos.SessionType.ASYNC).build()) + .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder() + .setSessionType(TransportProtos.SessionType.ASYNC).build()) .build(), null); } futureToSet.set(devices.get(deviceName)); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 77b75dc07a..79b022c6b4 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -708,6 +708,7 @@ public class DefaultTransportService implements TransportService { log.debug("Stopping scheduler to avoid resending response if request has been ack."); currentSession.getScheduledFuture().cancel(false); } + log.warn("54) session [{}] deregisterSession Stopping scheduler to avoid resending response if request has been ack.", toSessionId(sessionInfo)); sessions.remove(toSessionId(sessionInfo)); } From d46967270629578ee5809e92b7de7edc8f81df8c Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Thu, 3 Jun 2021 10:44:11 +0300 Subject: [PATCH 10/19] LWM2M: fix bug test --- .../DefaultLwM2MTransportMsgHandler.java | 54 +++++++++---------- .../server/LwM2mTransportCoapResource.java | 1 + 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index fecd149230..e3c4fd4646 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -189,7 +189,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); if (sessionInfo != null) { transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); - log.warn("40) sessionId [{}] Registering rpc subscription after Registration client",new UUID (sessionInfo.getSessionIdMSB(),sessionInfo.getSessionIdLSB())); + log.warn("40) sessionId [{}] Registering rpc subscription after Registration client", new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); transportService.process(TransportProtos.TransportToDeviceActorMsg.newBuilder() .setSessionInfo(sessionInfo) .setSessionEvent(DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN)) @@ -252,7 +252,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler unRegistrationExecutor.submit(() -> { try { this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId()); -// this.closeClientSession(registration); + this.removeClientCash(registration); } catch (Throwable t) { log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t); this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client Unable un Registration, %s", t.getMessage()), registration.getId()); @@ -260,15 +260,15 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler }); } - private void closeClientSession(Registration registration) { + private void removeClientCash(Registration registration) { SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registration); if (sessionInfo != null) { - transportService.deregisterSession(sessionInfo); - // TO DO may problem, better by registrationId +// transportService.deregisterSession(sessionInfo); +// this.doCloseSession(sessionInfo); sessionStore.remove(registration.getEndpoint()); - this.doCloseSession(sessionInfo); + clientContext.removeClientByRegistrationId(registration.getId()); - log.warn("52) Client close session [{}]: [{}] unReg [{}] name [{}] profile ", new UUID (sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()), registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType()); + log.warn("52) Client close session [{}]: [{}] unReg [{}] name [{}] profile ", new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()), registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType()); } else { log.error("Client close session: [{}] unReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); } @@ -355,7 +355,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo); if (msg.getSharedUpdatedCount() > 0 && lwM2MClient != null) { - log.warn ("2) OnAttributeUpdate, SharedUpdatedList() [{}]", msg.getSharedUpdatedList()); + log.warn("2) OnAttributeUpdate, SharedUpdatedList() [{}]", msg.getSharedUpdatedList()); msg.getSharedUpdatedList().forEach(tsKvProto -> { String pathName = tsKvProto.getKv().getKey(); String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); @@ -399,9 +399,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } }); log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo); - } - else if (lwM2MClient == null) { - log.error ("OnAttributeUpdate, lwM2MClient is null"); + } else if (lwM2MClient == null) { + log.error("OnAttributeUpdate, lwM2MClient is null"); } } @@ -450,7 +449,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler // #1 this.checkRpcRequestTimeout(); UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB()); - log.warn ("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, requestUUID); + log.warn("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, requestUUID); String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null"; LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName()); if (!this.rpcSubscriptions.containsKey(requestUUID)) { @@ -482,14 +481,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } private void checkRpcRequestTimeout() { - log.warn ("4.1) before rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); + log.warn("4.1) before rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); if (rpcSubscriptions.size() > 0) { Set rpcSubscriptionsToRemove = rpcSubscriptions.entrySet().stream().filter(kv -> System.currentTimeMillis() > kv.getValue()).map(Map.Entry::getKey).collect(Collectors.toSet()); - log.warn ("4.2) System.currentTimeMillis(): [{}]", System.currentTimeMillis()); - log.warn ("4.3) rpcSubscriptionsToRemove: [{}]", rpcSubscriptionsToRemove); + log.warn("4.2) System.currentTimeMillis(): [{}]", System.currentTimeMillis()); + log.warn("4.3) rpcSubscriptionsToRemove: [{}]", rpcSubscriptionsToRemove); rpcSubscriptionsToRemove.forEach(rpcSubscriptions::remove); } - log.warn ("4.4) after rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); + log.warn("4.4) after rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); } public void sentRpcResponse(Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) { @@ -515,7 +514,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler @Override public void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceResponse, SessionInfoProto sessionInfo) { - log.warn ("5) onToDeviceRpcResponse: [{}], sessionUUID: [{}]", toDeviceResponse, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); + log.warn("5) onToDeviceRpcResponse: [{}], sessionUUID: [{}]", toDeviceResponse, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); transportService.process(sessionInfo, toDeviceResponse, null); } @@ -901,9 +900,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler ResourceModel.Type expectedType = this.helper.getResourceModelTypeEqualsKvProtoValueType(currentType, pathIdVer); return this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); - } - - else { + } else { return null; } } @@ -1284,8 +1281,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), getValueFromKvProto(tsKvProto.getKv()), pathIdVer); }); - } - else { + } else { log.error("UpdateAttributeFromThingsboard, lwM2MClient is null"); } } @@ -1299,7 +1295,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler SessionInfoProto sessionInfoProto = lwM2MClient.getSession(); if (sessionInfoProto == null) { log.info("[{}] [{}]", lwM2MClient.getEndpoint(), CLIENT_NOT_AUTHORIZED); - this.closeClientSession(lwM2MClient.getRegistration()); + this.removeClientCash(lwM2MClient.getRegistration()); } return sessionInfoProto; } @@ -1377,7 +1373,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) && response.getType().equals(OtaPackageType.FIRMWARE.name())) { - log.warn ("7) firmware start with ver: [{}]", response.getVersion()); + log.warn("7) firmware start with ver: [{}]", response.getVersion()); lwM2MClient.getFwUpdate().setRpcRequest(rpcRequest); lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion()); lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle()); @@ -1385,9 +1381,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler lwM2MClient.getFwUpdate().setCurrentId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())); if (rpcRequest == null) { lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest); - } - else { - lwM2MClient.getFwUpdate().writeFwSwWare(handler, lwM2mTransportRequest); + } else { + lwM2MClient.getFwUpdate().writeFwSwWare(handler, lwM2mTransportRequest); } } else { log.trace("OtaPackage [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); @@ -1421,9 +1416,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest); if (rpcRequest == null) { lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest); - } - else { - lwM2MClient.getSwUpdate().writeFwSwWare(handler, lwM2mTransportRequest); + } else { + lwM2MClient.getSwUpdate().writeFwSwWare(handler, lwM2mTransportRequest); } } else { log.trace("Software [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java index c03b38451a..d2449c4634 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java @@ -79,6 +79,7 @@ public class LwM2mTransportCoapResource extends AbstractLwm2mTransportResource { } String resource = exchange.getRequestOptions().getUriPath().get(0); String token = exchange.getRequestOptions().getUriPath().get(1); + exchange.respond(CoAP.ResponseCode.CONTENT, this.getFwData(currentId)); } From 45fa1a7bd2a3a6bd1b9fd34da8bc8295cf0e531f Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Thu, 3 Jun 2021 17:05:21 +0300 Subject: [PATCH 11/19] LWM2M: add response FirmWareUpdate --- .../AbstractLwm2mTransportResource.java | 2 + .../DefaultLwM2MTransportMsgHandler.java | 4 +- .../server/LwM2mTransportCoapResource.java | 44 +++++++++++++++---- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java index 07821abc0c..28c10df718 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java @@ -89,4 +89,6 @@ public abstract class AbstractLwm2mTransportResource extends LwM2mCoapResource { exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR); } } + + } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index e3c4fd4646..0fe5df844f 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -139,6 +139,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public final LwM2mClientContext clientContext; public final LwM2mTransportRequest lwM2mTransportRequest; private final Map rpcSubscriptions; + private final Map getCoapResource; public DefaultLwM2MTransportMsgHandler(TransportService transportService, LwM2MTransportServerConfig config, LwM2mTransportServerHelper helper, LwM2mClientContext clientContext, @@ -154,6 +155,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler this.context = context; this.adaptor = adaptor; this.rpcSubscriptions = new ConcurrentHashMap<>(); + this.getCoapResource = new ConcurrentHashMap<>(); this.sessionStore = sessionStore; } @@ -199,7 +201,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler .setSessionType(TransportProtos.SessionType.ASYNC).build()) .build(), null); this.getInfoFirmwareUpdate(lwM2MClient, null); - this.getInfoSoftwareUpdate(lwM2MClient, null); +// this.getInfoSoftwareUpdate(lwM2MClient, null); this.initLwM2mFromClientValue(registration, lwM2MClient); this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration.getId()); } else { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java index d2449c4634..0f2e885274 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java @@ -30,6 +30,9 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_COAP_RESOURCE; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_COAP_RESOURCE; + @Slf4j public class LwM2mTransportCoapResource extends AbstractLwm2mTransportResource { private final ConcurrentMap tokenToObserveRelationMap = new ConcurrentHashMap<>(); @@ -64,9 +67,9 @@ public class LwM2mTransportCoapResource extends AbstractLwm2mTransportResource { @Override protected void processHandleGet(CoapExchange exchange) { log.warn("1) processHandleGet [{}]", exchange); -// exchange.respond(CoAP.ResponseCode.BAD_REQUEST); -// int ver = 10; - int ver = 9; + // exchange.respond(CoAP.ResponseCode.BAD_REQUEST); + int ver = 10; +// int ver = 9; UUID currentId; if (ver == 10) { long mSB = 4951557297924280811L; @@ -77,10 +80,37 @@ public class LwM2mTransportCoapResource extends AbstractLwm2mTransportResource { long lSb = -9086716326447629319L; currentId = new UUID(mSB, lSb); } - String resource = exchange.getRequestOptions().getUriPath().get(0); + + String coapResource = exchange.getRequestOptions().getUriPath().get(0); String token = exchange.getRequestOptions().getUriPath().get(1); + if (exchange.getRequestOptions().getBlock2() != null) { + int chunkSize = exchange.getRequestOptions().getBlock2().getSzx(); + int chunk = 0; + Response response = new Response(CoAP.ResponseCode.CONTENT); + byte[] fwData = this.getFwData(currentId); + if (fwData != null && fwData.length > 0) { + response.setPayload(fwData); + boolean moreFlag = fwData.length > chunkSize; + response.getOptions().setBlock2(chunkSize, moreFlag, chunk); + exchange.respond(response); + } + + } +// List options = exchange.advanced().getRequest().getOptions().getUriPath(); +// options.stream() +// .filter(o -> FW_COAP_RESOURCE.equals(o)) +// .findFirst() +// .ifPresent(o -> System.err.println(o.getNumber() + " " + o.getStringValue())); + + if (FW_COAP_RESOURCE.equals(coapResource)) { + + } + else if (SW_COAP_RESOURCE.equals(coapResource)) { + + } + + - exchange.respond(CoAP.ResponseCode.CONTENT, this.getFwData(currentId)); } @@ -138,9 +168,7 @@ public class LwM2mTransportCoapResource extends AbstractLwm2mTransportResource { } private byte[] getFwData(UUID currentId) { - int chunkSize = 0; - int chunk = 0; - return ((DefaultLwM2MTransportMsgHandler) handler).otaPackageDataCache.get(currentId.toString(), chunkSize, chunk); + return ((DefaultLwM2MTransportMsgHandler) handler).otaPackageDataCache.get(currentId.toString()); } } From 36c700810492ea3d39a24a50225f1c6ce6f0c1e4 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Fri, 4 Jun 2021 16:26:44 +0300 Subject: [PATCH 12/19] LWM2M: front add Firmware/Software update strategy --- .../widget_bundles/control_widgets.json | 6 +- .../AbstractLwm2mTransportResource.java | 4 +- .../DefaultLwM2MTransportMsgHandler.java | 14 ++++- .../server/LwM2mTransportCoapResource.java | 4 +- .../lwm2m/server/LwM2mTransportRequest.java | 10 ++-- .../lwm2m/server/client/LwM2mClient.java | 5 -- .../server/client/LwM2mClientContextImpl.java | 2 +- .../lwm2m/server/client/LwM2mFwSwUpdate.java | 6 +- ...ile-transport-configuration.component.html | 58 ++++++++++++++----- ...ofile-transport-configuration.component.ts | 15 +++-- .../lwm2m/lwm2m-profile-config.models.ts | 8 ++- .../assets/locale/locale.constant-en_US.json | 12 +++- 12 files changed, 97 insertions(+), 47 deletions(-) diff --git a/application/src/main/data/json/system/widget_bundles/control_widgets.json b/application/src/main/data/json/system/widget_bundles/control_widgets.json index 8fea056506..cd0d95ef2a 100644 --- a/application/src/main/data/json/system/widget_bundles/control_widgets.json +++ b/application/src/main/data/json/system/widget_bundles/control_widgets.json @@ -17,9 +17,9 @@ "sizeY": 5.5, "resources": [], "templateHtml": "
", - "templateCss": ".cmd .cursor.blink {\n -webkit-animation-name: terminal-underline;\n -moz-animation-name: terminal-underline;\n -ms-animation-name: terminal-underline;\n animation-name: terminal-underline;\n}\n.terminal .inverted, .cmd .inverted {\n border-bottom-color: #aaa;\n}\n", - "controllerScript": "var requestTimeout = 500;\nvar multiParams = false;\n\nself.onInit = function() {\n var subscription = self.ctx.defaultSubscription;\n var utils = self.ctx.$scope.$injector.get(self.ctx.servicesMap.get('utils'));\n var rpcEnabled = subscription.rpcEnabled;\n var deviceName = 'Simulated';\n var prompt;\n if (subscription.targetDeviceName && subscription.targetDeviceName.length) {\n deviceName = subscription.targetDeviceName;\n }\n if (self.ctx.settings.requestTimeout) {\n requestTimeout = self.ctx.settings.requestTimeout;\n }\n if (self.ctx.settings.multiParams) {\n multiParams = self.ctx.settings.multiParams;\n }\n var greetings = 'Welcome to ThingsBoard RPC debug terminal.\\n\\n';\n if (!rpcEnabled) {\n greetings += 'Target device is not set!\\n\\n';\n prompt = '';\n } else {\n greetings += 'Current target device for RPC commands: [[b;#fff;]' + deviceName + ']\\n\\n';\n greetings += 'Please type [[b;#fff;]\\'help\\'] to see usage.\\n';\n prompt = '[[b;#8bc34a;]' + deviceName +']> ';\n }\n \n var terminal = $('#device-terminal', self.ctx.$container).terminal(\n function(command) {\n if (command !== '') {\n try {\n var localCommand = command.trim();\n var requestUUID = utils.guid();\n if (localCommand === 'help') {\n printUsage(this);\n } else {\n var cmdObj = $.terminal.parse_command(localCommand);\n if (cmdObj.args) {\n if (!multiParams && cmdObj.args.length > 1) {\n this.error(\"Wrong number of arguments!\");\n this.echo(' ');\n }\n else {\n if (cmdObj.args.length) {\n var params = getMultiParams(cmdObj.args);\n }\n performRpc(this, cmdObj.name, params, requestUUID);\n }\n }\n }\n } catch(e) {\n this.error(new String(e));\n }\n } else {\n this.echo('');\n }\n }, {\n greetings: greetings,\n prompt: prompt,\n enabled: rpcEnabled\n });\n \n \n \n if (!rpcEnabled) {\n terminal.error('No RPC target detected!').pause();\n }\n}\n\n\nfunction printUsage(terminal) {\n var commandsListText = '\\n[[b;#fff;]Usage:]\\n';\n commandsListText += ' [params body]]\\n\\n';\n commandsListText += '[[b;#fff;]Example 1 (multiParams===false):]\\n'; \n commandsListText += ' myRemoteMethod1 myText\\n\\n'; \n commandsListText += '[[b;#fff;]Example 2 (multiParams===false):]\\n'; \n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\":2,\\\\\"key2\\\\\":\\\\\"myVal\\\\\"}\"\\n\\n'; \n commandsListText += '[[b;#fff;]Example 3 (multiParams===true)]\\n'; \n commandsListText += ' [params body] = \"all the string after the method, including spaces\"]\\n';\n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\": \"battery level\", \\\\\"key2\\\\\": \\\\\"myVal\\\\\"}\"\\n'; \n terminal.echo(new String(commandsListText));\n}\n\nfunction performRpc(terminal, method, params, requestUUID) {\n terminal.pause();\n self.ctx.controlApi.sendTwoWayCommand(method, params, requestTimeout, requestUUID).subscribe(\n function success(responseBody) {\n terminal.echo(JSON.stringify(responseBody));\n terminal.echo(' ');\n terminal.resume();\n },\n function fail() {\n var errorText = self.ctx.defaultSubscription.rpcErrorText;\n terminal.error(errorText);\n terminal.echo(' ');\n terminal.resume();\n }\n );\n}\n\nfunction getMultiParams(cmdObj) {\n var params = \"\";\n cmdObj.forEach((element) => {\n try {\n params += \" \" + JSON.strigify(JSON.parse(element));\n } catch (e) {\n params += \" \" + element;\n }\n })\n return params.trim();\n}\n\n \nself.onDestroy = function() {\n}", - "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"multiParams\": {\n \"title\": \"RPC params All line\",\n \"type\": \"boolean\",\n \"default\": false\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"requestTimeout\",\n \"multiParams\"\n ]\n}", + "templateCss": ".cmd .cursor.blink {\n -webkit-animation-name: terminal-underline;\n -moz-animation-name: terminal-underline;\n -ms-animation-name: terminal-underline;\n animation-name: terminal-underline;\n}\n.terminal .inverted, .cmd .inverted {\n border-bottom-color: #aaa;\n}\n\n", + "controllerScript": "var requestTimeout = 500;\nvar multiParams = false;\nvar useRowStyleFunction = false;\nvar styleObj = {};\n\nself.onInit = function() {\n var subscription = self.ctx.defaultSubscription;\n var utils = self.ctx.$scope.$injector.get(self.ctx.servicesMap.get('utils'));\n var rpcEnabled = subscription.rpcEnabled;\n var deviceName = 'Simulated';\n var prompt;\n if (subscription.targetDeviceName && subscription.targetDeviceName.length) {\n deviceName = subscription.targetDeviceName;\n }\n if (self.ctx.settings.requestTimeout) {\n requestTimeout = self.ctx.settings.requestTimeout;\n }\n if (self.ctx.settings.multiParams) {\n multiParams = self.ctx.settings.multiParams;\n }\n if (self.ctx.settings.useRowStyleFunction && self.ctx.settings.rowStyleFunction) {\n try {\n var style = self.ctx.settings.rowStyleFunction;\n styleObj = JSON.parse(style);\n if ((typeof styleObj !== \"object\")) {\n styleObj = null;\n throw new URIError(`${style === null ? 'null' : typeof style} instead of style object`);\n }\n else if (typeof styleObj === \"object\" && (typeof styleObj.length) === \"number\") {\n styleObj = null;\n throw new URIError('Array instead of style object');\n }\n }\n catch (e) {\n console.log(`Row style function in widget ` +\n `returns '${e}'. Please check your row style function.`); \n }\n useRowStyleFunction = self.ctx.settings.useRowStyleFunction;\n \n }\n var greetings = 'Welcome to ThingsBoard RPC debug terminal.\\n\\n';\n if (!rpcEnabled) {\n greetings += 'Target device is not set!\\n\\n';\n prompt = '';\n } else {\n greetings += 'Current target device for RPC commands: [[b;#fff;]' + deviceName + ']\\n\\n';\n greetings += 'Please type [[b;#fff;]\\'help\\'] to see usage.\\n';\n prompt = '[[b;#8bc34a;]' + deviceName +']> ';\n }\n \n var terminal = $('#device-terminal', self.ctx.$container).terminal(\n function(command) {\n if (command !== '') {\n try {\n var localCommand = command.trim();\n var requestUUID = utils.guid();\n if (localCommand === 'help') {\n printUsage(this);\n } else {\n var cmdObj = $.terminal.parse_command(localCommand);\n if (cmdObj.args) {\n if (!multiParams && cmdObj.args.length > 1) {\n this.error(\"Wrong number of arguments!\");\n this.echo(' ');\n }\n else {\n if (cmdObj.args.length) {\n var params = getMultiParams(cmdObj.args);\n }\n performRpc(this, cmdObj.name, params, requestUUID);\n }\n }\n \n }\n } catch(e) {\n this.error(new String(e));\n }\n } else {\n this.echo('');\n }\n }, {\n greetings: greetings,\n prompt: prompt,\n enabled: rpcEnabled\n });\n \n if (styleObj && styleObj !== null) {\n terminal.css(styleObj);\n }\n \n if (!rpcEnabled) {\n terminal.error('No RPC target detected!').pause();\n }\n}\n\n\nfunction printUsage(terminal) {\n var commandsListText = '\\n[[b;#fff;]Usage:]\\n';\n commandsListText += ' [params body]]\\n\\n';\n commandsListText += '[[b;#fff;]Example 1 (multiParams===false):]\\n'; \n commandsListText += ' myRemoteMethod1 myText\\n\\n'; \n commandsListText += '[[b;#fff;]Example 2 (multiParams===false):]\\n'; \n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\":2,\\\\\"key2\\\\\":\\\\\"myVal\\\\\"}\"\\n\\n'; \n commandsListText += '[[b;#fff;]Example 3 (multiParams===true)]\\n'; \n commandsListText += ' [params body] = \"all the string after the method, including spaces\"]\\n';\n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\": \"battery level\", \\\\\"key2\\\\\": \\\\\"myVal\\\\\"}\"\\n'; \n terminal.echo(new String(commandsListText));\n}\n\nfunction performRpc(terminal, method, params, requestUUID) {\n terminal.pause();\n self.ctx.controlApi.sendTwoWayCommand(method, params, requestTimeout, requestUUID).subscribe(\n function success(responseBody) {\n terminal.echo(JSON.stringify(responseBody));\n terminal.echo(' ');\n terminal.resume();\n },\n function fail() {\n var errorText = self.ctx.defaultSubscription.rpcErrorText;\n terminal.error(errorText);\n terminal.echo(' ');\n terminal.resume();\n }\n );\n}\n\nfunction getMultiParams(cmdObj) {\n var params = \"\";\n cmdObj.forEach((element) => {\n try {\n params += \" \" + JSON.strigify(JSON.parse(element));\n } catch (e) {\n params += \" \" + element;\n }\n })\n return params.trim();\n}\n\n \nself.onDestroy = function() {\n}", + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"multiParams\": {\n \"title\": \"RPC params All line\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"useRowStyleFunction\": {\n \"title\": \"Use row style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"rowStyleFunction\": {\n \"title\": \"Row style function: f(entity, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"requestTimeout\",\n \"multiParams\",\n \"useRowStyleFunction\",\n {\n \"key\": \"rowStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useRowStyleFunction === true\"\n }\n ]\n}", "dataKeySettingsSchema": "{}\n", "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":true,\"backgroundColor\":\"#010101\",\"color\":\"rgba(255, 254, 254, 0.87)\",\"padding\":\"0px\",\"settings\":{\"parseGpioStatusFunction\":\"return body[pin] === true;\",\"gpioStatusChangeRequest\":{\"method\":\"setGpioStatus\",\"paramsBody\":\"{\\n \\\"pin\\\": \\\"{$pin}\\\",\\n \\\"enabled\\\": \\\"{$enabled}\\\"\\n}\"},\"requestTimeout\":500,\"switchPanelBackgroundColor\":\"#b71c1c\",\"gpioStatusRequest\":{\"method\":\"getGpioStatus\",\"paramsBody\":\"{}\"},\"gpioList\":[{\"pin\":1,\"label\":\"GPIO 1\",\"row\":0,\"col\":0,\"_uniqueKey\":0},{\"pin\":2,\"label\":\"GPIO 2\",\"row\":0,\"col\":1,\"_uniqueKey\":1},{\"pin\":3,\"label\":\"GPIO 3\",\"row\":1,\"col\":0,\"_uniqueKey\":2}]},\"title\":\"RPC debug terminal\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java index 28c10df718..50eb468b17 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java @@ -24,11 +24,9 @@ import org.thingsboard.server.common.transport.TransportServiceCallback; @Slf4j public abstract class AbstractLwm2mTransportResource extends LwM2mCoapResource { - protected final LwM2mTransportMsgHandler handler; - public AbstractLwm2mTransportResource(LwM2mTransportMsgHandler handler, String name) { + public AbstractLwm2mTransportResource(String name) { super(name); - this.handler = handler; } @Override diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index 0fe5df844f..8dc1bd64c9 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -61,6 +61,7 @@ import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mFwSwUpdate; import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue; import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; @@ -201,7 +202,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler .setSessionType(TransportProtos.SessionType.ASYNC).build()) .build(), null); this.getInfoFirmwareUpdate(lwM2MClient, null); -// this.getInfoSoftwareUpdate(lwM2MClient, null); + this.getInfoSoftwareUpdate(lwM2MClient, null); this.initLwM2mFromClientValue(registration, lwM2MClient); this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration.getId()); } else { @@ -660,10 +661,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler /** version != null * set setClient_fw_info... = value **/ - if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { + if (lwM2MClient.getFwUpdate() != null && lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { lwM2MClient.getFwUpdate().initReadValue(this, this.lwM2mTransportRequest, path); } - if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { + if (lwM2MClient.getSwUpdate() != null && lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { lwM2MClient.getSwUpdate().initReadValue(this, this.lwM2mTransportRequest, path); } @@ -1376,11 +1377,15 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) && response.getType().equals(OtaPackageType.FIRMWARE.name())) { log.warn("7) firmware start with ver: [{}]", response.getVersion()); + lwM2MClient.setFwUpdate(new LwM2mFwSwUpdate(lwM2MClient, OtaPackageType.FIRMWARE)); +// clientContext.getProfile(lwM2MClient.getProfileId()).getPostAttributeLwm2mProfile(); + lwM2MClient.getFwUpdate().setTypeUpdateByURL(true); lwM2MClient.getFwUpdate().setRpcRequest(rpcRequest); lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion()); lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle()); log.warn("11) OtaPackageIdMSB: [{}] OtaPackageIdLSB: [{}]", response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB()); lwM2MClient.getFwUpdate().setCurrentId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())); + if (rpcRequest == null) { lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest); } else { @@ -1411,6 +1416,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) && response.getType().equals(OtaPackageType.SOFTWARE.name())) { + lwM2MClient.setSwUpdate(new LwM2mFwSwUpdate(lwM2MClient, OtaPackageType.SOFTWARE)); +// clientContext.getProfile(lwM2MClient.getProfileId()).getPostAttributeLwm2mProfile(); + lwM2MClient.getSwUpdate().setTypeUpdateByURL(false); lwM2MClient.getSwUpdate().setRpcRequest(rpcRequest); lwM2MClient.getSwUpdate().setCurrentVersion(response.getVersion()); lwM2MClient.getSwUpdate().setCurrentTitle(response.getTitle()); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java index 0f2e885274..f2aa4dbf24 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java @@ -37,9 +37,11 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.S public class LwM2mTransportCoapResource extends AbstractLwm2mTransportResource { private final ConcurrentMap tokenToObserveRelationMap = new ConcurrentHashMap<>(); private final ConcurrentMap tokenToObserveNotificationSeqMap = new ConcurrentHashMap<>(); + private final LwM2mTransportMsgHandler handler; public LwM2mTransportCoapResource(LwM2mTransportMsgHandler handler, String name) { - super(handler, name); + super(name); + this.handler = handler; this.setObservable(true); // enable observing this.addObserver(new CoapResourceObserver()); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java index 4450859e3e..98b40e74fc 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java @@ -163,12 +163,12 @@ public class LwM2mTransportRequest { if (lwm2mClientRpcRequest != null) { ResourceModel resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider()); String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null"; - this.handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); + handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); } } } else if (lwm2mClientRpcRequest != null) { String errorMsg = String.format("Path %s not found in object version", targetIdVer); - this.handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); + handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); } } else { switch (typeOper) { @@ -185,10 +185,10 @@ public class LwM2mTransportRequest { } String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO, typeOper.name(), paths); - this.handler.sendLogsToThingsboard(msg, registration.getId()); + handler.sendLogsToThingsboard(msg, registration.getId()); if (lwm2mClientRpcRequest != null) { String valueMsg = String.format("Paths - %s", paths); - this.handler.sentRpcResponse(lwm2mClientRpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); + handler.sentRpcResponse(lwm2mClientRpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); } break; case OBSERVE_CANCEL: @@ -208,7 +208,7 @@ public class LwM2mTransportRequest { break; // lwm2mClientRpcRequest != null case FW_UPDATE: - this.handler.getInfoFirmwareUpdate(lwM2MClient, lwm2mClientRpcRequest); + handler.getInfoFirmwareUpdate(lwM2MClient, lwm2mClientRpcRequest); break; } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java index a6a1fadbf3..602596ed2b 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java @@ -31,7 +31,6 @@ import org.eclipse.leshan.server.registration.Registration; import org.eclipse.leshan.server.security.SecurityInfo; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; @@ -75,8 +74,6 @@ public class LwM2mClient implements Cloneable { @Getter private UUID deviceId; @Getter - private UUID sessionId; - @Getter private SessionInfoProto session; @Getter private UUID profileId; @@ -120,8 +117,6 @@ public class LwM2mClient implements Cloneable { this.init = false; this.queuedRequests = new ConcurrentLinkedQueue<>(); - this.fwUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.FIRMWARE); - this.swUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.SOFTWARE); if (this.credentials != null && this.credentials.hasDeviceInfo()) { this.session = createSession(nodeId, sessionId, credentials); this.deviceId = new UUID(session.getDeviceIdMSB(), session.getDeviceIdLSB()); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java index a29edf6424..da59528fc1 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java @@ -192,7 +192,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { @Override public LwM2mClientProfile getProfile(Registration registration) { - return this.getProfiles().get(getOrRegister(registration).getProfileId()); + return this.getProfiles().get(this.getOrRegister(registration).getProfileId()); } @Override diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java index c3976c84ac..9cafc8f792 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java @@ -32,12 +32,12 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; +import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; import static org.thingsboard.server.common.data.ota.OtaPackageKey.STATE; import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey; -import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_NAME_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID; @@ -107,12 +107,16 @@ public class LwM2mFwSwUpdate { @Getter @Setter private volatile Lwm2mClientRpcRequest rpcRequest; + @Getter + @Setter + private volatile boolean typeUpdateByURL; public LwM2mFwSwUpdate(LwM2mClient lwM2MClient, OtaPackageType type) { this.lwM2MClient = lwM2MClient; this.pendingInfoRequestsStart = new CopyOnWriteArrayList<>(); this.type = type; this.stateUpdate = null; + this.typeUpdateByURL = false; this.initPathId(); } diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html index a29605a527..7c3ec6cacf 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html @@ -20,20 +20,6 @@
-
- - {{ 'device-profile.lwm2m.client-only-observe-after-connect-label' | translate }} - - {{ 'device-profile.lwm2m.client-only-observe-after-connect' | translate: - {count: 1} }} - {{ 'device-profile.lwm2m.client-only-observe-after-connect' | translate: - {count: 2} }} - - -
- +
@@ -153,6 +139,48 @@
+ + +
+
+ + {{ 'device-profile.lwm2m.client-only-observe-after-connect-label' | translate }} + + {{ 'device-profile.lwm2m.client-only-observe-after-connect' | translate: + {count: 1} }} + {{ 'device-profile.lwm2m.client-only-observe-after-connect' | translate: + {count: 2} }} + + +
+
+ + {{ 'device-profile.lwm2m.fw-update-url-label' | translate }} + + {{ 'device-profile.lwm2m.fw-update-url' | translate: + {count: 1} }} + {{ 'device-profile.lwm2m.fw-update-url' | translate: + {count: 2} }} + {{ 'device-profile.lwm2m.fw-update-url' | translate: + {count: 3} }} + + + + {{ 'device-profile.lwm2m.sw-update-url-label' | translate }} + + {{ 'device-profile.lwm2m.sw-update-url' | translate: + {count: 1} }} + {{ 'device-profile.lwm2m.sw-update-url' | translate: + {count: 2} }} + + +
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts index 0a943ab5af..3342d24791 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts @@ -80,7 +80,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro constructor(private fb: FormBuilder, private deviceProfileService: DeviceProfileService) { this.lwm2mDeviceProfileFormGroup = this.fb.group({ - clientOnlyObserveAfterConnect: [1, []], objectIds: [null, Validators.required], observeAttrTelemetry: [null, Validators.required], shortId: [null, Validators.required], @@ -90,6 +89,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro binding:[], bootstrapServer: [null, Validators.required], lwm2mServer: [null, Validators.required], + clientOnlyObserveAfterConnect: [1, []], + fwUpdateUrl: [1, []], + swUpdateUrl: [1, []], }); this.lwm2mDeviceConfigFormGroup = this.fb.group({ configurationJson: [null, Validators.required] @@ -150,7 +152,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro private updateWriteValue = (value: ModelValue): void => { this.lwm2mDeviceProfileFormGroup.patchValue({ - clientOnlyObserveAfterConnect: this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect, objectIds: value, observeAttrTelemetry: this.getObserveAttrTelemetryObjects(value.objectsList), shortId: this.configurationValue.bootstrap.servers.shortId, @@ -159,7 +160,10 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro notifIfDisabled: this.configurationValue.bootstrap.servers.notifIfDisabled, binding: this.configurationValue.bootstrap.servers.binding, bootstrapServer: this.configurationValue.bootstrap.bootstrapServer, - lwm2mServer: this.configurationValue.bootstrap.lwm2mServer + lwm2mServer: this.configurationValue.bootstrap.lwm2mServer, + clientOnlyObserveAfterConnect: this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect, + fwUpdateUrl: this.configurationValue.clientLwM2mSettings.fwUpdateUrl, + swUpdateUrl: this.configurationValue.clientLwM2mSettings.swUpdateUrl }, {emitEvent: false}); } @@ -181,8 +185,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro private updateDeviceProfileValue(config): void { if (this.lwm2mDeviceProfileFormGroup.valid) { - this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect = - config.clientOnlyObserveAfterConnect; this.updateObserveAttrTelemetryFromGroupToJson(config.observeAttrTelemetry.clientLwM2M); this.configurationValue.bootstrap.bootstrapServer = config.bootstrapServer; this.configurationValue.bootstrap.lwm2mServer = config.lwm2mServer; @@ -192,6 +194,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro bootstrapServers.defaultMinPeriod = config.defaultMinPeriod; bootstrapServers.notifIfDisabled = config.notifIfDisabled; bootstrapServers.binding = config.binding; + this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect = config.clientOnlyObserveAfterConnect; + this.configurationValue.clientLwM2mSettings.fwUpdateUrl = config.fwUpdateUrl; + this.configurationValue.clientLwM2mSettings.swUpdateUrl = config.swUpdateUrl; this.upDateJsonAllConfig(); this.updateModel(); } diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts index acea41394a..af4bdc79b0 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts @@ -166,7 +166,9 @@ export interface Lwm2mProfileConfigModels { } export interface ClientLwM2mSettings { - clientOnlyObserveAfterConnect: number; + clientOnlyObserveAfterConnect: string; + fwUpdateUrl: string; + swUpdateUrl: string; } export interface ObservableAttributes { @@ -236,7 +238,9 @@ export function getDefaultProfileConfig(hostname?: any): Lwm2mProfileConfigModel function getDefaultProfileClientLwM2mSettingsConfig(): ClientLwM2mSettings { return { - clientOnlyObserveAfterConnect: 1 + clientOnlyObserveAfterConnect: "1", + fwUpdateUrl: "1", + swUpdateUrl: "1" }; } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 08ddca091d..f23ff7c3ab 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1186,9 +1186,6 @@ "device-profile-file": "Device profile file", "invalid-device-profile-file-error": "Unable to import device profile: Invalid device profile data structure.", "lwm2m": { - "client-only-observe-after-connect-label": "Strategy", - "client-only-observe-after-connect": "{ count, plural, 1 {1: Only Observe Request to the client after the initial connection} other {2: Read All Resources & Observe Request to the client after registration} }", - "client-only-observe-after-connect-tip": "{ count, plural, 1 {Strategy 1: After the initial connection of the LWM2M Client, the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} other {Strategy 2: After the registration, request the client to read all the resource values for all objects that the LWM2M client has,\n then execute: the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} }", "object-list": "Object list", "object-list-empty": "No objects selected.", "no-objects-matching": "No objects matching '{{object}}' were found.", @@ -1236,6 +1233,7 @@ "default-min-period": "Minimum Period between two notifications (sec)", "notif-if-disabled": "Notification Storing When Disabled or Offline", "binding": "Binding", + "bootstrap-tab": "Bootstrap", "bootstrap-server": "Bootstrap Server", "lwm2m-server": "LwM2M Server", "server-host": "Host", @@ -1248,6 +1246,14 @@ "client-hold-off-time-tip": "Client Hold Off Time for use with a Bootstrap-Server only", "bootstrap-server-account-timeout": "Account after the timeout", "bootstrap-server-account-timeout-tip": "Bootstrap-Server Account after the timeout value given by this resource.", + "others-tab": "Other settings...", + "client-only-observe-after-connect-label": "Strategy", + "client-only-observe-after-connect": "{ count, plural, 1 {1: Only Observe Request to the client after the initial connection} other {2: Read All Resources & Observe Request to the client after registration} }", + "client-only-observe-after-connect-tip": "{ count, plural, 1 {Strategy 1: After the initial connection of the LWM2M Client, the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} other {Strategy 2: After the registration, request the client to read all the resource values for all objects that the LWM2M client has,\n then execute: the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} }", + "fw-update-url-label": "Firmware update strategy", + "fw-update-url": "{ count, plural, 1 {Push firmware update as binary file using Object 5 and Resource 0 (Package).} 2 {Push firmware update as binary file using Object 5 and Resource 0 (Package).} other {Push firmware update as binary file using Object 19 and Resource 0 (Data).} }", + "sw-update-url-label": "Software update strategy", + "sw-update-url": "{ count, plural, 1 {Push binary file using Object 9 and Resource 2 (Package).} other {Auto-generate unique CoAP URL to download the package and push software update using Object 9 and Resource 3 (Package URI).} }", "config-json-tab": "Json Config Profile Device" } }, From 6fbd34d6a11d9227932e44fca4e15e7020ee9ec7 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Sun, 6 Jun 2021 21:46:30 +0300 Subject: [PATCH 13/19] LWM2M: firmwareUpdate & coapRecourse --- .../widget_bundles/control_widgets.json | 2 +- .../LwM2MServerSecurityInfoRepository.java | 6 +- .../src/main/resources/thingsboard.yml | 12 +- .../LwM2MTransportBootstrapService.java | 2 +- .../lwm2m/config/LwM2MSecureServerConfig.java | 4 + .../config/LwM2MTransportBootstrapConfig.java | 7 + .../config/LwM2MTransportServerConfig.java | 16 ++ ...va => AbstractLwM2mTransportResource.java} | 4 +- .../DefaultLwM2MTransportMsgHandler.java | 216 ++++++++--------- .../server/DefaultLwM2mTransportService.java | 11 +- .../lwm2m/server/LwM2mNetworkConfig.java | 17 +- .../lwm2m/server/LwM2mOtaConvert.java | 25 ++ .../server/LwM2mTransportCoapResource.java | 75 ++---- .../server/LwM2mTransportMsgHandler.java | 4 +- .../lwm2m/server/LwM2mTransportRequest.java | 42 ++-- .../lwm2m/server/LwM2mTransportUtil.java | 228 +++++++++++++++--- .../lwm2m/server/client/LwM2mClient.java | 17 ++ .../server/client/LwM2mClientProfile.java | 30 ++- ...equest.java => LwM2mClientRpcRequest.java} | 6 +- .../lwm2m/server/client/LwM2mFwSwUpdate.java | 193 +++++++++++---- .../src/main/resources/tb-lwm2m-transport.yml | 20 +- ...ile-transport-configuration.component.html | 30 +-- ...ofile-transport-configuration.component.ts | 18 +- .../lwm2m/lwm2m-profile-config.models.ts | 12 +- .../assets/locale/locale.constant-en_US.json | 14 +- 25 files changed, 676 insertions(+), 335 deletions(-) rename common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/{AbstractLwm2mTransportResource.java => AbstractLwM2mTransportResource.java} (95%) create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mOtaConvert.java rename common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/{Lwm2mClientRpcRequest.java => LwM2mClientRpcRequest.java} (98%) diff --git a/application/src/main/data/json/system/widget_bundles/control_widgets.json b/application/src/main/data/json/system/widget_bundles/control_widgets.json index cd0d95ef2a..23b0b90ac3 100644 --- a/application/src/main/data/json/system/widget_bundles/control_widgets.json +++ b/application/src/main/data/json/system/widget_bundles/control_widgets.json @@ -18,7 +18,7 @@ "resources": [], "templateHtml": "
", "templateCss": ".cmd .cursor.blink {\n -webkit-animation-name: terminal-underline;\n -moz-animation-name: terminal-underline;\n -ms-animation-name: terminal-underline;\n animation-name: terminal-underline;\n}\n.terminal .inverted, .cmd .inverted {\n border-bottom-color: #aaa;\n}\n\n", - "controllerScript": "var requestTimeout = 500;\nvar multiParams = false;\nvar useRowStyleFunction = false;\nvar styleObj = {};\n\nself.onInit = function() {\n var subscription = self.ctx.defaultSubscription;\n var utils = self.ctx.$scope.$injector.get(self.ctx.servicesMap.get('utils'));\n var rpcEnabled = subscription.rpcEnabled;\n var deviceName = 'Simulated';\n var prompt;\n if (subscription.targetDeviceName && subscription.targetDeviceName.length) {\n deviceName = subscription.targetDeviceName;\n }\n if (self.ctx.settings.requestTimeout) {\n requestTimeout = self.ctx.settings.requestTimeout;\n }\n if (self.ctx.settings.multiParams) {\n multiParams = self.ctx.settings.multiParams;\n }\n if (self.ctx.settings.useRowStyleFunction && self.ctx.settings.rowStyleFunction) {\n try {\n var style = self.ctx.settings.rowStyleFunction;\n styleObj = JSON.parse(style);\n if ((typeof styleObj !== \"object\")) {\n styleObj = null;\n throw new URIError(`${style === null ? 'null' : typeof style} instead of style object`);\n }\n else if (typeof styleObj === \"object\" && (typeof styleObj.length) === \"number\") {\n styleObj = null;\n throw new URIError('Array instead of style object');\n }\n }\n catch (e) {\n console.log(`Row style function in widget ` +\n `returns '${e}'. Please check your row style function.`); \n }\n useRowStyleFunction = self.ctx.settings.useRowStyleFunction;\n \n }\n var greetings = 'Welcome to ThingsBoard RPC debug terminal.\\n\\n';\n if (!rpcEnabled) {\n greetings += 'Target device is not set!\\n\\n';\n prompt = '';\n } else {\n greetings += 'Current target device for RPC commands: [[b;#fff;]' + deviceName + ']\\n\\n';\n greetings += 'Please type [[b;#fff;]\\'help\\'] to see usage.\\n';\n prompt = '[[b;#8bc34a;]' + deviceName +']> ';\n }\n \n var terminal = $('#device-terminal', self.ctx.$container).terminal(\n function(command) {\n if (command !== '') {\n try {\n var localCommand = command.trim();\n var requestUUID = utils.guid();\n if (localCommand === 'help') {\n printUsage(this);\n } else {\n var cmdObj = $.terminal.parse_command(localCommand);\n if (cmdObj.args) {\n if (!multiParams && cmdObj.args.length > 1) {\n this.error(\"Wrong number of arguments!\");\n this.echo(' ');\n }\n else {\n if (cmdObj.args.length) {\n var params = getMultiParams(cmdObj.args);\n }\n performRpc(this, cmdObj.name, params, requestUUID);\n }\n }\n \n }\n } catch(e) {\n this.error(new String(e));\n }\n } else {\n this.echo('');\n }\n }, {\n greetings: greetings,\n prompt: prompt,\n enabled: rpcEnabled\n });\n \n if (styleObj && styleObj !== null) {\n terminal.css(styleObj);\n }\n \n if (!rpcEnabled) {\n terminal.error('No RPC target detected!').pause();\n }\n}\n\n\nfunction printUsage(terminal) {\n var commandsListText = '\\n[[b;#fff;]Usage:]\\n';\n commandsListText += ' [params body]]\\n\\n';\n commandsListText += '[[b;#fff;]Example 1 (multiParams===false):]\\n'; \n commandsListText += ' myRemoteMethod1 myText\\n\\n'; \n commandsListText += '[[b;#fff;]Example 2 (multiParams===false):]\\n'; \n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\":2,\\\\\"key2\\\\\":\\\\\"myVal\\\\\"}\"\\n\\n'; \n commandsListText += '[[b;#fff;]Example 3 (multiParams===true)]\\n'; \n commandsListText += ' [params body] = \"all the string after the method, including spaces\"]\\n';\n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\": \"battery level\", \\\\\"key2\\\\\": \\\\\"myVal\\\\\"}\"\\n'; \n terminal.echo(new String(commandsListText));\n}\n\nfunction performRpc(terminal, method, params, requestUUID) {\n terminal.pause();\n self.ctx.controlApi.sendTwoWayCommand(method, params, requestTimeout, requestUUID).subscribe(\n function success(responseBody) {\n terminal.echo(JSON.stringify(responseBody));\n terminal.echo(' ');\n terminal.resume();\n },\n function fail() {\n var errorText = self.ctx.defaultSubscription.rpcErrorText;\n terminal.error(errorText);\n terminal.echo(' ');\n terminal.resume();\n }\n );\n}\n\nfunction getMultiParams(cmdObj) {\n var params = \"\";\n cmdObj.forEach((element) => {\n try {\n params += \" \" + JSON.strigify(JSON.parse(element));\n } catch (e) {\n params += \" \" + element;\n }\n })\n return params.trim();\n}\n\n \nself.onDestroy = function() {\n}", + "controllerScript": "var requestTimeout = 500;\nvar multiParams = false;\nvar useRowStyleFunction = false;\nvar styleObj = {};\n\nself.onInit = function() {\n var subscription = self.ctx.defaultSubscription;\n var utils = self.ctx.$scope.$injector.get(self.ctx.servicesMap.get('utils'));\n var rpcEnabled = subscription.rpcEnabled;\n var deviceName = 'Simulated';\n var prompt;\n if (subscription.targetDeviceName && subscription.targetDeviceName.length) {\n deviceName = subscription.targetDeviceName;\n }\n if (self.ctx.settings.requestTimeout) {\n requestTimeout = self.ctx.settings.requestTimeout;\n }\n if (self.ctx.settings.multiParams) {\n multiParams = self.ctx.settings.multiParams;\n }\n if (self.ctx.settings.useRowStyleFunction && self.ctx.settings.rowStyleFunction) {\n try {\n var style = self.ctx.settings.rowStyleFunction;\n styleObj = JSON.parse(style);\n if ((typeof styleObj !== \"object\")) {\n styleObj = null;\n throw new URIError(`${style === null ? 'null' : typeof style} instead of style object`);\n }\n else if (typeof styleObj === \"object\" && (typeof styleObj.length) === \"number\") {\n styleObj = null;\n throw new URIError('Array instead of style object');\n }\n }\n catch (e) {\n console.log(`Row style function in widget ` +\n `returns '${e}'. Please check your row style function.`); \n }\n useRowStyleFunction = self.ctx.settings.useRowStyleFunction;\n \n }\n var greetings = 'Welcome to ThingsBoard RPC debug terminal.\\n\\n';\n if (!rpcEnabled) {\n greetings += 'Target device is not set!\\n\\n';\n prompt = '';\n } else {\n greetings += 'Current target device for RPC commands: [[b;#fff;]' + deviceName + ']\\n\\n';\n greetings += 'Please type [[b;#fff;]\\'help\\'] to see usage.\\n';\n prompt = '[[b;#8bc34a;]' + deviceName +']> ';\n }\n \n var terminal = $('#device-terminal', self.ctx.$container).terminal(\n function(command) {\n if (command !== '') {\n try {\n var localCommand = command.trim();\n var requestUUID = uuidv4();\n if (localCommand === 'help') {\n printUsage(this);\n } else {\n var cmdObj = $.terminal.parse_command(localCommand);\n if (cmdObj.args) {\n if (!multiParams && cmdObj.args.length > 1) {\n this.error(\"Wrong number of arguments!\");\n this.echo(' ');\n }\n else {\n if (cmdObj.args.length) {\n var params = getMultiParams(cmdObj.args);\n }\n performRpc(this, cmdObj.name, params, requestUUID);\n }\n }\n \n }\n } catch(e) {\n this.error(new String(e));\n }\n } else {\n this.echo('');\n }\n }, {\n greetings: greetings,\n prompt: prompt,\n enabled: rpcEnabled\n });\n \n if (styleObj && styleObj !== null) {\n terminal.css(styleObj);\n }\n \n if (!rpcEnabled) {\n terminal.error('No RPC target detected!').pause();\n }\n}\n\n\nfunction printUsage(terminal) {\n var commandsListText = '\\n[[b;#fff;]Usage:]\\n';\n commandsListText += ' [params body]]\\n\\n';\n commandsListText += '[[b;#fff;]Example 1 (multiParams===false):]\\n'; \n commandsListText += ' myRemoteMethod1 myText\\n\\n'; \n commandsListText += '[[b;#fff;]Example 2 (multiParams===false):]\\n'; \n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\":2,\\\\\"key2\\\\\":\\\\\"myVal\\\\\"}\"\\n\\n'; \n commandsListText += '[[b;#fff;]Example 3 (multiParams===true)]\\n'; \n commandsListText += ' [params body] = \"all the string after the method, including spaces\"]\\n';\n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\": \"battery level\", \\\\\"key2\\\\\": \\\\\"myVal\\\\\"}\"\\n'; \n terminal.echo(new String(commandsListText));\n}\n\nfunction performRpc(terminal, method, params, requestUUID) {\n terminal.pause();\n self.ctx.controlApi.sendTwoWayCommand(method, params, requestTimeout, requestUUID).subscribe(\n function success(responseBody) {\n terminal.echo(JSON.stringify(responseBody));\n terminal.echo(' ');\n terminal.resume();\n },\n function fail() {\n var errorText = self.ctx.defaultSubscription.rpcErrorText;\n terminal.error(errorText);\n terminal.echo(' ');\n terminal.resume();\n }\n );\n}\n\nfunction getMultiParams(cmdObj) {\n var params = \"\";\n cmdObj.forEach((element) => {\n try {\n params += \" \" + JSON.strigify(JSON.parse(element));\n } catch (e) {\n params += \" \" + element;\n }\n })\n return params.trim();\n}\n\n\nfunction uuidv4() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\n \nself.onDestroy = function() {\n}", "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"multiParams\": {\n \"title\": \"RPC params All line\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"useRowStyleFunction\": {\n \"title\": \"Use row style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"rowStyleFunction\": {\n \"title\": \"Row style function: f(entity, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"requestTimeout\",\n \"multiParams\",\n \"useRowStyleFunction\",\n {\n \"key\": \"rowStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useRowStyleFunction === true\"\n }\n ]\n}", "dataKeySettingsSchema": "{}\n", "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":true,\"backgroundColor\":\"#010101\",\"color\":\"rgba(255, 254, 254, 0.87)\",\"padding\":\"0px\",\"settings\":{\"parseGpioStatusFunction\":\"return body[pin] === true;\",\"gpioStatusChangeRequest\":{\"method\":\"setGpioStatus\",\"paramsBody\":\"{\\n \\\"pin\\\": \\\"{$pin}\\\",\\n \\\"enabled\\\": \\\"{$enabled}\\\"\\n}\"},\"requestTimeout\":500,\"switchPanelBackgroundColor\":\"#b71c1c\",\"gpioStatusRequest\":{\"method\":\"getGpioStatus\",\"paramsBody\":\"{}\"},\"gpioList\":[{\"pin\":1,\"label\":\"GPIO 1\",\"row\":0,\"col\":0,\"_uniqueKey\":0},{\"pin\":2,\"label\":\"GPIO 2\",\"row\":0,\"col\":1,\"_uniqueKey\":1},{\"pin\":3,\"label\":\"GPIO 3\",\"row\":1,\"col\":0,\"_uniqueKey\":2}]},\"title\":\"RPC debug terminal\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" diff --git a/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServerSecurityInfoRepository.java b/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServerSecurityInfoRepository.java index 06190cdf70..e3b09ef044 100644 --- a/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServerSecurityInfoRepository.java +++ b/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServerSecurityInfoRepository.java @@ -66,18 +66,18 @@ public class LwM2MServerSecurityInfoRepository { bsServ.setServerId(serverConfig.getId()); switch (securityMode) { case NO_SEC: - bsServ.setHost(serverConfig.getHost()); + bsServ.setHost(serverConfig.getHostRequests()); bsServ.setPort(serverConfig.getPort()); bsServ.setServerPublicKey(""); break; case PSK: - bsServ.setHost(serverConfig.getSecureHost()); + bsServ.setHost(serverConfig.getSecureHostRequests()); bsServ.setPort(serverConfig.getSecurePort()); bsServ.setServerPublicKey(""); break; case RPK: case X509: - bsServ.setHost(serverConfig.getSecureHost()); + bsServ.setHost(serverConfig.getSecureHostRequests()); bsServ.setPort(serverConfig.getSecurePort()); bsServ.setServerPublicKey(getPublicKey(serverConfig.getCertificateAlias(), this.serverConfig.getPublicX(), this.serverConfig.getPublicY())); break; diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 78658fe8fd..7925f97e89 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -639,9 +639,13 @@ transport: server: id: "${LWM2M_SERVER_ID:123}" bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}" + # the host to receive requests to the server + bind_address_requests: "${LWM2M_BIND_ADDRESS_REQUESTS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT:5685}" security: bind_address: "${LWM2M_BIND_ADDRESS_SECURITY:0.0.0.0}" + # the security host to receive requests to the server + bind_address_requests: "${LWM2M_BIND_ADDRESS_SECURITY_REQUESTS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_SECURITY:5686}" # Only for RPK: Public & Private Key. If the keystore file is missing or not working public_x: "${LWM2M_SERVER_PUBLIC_X:05064b9e6762dd8d8b8a52355d7b4d8b9a3d64e6d2ee277d76c248861353f358}" @@ -654,9 +658,13 @@ transport: enable: "${LWM2M_ENABLED_BS:true}" id: "${LWM2M_SERVER_ID_BS:111}" bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" + # the host to receive requests to the server + bind_address_requests: "${LWM2M_BIND_ADDRESS_REQUESTS_BS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_BS:5687}" security: - bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" + bind_address: "${LWM2M_BIND_ADDRESS_SECURITY_BS:0.0.0.0}" + # the security host to receive requests to the server + bind_address_requests: "${LWM2M_BIND_ADDRESS_SECURITY_REQUESTS_BS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_SECURITY_BS:5688}" # Only for RPK: Public & Private Key. If the keystore file is missing or not working public_x: "${LWM2M_SERVER_PUBLIC_X_BS:5017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f91}" @@ -675,6 +683,8 @@ transport: root_alias: "${LWM2M_SERVER_ROOT_CA:rootca}" enable_gen_new_key_psk_rpk: "${ENABLE_GEN_NEW_KEY_PSK_RPK:false}" timeout: "${LWM2M_TIMEOUT:120000}" + blockwise_lifetime: "${BLOCKWISE_LIFETIME:300000}" + block2_option_enable: "${BLOCK2_OPTION_ENABLED:true}" recommended_ciphers: "${LWM2M_RECOMMENDED_CIPHERS:false}" recommended_supported_groups: "${LWM2M_RECOMMENDED_SUPPORTED_GROUPS:true}" response_pool_size: "${LWM2M_RESPONSE_POOL_SIZE:100}" diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java index 9348cb31a5..04c2fd62fb 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java @@ -102,7 +102,7 @@ public class LwM2MTransportBootstrapService { builder.setLocalSecureAddress(bootstrapConfig.getSecureHost(), bootstrapConfig.getSecurePort()); /** Create CoAP Config */ - builder.setCoapConfig(getCoapConfig(bootstrapConfig.getPort(), bootstrapConfig.getSecurePort())); + builder.setCoapConfig(getCoapConfig(bootstrapConfig.getPort(), bootstrapConfig.getSecurePort(), serverConfig)); /** Define model provider (Create Models )*/ diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MSecureServerConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MSecureServerConfig.java index fcca9fb975..e30cc01456 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MSecureServerConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MSecureServerConfig.java @@ -21,10 +21,14 @@ public interface LwM2MSecureServerConfig { String getHost(); + String getHostRequests(); + Integer getPort(); String getSecureHost(); + String getSecureHostRequests(); + Integer getSecurePort(); String getPublicX(); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportBootstrapConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportBootstrapConfig.java index c0379f9cee..45b6aa796b 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportBootstrapConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportBootstrapConfig.java @@ -34,6 +34,10 @@ public class LwM2MTransportBootstrapConfig implements LwM2MSecureServerConfig { @Value("${transport.lwm2m.bootstrap.bind_address:}") private String host; + @Getter + @Value("${transport.lwm2m.bootstrap.bind_address_requests:}") + private String hostRequests; + @Getter @Value("${transport.lwm2m.bootstrap.bind_port:}") private Integer port; @@ -42,6 +46,9 @@ public class LwM2MTransportBootstrapConfig implements LwM2MSecureServerConfig { @Value("${transport.lwm2m.bootstrap.security.bind_address:}") private String secureHost; + @Getter + @Value("${transport.lwm2m.bootstrap.security.bind_address_requests:}") + private String secureHostRequests; @Getter @Value("${transport.lwm2m.bootstrap.security.bind_port:}") private Integer securePort; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportServerConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportServerConfig.java index 25c7766895..83601f4047 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportServerConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportServerConfig.java @@ -44,6 +44,14 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig { @Value("${transport.lwm2m.timeout:}") private Long timeout; + @Getter + @Value("${transport.lwm2m.blockwise_lifetime:}") + private Long blockwiseLifetime; + + @Getter + @Value("${transport.lwm2m.block2_option_enable:}") + private boolean block2OptionEnable; + @Getter @Value("${transport.sessions.report_timeout}") private long sessionReportTimeout; @@ -112,6 +120,10 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig { @Value("${transport.lwm2m.server.bind_address:}") private String host; + @Getter + @Value("${transport.lwm2m.server.bind_address_requests:}") + private String hostRequests; + @Getter @Value("${transport.lwm2m.server.bind_port:}") private Integer port; @@ -120,6 +132,10 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig { @Value("${transport.lwm2m.server.security.bind_address:}") private String secureHost; + @Getter + @Value("${transport.lwm2m.server.security.bind_address_requests:}") + private String secureHostRequests; + @Getter @Value("${transport.lwm2m.server.security.bind_port:}") private Integer securePort; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwM2mTransportResource.java similarity index 95% rename from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java rename to common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwM2mTransportResource.java index 50eb468b17..2c82facd23 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwm2mTransportResource.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/AbstractLwM2mTransportResource.java @@ -23,9 +23,9 @@ import org.eclipse.leshan.core.californium.LwM2mCoapResource; import org.thingsboard.server.common.transport.TransportServiceCallback; @Slf4j -public abstract class AbstractLwm2mTransportResource extends LwM2mCoapResource { +public abstract class AbstractLwM2mTransportResource extends LwM2mCoapResource { - public AbstractLwm2mTransportResource(String name) { + public AbstractLwM2mTransportResource(String name) { super(name); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index 8dc1bd64c9..d82dbcbf08 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -61,8 +61,8 @@ import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientRpcRequest; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mFwSwUpdate; -import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue; import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters; @@ -89,18 +89,17 @@ import java.util.stream.Collectors; import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; -import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED; -import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_ID; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_5_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_STATE_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_TELEMETRY; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_STRATEGY_2; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE; @@ -110,8 +109,8 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_ID; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_RESULT_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertJsonArrayToSet; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertOtaUpdateValueToString; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getAckCallback; @@ -186,7 +185,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public void onRegistered(Registration registration, Collection previousObservations) { registrationExecutor.submit(() -> { try { - log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); + String msgReg = previousObservations != null ? String.format("%s %s Client: create after Registration", registration.getEndpoint(), registration.getId()) : + String.format("%s %s Client: create after UpdateRegistration", registration.getEndpoint(), registration.getId()); + log.warn(msgReg); LwM2mClient lwM2MClient = this.clientContext.registerOrUpdate(registration); if (lwM2MClient != null) { SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); @@ -204,7 +205,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler this.getInfoFirmwareUpdate(lwM2MClient, null); this.getInfoSoftwareUpdate(lwM2MClient, null); this.initLwM2mFromClientValue(registration, lwM2MClient); - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration.getId()); + this.sendLogsToThingsboard(LOG_LW2M_INFO + ": " + msgReg, registration.getId()); } else { log.error("Client: [{}] onRegistered [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); } @@ -223,28 +224,33 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler * @param registration - Registration LwM2M Client */ public void updatedReg(Registration registration) { - updateRegistrationExecutor.submit(() -> { - try { - LwM2mClient client = clientContext.getOrRegister(registration); - if (client != null && client.getSession() != null) { - SessionInfoProto sessionInfo = client.getSession(); - this.reportActivityAndRegister(sessionInfo); - if (registration.getBindingMode().useQueueMode()) { - LwM2mQueuedRequest request; - while ((request = client.getQueuedRequests().poll()) != null) { - request.send(); + try { + LwM2mClient client = clientContext.getOrRegister(registration); + if (client != null) { + updateRegistrationExecutor.submit(() -> { + if (client != null && client.getSession() != null) { + SessionInfoProto sessionInfo = client.getSession(); + this.reportActivityAndRegister(sessionInfo); + if (registration.getBindingMode().useQueueMode()) { + LwM2mQueuedRequest request; + while ((request = client.getQueuedRequests().poll()) != null) { + request.send(); + } } + this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client update Registration", registration.getId()); + } else { + log.error("Client: [{}] updatedReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); + this.sendLogsToThingsboard(LOG_LW2M_ERROR + ": Client update Registration", registration.getId()); } - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client update Registration", registration.getId()); - } else { - log.error("Client: [{}] updatedReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); - this.sendLogsToThingsboard(LOG_LW2M_ERROR + ": Client update Registration", registration.getId()); - } - } catch (Throwable t) { - log.error("[{}] endpoint [{}] error Unable update registration.", registration.getEndpoint(), t); - this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client update Registration, %s", t.getMessage()), registration.getId()); + }); } - }); + else { + this.onRegistered(registration, null); + } + } catch (Throwable t) { + log.error("[{}] endpoint [{}] error Unable update registration.", registration.getEndpoint(), t); + this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client update Registration, %s", t.getMessage()), registration.getId()); + } } /** @@ -304,7 +310,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler * @param response - observe */ @Override - public void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest) { + public void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, LwM2mClientRpcRequest rpcRequest) { if (response.getContent() != null) { LwM2mClient lwM2MClient = clientContext.getOrRegister(registration); ObjectModel objectModelVersion = lwM2MClient.getObjectModel(path, this.config.getModelProvider()); @@ -327,7 +333,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } private void sendRpcRequestAfterReadResponse(Registration registration, LwM2mClient lwM2MClient, String pathIdVer, ReadResponse response, - Lwm2mClientRpcRequest rpcRequest) { + LwM2mClientRpcRequest rpcRequest) { Object value = null; if (response.getContent() instanceof LwM2mObject) { value = lwM2MClient.objectToString((LwM2mObject) response.getContent(), this.converter, pathIdVer); @@ -457,10 +463,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName()); if (!this.rpcSubscriptions.containsKey(requestUUID)) { this.rpcSubscriptions.put(requestUUID, toDeviceRpcRequestMsg.getExpirationTime()); - Lwm2mClientRpcRequest lwm2mClientRpcRequest = null; + LwM2mClientRpcRequest lwm2mClientRpcRequest = null; try { Registration registration = clientContext.getClient(sessionInfo).getRegistration(); - lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(lwM2mTypeOper, bodyParams, toDeviceRpcRequestMsg.getRequestId(), sessionInfo, registration, this); + lwm2mClientRpcRequest = new LwM2mClientRpcRequest(lwM2mTypeOper, bodyParams, toDeviceRpcRequestMsg.getRequestId(), sessionInfo, registration, this); if (lwm2mClientRpcRequest.getErrorMsg() != null) { lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); @@ -472,7 +478,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } } catch (Exception e) { if (lwm2mClientRpcRequest == null) { - lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(); + lwm2mClientRpcRequest = new LwM2mClientRpcRequest(); } lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); if (lwm2mClientRpcRequest.getErrorMsg() == null) { @@ -494,7 +500,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler log.warn("4.4) after rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); } - public void sentRpcResponse(Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) { + public void sentRpcResponse(LwM2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) { rpcRequest.setResponseCode(requestCode); if (LOG_LW2M_ERROR.equals(typeMsg)) { rpcRequest.setInfoMsg(null); @@ -604,7 +610,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(registration); Set clientObjects = clientContext.getSupportedIdVerInClient(registration); if (clientObjects != null && clientObjects.size() > 0) { - if (LWM2M_STRATEGY_2 == LwM2mTransportUtil.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { + if (LwM2mTransportUtil.LwM2MClientStrategy.CLIENT_STRATEGY_2.code == lwM2MClientProfile.getClientStrategy()) { // #2 lwM2MClient.getPendingReadRequests().addAll(clientObjects); clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, READ, ContentFormat.TLV.getName(), @@ -668,53 +674,11 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler lwM2MClient.getSwUpdate().initReadValue(this, this.lwM2mTransportRequest, path); } - /** - * Before operation Execute (FwUpdate) inspection Update Result : - * - after finished operation Write result: success (FwUpdate): fw_state = DOWNLOADED - * - before start operation Execute (FwUpdate) Update Result = 0 - Initial value - * - start Execute (FwUpdate) - * After finished operation Execute (FwUpdate) inspection Update Result : - * - after start operation Execute (FwUpdate): fw_state = UPDATING - * - after success finished operation Execute (FwUpdate) Update Result == 1 ("Firmware updated successfully") - * - finished operation Execute (FwUpdate) - */ - if (lwM2MClient.getFwUpdate() != null - && (convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) { - if (DOWNLOADED.name().equals(lwM2MClient.getFwUpdate().getStateUpdate()) - && lwM2MClient.getFwUpdate().conditionalFwExecuteStart()) { - lwM2MClient.getFwUpdate().executeFwSwWare(this, this.lwM2mTransportRequest); - } else if (UPDATING.name().equals(lwM2MClient.getFwUpdate().getStateUpdate()) - && lwM2MClient.getFwUpdate().conditionalFwExecuteAfterSuccess()) { - lwM2MClient.getFwUpdate().finishFwSwUpdate(this, true); - } else if (UPDATING.name().equals(lwM2MClient.getFwUpdate().getStateUpdate()) - && lwM2MClient.getFwUpdate().conditionalFwExecuteAfterError()) { - lwM2MClient.getFwUpdate().finishFwSwUpdate(this, false); - } - } - - /** - * Before operation Execute (SwUpdate) inspection Update Result : - * - after finished operation Write result: success (SwUpdate): fw_state = DOWNLOADED - * - before operation Execute (SwUpdate) Update Result = 3 - Successfully Downloaded and package integrity verified - * - start Execute (SwUpdate) - * After finished operation Execute (SwUpdate) inspection Update Result : - * - after start operation Execute (SwUpdate): fw_state = UPDATING - * - after success finished operation Execute (SwUpdate) Update Result == 2 "Software successfully installed."" - * - after success finished operation Execute (SwUpdate) Update Result == 2 "Software successfully installed."" - * - finished operation Execute (SwUpdate) - */ - if (lwM2MClient.getSwUpdate() != null - && (convertPathFromObjectIdToIdVer(SW_RESULT_ID, registration).equals(path))) { - if (DOWNLOADED.name().equals(lwM2MClient.getSwUpdate().getStateUpdate()) - && lwM2MClient.getSwUpdate().conditionalSwUpdateExecute()) { - lwM2MClient.getSwUpdate().executeFwSwWare(this, this.lwM2mTransportRequest); - } else if (UPDATING.name().equals(lwM2MClient.getSwUpdate().getStateUpdate()) - && lwM2MClient.getSwUpdate().conditionalSwExecuteAfterSuccess()) { - lwM2MClient.getSwUpdate().finishFwSwUpdate(this, true); - } else if (UPDATING.name().equals(lwM2MClient.getSwUpdate().getStateUpdate()) - && lwM2MClient.getSwUpdate().conditionalSwExecuteAfterError()) { - lwM2MClient.getSwUpdate().finishFwSwUpdate(this, false); - } + if ((convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path)) || + (convertPathFromObjectIdToIdVer(FW_STATE_ID, registration).equals(path))) { + LwM2mFwSwUpdate fwUpdate = lwM2MClient.getFwUpdate(clientContext); + log.warn("93) path: [{}] value: [{}]", path, lwM2mResource.getValue()); + fwUpdate.updateStateOta(this, lwM2mTransportRequest, registration, path, ((Long) lwM2mResource.getValue()).intValue()); } Set paths = new HashSet<>(); paths.add(path); @@ -722,6 +686,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } else { log.error("Fail update Resource [{}]", lwM2mResource); } + } @@ -869,8 +834,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler valueKvProto = new JsonObject(); Object finalvalueKvProto = valueKvProto; Gson gson = new GsonBuilder().create(); + ResourceModel.Type finalCurrentType = currentType; resourceValue.getValues().forEach((k, v) -> { - Object val = this.converter.convertValue(v, currentType, expectedType, + Object val = this.converter.convertValue(v, finalCurrentType, expectedType, new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); JsonElement element = gson.toJsonTree(val, val.getClass()); ((JsonObject) finalvalueKvProto).add(String.valueOf(k), element); @@ -880,6 +846,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler valueKvProto = this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); } + LwM2mOtaConvert lwM2mOtaConvert = convertOtaUpdateValueToString (pathIdVer, valueKvProto, currentType); + valueKvProto = lwM2mOtaConvert.getValue(); + currentType = lwM2mOtaConvert.getCurrentType(); return valueKvProto != null ? this.helper.getKvAttrTelemetryToThingsboard(currentType, resourceName, valueKvProto, resourceValue.isMultiInstances()) : null; } } catch (Exception e) { @@ -1072,7 +1041,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler * @param parametersNew - * @return ResultsAnalyzerParameters: add && new */ - private ResultsAnalyzerParameters getAnalyzerParameters(Set parametersOld, Set parametersNew) { + private ResultsAnalyzerParameters getAnalyzerParameters + (Set parametersOld, Set parametersNew) { ResultsAnalyzerParameters analyzerParameters = null; if (!parametersOld.equals(parametersNew)) { analyzerParameters = new ResultsAnalyzerParameters(); @@ -1084,7 +1054,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler return analyzerParameters; } - private ResultsAnalyzerParameters getAnalyzerParametersIn(Set parametersObserve, Set parameters) { + private ResultsAnalyzerParameters getAnalyzerParametersIn + (Set parametersObserve, Set parameters) { ResultsAnalyzerParameters analyzerParameters = new ResultsAnalyzerParameters(); analyzerParameters.setPathPostParametersAdd(parametersObserve .stream().filter(parameters::contains).collect(Collectors.toSet())); @@ -1113,7 +1084,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler }); } - private ResultsAnalyzerParameters getAnalyzerKeyName(ConcurrentHashMap keyNameOld, ConcurrentHashMap keyNameNew) { + private ResultsAnalyzerParameters getAnalyzerKeyName + (ConcurrentHashMap keyNameOld, ConcurrentHashMap keyNameNew) { ResultsAnalyzerParameters analyzerParameters = new ResultsAnalyzerParameters(); Set paths = keyNameNew.entrySet() .stream() @@ -1133,7 +1105,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler * @param attributeLwm2mNew - * @return */ - private void getAnalyzerAttributeLwm2m(Set registrationIds, JsonObject attributeLwm2mOld, JsonObject attributeLwm2mNew) { + private void getAnalyzerAttributeLwm2m(Set registrationIds, JsonObject attributeLwm2mOld, JsonObject + attributeLwm2mNew) { ResultsAnalyzerParameters analyzerParameters = new ResultsAnalyzerParameters(); ConcurrentHashMap lwm2mAttributesOld = new Gson().fromJson(attributeLwm2mOld.toString(), new TypeToken>() { @@ -1199,7 +1172,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler ); } - private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) { + private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String + path) { if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) { lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), path, WRITE_REPLACE, ContentFormat.TLV.getName(), valueNew, @@ -1245,7 +1219,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler * @param attributesResponse - * @param sessionInfo - */ - public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg attributesResponse, TransportProtos.SessionInfoProto sessionInfo) { + public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg + attributesResponse, TransportProtos.SessionInfoProto sessionInfo) { try { List tsKvProtos = attributesResponse.getSharedAttributeListList(); this.updateAttributeFromThingsboard(tsKvProtos, sessionInfo); @@ -1264,7 +1239,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler * @param tsKvProtos * @param sessionInfo */ - public void updateAttributeFromThingsboard(List tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { + public void updateAttributeFromThingsboard + (List tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo); if (lwM2MClient != null) { log.warn("1) UpdateAttributeFromThingsboard, tsKvProtos [{}]", tsKvProtos); @@ -1327,8 +1303,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler * @param sessionInfo - */ private void reportActivityAndRegister(SessionInfoProto sessionInfo) { - if (sessionInfo != null && transportService.reportActivity(sessionInfo) == null) { - transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); + if (sessionInfo != null) { + if (transportService.reportActivity(sessionInfo) == null) { + transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); + } this.reportActivitySubscription(sessionInfo); } } @@ -1365,8 +1343,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } } - public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient, Lwm2mClientRpcRequest rpcRequest) { - if (lwM2MClient.getRegistration().getSupportedVersion(FW_ID) != null) { + public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient, LwM2mClientRpcRequest rpcRequest) { + if (lwM2MClient.getRegistration().getSupportedVersion(FW_5_ID) != null) { SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); if (sessionInfo != null) { DefaultLwM2MTransportMsgHandler handler = this; @@ -1376,20 +1354,21 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) && response.getType().equals(OtaPackageType.FIRMWARE.name())) { - log.warn("7) firmware start with ver: [{}]", response.getVersion()); - lwM2MClient.setFwUpdate(new LwM2mFwSwUpdate(lwM2MClient, OtaPackageType.FIRMWARE)); -// clientContext.getProfile(lwM2MClient.getProfileId()).getPostAttributeLwm2mProfile(); - lwM2MClient.getFwUpdate().setTypeUpdateByURL(true); - lwM2MClient.getFwUpdate().setRpcRequest(rpcRequest); - lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion()); - lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle()); - log.warn("11) OtaPackageIdMSB: [{}] OtaPackageIdLSB: [{}]", response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB()); - lwM2MClient.getFwUpdate().setCurrentId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())); - - if (rpcRequest == null) { - lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest); - } else { - lwM2MClient.getFwUpdate().writeFwSwWare(handler, lwM2mTransportRequest); + LwM2mFwSwUpdate fwUpdate = lwM2MClient.getFwUpdate(clientContext); + if (!FAILED.name().equals(fwUpdate.getStateUpdate())) { + log.warn("7) firmware start with ver: [{}]", response.getVersion()); + fwUpdate.setRpcRequest(rpcRequest); + fwUpdate.setCurrentVersion(response.getVersion()); + fwUpdate.setCurrentTitle(response.getTitle()); + fwUpdate.setCurrentId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())); + if (rpcRequest == null) { + fwUpdate.sendReadObserveInfo(lwM2mTransportRequest); + } else { + fwUpdate.writeFwSwWare(handler, lwM2mTransportRequest); + } + } + else { + log.warn("7_1) OtaPackage [{}] [{}] [{}]", lwM2MClient.getDeviceName(), response.getVersion(), fwUpdate.getStateUpdate()); } } else { log.trace("OtaPackage [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); @@ -1405,7 +1384,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } } - public void getInfoSoftwareUpdate(LwM2mClient lwM2MClient, Lwm2mClientRpcRequest rpcRequest) { + public void getInfoSoftwareUpdate(LwM2mClient lwM2MClient, LwM2mClientRpcRequest rpcRequest) { if (lwM2MClient.getRegistration().getSupportedVersion(SW_ID) != null) { SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); if (sessionInfo != null) { @@ -1416,18 +1395,16 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) && response.getType().equals(OtaPackageType.SOFTWARE.name())) { - lwM2MClient.setSwUpdate(new LwM2mFwSwUpdate(lwM2MClient, OtaPackageType.SOFTWARE)); -// clientContext.getProfile(lwM2MClient.getProfileId()).getPostAttributeLwm2mProfile(); - lwM2MClient.getSwUpdate().setTypeUpdateByURL(false); - lwM2MClient.getSwUpdate().setRpcRequest(rpcRequest); - lwM2MClient.getSwUpdate().setCurrentVersion(response.getVersion()); - lwM2MClient.getSwUpdate().setCurrentTitle(response.getTitle()); - lwM2MClient.getSwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId()); - lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest); + LwM2mFwSwUpdate swUpdate = lwM2MClient.getSwUpdate(clientContext); + swUpdate.setRpcRequest(rpcRequest); + swUpdate.setCurrentVersion(response.getVersion()); + swUpdate.setCurrentTitle(response.getTitle()); + swUpdate.setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId()); + swUpdate.sendReadObserveInfo(lwM2mTransportRequest); if (rpcRequest == null) { - lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest); + swUpdate.sendReadObserveInfo(lwM2mTransportRequest); } else { - lwM2MClient.getSwUpdate().writeFwSwWare(handler, lwM2mTransportRequest); + swUpdate.writeFwSwWare(handler, lwM2mTransportRequest); } } else { log.trace("Software [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); @@ -1443,7 +1420,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } } - private TransportProtos.GetOtaPackageRequestMsg createOtaPackageRequestMsg(SessionInfoProto sessionInfo, String nameFwSW) { + private TransportProtos.GetOtaPackageRequestMsg createOtaPackageRequestMsg(SessionInfoProto sessionInfo, String + nameFwSW) { return TransportProtos.GetOtaPackageRequestMsg.newBuilder() .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java index 688ab88eeb..c0afe4fa81 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java @@ -63,8 +63,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8; import static org.thingsboard.server.transport.lwm2m.server.LwM2mNetworkConfig.getCoapConfig; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_COAP_RESOURCE; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_COAP_RESOURCE; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.OTA_COAP_RESOURCE; @Slf4j @Component @@ -104,10 +103,8 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { */ - LwM2mTransportCoapResource fwCoapResource = new LwM2mTransportCoapResource(handler, FW_COAP_RESOURCE); - LwM2mTransportCoapResource swCoapResource = new LwM2mTransportCoapResource(handler, SW_COAP_RESOURCE); - this.server.coap().getServer().add(fwCoapResource); - this.server.coap().getServer().add(swCoapResource); + LwM2mTransportCoapResource otaCoapResource = new LwM2mTransportCoapResource(handler, OTA_COAP_RESOURCE); + this.server.coap().getServer().add(otaCoapResource); this.startLhServer(); this.context.setServer(server); } @@ -138,7 +135,7 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { builder.setEncoder(new DefaultLwM2mNodeEncoder(LwM2mValueConverterImpl.getInstance())); /* Create CoAP Config */ - builder.setCoapConfig(getCoapConfig(config.getPort(), config.getSecurePort())); + builder.setCoapConfig(getCoapConfig(config.getPort(), config.getSecurePort(), config)); /* Define model provider (Create Models )*/ LwM2mModelProvider modelProvider = new LwM2mVersionedModelProvider(this.lwM2mClientContext, this.helper, this.context); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java index 280cb7dde4..9e07b0b6db 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java @@ -16,10 +16,12 @@ package org.thingsboard.server.transport.lwm2m.server; import org.eclipse.californium.core.network.config.NetworkConfig; +import org.eclipse.californium.core.network.config.NetworkConfigDefaults; +import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; public class LwM2mNetworkConfig { - public static NetworkConfig getCoapConfig(Integer serverPortNoSec, Integer serverSecurePort) { + public static NetworkConfig getCoapConfig(Integer serverPortNoSec, Integer serverSecurePort, LwM2MTransportServerConfig config) { NetworkConfig coapConfig = new NetworkConfig(); coapConfig.setInt(NetworkConfig.Keys.COAP_PORT,serverPortNoSec); coapConfig.setInt(NetworkConfig.Keys.COAP_SECURE_PORT,serverSecurePort); @@ -41,7 +43,7 @@ public class LwM2mNetworkConfig { CoAP client will try to use block mode or adapt the block size when receiving a 4.13 Entity too large response code */ - coapConfig.setBoolean(NetworkConfig.Keys.BLOCKWISE_STRICT_BLOCK2_OPTION, true); + coapConfig.setBoolean(NetworkConfig.Keys.BLOCKWISE_STRICT_BLOCK2_OPTION, config.isBlock2OptionEnable()); /** Property to indicate if the response should always include the Block2 option \ when client request early blockwise negociation but the response can be sent on one packet. @@ -49,8 +51,15 @@ public class LwM2mNetworkConfig { - value of true indicate that the server will response with block2 option event if no further blocks are required. */ coapConfig.setBoolean(NetworkConfig.Keys.BLOCKWISE_ENTITY_TOO_LARGE_AUTO_FAILOVER, true); - - coapConfig.setInt(NetworkConfig.Keys.BLOCKWISE_STATUS_LIFETIME, 300000); + /** + * The maximum amount of time (in milliseconds) allowed between + * transfers of individual blocks in a blockwise transfer before the + * blockwise transfer state is discarded. + *

+ * The default value of this property is + * {@link NetworkConfigDefaults#DEFAULT_BLOCKWISE_STATUS_LIFETIME} = 5 * 60 * 1000; // 5 mins [ms]. + */ + coapConfig.setLong(NetworkConfig.Keys.BLOCKWISE_STATUS_LIFETIME, config.getBlockwiseLifetime()); /** !!! REQUEST_ENTITY_TOO_LARGE CODE=4.13 The maximum size of a resource body (in bytes) that will be accepted diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mOtaConvert.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mOtaConvert.java new file mode 100644 index 0000000000..7b7c56adb3 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mOtaConvert.java @@ -0,0 +1,25 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.transport.lwm2m.server; + +import lombok.Data; +import org.eclipse.leshan.core.model.ResourceModel; + +@Data +public class LwM2mOtaConvert { + private ResourceModel.Type currentType; + private Object value; +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java index f2aa4dbf24..7ba491d6d1 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java @@ -30,11 +30,10 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_COAP_RESOURCE; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_COAP_RESOURCE; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.OTA_COAP_RESOURCE; @Slf4j -public class LwM2mTransportCoapResource extends AbstractLwm2mTransportResource { +public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource { private final ConcurrentMap tokenToObserveRelationMap = new ConcurrentHashMap<>(); private final ConcurrentMap tokenToObserveNotificationSeqMap = new ConcurrentHashMap<>(); private final LwM2mTransportMsgHandler handler; @@ -68,52 +67,11 @@ public class LwM2mTransportCoapResource extends AbstractLwm2mTransportResource { @Override protected void processHandleGet(CoapExchange exchange) { - log.warn("1) processHandleGet [{}]", exchange); - // exchange.respond(CoAP.ResponseCode.BAD_REQUEST); - int ver = 10; -// int ver = 9; - UUID currentId; - if (ver == 10) { - long mSB = 4951557297924280811L; - long lSb = -8451242882176289074L; - currentId = new UUID(mSB, lSb); - } else { - long mSB = 9085827945869414891L; - long lSb = -9086716326447629319L; - currentId = new UUID(mSB, lSb); + log.warn("90) processHandleGet [{}]", exchange); + if (exchange.getRequestOptions().getUriPath().size() == 2 && + OTA_COAP_RESOURCE.equals(exchange.getRequestOptions().getUriPath().get(0))) { + this.sentOtaData(exchange); } - - String coapResource = exchange.getRequestOptions().getUriPath().get(0); - String token = exchange.getRequestOptions().getUriPath().get(1); - if (exchange.getRequestOptions().getBlock2() != null) { - int chunkSize = exchange.getRequestOptions().getBlock2().getSzx(); - int chunk = 0; - Response response = new Response(CoAP.ResponseCode.CONTENT); - byte[] fwData = this.getFwData(currentId); - if (fwData != null && fwData.length > 0) { - response.setPayload(fwData); - boolean moreFlag = fwData.length > chunkSize; - response.getOptions().setBlock2(chunkSize, moreFlag, chunk); - exchange.respond(response); - } - - } -// List options = exchange.advanced().getRequest().getOptions().getUriPath(); -// options.stream() -// .filter(o -> FW_COAP_RESOURCE.equals(o)) -// .findFirst() -// .ifPresent(o -> System.err.println(o.getNumber() + " " + o.getStringValue())); - - if (FW_COAP_RESOURCE.equals(coapResource)) { - - } - else if (SW_COAP_RESOURCE.equals(coapResource)) { - - } - - - - } @Override @@ -169,7 +127,26 @@ public class LwM2mTransportCoapResource extends AbstractLwm2mTransportResource { } } - private byte[] getFwData(UUID currentId) { + private void sentOtaData (CoapExchange exchange) { + String idStr = exchange.getRequestOptions().getUriPath().get(1); + UUID currentId = UUID.fromString(idStr); + if (exchange.getRequestOptions().getBlock2() != null) { + int chunkSize = exchange.getRequestOptions().getBlock2().getSzx(); + int chunk = 0; + Response response = new Response(CoAP.ResponseCode.CONTENT); + byte[] fwData = this.getOtaData(currentId); + if (fwData != null && fwData.length > 0) { + response.setPayload(fwData); + boolean moreFlag = fwData.length > chunkSize; + response.getOptions().setBlock2(chunkSize, moreFlag, chunk); + log.warn("91) Send currentId: [{}], length: [{}], chunkSize [{}], moreFlag [{}]", currentId.toString(), fwData.length, chunkSize, moreFlag); + exchange.respond(response); + } + + } + } + + private byte[] getOtaData(UUID currentId) { return ((DefaultLwM2MTransportMsgHandler) handler).otaPackageDataCache.get(currentId.toString()); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportMsgHandler.java index 794df65db5..0ce018303c 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportMsgHandler.java @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; -import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientRpcRequest; import java.util.Collection; import java.util.Optional; @@ -39,7 +39,7 @@ public interface LwM2mTransportMsgHandler { void setCancelObservationsAll(Registration registration); - void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest); + void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, LwM2mClientRpcRequest rpcRequest); void onAttributeUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java index 98b40e74fc..f0484d521c 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java @@ -55,7 +55,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; -import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientRpcRequest; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; import javax.annotation.PostConstruct; @@ -75,7 +75,7 @@ import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWN import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getContentFormatByResourceModelType; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEFAULT_TIMEOUT; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_ID; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_5_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_UPDATE_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO; @@ -126,7 +126,7 @@ public class LwM2mTransportRequest { */ public void sendAllRequest(Registration registration, String targetIdVer, LwM2mTypeOper typeOper, - String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest lwm2mClientRpcRequest) { + String contentFormatName, Object params, long timeoutInMs, LwM2mClientRpcRequest lwm2mClientRpcRequest) { try { String target = convertPathFromIdVerToObjectId(targetIdVer); ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT; @@ -143,7 +143,7 @@ public class LwM2mTransportRequest { } catch (ClientSleepingException e) { DownlinkRequest finalRequest = request; long finalTimeoutInMs = timeoutInMs; - Lwm2mClientRpcRequest finalRpcRequest = lwm2mClientRpcRequest; + LwM2mClientRpcRequest finalRpcRequest = lwm2mClientRpcRequest; lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs, finalRpcRequest)); } catch (Exception e) { log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper.name(), e); @@ -225,7 +225,7 @@ public class LwM2mTransportRequest { private DownlinkRequest createRequest(Registration registration, LwM2mClient lwM2MClient, LwM2mTypeOper typeOper, ContentFormat contentFormat, String target, String targetIdVer, - LwM2mPath resultIds, Object params, Lwm2mClientRpcRequest rpcRequest) { + LwM2mPath resultIds, Object params, LwM2mClientRpcRequest rpcRequest) { DownlinkRequest request = null; switch (typeOper) { case READ: @@ -330,7 +330,7 @@ public class LwM2mTransportRequest { @SuppressWarnings({"error sendRequest"}) private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, - long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { + long timeoutInMs, LwM2mClientRpcRequest rpcRequest) { context.getServer().send(registration, request, timeoutInMs, (ResponseCallback) response -> { if (!lwM2MClient.isInit()) { @@ -354,13 +354,13 @@ public class LwM2mTransportRequest { /** Not Found set setClient_fw_info... = empty **/ - if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { + if (lwM2MClient.getFwUpdate() != null && lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { lwM2MClient.getFwUpdate().initReadValue(handler, this, request.getPath().toString()); } - if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { + if (lwM2MClient.getSwUpdate() != null && lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { lwM2MClient.getSwUpdate().initReadValue(handler, this, request.getPath().toString()); } - if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { + if (request.getPath().toString().equals(FW_PACKAGE_5_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { this.afterWriteFwSWUpdateError(registration, request, response.getErrorMessage()); } if (request.getPath().toString().equals(FW_UPDATE_ID) || request.getPath().toString().equals(SW_INSTALL_ID)) { @@ -371,13 +371,13 @@ public class LwM2mTransportRequest { /** version == null set setClient_fw_info... = empty **/ - if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { + if (lwM2MClient.getFwUpdate() != null && lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { lwM2MClient.getFwUpdate().initReadValue(handler, this, request.getPath().toString()); } - if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { + if (lwM2MClient.getSwUpdate() != null && lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { lwM2MClient.getSwUpdate().initReadValue(handler, this, request.getPath().toString()); } - if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { + if (request.getPath().toString().equals(FW_PACKAGE_5_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { this.afterWriteFwSWUpdateError(registration, request, e.getMessage()); } if (request.getPath().toString().equals(FW_UPDATE_ID) || request.getPath().toString().equals(SW_INSTALL_ID)) { @@ -389,7 +389,7 @@ public class LwM2mTransportRequest { String msg = String.format("%s: SendRequest %s: Resource path - %s msg error - %s", LOG_LW2M_ERROR, request.getClass().getName().toString(), request.getPath().toString(), e.getMessage()); handler.sendLogsToThingsboard(msg, registration.getId()); - log.error("[{}] [{}] - [{}] error SendRequest", request.getClass().getName().toString(), request.getPath().toString(), e.toString()); + log.error(" [{}] [{}] - [{}] error SendRequest", request.getClass().getName().toString(), request.getPath().toString(), e.toString()); if (rpcRequest != null) { handler.sentRpcResponse(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR); } @@ -398,7 +398,7 @@ public class LwM2mTransportRequest { private WriteRequest getWriteRequestSingleResource(ContentFormat contentFormat, Integer objectId, Integer instanceId, Integer resourceId, Object value, ResourceModel.Type type, - Registration registration, Lwm2mClientRpcRequest rpcRequest) { + Registration registration, LwM2mClientRpcRequest rpcRequest) { try { if (type != null) { switch (type) { @@ -444,7 +444,7 @@ public class LwM2mTransportRequest { } private void handleResponse(Registration registration, final String path, LwM2mResponse response, - DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { + DownlinkRequest request, LwM2mClientRpcRequest rpcRequest) { responseRequestExecutor.submit(() -> { try { this.sendResponse(registration, path, response, request, rpcRequest); @@ -462,7 +462,7 @@ public class LwM2mTransportRequest { * @param response - */ private void sendResponse(Registration registration, String path, LwM2mResponse response, - DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { + DownlinkRequest request, LwM2mClientRpcRequest rpcRequest) { String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); String msgLog = ""; if (response instanceof ReadResponse) { @@ -509,7 +509,7 @@ public class LwM2mTransportRequest { } } - private void infoWriteResponse(Registration registration, LwM2mResponse response, DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { + private void infoWriteResponse(Registration registration, LwM2mResponse response, DownlinkRequest request, LwM2mClientRpcRequest rpcRequest) { try { LwM2mNode node = ((WriteRequest) request).getNode(); String msg = null; @@ -546,7 +546,7 @@ public class LwM2mTransportRequest { } if (msg != null) { handler.sendLogsToThingsboard(msg, registration.getId()); - if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { + if (request.getPath().toString().equals(FW_PACKAGE_5_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { this.afterWriteSuccessFwSwUpdate(registration, request); if (rpcRequest != null) { rpcRequest.setInfoMsg(msg); @@ -568,7 +568,7 @@ public class LwM2mTransportRequest { */ private void afterWriteSuccessFwSwUpdate(Registration registration, DownlinkRequest request) { LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); - if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) { + if (request.getPath().toString().equals(FW_PACKAGE_5_ID) && lwM2MClient.getFwUpdate() != null) { lwM2MClient.getFwUpdate().setStateUpdate(DOWNLOADED.name()); lwM2MClient.getFwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null); } @@ -583,7 +583,7 @@ public class LwM2mTransportRequest { */ private void afterWriteFwSWUpdateError(Registration registration, DownlinkRequest request, String msgError) { LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); - if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) { + if (request.getPath().toString().equals(FW_PACKAGE_5_ID) && lwM2MClient.getFwUpdate() != null) { lwM2MClient.getFwUpdate().setStateUpdate(FAILED.name()); lwM2MClient.getFwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError); } @@ -603,7 +603,7 @@ public class LwM2mTransportRequest { } } - private void afterObserveCancel(Registration registration, int observeCancelCnt, String observeCancelMsg, Lwm2mClientRpcRequest rpcRequest) { + private void afterObserveCancel(Registration registration, int observeCancelCnt, String observeCancelMsg, LwM2mClientRpcRequest rpcRequest) { handler.sendLogsToThingsboard(observeCancelMsg, registration.getId()); log.warn("[{}]", observeCancelMsg); if (rpcRequest != null) { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java index 2e7681250a..9be2c24053 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java @@ -89,6 +89,11 @@ import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.VERI @Slf4j public class LwM2mTransportUtil { + public static final String EVENT_AWAKE = "AWAKE"; + public static final String RESPONSE_REQUEST_CHANNEL = "RESP_REQ"; + public static final String RESPONSE_CHANNEL = "RESP"; + public static final String OBSERVE_CHANNEL = "OBSERVE"; + public static final String TRANSPORT_DEFAULT_LWM2M_VERSION = "1.0"; public static final String CLIENT_LWM2M_SETTINGS = "clientLwM2mSettings"; public static final String BOOTSTRAP = "bootstrap"; @@ -116,9 +121,6 @@ public class LwM2mTransportUtil { public static final String LOG_LW2M_WARN = "warn"; public static final String LOG_LW2M_VALUE = "value"; - public static final int LWM2M_STRATEGY_1 = 1; - public static final int LWM2M_STRATEGY_2 = 2; - public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized"; public static final String LWM2M_VERSION_DEFAULT = "1.0"; @@ -132,19 +134,22 @@ public class LwM2mTransportUtil { public static final String FINISH_VALUE_KEY = ","; public static final String START_JSON_KEY = "{"; public static final String FINISH_JSON_KEY = "}"; - // public static final String contentFormatNameKey = "contentFormatName"; public static final String INFO_KEY = "info"; - // public static final String TIME_OUT_IN_MS = "timeOutInMs"; public static final String RESULT_KEY = "result"; public static final String ERROR_KEY = "error"; public static final String METHOD_KEY = "methodName"; + public static final String OTA_COAP_RESOURCE = "firmwarePackage"; // Firmware - public static final String FW_COAP_RESOURCE = "fw"; public static final String FW_UPDATE = "Firmware update"; - public static final Integer FW_ID = 5; + public static final Integer FW_5_ID = 5; + public static final Integer FW_19_ID = 19; + // Package W - public static final String FW_PACKAGE_ID = "/5/0/0"; + public static final String FW_PACKAGE_5_ID = "/5/0/0"; + public static final String FW_PACKAGE_19_ID = "/19/0/0"; + // Package URI + public static final String FW_PACKAGE_URI_ID = "/5/0/1"; // State R public static final String FW_STATE_ID = "/5/0/3"; // Update Result R @@ -152,16 +157,27 @@ public class LwM2mTransportUtil { // PkgName R public static final String FW_NAME_ID = "/5/0/6"; // PkgVersion R - public static final String FW_VER_ID = "/5/0/7"; + public static final String FW_5_VER_ID = "/5/0/7"; + /** + * Quectel@Hi15RM1-HLB_V1.0@BC68JAR01A10,V150R100C20B300SP7,V150R100C20B300SP7@8 + * BC68JAR01A10 + * # Request prodct type number + * ATI + * Quectel + * BC68 + * Revision:BC68JAR01A10 + */ + public static final String FW_3_VER_ID = "/3/0/3"; // Update E public static final String FW_UPDATE_ID = "/5/0/2"; // Software - public static final String SW_COAP_RESOURCE = "sw"; public static final String SW_UPDATE = "Software update"; public static final Integer SW_ID = 9; // Package W public static final String SW_PACKAGE_ID = "/9/0/2"; + // Package URI + public static final String SW_PACKAGE_URI_ID = "/9/0/3"; // Update State R public static final String SW_UPDATE_STATE_ID = "/9/0/7"; // Update Result R @@ -234,7 +250,7 @@ public class LwM2mTransportUtil { DELETE(11, "Delete"), // only for RPC - FW_UPDATE(12,"FirmwareUpdate"); + FW_UPDATE(12, "FirmwareUpdate"); // FW_READ_INFO(12, "FirmwareReadInfo"), // SW_READ_INFO(15, "SoftwareReadInfo"), @@ -357,20 +373,11 @@ public class LwM2mTransportUtil { * FirmwareUpdateStatus { * DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED */ - public static OtaPackageUpdateStatus EqualsFwSateToFirmwareUpdateStatus(StateFw stateFw, UpdateResultFw updateResultFw) { + public static OtaPackageUpdateStatus equalsFwSateFwResultToFirmwareUpdateStatus(StateFw stateFw, UpdateResultFw updateResultFw) { switch (updateResultFw) { case INITIAL: - switch (stateFw) { - case IDLE: - return VERIFIED; - case DOWNLOADING: - return DOWNLOADING; - case DOWNLOADED: - return DOWNLOADED; - case UPDATING: - return UPDATING; - } - case UPDATE_SUCCESSFULLY: + return equalsFwSateToFirmwareUpdateStatus(stateFw); + case UPDATE_SUCCESSFULLY: return UPDATED; case NOT_ENOUGH: case OUT_OFF_MEMORY: @@ -386,6 +393,41 @@ public class LwM2mTransportUtil { } } + public static OtaPackageUpdateStatus equalsFwResultToFirmwareUpdateStatus(UpdateResultFw updateResultFw) { + switch (updateResultFw) { + case INITIAL: + return VERIFIED; + case UPDATE_SUCCESSFULLY: + return UPDATED; + case NOT_ENOUGH: + case OUT_OFF_MEMORY: + case CONNECTION_LOST: + case INTEGRITY_CHECK_FAILURE: + case UNSUPPORTED_TYPE: + case INVALID_URI: + case UPDATE_FAILED: + case UNSUPPORTED_PROTOCOL: + return FAILED; + default: + throw new CodecException("Invalid value stateFw %s for FirmwareUpdateStatus.", updateResultFw.name()); + } + } + + public static OtaPackageUpdateStatus equalsFwSateToFirmwareUpdateStatus(StateFw stateFw) { + switch (stateFw) { + case IDLE: + return VERIFIED; + case DOWNLOADING: + return DOWNLOADING; + case DOWNLOADED: + return DOWNLOADED; + case UPDATING: + return UPDATING; + default: + throw new CodecException("Invalid value stateFw %d for FirmwareUpdateStatus.", stateFw); + } + } + /** * SW Update State R * 0: INITIAL Before downloading. (see 5.1.2.1) @@ -499,6 +541,101 @@ public class LwM2mTransportUtil { } } + public enum LwM2MClientStrategy { + CLIENT_STRATEGY_1(1, "Read only resources marked as observation"), + CLIENT_STRATEGY_2(2, "Read all client resources"); + + public int code; + public String type; + + LwM2MClientStrategy(int code, String type) { + this.code = code; + this.type = type; + } + + public static LwM2MClientStrategy fromStrategyClientByType(String type) { + for (LwM2MClientStrategy to : LwM2MClientStrategy.values()) { + if (to.type.equals(type)) { + return to; + } + } + throw new IllegalArgumentException(String.format("Unsupported Client Strategy type : %s", type)); + } + + public static LwM2MClientStrategy fromStrategyClientByCode(int code) { + for (LwM2MClientStrategy to : LwM2MClientStrategy.values()) { + if (to.code == code) { + return to; + } + } + throw new IllegalArgumentException(String.format("Unsupported Client Strategy code : %s", code)); + } + } + + public enum LwM2MFirmwareUpdateStrategy { + OBJ_5_BINARY(1, "ObjectId 5, Binary"), + OBJ_5_TEMP_URL(2, "ObjectId 5, URI"), + OBJ_19_BINARY(3, "ObjectId 19, Binary"); + + public int code; + public String type; + + LwM2MFirmwareUpdateStrategy(int code, String type) { + this.code = code; + this.type = type; + } + + public static LwM2MFirmwareUpdateStrategy fromStrategyFwByType(String type) { + for (LwM2MFirmwareUpdateStrategy to : LwM2MFirmwareUpdateStrategy.values()) { + if (to.type.equals(type)) { + return to; + } + } + throw new IllegalArgumentException(String.format("Unsupported FW State type : %s", type)); + } + + public static LwM2MFirmwareUpdateStrategy fromStrategyFwByCode(int code) { + for (LwM2MFirmwareUpdateStrategy to : LwM2MFirmwareUpdateStrategy.values()) { + if (to.code == code) { + return to; + } + } + throw new IllegalArgumentException(String.format("Unsupported FW Strategy code : %s", code)); + } + } + + public enum LwM2MSoftwareUpdateStrategy { + BINARY(1, "ObjectId 9, Binary"), + TEMP_URL(2, "ObjectId 9, URI"); + + public int code; + public String type; + + LwM2MSoftwareUpdateStrategy(int code, String type) { + this.code = code; + this.type = type; + } + + public static LwM2MSoftwareUpdateStrategy fromStrategySwByType(String type) { + for (LwM2MSoftwareUpdateStrategy to : LwM2MSoftwareUpdateStrategy.values()) { + if (to.type.equals(type)) { + return to; + } + } + throw new IllegalArgumentException(String.format("Unsupported SW Strategy type : %s", type)); + } + + public static LwM2MSoftwareUpdateStrategy fromStrategySwByCode(int code) { + for (LwM2MSoftwareUpdateStrategy to : LwM2MSoftwareUpdateStrategy.values()) { + if (to.code == code) { + return to; + } + } + throw new IllegalArgumentException(String.format("Unsupported SW Strategy code : %s", code)); + } + + } + /** * FirmwareUpdateStatus { * DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED @@ -536,10 +673,6 @@ public class LwM2mTransportUtil { } } - public static final String EVENT_AWAKE = "AWAKE"; - public static final String RESPONSE_REQUEST_CHANNEL = "RESP_REQ"; - public static final String RESPONSE_CHANNEL = "RESP"; - public static final String OBSERVE_CHANNEL = "OBSERVE"; public static boolean equalsResourceValue(Object valueOld, Object valueNew, ResourceModel.Type type, LwM2mPath resourcePath) throws CodecException { @@ -560,6 +693,36 @@ public class LwM2mTransportUtil { } } + public static LwM2mOtaConvert convertOtaUpdateValueToString (String pathIdVer, Object value, ResourceModel.Type currentType) { + String path = convertPathFromIdVerToObjectId(pathIdVer); + LwM2mOtaConvert lwM2mOtaConvert = new LwM2mOtaConvert(); + if (path != null) { + if (FW_STATE_ID.equals(path)) { + lwM2mOtaConvert.setCurrentType(STRING); + lwM2mOtaConvert.setValue(StateFw.fromStateFwByCode(((Long) value).intValue()).type); + return lwM2mOtaConvert; + } + else if (FW_RESULT_ID.equals(path)) { + lwM2mOtaConvert.setCurrentType(STRING); + lwM2mOtaConvert.setValue(UpdateResultFw.fromUpdateResultFwByCode(((Long) value).intValue()).type); + return lwM2mOtaConvert; + } + else if (SW_UPDATE_STATE_ID.equals(path)) { + lwM2mOtaConvert.setCurrentType(STRING); + lwM2mOtaConvert.setValue(UpdateStateSw.fromUpdateStateSwByCode(((Long) value).intValue()).type); + return lwM2mOtaConvert; + } + else if (SW_RESULT_ID.equals(path)) { + lwM2mOtaConvert.setCurrentType(STRING); + lwM2mOtaConvert.setValue(UpdateResultSw.fromUpdateResultSwByCode(((Long) value).intValue()).type); + return lwM2mOtaConvert; + } + } + lwM2mOtaConvert.setCurrentType(currentType); + lwM2mOtaConvert.setValue(value); + return lwM2mOtaConvert; + } + public static LwM2mNode getLvM2mNodeToObject(LwM2mNode content) { if (content instanceof LwM2mObject) { return (LwM2mObject) content; @@ -635,11 +798,6 @@ public class LwM2mTransportUtil { return null; } - public static int getClientOnlyObserveAfterConnect(LwM2mClientProfile profile) { - return profile.getPostClientLwM2mSettings().getAsJsonObject().has("clientOnlyObserveAfterConnect") ? - profile.getPostClientLwM2mSettings().getAsJsonObject().get("clientOnlyObserveAfterConnect").getAsInt() : 1; - } - private static boolean getValidateCredentialsBodyFromThingsboard(JsonObject objectMsg) { return (objectMsg != null && !objectMsg.isJsonNull() && @@ -916,7 +1074,7 @@ public class LwM2mTransportUtil { case GREATER_THAN: case LESSER_THAN: case STEP: - if (value.getClass().getSimpleName().equals("String") ) { + if (value.getClass().getSimpleName().equals("String")) { value = Double.valueOf((String) value); } return serviceImpl.converter.convertValue(value, equalsResourceTypeGetSimpleName(value), FLOAT, new LwM2mPath(target)); @@ -930,11 +1088,11 @@ public class LwM2mTransportUtil { return new Attribute(key, attrValue); } catch (Exception e) { log.error("CreateAttribute, not valid parameter key: [{}], attrValue: [{}], error: [{}]", key, attrValue, e.getMessage()); - return null; + return null; } } - public static boolean isFwSwWords (String pathName) { + public static boolean isFwSwWords(String pathName) { return OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.VERSION).equals(pathName) || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.TITLE).equals(pathName) || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.CHECKSUM).equals(pathName) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java index 602596ed2b..1ebc9ac66e 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java @@ -31,6 +31,7 @@ import org.eclipse.leshan.server.registration.Registration; import org.eclipse.leshan.server.security.SecurityInfo; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; @@ -361,5 +362,21 @@ public class LwM2mClient implements Cloneable { } } + public LwM2mFwSwUpdate getFwUpdate (LwM2mClientContext clientContext) { + if (this.fwUpdate == null) { + LwM2mClientProfile lwM2mClientProfile = clientContext.getProfile(this.getProfileId()); + this.fwUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.FIRMWARE, lwM2mClientProfile.getFwUpdateStrategy()); + } + return this.fwUpdate; + } + + public LwM2mFwSwUpdate getSwUpdate (LwM2mClientContext clientContext) { + if (this.swUpdate == null) { + LwM2mClientProfile lwM2mClientProfile = clientContext.getProfile(this.getProfileId()); + this.swUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.SOFTWARE, lwM2mClientProfile.getSwUpdateStrategy()); + } + return this.fwUpdate; + } + } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientProfile.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientProfile.java index 19af453f3c..67edbf2747 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientProfile.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientProfile.java @@ -20,15 +20,23 @@ import com.google.gson.JsonArray; import com.google.gson.JsonObject; import lombok.Data; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2MClientStrategy; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2MSoftwareUpdateStrategy; @Data public class LwM2mClientProfile { + private final String clientStrategyStr = "clientStrategy"; + private final String fwUpdateStrategyStr = "fwUpdateStrategy"; + private final String swUpdateStrategyStr = "swUpdateStrategy"; private TenantId tenantId; /** - * {"clientLwM2mSettings": { - * clientUpdateValueAfterConnect: false; - * } + * "clientLwM2mSettings": { + * "fwUpdateStrategy": "1", + * "swUpdateStrategy": "1", + * "clientStrategy": "1" + * } **/ private JsonObject postClientLwM2mSettings; @@ -85,5 +93,21 @@ public class LwM2mClientProfile { } } + public int getClientStrategy() { + return this.postClientLwM2mSettings.getAsJsonObject().has(this.clientStrategyStr) ? + Integer.parseInt(this.postClientLwM2mSettings.getAsJsonObject().get(this.clientStrategyStr).getAsString()) : + LwM2MClientStrategy.CLIENT_STRATEGY_1.code; + } + public int getFwUpdateStrategy() { + return this.postClientLwM2mSettings.getAsJsonObject().has(this.fwUpdateStrategyStr) ? + Integer.parseInt(this.postClientLwM2mSettings.getAsJsonObject().get(this.fwUpdateStrategyStr).getAsString()) : + LwM2MFirmwareUpdateStrategy.OBJ_5_BINARY.code; + } + + public int getSwUpdateStrategy() { + return this.postClientLwM2mSettings.getAsJsonObject().has(this.swUpdateStrategyStr) ? + Integer.parseInt(this.postClientLwM2mSettings.getAsJsonObject().get(this.swUpdateStrategyStr).getAsString()) : + LwM2MSoftwareUpdateStrategy.BINARY.code; + } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientRpcRequest.java similarity index 98% rename from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java rename to common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientRpcRequest.java index d71c6b27f6..ca831b1413 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientRpcRequest.java @@ -57,7 +57,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.v @Slf4j @Data -public class Lwm2mClientRpcRequest { +public class LwM2mClientRpcRequest { private Registration registration; private TransportProtos.SessionInfoProto sessionInfo; @@ -75,10 +75,10 @@ public class Lwm2mClientRpcRequest { private String infoMsg; private String responseCode; - public Lwm2mClientRpcRequest() { + public LwM2mClientRpcRequest() { } - public Lwm2mClientRpcRequest(LwM2mTypeOper lwM2mTypeOper, String bodyParams, int requestId, + public LwM2mClientRpcRequest(LwM2mTypeOper lwM2mTypeOper, String bodyParams, int requestId, TransportProtos.SessionInfoProto sessionInfo, Registration registration, DefaultLwM2MTransportMsgHandler handler) { this.registration = registration; this.sessionInfo = sessionInfo; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java index 9cafc8f792..97496b91ce 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java @@ -20,6 +20,7 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.eclipse.leshan.core.request.ContentFormat; +import org.eclipse.leshan.server.registration.Registration; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus; import org.thingsboard.server.gen.transport.TransportProtos; @@ -36,20 +37,31 @@ import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; import static org.thingsboard.server.common.data.ota.OtaPackageKey.STATE; import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.INITIATED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATED; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_3_VER_ID; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_5_VER_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_NAME_ID; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_ID; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_19_ID; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_5_ID; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_URI_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_STATE_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_UPDATE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_UPDATE_ID; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_VER_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_19_BINARY; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_5_BINARY; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_5_TEMP_URL; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.OTA_COAP_RESOURCE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_INSTALL_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_NAME_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_PACKAGE_ID; @@ -59,6 +71,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.S import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_UPDATE_STATE_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_VER_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.equalsFwSateToFirmwareUpdateStatus; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.splitCamelCaseString; @Slf4j @@ -106,27 +119,29 @@ public class LwM2mFwSwUpdate { private final List pendingInfoRequestsStart; @Getter @Setter - private volatile Lwm2mClientRpcRequest rpcRequest; + private volatile LwM2mClientRpcRequest rpcRequest; @Getter @Setter - private volatile boolean typeUpdateByURL; + private volatile int updateStrategy; - public LwM2mFwSwUpdate(LwM2mClient lwM2MClient, OtaPackageType type) { + public LwM2mFwSwUpdate(LwM2mClient lwM2MClient, OtaPackageType type, int updateStrategy) { this.lwM2MClient = lwM2MClient; this.pendingInfoRequestsStart = new CopyOnWriteArrayList<>(); this.type = type; this.stateUpdate = null; - this.typeUpdateByURL = false; + this.updateStrategy = updateStrategy; this.initPathId(); } private void initPathId() { if (FIRMWARE.equals(this.type)) { - this.pathPackageId = FW_PACKAGE_ID; + this.pathPackageId = LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_5_BINARY.code == this.updateStrategy ? + FW_PACKAGE_5_ID : LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_5_TEMP_URL.code == this.updateStrategy ? + FW_PACKAGE_URI_ID : FW_PACKAGE_19_ID; this.pathStateId = FW_STATE_ID; this.pathResultId = FW_RESULT_ID; this.pathNameId = FW_NAME_ID; - this.pathVerId = FW_VER_ID; + this.pathVerId = FW_5_VER_ID; this.pathInstallId = FW_UPDATE_ID; this.wUpdate = FW_UPDATE; } else if (SOFTWARE.equals(this.type)) { @@ -147,13 +162,13 @@ public class LwM2mFwSwUpdate { } if (this.pendingInfoRequestsStart.size() == 0) { this.infoFwSwUpdate = false; - if (!OtaPackageUpdateStatus.DOWNLOADING.name().equals(this.stateUpdate)) { - boolean conditionalStart = this.type.equals(FIRMWARE) ? this.conditionalFwUpdateStart() : - this.conditionalSwUpdateStart(); - if (conditionalStart) { - this.writeFwSwWare(handler, request); - } +// if (!FAILED.name().equals(this.stateUpdate)) { + boolean conditionalStart = this.type.equals(FIRMWARE) ? this.conditionalFwUpdateStart(handler) : + this.conditionalSwUpdateStart(handler); + if (conditionalStart) { + this.writeFwSwWare(handler, request); } +// } } } @@ -163,31 +178,42 @@ public class LwM2mFwSwUpdate { */ public void writeFwSwWare(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) { if (this.currentId != null) { - this.stateUpdate = OtaPackageUpdateStatus.DOWNLOADING.name(); + this.stateUpdate = OtaPackageUpdateStatus.INITIATED.name(); this.sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null); - int chunkSize = 0; - int chunk = 0; - byte[] firmwareChunk = handler.otaPackageDataCache.get(this.currentId.toString(), chunkSize, chunk); String targetIdVer = convertPathFromObjectIdToIdVer(this.pathPackageId, this.lwM2MClient.getRegistration()); String fwMsg = String.format("%s: Start type operation %s paths: %s", LOG_LW2M_INFO, - LwM2mTransportUtil.LwM2mTypeOper.FW_UPDATE.name(), FW_PACKAGE_ID); + LwM2mTransportUtil.LwM2mTypeOper.FW_UPDATE.name(), this.pathPackageId); handler.sendLogsToThingsboard(fwMsg, lwM2MClient.getRegistration().getId()); log.warn("8) Start firmware Update. Send save to: [{}] ver: [{}] path: [{}]", this.lwM2MClient.getDeviceName(), this.currentVersion, targetIdVer); - request.sendAllRequest(this.lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, ContentFormat.OPAQUE.getName(), - firmwareChunk, handler.config.getTimeout(), this.rpcRequest); + if (LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_5_BINARY.code == this.updateStrategy) { + int chunkSize = 0; + int chunk = 0; + byte[] firmwareChunk = handler.otaPackageDataCache.get(this.currentId.toString(), chunkSize, chunk); + request.sendAllRequest(this.lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, ContentFormat.OPAQUE.getName(), + firmwareChunk, handler.config.getTimeout(), this.rpcRequest); + } else if (LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_5_TEMP_URL.code == this.updateStrategy) { + Registration registration = this.getLwM2MClient().getRegistration(); + String api = handler.config.getHostRequests(); + int port = registration.getIdentity().isSecure() ? handler.config.getSecurePort() : handler.config.getPort(); + String uri = "coap://" + api + ":" + Integer.valueOf(port) + "/" + OTA_COAP_RESOURCE + "/" + this.currentId.toString(); + request.sendAllRequest(this.lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, null, + uri, handler.config.getTimeout(), this.rpcRequest); + } else if (LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_19_BINARY.code == this.updateStrategy) { + + } } else { String msgError = "FirmWareId is null."; log.warn("6) [{}]", msgError); if (this.rpcRequest != null) { handler.sentRpcResponse(this.rpcRequest, CONTENT.name(), msgError, LOG_LW2M_ERROR); } - log.error (msgError); + log.error(msgError); this.sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError); } } public void sendLogs(DefaultLwM2MTransportMsgHandler handler, String typeOper, String typeInfo, String msgError) { - this.sendSateOnThingsBoard(handler); +// this.sendSateOnThingsBoard(handler); String msg = String.format("%s: %s, %s, pkgVer: %s: pkgName - %s state - %s.", typeInfo, this.wUpdate, typeOper, this.currentVersion, this.currentTitle, this.stateUpdate); if (LOG_LW2M_ERROR.equals(typeInfo)) { @@ -203,32 +229,50 @@ public class LwM2mFwSwUpdate { * send execute */ public void executeFwSwWare(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) { - this.setStateUpdate(UPDATING.name()); this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null); request.sendAllRequest(this.lwM2MClient.getRegistration(), this.pathInstallId, EXECUTE, ContentFormat.TLV.getName(), null, 0, this.rpcRequest); } /** - * Firmware start: + * Firmware start: Check if the version has changed and launch a new update. + * -ObjectId 5, Binary or ObjectId 5, URI * -- If the result of the update - errors (more than 1) - This means that the previous. the update failed. * - We launch the update regardless of the state of the firmware and its version. - * -- If the result of the update is not errors (equal to 1 or 0) and ver is not empty - This means that before the update has passed. - * -- If the result of the update is not errors and is empty - This means that there has not been an update yet. - * - Check if the version has changed and launch a new update. + * -- If the result of the update - errors (more than 1) - This means that the previous. the update failed. + * * ObjectId 5, Binary + * -- If the result of the update is not errors (equal to 1 or 0) and ver in Object 5 is not empty - it means that the previous update has passed. + * Compare current versions by equals. + * * ObjectId 5, URI + * -- If the result of the update is not errors (equal to 1 or 0) and ver in Object 5 is not empty - it means that the previous update has passed. + * Compare current versions by contains. */ - private boolean conditionalFwUpdateStart() { + private boolean conditionalFwUpdateStart(DefaultLwM2MTransportMsgHandler handler) { Long updateResultFw = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId); + String ver5 = (String) this.lwM2MClient.getResourceValue(null, this.pathVerId); + String pathName = (String) this.lwM2MClient.getResourceValue(null, this.pathNameId); + String ver3 = (String) this.lwM2MClient.getResourceValue(null, FW_3_VER_ID); // #1/#2 - return updateResultFw > LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code || - ( - (updateResultFw <= LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code - ) && - ( - (this.currentVersion != null && !this.currentVersion.equals(this.lwM2MClient.getResourceValue(null, this.pathVerId))) || - (this.currentTitle != null && !this.currentTitle.equals(this.lwM2MClient.getResourceValue(null, this.pathNameId))) - ) - ); + String fwMsg = null; + if ((this.currentVersion != null && ( + ver5 != null && ver5.equals(this.currentVersion) || + ver3 != null && ver3.contains(this.currentVersion) + )) || + (this.currentTitle != null && pathName != null && this.currentTitle.equals(pathName))) { + fwMsg = String.format("%s: The update was interrupted. The device has the same version: %s.", LOG_LW2M_ERROR, + this.currentVersion); + } + else if (updateResultFw != null && updateResultFw > LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code) { + fwMsg = String.format("%s: The update was interrupted. The device has the status UpdateResult: error (%d).", LOG_LW2M_ERROR, + updateResultFw); + } + if (fwMsg != null) { + handler.sendLogsToThingsboard(fwMsg, lwM2MClient.getRegistration().getId()); + return false; + } + else { + return true; + } } @@ -252,7 +296,7 @@ public class LwM2mFwSwUpdate { /** * After operation Execute success inspection Update Result : - * > 1 error: "Firmware updated successfully" + * > 1 error: "Firmware updated successfully" */ public boolean conditionalFwExecuteAfterError() { Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId); @@ -268,7 +312,7 @@ public class LwM2mFwSwUpdate { * - If Update Result is not errors and ver is not empty - This means that before unInstall update * * - Check if the version has changed and launch a new update. */ - private boolean conditionalSwUpdateStart() { + private boolean conditionalSwUpdateStart(DefaultLwM2MTransportMsgHandler handler) { Long updateResultSw = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId); // #1/#2 return updateResultSw >= LwM2mTransportUtil.UpdateResultSw.NOT_ENOUGH_STORAGE.code || @@ -296,7 +340,7 @@ public class LwM2mFwSwUpdate { * -- inspection Update Result: * ---- FW если Update Result == 1 ("Firmware updated successfully") или SW если Update Result == 2 ("Software successfully installed.") * -- fw_state/sw_state = UPDATED - * + *

* After finish operation Execute (error): * -- inspection updateResult and send to thingsboard info about error * --- send to telemetry ( key - this is name Update Result in model) ( @@ -329,7 +373,7 @@ public class LwM2mFwSwUpdate { /** * After operation Execute success inspection Update Result : - * >= 50 - error "NOT_ENOUGH_STORAGE" + * >= 50 - error "NOT_ENOUGH_STORAGE" */ public boolean conditionalSwExecuteAfterError() { Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId); @@ -358,18 +402,75 @@ public class LwM2mFwSwUpdate { public void sendReadObserveInfo(LwM2mTransportRequest request) { this.infoFwSwUpdate = true; - this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer( - this.pathVerId, this.lwM2MClient.getRegistration())); - this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer( - this.pathNameId, this.lwM2MClient.getRegistration())); this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer( this.pathStateId, this.lwM2MClient.getRegistration())); this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer( this.pathResultId, this.lwM2MClient.getRegistration())); + this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer( + FW_3_VER_ID, this.lwM2MClient.getRegistration())); + if (LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_5_BINARY.code == this.updateStrategy || + LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_19_BINARY.code == this.updateStrategy || + SOFTWARE.equals(this.type)) { + this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer( + this.pathVerId, this.lwM2MClient.getRegistration())); + this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer( + this.pathNameId, this.lwM2MClient.getRegistration())); + } this.pendingInfoRequestsStart.forEach(pathIdVer -> { request.sendAllRequest(this.lwM2MClient.getRegistration(), pathIdVer, OBSERVE, ContentFormat.TLV.getName(), null, 0, this.rpcRequest); }); } + + /** + * Before operation Execute (FwUpdate) inspection Update Result : + * - after finished operation Write result: success (FwUpdate): fw_state = DOWNLOADED + * - before start operation Execute (FwUpdate) Update Result = 0 - Initial value + * - start Execute (FwUpdate) + * After finished operation Execute (FwUpdate) inspection Update Result : + * - after start operation Execute (FwUpdate): fw_state = UPDATING + * - after success finished operation Execute (FwUpdate) Update Result == 1 ("Firmware updated successfully") + * - finished operation Execute (FwUpdate) + */ + public void updateStateOta(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request, + Registration registration, String path, int value) { + if (OBJ_5_BINARY.code == this.getUpdateStrategy()) { + if ((convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) { + if (DOWNLOADED.name().equals(this.getStateUpdate()) + && this.conditionalFwExecuteStart()) { + this.executeFwSwWare(handler, request); + } else if (UPDATING.name().equals(this.getStateUpdate()) + && this.conditionalFwExecuteAfterSuccess()) { + this.finishFwSwUpdate(handler, true); + } else if (UPDATING.name().equals(this.getStateUpdate()) + && this.conditionalFwExecuteAfterError()) { + this.finishFwSwUpdate(handler, false); + } + } + } else if (OBJ_5_TEMP_URL.code == this.getUpdateStrategy()) { + if ((convertPathFromObjectIdToIdVer(FW_STATE_ID, registration).equals(path))) { + String state = equalsFwSateToFirmwareUpdateStatus(LwM2mTransportUtil.StateFw.fromStateFwByCode(value)).name(); + if (!FAILED.name().equals(this.stateUpdate) && StringUtils.isNotEmpty(state) && !state.equals(this.stateUpdate)) { + this.stateUpdate = state; + this.sendSateOnThingsBoard(handler); + } + if (value == LwM2mTransportUtil.StateFw.DOWNLOADED.code) { + this.executeFwSwWare(handler, request); + } + } + if ((convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) { + if (value == LwM2mTransportUtil.UpdateResultFw.INITIAL.code) { + this.setStateUpdate(INITIATED.name()); + } else if (value == LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code) { + this.setStateUpdate(UPDATED.name()); + } else if (value > LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code) { + this.setStateUpdate(FAILED.name()); + } + this.sendSateOnThingsBoard(handler); + } + } else if (OBJ_19_BINARY.code == this.getUpdateStrategy()) { + + } + } } diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index 39acda4590..261d1c79f1 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -104,9 +104,13 @@ transport: server: id: "${LWM2M_SERVER_ID:123}" bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}" + # the host to receive requests to the server + bind_address_requests: "${LWM2M_BIND_ADDRESS_REQUESTS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT:5685}" security: bind_address: "${LWM2M_BIND_ADDRESS_SECURITY:0.0.0.0}" + # the security host to receive requests to the server + bind_address_requests: "${LWM2M_BIND_ADDRESS_SECURITY_REQUESTS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_SECURITY:5686}" # Only for RPK: Public & Private Key. If the keystore file is missing or not working public_x: "${LWM2M_SERVER_PUBLIC_X:05064b9e6762dd8d8b8a52355d7b4d8b9a3d64e6d2ee277d76c248861353f358}" @@ -114,13 +118,18 @@ transport: private_encoded: "${LWM2M_SERVER_PRIVATE_ENCODED:308193020100301306072a8648ce3d020106082a8648ce3d030107047930770201010420dc774b309e547ceb48fee547e104ce201a9c48c449dc5414cd04e7f5cf05f67ba00a06082a8648ce3d030107a1440342000405064b9e6762dd8d8b8a52355d7b4d8b9a3d64e6d2ee277d76c248861353f3585eeb1838e4f9e37b31fa347aef5ce3431eb54e0a2506910c5e0298817445721b}" # Only Certificate_x509: alias: "${LWM2M_KEYSTORE_ALIAS_SERVER:server}" + skip_validity_check_for_client_cert: "${TB_LWM2M_SERVER_SECURITY_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}" bootstrap: enable: "${LWM2M_ENABLED_BS:true}" id: "${LWM2M_SERVER_ID_BS:111}" bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" + # the host to receive requests to the server + bind_address_requests: "${LWM2M_BIND_ADDRESS_REQUESTS_BS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_BS:5687}" security: - bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" + bind_address: "${LWM2M_BIND_ADDRESS_SECURITY_BS:0.0.0.0}" + # the security host to receive requests to the server + bind_address_requests: "${LWM2M_BIND_ADDRESS_SECURITY_REQUESTS_BS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_SECURITY_BS:5688}" # Only for RPK: Public & Private Key. If the keystore file is missing or not working public_x: "${LWM2M_SERVER_PUBLIC_X_BS:5017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f91}" @@ -139,6 +148,8 @@ transport: root_alias: "${LWM2M_SERVER_ROOT_CA:rootca}" enable_gen_new_key_psk_rpk: "${ENABLE_GEN_NEW_KEY_PSK_RPK:false}" timeout: "${LWM2M_TIMEOUT:120000}" + blockwise_lifetime: "${BLOCKWISE_LIFETIME:300000}" + block2_option_enable: "${BLOCK2_OPTION_ENABLED:true}" recommended_ciphers: "${LWM2M_RECOMMENDED_CIPHERS:false}" recommended_supported_groups: "${LWM2M_RECOMMENDED_SUPPORTED_GROUPS:true}" response_pool_size: "${LWM2M_RESPONSE_POOL_SIZE:100}" @@ -150,6 +161,13 @@ transport: log_max_length: "${LWM2M_LOG_MAX_LENGTH:100}" # Use redis for Security and Registration stores redis.enabled: "${LWM2M_REDIS_ENABLED:false}" + snmp: + enabled: "${SNMP_ENABLED:true}" + response_processing: + # parallelism level for executor (workStealingPool) that is responsible for handling responses from SNMP devices + parallelism_level: "${SNMP_RESPONSE_PROCESSING_PARALLELISM_LEVEL:20}" + # to configure SNMP to work over UDP or TCP + underlying_protocol: "${SNMP_UNDERLYING_PROTOCOL:udp}" queue: type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ) diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html index 7c3ec6cacf..b164e168cf 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html @@ -144,36 +144,36 @@

- {{ 'device-profile.lwm2m.client-only-observe-after-connect-label' | translate }} - {{ 'device-profile.lwm2m.client-strategy-label' | translate }} + - {{ 'device-profile.lwm2m.client-only-observe-after-connect' | translate: + {{ 'device-profile.lwm2m.client-strategy' | translate: {count: 1} }} - {{ 'device-profile.lwm2m.client-only-observe-after-connect' | translate: + {{ 'device-profile.lwm2m.client-strategy' | translate: {count: 2} }}
- {{ 'device-profile.lwm2m.fw-update-url-label' | translate }} - - {{ 'device-profile.lwm2m.fw-update-url' | translate: + {{ 'device-profile.lwm2m.fw-update-strategy-label' | translate }} + + {{ 'device-profile.lwm2m.fw-update-strategy' | translate: {count: 1} }} - {{ 'device-profile.lwm2m.fw-update-url' | translate: + {{ 'device-profile.lwm2m.fw-update-strategy' | translate: {count: 2} }} - {{ 'device-profile.lwm2m.fw-update-url' | translate: + {{ 'device-profile.lwm2m.fw-update-strategy' | translate: {count: 3} }} - {{ 'device-profile.lwm2m.sw-update-url-label' | translate }} - - {{ 'device-profile.lwm2m.sw-update-url' | translate: + {{ 'device-profile.lwm2m.sw-update-strategy-label' | translate }} + + {{ 'device-profile.lwm2m.sw-update-strategy' | translate: {count: 1} }} - {{ 'device-profile.lwm2m.sw-update-url' | translate: + {{ 'device-profile.lwm2m.sw-update-strategy' | translate: {count: 2} }} diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts index 3342d24791..886ed12c47 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts @@ -89,9 +89,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro binding:[], bootstrapServer: [null, Validators.required], lwm2mServer: [null, Validators.required], - clientOnlyObserveAfterConnect: [1, []], - fwUpdateUrl: [1, []], - swUpdateUrl: [1, []], + clientStrategy: [1, []], + fwUpdateStrategy: [1, []], + swUpdateStrategy: [1, []], }); this.lwm2mDeviceConfigFormGroup = this.fb.group({ configurationJson: [null, Validators.required] @@ -161,9 +161,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro binding: this.configurationValue.bootstrap.servers.binding, bootstrapServer: this.configurationValue.bootstrap.bootstrapServer, lwm2mServer: this.configurationValue.bootstrap.lwm2mServer, - clientOnlyObserveAfterConnect: this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect, - fwUpdateUrl: this.configurationValue.clientLwM2mSettings.fwUpdateUrl, - swUpdateUrl: this.configurationValue.clientLwM2mSettings.swUpdateUrl + clientStrategy: this.configurationValue.clientLwM2mSettings.clientStrategy, + fwUpdateStrategy: this.configurationValue.clientLwM2mSettings.fwUpdateStrategy, + swUpdateStrategy: this.configurationValue.clientLwM2mSettings.swUpdateStrategy }, {emitEvent: false}); } @@ -194,9 +194,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro bootstrapServers.defaultMinPeriod = config.defaultMinPeriod; bootstrapServers.notifIfDisabled = config.notifIfDisabled; bootstrapServers.binding = config.binding; - this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect = config.clientOnlyObserveAfterConnect; - this.configurationValue.clientLwM2mSettings.fwUpdateUrl = config.fwUpdateUrl; - this.configurationValue.clientLwM2mSettings.swUpdateUrl = config.swUpdateUrl; + this.configurationValue.clientLwM2mSettings.clientStrategy = config.clientStrategy; + this.configurationValue.clientLwM2mSettings.fwUpdateStrategy = config.fwUpdateStrategy; + this.configurationValue.clientLwM2mSettings.swUpdateStrategy = config.swUpdateStrategy; this.upDateJsonAllConfig(); this.updateModel(); } diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts index af4bdc79b0..48613f58de 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts @@ -166,9 +166,9 @@ export interface Lwm2mProfileConfigModels { } export interface ClientLwM2mSettings { - clientOnlyObserveAfterConnect: string; - fwUpdateUrl: string; - swUpdateUrl: string; + clientStrategy: string; + fwUpdateStrategy: string; + swUpdateStrategy: string; } export interface ObservableAttributes { @@ -238,9 +238,9 @@ export function getDefaultProfileConfig(hostname?: any): Lwm2mProfileConfigModel function getDefaultProfileClientLwM2mSettingsConfig(): ClientLwM2mSettings { return { - clientOnlyObserveAfterConnect: "1", - fwUpdateUrl: "1", - swUpdateUrl: "1" + clientStrategy: "1", + fwUpdateStrategy: "1", + swUpdateStrategy: "1" }; } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index d0209301fa..f6d86e4e84 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1247,13 +1247,13 @@ "bootstrap-server-account-timeout": "Account after the timeout", "bootstrap-server-account-timeout-tip": "Bootstrap-Server Account after the timeout value given by this resource.", "others-tab": "Other settings...", - "client-only-observe-after-connect-label": "Strategy", - "client-only-observe-after-connect": "{ count, plural, 1 {1: Only Observe Request to the client after the initial connection} other {2: Read All Resources & Observe Request to the client after registration} }", - "client-only-observe-after-connect-tip": "{ count, plural, 1 {Strategy 1: After the initial connection of the LWM2M Client, the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} other {Strategy 2: After the registration, request the client to read all the resource values for all objects that the LWM2M client has,\n then execute: the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} }", - "fw-update-url-label": "Firmware update strategy", - "fw-update-url": "{ count, plural, 1 {Push firmware update as binary file using Object 5 and Resource 0 (Package).} 2 {Push firmware update as binary file using Object 5 and Resource 0 (Package).} other {Push firmware update as binary file using Object 19 and Resource 0 (Data).} }", - "sw-update-url-label": "Software update strategy", - "sw-update-url": "{ count, plural, 1 {Push binary file using Object 9 and Resource 2 (Package).} other {Auto-generate unique CoAP URL to download the package and push software update using Object 9 and Resource 3 (Package URI).} }", + "client-strategy-label": "Strategy", + "client-strategy-connect": "{ count, plural, 1 {1: Only Observe Request to the client after the initial connection} other {2: Read All Resources & Observe Request to the client after registration} }", + "client-strategy-tip": "{ count, plural, 1 {Strategy 1: After the initial connection of the LWM2M Client, the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} other {Strategy 2: After the registration, request the client to read all the resource values for all objects that the LWM2M client has,\n then execute: the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} }", + "fw-update-strategy-label": "Firmware update strategy", + "fw-update-strategy": "{ count, plural, 1 {Push firmware update as binary file using Object 5 and Resource 0 (Package).} 2 {Auto-generate unique CoAP URL to download the package and push firmware update as Object 5 and Resource 1 (Package URI).} other {Push firmware update as binary file using Object 19 and Resource 0 (Data).} }", + "sw-update-strategy-label": "Software update strategy", + "sw-update-strategy": "{ count, plural, 1 {Push binary file using Object 9 and Resource 2 (Package).} other {Auto-generate unique CoAP URL to download the package and push software update using Object 9 and Resource 3 (Package URI).} }", "config-json-tab": "Json Config Profile Device" } }, From f38fc26dcbb0758815483488c2dfa94f3d0625ac Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Sun, 6 Jun 2021 22:31:54 +0300 Subject: [PATCH 14/19] LWM2M: merge with master --- .../lwm2m/server/DefaultLwM2MTransportMsgHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index d82dbcbf08..10f2dfeff5 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -461,7 +461,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler log.warn("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, requestUUID); String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null"; LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName()); - if (!this.rpcSubscriptions.containsKey(requestUUID)) { +// if (!this.rpcSubscriptions.containsKey(requestUUID)) { this.rpcSubscriptions.put(requestUUID, toDeviceRpcRequestMsg.getExpirationTime()); LwM2mClientRpcRequest lwm2mClientRpcRequest = null; try { @@ -486,7 +486,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); } - } +// } } private void checkRpcRequestTimeout() { From 99dc49db26b70ab5af397a0c95b19a73c1c7bddd Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Mon, 7 Jun 2021 08:56:09 +0300 Subject: [PATCH 15/19] LWM2M: six bug send log fw_state --- .../transport/lwm2m/server/client/LwM2mFwSwUpdate.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java index 97496b91ce..410d5a2e9a 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java @@ -449,9 +449,9 @@ public class LwM2mFwSwUpdate { } } } else if (OBJ_5_TEMP_URL.code == this.getUpdateStrategy()) { - if ((convertPathFromObjectIdToIdVer(FW_STATE_ID, registration).equals(path))) { + if (this.currentId != null && (convertPathFromObjectIdToIdVer(FW_STATE_ID, registration).equals(path))) { String state = equalsFwSateToFirmwareUpdateStatus(LwM2mTransportUtil.StateFw.fromStateFwByCode(value)).name(); - if (!FAILED.name().equals(this.stateUpdate) && StringUtils.isNotEmpty(state) && !state.equals(this.stateUpdate)) { + if (StringUtils.isNotEmpty(state) && !FAILED.name().equals(this.stateUpdate) && !state.equals(this.stateUpdate)) { this.stateUpdate = state; this.sendSateOnThingsBoard(handler); } @@ -460,9 +460,9 @@ public class LwM2mFwSwUpdate { } } if ((convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) { - if (value == LwM2mTransportUtil.UpdateResultFw.INITIAL.code) { + if (this.currentId != null && value == LwM2mTransportUtil.UpdateResultFw.INITIAL.code) { this.setStateUpdate(INITIATED.name()); - } else if (value == LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code) { + } else if (this.currentId != null && value == LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code) { this.setStateUpdate(UPDATED.name()); } else if (value > LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code) { this.setStateUpdate(FAILED.name()); From 9fd2d34e7c466c9465037cf33c78deae511f03e9 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Mon, 7 Jun 2021 21:15:12 +0300 Subject: [PATCH 16/19] LWM2M: add update Firmware from terminal --- .../DefaultLwM2MTransportMsgHandler.java | 81 ++++++++++++------- .../server/client/LwM2mClientContext.java | 2 + .../server/client/LwM2mClientContextImpl.java | 42 +++++----- .../lwm2m/server/client/LwM2mFwSwUpdate.java | 1 + 4 files changed, 73 insertions(+), 53 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index 10f2dfeff5..9304a36e60 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -90,6 +90,7 @@ import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.INITIATED; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST; @@ -139,7 +140,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public final LwM2mClientContext clientContext; public final LwM2mTransportRequest lwM2mTransportRequest; private final Map rpcSubscriptions; - private final Map getCoapResource; + public final Map firmwareUpdateState; public DefaultLwM2MTransportMsgHandler(TransportService transportService, LwM2MTransportServerConfig config, LwM2mTransportServerHelper helper, LwM2mClientContext clientContext, @@ -155,7 +156,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler this.context = context; this.adaptor = adaptor; this.rpcSubscriptions = new ConcurrentHashMap<>(); - this.getCoapResource = new ConcurrentHashMap<>(); + this.firmwareUpdateState = new ConcurrentHashMap<>(); this.sessionStore = sessionStore; } @@ -187,7 +188,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler try { String msgReg = previousObservations != null ? String.format("%s %s Client: create after Registration", registration.getEndpoint(), registration.getId()) : String.format("%s %s Client: create after UpdateRegistration", registration.getEndpoint(), registration.getId()); - log.warn(msgReg); + log.warn(msgReg); LwM2mClient lwM2MClient = this.clientContext.registerOrUpdate(registration); if (lwM2MClient != null) { SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); @@ -202,7 +203,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder() .setSessionType(TransportProtos.SessionType.ASYNC).build()) .build(), null); - this.getInfoFirmwareUpdate(lwM2MClient, null); + if (!(this.firmwareUpdateState.containsKey(lwM2MClient.getEndpoint()) && this.firmwareUpdateState.get(lwM2MClient.getEndpoint()) == 3)) { + this.getInfoFirmwareUpdate(lwM2MClient, null); + } this.getInfoSoftwareUpdate(lwM2MClient, null); this.initLwM2mFromClientValue(registration, lwM2MClient); this.sendLogsToThingsboard(LOG_LW2M_INFO + ": " + msgReg, registration.getId()); @@ -243,8 +246,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler this.sendLogsToThingsboard(LOG_LW2M_ERROR + ": Client update Registration", registration.getId()); } }); - } - else { + } else { this.onRegistered(registration, null); } } catch (Throwable t) { @@ -458,35 +460,43 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler // #1 this.checkRpcRequestTimeout(); UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB()); - log.warn("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, requestUUID); + log.warn("4) toDeviceRpcRequestMsg: [{}], requestUUID: [{}]", toDeviceRpcRequestMsg, requestUUID); String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null"; LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName()); -// if (!this.rpcSubscriptions.containsKey(requestUUID)) { + if (!this.rpcSubscriptions.containsKey(requestUUID)) { this.rpcSubscriptions.put(requestUUID, toDeviceRpcRequestMsg.getExpirationTime()); LwM2mClientRpcRequest lwm2mClientRpcRequest = null; try { - Registration registration = clientContext.getClient(sessionInfo).getRegistration(); - lwm2mClientRpcRequest = new LwM2mClientRpcRequest(lwM2mTypeOper, bodyParams, toDeviceRpcRequestMsg.getRequestId(), sessionInfo, registration, this); - if (lwm2mClientRpcRequest.getErrorMsg() != null) { - lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); - this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); + Registration registration = clientContext.getRegistration(sessionInfo); + if (registration != null) { + lwm2mClientRpcRequest = new LwM2mClientRpcRequest(lwM2mTypeOper, bodyParams, toDeviceRpcRequestMsg.getRequestId(), sessionInfo, registration, this); + if (lwm2mClientRpcRequest.getErrorMsg() != null) { + lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); + this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); + } else { + lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), + null, + lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), + this.config.getBlockwiseLifetime(), lwm2mClientRpcRequest); + } } else { - lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), - null, - lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), - this.config.getTimeout(), lwm2mClientRpcRequest); + this.sentErrorRpcResponse(lwm2mClientRpcRequest, "registration == null", sessionInfo); } } catch (Exception e) { - if (lwm2mClientRpcRequest == null) { - lwm2mClientRpcRequest = new LwM2mClientRpcRequest(); - } - lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); - if (lwm2mClientRpcRequest.getErrorMsg() == null) { - lwm2mClientRpcRequest.setErrorMsg(e.getMessage()); - } - this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); + this.sentErrorRpcResponse(lwm2mClientRpcRequest, e.getMessage(), sessionInfo); } -// } + } + } + + private void sentErrorRpcResponse(LwM2mClientRpcRequest lwm2mClientRpcRequest, String msgError, SessionInfoProto sessionInfo) { + if (lwm2mClientRpcRequest == null) { + lwm2mClientRpcRequest = new LwM2mClientRpcRequest(); + } + lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); + if (lwm2mClientRpcRequest.getErrorMsg() == null) { + lwm2mClientRpcRequest.setErrorMsg(msgError); + } + this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); } private void checkRpcRequestTimeout() { @@ -846,7 +856,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler valueKvProto = this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); } - LwM2mOtaConvert lwM2mOtaConvert = convertOtaUpdateValueToString (pathIdVer, valueKvProto, currentType); + LwM2mOtaConvert lwM2mOtaConvert = convertOtaUpdateValueToString(pathIdVer, valueKvProto, currentType); valueKvProto = lwM2mOtaConvert.getValue(); currentType = lwM2mOtaConvert.getCurrentType(); return valueKvProto != null ? this.helper.getKvAttrTelemetryToThingsboard(currentType, resourceName, valueKvProto, resourceValue.isMultiInstances()) : null; @@ -1355,6 +1365,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) && response.getType().equals(OtaPackageType.FIRMWARE.name())) { LwM2mFwSwUpdate fwUpdate = lwM2MClient.getFwUpdate(clientContext); + if (rpcRequest != null) { + fwUpdate.setStateUpdate(INITIATED.name()); + } if (!FAILED.name().equals(fwUpdate.getStateUpdate())) { log.warn("7) firmware start with ver: [{}]", response.getVersion()); fwUpdate.setRpcRequest(rpcRequest); @@ -1366,12 +1379,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } else { fwUpdate.writeFwSwWare(handler, lwM2mTransportRequest); } - } - else { - log.warn("7_1) OtaPackage [{}] [{}] [{}]", lwM2MClient.getDeviceName(), response.getVersion(), fwUpdate.getStateUpdate()); + } else { + String msgError = String.format("OtaPackage device: %s, version: %s, stateUpdate: %s", + lwM2MClient.getDeviceName(), response.getVersion(), fwUpdate.getStateUpdate()); + log.warn("7_1 [{}]", msgError); } } else { - log.trace("OtaPackage [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); + String msgError = String.format("OtaPackage device: %s, responseStatus: %s", + lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); + log.trace(msgError); + if (rpcRequest != null) { + sentErrorRpcResponse(rpcRequest, msgError, sessionInfo); + } } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java index bb3e97b7e4..2773c4c989 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java @@ -35,6 +35,8 @@ public interface LwM2mClientContext { LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo); + Registration getRegistration(TransportProtos.SessionInfoProto sessionInfo); + LwM2mClient getOrRegister(Registration registration); LwM2mClient registerOrUpdate(Registration registration); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java index da59528fc1..50a1cf5c17 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java @@ -73,7 +73,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { if (registration == null) { return client; } - if (lwM2mClientsByRegistrationId.size()>0) { + if (lwM2mClientsByRegistrationId.size() > 0) { client = this.lwM2mClientsByRegistrationId.get(registration.getId()); } if (client == null) { @@ -91,32 +91,31 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { Predicate isClientFilter = c -> (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))); -// if (this.lwM2mClientsByEndpoint.size()>0) { -// lwM2mClient = this.lwM2mClientsByEndpoint.values().stream().filter(c -> -// (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) -// .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) -// ).findAny().get(); -// } - if (this.lwM2mClientsByEndpoint.size()>0) { - lwM2mClient = this.lwM2mClientsByEndpoint.values().stream().filter(isClientFilter).findAny().get(); + if (this.lwM2mClientsByEndpoint.size() > 0) { + lwM2mClient = this.lwM2mClientsByEndpoint.values().stream().filter(isClientFilter).findAny().orElse(null); } -// if (lwM2mClient == null && this.lwM2mClientsByRegistrationId.size() > 0) { -// lwM2mClient = this.lwM2mClientsByRegistrationId.values().stream().filter(c -> -// (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) -// .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) -// ).findAny().get(); -// } if (lwM2mClient == null && this.lwM2mClientsByRegistrationId.size() > 0) { - lwM2mClient = this.lwM2mClientsByRegistrationId.values().stream().filter(isClientFilter).findAny().get(); + lwM2mClient = this.lwM2mClientsByRegistrationId.values().stream().filter(isClientFilter).findAny().orElse(null); } - if (lwM2mClient == null){ + if (lwM2mClient == null) { log.warn("Device TimeOut? lwM2mClient is null."); - log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}]", sessionInfo, lwM2mClientsByEndpoint.values().size()); + log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}] lwM2mClientsByRegistrationId: [{}]", sessionInfo, lwM2mClientsByEndpoint.values(), lwM2mClientsByRegistrationId.values()); log.error("", new RuntimeException()); } return lwM2mClient; } + @Override + public Registration getRegistration(TransportProtos.SessionInfoProto sessionInfo) { + Registration registration = this.getClient(sessionInfo).getRegistration(); + if (registration == null) { + log.warn("Device TimeOut? registration is null."); + log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}]", sessionInfo, lwM2mClientsByEndpoint.values().size()); + log.error("", new RuntimeException()); + } + return registration; + } + @Override public LwM2mClient registerOrUpdate(Registration registration) { LwM2mClient lwM2MClient = lwM2mClientsByEndpoint.get(registration.getEndpoint()); @@ -139,10 +138,10 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { EndpointSecurityInfo securityInfo = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endpoint, LwM2mTransportUtil.LwM2mTypeServer.CLIENT); if (securityInfo.getSecurityMode() != null) { if (securityInfo.getDeviceProfile() != null) { - UUID profileUuid = profileUpdate(securityInfo.getDeviceProfile())!= null ? + UUID profileUuid = profileUpdate(securityInfo.getDeviceProfile()) != null ? securityInfo.getDeviceProfile().getUuidId() : null; // TODO: for tests bug. - if (profileUuid== null) { + if (profileUuid == null) { log.trace("input parameters toClientProfile if the result is null: [{}]", securityInfo.getDeviceProfile()); } LwM2mClient client; @@ -207,8 +206,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { if (lwM2MClientProfile != null) { profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile); return lwM2MClientProfile; - } - else { + } else { return null; } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java index 410d5a2e9a..a4efc35cf4 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java @@ -458,6 +458,7 @@ public class LwM2mFwSwUpdate { if (value == LwM2mTransportUtil.StateFw.DOWNLOADED.code) { this.executeFwSwWare(handler, request); } + handler.firmwareUpdateState.put(lwM2MClient.getEndpoint(), value); } if ((convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) { if (this.currentId != null && value == LwM2mTransportUtil.UpdateResultFw.INITIAL.code) { From 090fde16b4f98caa9c8fd3889c9dad5aa44b054a Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 8 Jun 2021 11:27:49 +0300 Subject: [PATCH 17/19] LWM2M: add new log.warn --- .../server/DefaultLwM2MTransportMsgHandler.java | 12 ++++++++---- .../lwm2m/server/LwM2mTransportCoapResource.java | 3 ++- .../lwm2m/server/client/LwM2mFwSwUpdate.java | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index 9304a36e60..e286cc6570 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -274,8 +274,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler private void removeClientCash(Registration registration) { SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registration); if (sessionInfo != null) { -// transportService.deregisterSession(sessionInfo); -// this.doCloseSession(sessionInfo); + transportService.deregisterSession(sessionInfo); + this.doCloseSession(sessionInfo); sessionStore.remove(registration.getEndpoint()); clientContext.removeClientByRegistrationId(registration.getId()); @@ -1283,7 +1283,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler if (lwM2MClient != null) { SessionInfoProto sessionInfoProto = lwM2MClient.getSession(); if (sessionInfoProto == null) { - log.info("[{}] [{}]", lwM2MClient.getEndpoint(), CLIENT_NOT_AUTHORIZED); + log.trace("[{}] [{}]", lwM2MClient.getEndpoint(), CLIENT_NOT_AUTHORIZED); this.removeClientCash(lwM2MClient.getRegistration()); } return sessionInfoProto; @@ -1322,7 +1322,11 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } private void reportActivity() { - clientContext.getLwM2mClients().forEach(client -> reportActivityAndRegister(client.getSession())); + clientContext.getLwM2mClients().forEach(client -> { + log.warn("0_01) reportActivity clientEndpoint: [{}] session: [{}]", client.getEndpoint(), client.getSession()); + reportActivityAndRegister(client.getSession()); + } + ); } /** diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java index 7ba491d6d1..b185d18a28 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java @@ -135,11 +135,12 @@ public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource { int chunk = 0; Response response = new Response(CoAP.ResponseCode.CONTENT); byte[] fwData = this.getOtaData(currentId); + log.warn("91) read softWare data (length): [{}]", fwData.length); if (fwData != null && fwData.length > 0) { response.setPayload(fwData); boolean moreFlag = fwData.length > chunkSize; response.getOptions().setBlock2(chunkSize, moreFlag, chunk); - log.warn("91) Send currentId: [{}], length: [{}], chunkSize [{}], moreFlag [{}]", currentId.toString(), fwData.length, chunkSize, moreFlag); + log.warn("92) Send currentId: [{}], length: [{}], chunkSize [{}], moreFlag [{}]", currentId.toString(), fwData.length, chunkSize, moreFlag); exchange.respond(response); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java index a4efc35cf4..f1728cdea6 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java @@ -196,6 +196,7 @@ public class LwM2mFwSwUpdate { String api = handler.config.getHostRequests(); int port = registration.getIdentity().isSecure() ? handler.config.getSecurePort() : handler.config.getPort(); String uri = "coap://" + api + ":" + Integer.valueOf(port) + "/" + OTA_COAP_RESOURCE + "/" + this.currentId.toString(); + log.warn("89) coapUri: [{}]", uri); request.sendAllRequest(this.lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, null, uri, handler.config.getTimeout(), this.rpcRequest); } else if (LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_19_BINARY.code == this.updateStrategy) { From c3bfb7626effdbb2f707e8c2da084cb3688c2d5b Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 8 Jun 2021 15:16:23 +0300 Subject: [PATCH 18/19] LWM2M: del from yml --- .../lwm2m/LwM2MServerSecurityInfoRepository.java | 6 +++--- application/src/main/resources/thingsboard.yml | 10 ---------- .../lwm2m/config/LwM2MSecureServerConfig.java | 4 ---- .../lwm2m/config/LwM2MTransportServerConfig.java | 16 ---------------- .../server/DefaultLwM2mTransportService.java | 4 ++-- .../lwm2m/server/LwM2mNetworkConfig.java | 6 ++++-- .../lwm2m/server/LwM2mTransportCoapResource.java | 8 +++++--- .../lwm2m/server/LwM2mTransportUtil.java | 4 +++- .../lwm2m/server/client/LwM2mFwSwUpdate.java | 7 ++++--- .../src/main/resources/tb-lwm2m-transport.yml | 10 ---------- .../src/assets/locale/locale.constant-en_US.json | 6 ++++++ 11 files changed, 27 insertions(+), 54 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServerSecurityInfoRepository.java b/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServerSecurityInfoRepository.java index e3b09ef044..06190cdf70 100644 --- a/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServerSecurityInfoRepository.java +++ b/application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServerSecurityInfoRepository.java @@ -66,18 +66,18 @@ public class LwM2MServerSecurityInfoRepository { bsServ.setServerId(serverConfig.getId()); switch (securityMode) { case NO_SEC: - bsServ.setHost(serverConfig.getHostRequests()); + bsServ.setHost(serverConfig.getHost()); bsServ.setPort(serverConfig.getPort()); bsServ.setServerPublicKey(""); break; case PSK: - bsServ.setHost(serverConfig.getSecureHostRequests()); + bsServ.setHost(serverConfig.getSecureHost()); bsServ.setPort(serverConfig.getSecurePort()); bsServ.setServerPublicKey(""); break; case RPK: case X509: - bsServ.setHost(serverConfig.getSecureHostRequests()); + bsServ.setHost(serverConfig.getSecureHost()); bsServ.setPort(serverConfig.getSecurePort()); bsServ.setServerPublicKey(getPublicKey(serverConfig.getCertificateAlias(), this.serverConfig.getPublicX(), this.serverConfig.getPublicY())); break; diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 7925f97e89..54721ba2fa 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -639,13 +639,9 @@ transport: server: id: "${LWM2M_SERVER_ID:123}" bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}" - # the host to receive requests to the server - bind_address_requests: "${LWM2M_BIND_ADDRESS_REQUESTS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT:5685}" security: bind_address: "${LWM2M_BIND_ADDRESS_SECURITY:0.0.0.0}" - # the security host to receive requests to the server - bind_address_requests: "${LWM2M_BIND_ADDRESS_SECURITY_REQUESTS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_SECURITY:5686}" # Only for RPK: Public & Private Key. If the keystore file is missing or not working public_x: "${LWM2M_SERVER_PUBLIC_X:05064b9e6762dd8d8b8a52355d7b4d8b9a3d64e6d2ee277d76c248861353f358}" @@ -658,13 +654,9 @@ transport: enable: "${LWM2M_ENABLED_BS:true}" id: "${LWM2M_SERVER_ID_BS:111}" bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" - # the host to receive requests to the server - bind_address_requests: "${LWM2M_BIND_ADDRESS_REQUESTS_BS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_BS:5687}" security: bind_address: "${LWM2M_BIND_ADDRESS_SECURITY_BS:0.0.0.0}" - # the security host to receive requests to the server - bind_address_requests: "${LWM2M_BIND_ADDRESS_SECURITY_REQUESTS_BS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_SECURITY_BS:5688}" # Only for RPK: Public & Private Key. If the keystore file is missing or not working public_x: "${LWM2M_SERVER_PUBLIC_X_BS:5017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f91}" @@ -683,8 +675,6 @@ transport: root_alias: "${LWM2M_SERVER_ROOT_CA:rootca}" enable_gen_new_key_psk_rpk: "${ENABLE_GEN_NEW_KEY_PSK_RPK:false}" timeout: "${LWM2M_TIMEOUT:120000}" - blockwise_lifetime: "${BLOCKWISE_LIFETIME:300000}" - block2_option_enable: "${BLOCK2_OPTION_ENABLED:true}" recommended_ciphers: "${LWM2M_RECOMMENDED_CIPHERS:false}" recommended_supported_groups: "${LWM2M_RECOMMENDED_SUPPORTED_GROUPS:true}" response_pool_size: "${LWM2M_RESPONSE_POOL_SIZE:100}" diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MSecureServerConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MSecureServerConfig.java index e30cc01456..fcca9fb975 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MSecureServerConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MSecureServerConfig.java @@ -21,14 +21,10 @@ public interface LwM2MSecureServerConfig { String getHost(); - String getHostRequests(); - Integer getPort(); String getSecureHost(); - String getSecureHostRequests(); - Integer getSecurePort(); String getPublicX(); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportServerConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportServerConfig.java index 83601f4047..25c7766895 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportServerConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportServerConfig.java @@ -44,14 +44,6 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig { @Value("${transport.lwm2m.timeout:}") private Long timeout; - @Getter - @Value("${transport.lwm2m.blockwise_lifetime:}") - private Long blockwiseLifetime; - - @Getter - @Value("${transport.lwm2m.block2_option_enable:}") - private boolean block2OptionEnable; - @Getter @Value("${transport.sessions.report_timeout}") private long sessionReportTimeout; @@ -120,10 +112,6 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig { @Value("${transport.lwm2m.server.bind_address:}") private String host; - @Getter - @Value("${transport.lwm2m.server.bind_address_requests:}") - private String hostRequests; - @Getter @Value("${transport.lwm2m.server.bind_port:}") private Integer port; @@ -132,10 +120,6 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig { @Value("${transport.lwm2m.server.security.bind_address:}") private String secureHost; - @Getter - @Value("${transport.lwm2m.server.security.bind_address_requests:}") - private String secureHostRequests; - @Getter @Value("${transport.lwm2m.server.security.bind_port:}") private Integer securePort; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java index c0afe4fa81..0c99aae9ce 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java @@ -63,7 +63,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8; import static org.thingsboard.server.transport.lwm2m.server.LwM2mNetworkConfig.getCoapConfig; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.OTA_COAP_RESOURCE; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FIRMWARE_UPDATE_COAP_RECOURSE; @Slf4j @Component @@ -103,7 +103,7 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { */ - LwM2mTransportCoapResource otaCoapResource = new LwM2mTransportCoapResource(handler, OTA_COAP_RESOURCE); + LwM2mTransportCoapResource otaCoapResource = new LwM2mTransportCoapResource(handler, FIRMWARE_UPDATE_COAP_RECOURSE); this.server.coap().getServer().add(otaCoapResource); this.startLhServer(); this.context.setServer(server); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java index 9e07b0b6db..00f70dbcf7 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java @@ -19,6 +19,8 @@ import org.eclipse.californium.core.network.config.NetworkConfig; import org.eclipse.californium.core.network.config.NetworkConfigDefaults; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; +import static org.eclipse.californium.core.network.config.NetworkConfigDefaults.DEFAULT_BLOCKWISE_STATUS_LIFETIME; + public class LwM2mNetworkConfig { public static NetworkConfig getCoapConfig(Integer serverPortNoSec, Integer serverSecurePort, LwM2MTransportServerConfig config) { @@ -43,7 +45,7 @@ public class LwM2mNetworkConfig { CoAP client will try to use block mode or adapt the block size when receiving a 4.13 Entity too large response code */ - coapConfig.setBoolean(NetworkConfig.Keys.BLOCKWISE_STRICT_BLOCK2_OPTION, config.isBlock2OptionEnable()); + coapConfig.setBoolean(NetworkConfig.Keys.BLOCKWISE_STRICT_BLOCK2_OPTION, true); /** Property to indicate if the response should always include the Block2 option \ when client request early blockwise negociation but the response can be sent on one packet. @@ -59,7 +61,7 @@ public class LwM2mNetworkConfig { * The default value of this property is * {@link NetworkConfigDefaults#DEFAULT_BLOCKWISE_STATUS_LIFETIME} = 5 * 60 * 1000; // 5 mins [ms]. */ - coapConfig.setLong(NetworkConfig.Keys.BLOCKWISE_STATUS_LIFETIME, config.getBlockwiseLifetime()); + coapConfig.setLong(NetworkConfig.Keys.BLOCKWISE_STATUS_LIFETIME, DEFAULT_BLOCKWISE_STATUS_LIFETIME); /** !!! REQUEST_ENTITY_TOO_LARGE CODE=4.13 The maximum size of a resource body (in bytes) that will be accepted diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java index b185d18a28..4e45b172cb 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java @@ -30,7 +30,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.OTA_COAP_RESOURCE; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FIRMWARE_UPDATE_COAP_RECOURSE; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SOFTWARE_UPDATE_COAP_RECOURSE; @Slf4j public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource { @@ -69,7 +70,8 @@ public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource { protected void processHandleGet(CoapExchange exchange) { log.warn("90) processHandleGet [{}]", exchange); if (exchange.getRequestOptions().getUriPath().size() == 2 && - OTA_COAP_RESOURCE.equals(exchange.getRequestOptions().getUriPath().get(0))) { + (FIRMWARE_UPDATE_COAP_RECOURSE.equals(exchange.getRequestOptions().getUriPath().get(0)) || + SOFTWARE_UPDATE_COAP_RECOURSE.equals(exchange.getRequestOptions().getUriPath().get(0)))) { this.sentOtaData(exchange); } } @@ -127,7 +129,7 @@ public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource { } } - private void sentOtaData (CoapExchange exchange) { + private void sentOtaData(CoapExchange exchange) { String idStr = exchange.getRequestOptions().getUriPath().get(1); UUID currentId = UUID.fromString(idStr); if (exchange.getRequestOptions().getBlock2() != null) { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java index 9be2c24053..3000d9704a 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java @@ -139,8 +139,9 @@ public class LwM2mTransportUtil { public static final String ERROR_KEY = "error"; public static final String METHOD_KEY = "methodName"; - public static final String OTA_COAP_RESOURCE = "firmwarePackage"; + // Firmware + public static final String FIRMWARE_UPDATE_COAP_RECOURSE = "firmwareUpdateCoapRecourse"; public static final String FW_UPDATE = "Firmware update"; public static final Integer FW_5_ID = 5; public static final Integer FW_19_ID = 19; @@ -172,6 +173,7 @@ public class LwM2mTransportUtil { public static final String FW_UPDATE_ID = "/5/0/2"; // Software + public static final String SOFTWARE_UPDATE_COAP_RECOURSE = "softwareUpdateCoapRecourse"; public static final String SW_UPDATE = "Software update"; public static final Integer SW_ID = 9; // Package W diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java index f1728cdea6..0f81f60004 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java @@ -43,6 +43,7 @@ import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.INIT import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATED; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FIRMWARE_UPDATE_COAP_RECOURSE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_3_VER_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_5_VER_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_NAME_ID; @@ -61,7 +62,6 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.OTA_COAP_RESOURCE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_INSTALL_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_NAME_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_PACKAGE_ID; @@ -193,9 +193,10 @@ public class LwM2mFwSwUpdate { firmwareChunk, handler.config.getTimeout(), this.rpcRequest); } else if (LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_5_TEMP_URL.code == this.updateStrategy) { Registration registration = this.getLwM2MClient().getRegistration(); - String api = handler.config.getHostRequests(); +// String api = handler.config.getHostRequests(); + String api = "0.0.0.0"; int port = registration.getIdentity().isSecure() ? handler.config.getSecurePort() : handler.config.getPort(); - String uri = "coap://" + api + ":" + Integer.valueOf(port) + "/" + OTA_COAP_RESOURCE + "/" + this.currentId.toString(); + String uri = "coap://" + api + ":" + Integer.valueOf(port) + "/" + FIRMWARE_UPDATE_COAP_RECOURSE + "/" + this.currentId.toString(); log.warn("89) coapUri: [{}]", uri); request.sendAllRequest(this.lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, null, uri, handler.config.getTimeout(), this.rpcRequest); diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index 261d1c79f1..6a0b71a971 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -104,13 +104,9 @@ transport: server: id: "${LWM2M_SERVER_ID:123}" bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}" - # the host to receive requests to the server - bind_address_requests: "${LWM2M_BIND_ADDRESS_REQUESTS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT:5685}" security: bind_address: "${LWM2M_BIND_ADDRESS_SECURITY:0.0.0.0}" - # the security host to receive requests to the server - bind_address_requests: "${LWM2M_BIND_ADDRESS_SECURITY_REQUESTS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_SECURITY:5686}" # Only for RPK: Public & Private Key. If the keystore file is missing or not working public_x: "${LWM2M_SERVER_PUBLIC_X:05064b9e6762dd8d8b8a52355d7b4d8b9a3d64e6d2ee277d76c248861353f358}" @@ -123,13 +119,9 @@ transport: enable: "${LWM2M_ENABLED_BS:true}" id: "${LWM2M_SERVER_ID_BS:111}" bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" - # the host to receive requests to the server - bind_address_requests: "${LWM2M_BIND_ADDRESS_REQUESTS_BS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_BS:5687}" security: bind_address: "${LWM2M_BIND_ADDRESS_SECURITY_BS:0.0.0.0}" - # the security host to receive requests to the server - bind_address_requests: "${LWM2M_BIND_ADDRESS_SECURITY_REQUESTS_BS:0.0.0.0}" bind_port: "${LWM2M_BIND_PORT_SECURITY_BS:5688}" # Only for RPK: Public & Private Key. If the keystore file is missing or not working public_x: "${LWM2M_SERVER_PUBLIC_X_BS:5017c87a1c1768264656b3b355434b0def6edb8b9bf166a4762d9930cd730f91}" @@ -148,8 +140,6 @@ transport: root_alias: "${LWM2M_SERVER_ROOT_CA:rootca}" enable_gen_new_key_psk_rpk: "${ENABLE_GEN_NEW_KEY_PSK_RPK:false}" timeout: "${LWM2M_TIMEOUT:120000}" - blockwise_lifetime: "${BLOCKWISE_LIFETIME:300000}" - block2_option_enable: "${BLOCK2_OPTION_ENABLED:true}" recommended_ciphers: "${LWM2M_RECOMMENDED_CIPHERS:false}" recommended_supported_groups: "${LWM2M_RECOMMENDED_SUPPORTED_GROUPS:true}" response_pool_size: "${LWM2M_RESPONSE_POOL_SIZE:100}" diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 465aa8faf2..774f5f99d9 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1255,10 +1255,16 @@ "client-strategy-label": "Strategy", "client-strategy-connect": "{ count, plural, 1 {1: Only Observe Request to the client after the initial connection} other {2: Read All Resources & Observe Request to the client after registration} }", "client-strategy-tip": "{ count, plural, 1 {Strategy 1: After the initial connection of the LWM2M Client, the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} other {Strategy 2: After the registration, request the client to read all the resource values for all objects that the LWM2M client has,\n then execute: the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} }", + "ota-update-strategy": "Ota update strategy", "fw-update-strategy-label": "Firmware update strategy", "fw-update-strategy": "{ count, plural, 1 {Push firmware update as binary file using Object 5 and Resource 0 (Package).} 2 {Auto-generate unique CoAP URL to download the package and push firmware update as Object 5 and Resource 1 (Package URI).} other {Push firmware update as binary file using Object 19 and Resource 0 (Data).} }", "sw-update-strategy-label": "Software update strategy", "sw-update-strategy": "{ count, plural, 1 {Push binary file using Object 9 and Resource 2 (Package).} other {Auto-generate unique CoAP URL to download the package and push software update using Object 9 and Resource 3 (Package URI).} }", + "blockwise-settings": "Blockwise settings", + "blockwise-enabled": "Enable blockwise", + "blockwise-status-lifetime": "Blockwise Status Lifetime", + "fw-update-recourse": "Firmware update Coap recourse", + "sw-update-recourse": "Software update Coap recourse", "config-json-tab": "Json Config Profile Device" } }, From 334ee3c38468cbaeea17b0dc086a51388ccf7a24 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 8 Jun 2021 15:17:32 +0300 Subject: [PATCH 19/19] LWM2M: del from yml (double) --- .../main/data/json/system/widget_bundles/control_widgets.json | 2 +- .../transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/main/data/json/system/widget_bundles/control_widgets.json b/application/src/main/data/json/system/widget_bundles/control_widgets.json index 23b0b90ac3..e8c6539a30 100644 --- a/application/src/main/data/json/system/widget_bundles/control_widgets.json +++ b/application/src/main/data/json/system/widget_bundles/control_widgets.json @@ -18,7 +18,7 @@ "resources": [], "templateHtml": "
", "templateCss": ".cmd .cursor.blink {\n -webkit-animation-name: terminal-underline;\n -moz-animation-name: terminal-underline;\n -ms-animation-name: terminal-underline;\n animation-name: terminal-underline;\n}\n.terminal .inverted, .cmd .inverted {\n border-bottom-color: #aaa;\n}\n\n", - "controllerScript": "var requestTimeout = 500;\nvar multiParams = false;\nvar useRowStyleFunction = false;\nvar styleObj = {};\n\nself.onInit = function() {\n var subscription = self.ctx.defaultSubscription;\n var utils = self.ctx.$scope.$injector.get(self.ctx.servicesMap.get('utils'));\n var rpcEnabled = subscription.rpcEnabled;\n var deviceName = 'Simulated';\n var prompt;\n if (subscription.targetDeviceName && subscription.targetDeviceName.length) {\n deviceName = subscription.targetDeviceName;\n }\n if (self.ctx.settings.requestTimeout) {\n requestTimeout = self.ctx.settings.requestTimeout;\n }\n if (self.ctx.settings.multiParams) {\n multiParams = self.ctx.settings.multiParams;\n }\n if (self.ctx.settings.useRowStyleFunction && self.ctx.settings.rowStyleFunction) {\n try {\n var style = self.ctx.settings.rowStyleFunction;\n styleObj = JSON.parse(style);\n if ((typeof styleObj !== \"object\")) {\n styleObj = null;\n throw new URIError(`${style === null ? 'null' : typeof style} instead of style object`);\n }\n else if (typeof styleObj === \"object\" && (typeof styleObj.length) === \"number\") {\n styleObj = null;\n throw new URIError('Array instead of style object');\n }\n }\n catch (e) {\n console.log(`Row style function in widget ` +\n `returns '${e}'. Please check your row style function.`); \n }\n useRowStyleFunction = self.ctx.settings.useRowStyleFunction;\n \n }\n var greetings = 'Welcome to ThingsBoard RPC debug terminal.\\n\\n';\n if (!rpcEnabled) {\n greetings += 'Target device is not set!\\n\\n';\n prompt = '';\n } else {\n greetings += 'Current target device for RPC commands: [[b;#fff;]' + deviceName + ']\\n\\n';\n greetings += 'Please type [[b;#fff;]\\'help\\'] to see usage.\\n';\n prompt = '[[b;#8bc34a;]' + deviceName +']> ';\n }\n \n var terminal = $('#device-terminal', self.ctx.$container).terminal(\n function(command) {\n if (command !== '') {\n try {\n var localCommand = command.trim();\n var requestUUID = uuidv4();\n if (localCommand === 'help') {\n printUsage(this);\n } else {\n var cmdObj = $.terminal.parse_command(localCommand);\n if (cmdObj.args) {\n if (!multiParams && cmdObj.args.length > 1) {\n this.error(\"Wrong number of arguments!\");\n this.echo(' ');\n }\n else {\n if (cmdObj.args.length) {\n var params = getMultiParams(cmdObj.args);\n }\n performRpc(this, cmdObj.name, params, requestUUID);\n }\n }\n \n }\n } catch(e) {\n this.error(new String(e));\n }\n } else {\n this.echo('');\n }\n }, {\n greetings: greetings,\n prompt: prompt,\n enabled: rpcEnabled\n });\n \n if (styleObj && styleObj !== null) {\n terminal.css(styleObj);\n }\n \n if (!rpcEnabled) {\n terminal.error('No RPC target detected!').pause();\n }\n}\n\n\nfunction printUsage(terminal) {\n var commandsListText = '\\n[[b;#fff;]Usage:]\\n';\n commandsListText += ' [params body]]\\n\\n';\n commandsListText += '[[b;#fff;]Example 1 (multiParams===false):]\\n'; \n commandsListText += ' myRemoteMethod1 myText\\n\\n'; \n commandsListText += '[[b;#fff;]Example 2 (multiParams===false):]\\n'; \n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\":2,\\\\\"key2\\\\\":\\\\\"myVal\\\\\"}\"\\n\\n'; \n commandsListText += '[[b;#fff;]Example 3 (multiParams===true)]\\n'; \n commandsListText += ' [params body] = \"all the string after the method, including spaces\"]\\n';\n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\": \"battery level\", \\\\\"key2\\\\\": \\\\\"myVal\\\\\"}\"\\n'; \n terminal.echo(new String(commandsListText));\n}\n\nfunction performRpc(terminal, method, params, requestUUID) {\n terminal.pause();\n self.ctx.controlApi.sendTwoWayCommand(method, params, requestTimeout, requestUUID).subscribe(\n function success(responseBody) {\n terminal.echo(JSON.stringify(responseBody));\n terminal.echo(' ');\n terminal.resume();\n },\n function fail() {\n var errorText = self.ctx.defaultSubscription.rpcErrorText;\n terminal.error(errorText);\n terminal.echo(' ');\n terminal.resume();\n }\n );\n}\n\nfunction getMultiParams(cmdObj) {\n var params = \"\";\n cmdObj.forEach((element) => {\n try {\n params += \" \" + JSON.strigify(JSON.parse(element));\n } catch (e) {\n params += \" \" + element;\n }\n })\n return params.trim();\n}\n\n\nfunction uuidv4() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\n \nself.onDestroy = function() {\n}", + "controllerScript": "var requestTimeout = 500;\nvar multiParams = false;\nvar useRowStyleFunction = false;\nvar styleObj = {};\n\nself.onInit = function() {\n var subscription = self.ctx.defaultSubscription;\n var rpcEnabled = subscription.rpcEnabled;\n var deviceName = 'Simulated';\n var prompt;\n if (subscription.targetDeviceName && subscription.targetDeviceName.length) {\n deviceName = subscription.targetDeviceName;\n }\n if (self.ctx.settings.requestTimeout) {\n requestTimeout = self.ctx.settings.requestTimeout;\n }\n if (self.ctx.settings.multiParams) {\n multiParams = self.ctx.settings.multiParams;\n }\n if (self.ctx.settings.useRowStyleFunction && self.ctx.settings.rowStyleFunction) {\n try {\n var style = self.ctx.settings.rowStyleFunction;\n styleObj = JSON.parse(style);\n if ((typeof styleObj !== \"object\")) {\n styleObj = null;\n throw new URIError(`${style === null ? 'null' : typeof style} instead of style object`);\n }\n else if (typeof styleObj === \"object\" && (typeof styleObj.length) === \"number\") {\n styleObj = null;\n throw new URIError('Array instead of style object');\n }\n }\n catch (e) {\n console.log(`Row style function in widget ` +\n `returns '${e}'. Please check your row style function.`); \n }\n useRowStyleFunction = self.ctx.settings.useRowStyleFunction;\n \n }\n var greetings = 'Welcome to ThingsBoard RPC debug terminal.\\n\\n';\n if (!rpcEnabled) {\n greetings += 'Target device is not set!\\n\\n';\n prompt = '';\n } else {\n greetings += 'Current target device for RPC commands: [[b;#fff;]' + deviceName + ']\\n\\n';\n greetings += 'Please type [[b;#fff;]\\'help\\'] to see usage.\\n';\n prompt = '[[b;#8bc34a;]' + deviceName +']> ';\n }\n \n var terminal = $('#device-terminal', self.ctx.$container).terminal(\n function(command) {\n if (command !== '') {\n try {\n var localCommand = command.trim();\n var requestUUID = uuidv4();\n if (localCommand === 'help') {\n printUsage(this);\n } else {\n var cmdObj = $.terminal.parse_command(localCommand);\n if (cmdObj.args) {\n if (!multiParams && cmdObj.args.length > 1) {\n this.error(\"Wrong number of arguments!\");\n this.echo(' ');\n }\n else {\n if (cmdObj.args.length) {\n var params = getMultiParams(cmdObj.args);\n }\n performRpc(this, cmdObj.name, params, requestUUID);\n }\n }\n \n }\n } catch(e) {\n this.error(new String(e));\n }\n } else {\n this.echo('');\n }\n }, {\n greetings: greetings,\n prompt: prompt,\n enabled: rpcEnabled\n });\n \n if (styleObj && styleObj !== null) {\n terminal.css(styleObj);\n }\n \n if (!rpcEnabled) {\n terminal.error('No RPC target detected!').pause();\n }\n}\n\n\nfunction printUsage(terminal) {\n var commandsListText = '\\n[[b;#fff;]Usage:]\\n';\n commandsListText += ' [params body]]\\n\\n';\n commandsListText += '[[b;#fff;]Example 1 (multiParams===false):]\\n'; \n commandsListText += ' myRemoteMethod1 myText\\n\\n'; \n commandsListText += '[[b;#fff;]Example 2 (multiParams===false):]\\n'; \n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\":2,\\\\\"key2\\\\\":\\\\\"myVal\\\\\"}\"\\n\\n'; \n commandsListText += '[[b;#fff;]Example 3 (multiParams===true)]\\n'; \n commandsListText += ' [params body] = \"all the string after the method, including spaces\"]\\n';\n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\": \"battery level\", \\\\\"key2\\\\\": \\\\\"myVal\\\\\"}\"\\n'; \n terminal.echo(new String(commandsListText));\n}\n\nfunction performRpc(terminal, method, params, requestUUID) {\n terminal.pause();\n self.ctx.controlApi.sendTwoWayCommand(method, params, requestTimeout, requestUUID).subscribe(\n function success(responseBody) {\n terminal.echo(JSON.stringify(responseBody));\n terminal.echo(' ');\n terminal.resume();\n },\n function fail() {\n var errorText = self.ctx.defaultSubscription.rpcErrorText;\n terminal.error(errorText);\n terminal.echo(' ');\n terminal.resume();\n }\n );\n}\n\nfunction getMultiParams(cmdObj) {\n var params = \"\";\n cmdObj.forEach((element) => {\n try {\n params += \" \" + JSON.strigify(JSON.parse(element));\n } catch (e) {\n params += \" \" + element;\n }\n })\n return params.trim();\n}\n\n\nfunction uuidv4() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\n \nself.onDestroy = function() {\n}", "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"multiParams\": {\n \"title\": \"RPC params All line\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"useRowStyleFunction\": {\n \"title\": \"Use row style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"rowStyleFunction\": {\n \"title\": \"Row style function: f(entity, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"requestTimeout\",\n \"multiParams\",\n \"useRowStyleFunction\",\n {\n \"key\": \"rowStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useRowStyleFunction === true\"\n }\n ]\n}", "dataKeySettingsSchema": "{}\n", "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":true,\"backgroundColor\":\"#010101\",\"color\":\"rgba(255, 254, 254, 0.87)\",\"padding\":\"0px\",\"settings\":{\"parseGpioStatusFunction\":\"return body[pin] === true;\",\"gpioStatusChangeRequest\":{\"method\":\"setGpioStatus\",\"paramsBody\":\"{\\n \\\"pin\\\": \\\"{$pin}\\\",\\n \\\"enabled\\\": \\\"{$enabled}\\\"\\n}\"},\"requestTimeout\":500,\"switchPanelBackgroundColor\":\"#b71c1c\",\"gpioStatusRequest\":{\"method\":\"getGpioStatus\",\"paramsBody\":\"{}\"},\"gpioList\":[{\"pin\":1,\"label\":\"GPIO 1\",\"row\":0,\"col\":0,\"_uniqueKey\":0},{\"pin\":2,\"label\":\"GPIO 2\",\"row\":0,\"col\":1,\"_uniqueKey\":1},{\"pin\":3,\"label\":\"GPIO 3\",\"row\":1,\"col\":0,\"_uniqueKey\":2}]},\"title\":\"RPC debug terminal\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index e286cc6570..9a5c74467d 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -477,7 +477,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), null, lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), - this.config.getBlockwiseLifetime(), lwm2mClientRpcRequest); + 0, lwm2mClientRpcRequest); } } else { this.sentErrorRpcResponse(lwm2mClientRpcRequest, "registration == null", sessionInfo);