diff --git a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java b/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java index c8f10b3d78..9fcf5a7ec9 100644 --- a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java +++ b/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java @@ -115,7 +115,7 @@ public class FirmwareController extends BaseController { @ResponseBody public Firmware saveFirmwareData(@PathVariable(FIRMWARE_ID) String strFirmwareId, @RequestParam(required = false) String checksum, - @RequestParam(required = false) String checksumAlgorithm, + @RequestParam() String checksumAlgorithm, @RequestBody MultipartFile file) throws ThingsboardException { checkParameter(FIRMWARE_ID, strFirmwareId); try { @@ -129,18 +129,17 @@ public class FirmwareController extends BaseController { firmware.setVersion(info.getVersion()); firmware.setAdditionalInfo(info.getAdditionalInfo()); - byte[] data = file.getBytes(); - if (StringUtils.isEmpty(checksumAlgorithm)) { - checksumAlgorithm = "sha256"; - checksum = Hashing.sha256().hashBytes(data).toString(); + ByteBuffer data = ByteBuffer.wrap(file.getBytes()); + if (StringUtils.isEmpty(checksum)) { + checksum = firmwareService.generateChecksum(checksumAlgorithm, data); } firmware.setChecksumAlgorithm(checksumAlgorithm); firmware.setChecksum(checksum); firmware.setFileName(file.getOriginalFilename()); firmware.setContentType(file.getContentType()); - firmware.setData(ByteBuffer.wrap(data)); - firmware.setDataSize((long) data.length); + firmware.setData(data); + firmware.setDataSize((long) data.array().length); return firmwareService.saveFirmware(firmware); } catch (Exception e) { throw handleException(e); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java index 0fd26fee6e..0ba34ae90f 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java @@ -22,12 +22,16 @@ 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(String checksumAlgorithm, ByteBuffer data); + Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId); FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId); 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 73ca2cdf9d..2b990d6b6b 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 @@ -456,9 +456,6 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement deviceSessionCtx.getPayloadAdaptor() .convertToPublish(deviceSessionCtx, firmwareChunk, requestId, chunk) .ifPresent(deviceSessionCtx.getChannel()::writeAndFlush); - if (firmwareChunk != null && chunkSize != firmwareChunk.length) { - scheduler.schedule(() -> processDisconnect(ctx), 60, TimeUnit.SECONDS); - } } catch (Exception e) { log.trace("[{}] Failed to send firmware response!", sessionId, e); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java b/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java index 5a80fc75f6..c2b5394ae2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java @@ -101,6 +101,32 @@ public class BaseFirmwareService implements FirmwareService { } } + @Override + public String generateChecksum(String checksumAlgorithm, ByteBuffer data) { + + if (data == null || !data.hasArray() || data.array().length == 0) { + throw new DataValidationException("Firmware data should be specified!"); + } + + HashFunction hashFunction; + switch (checksumAlgorithm) { + case "sha256": + hashFunction = Hashing.sha256(); + break; + case "md5": + hashFunction = Hashing.md5(); + break; + case "crc32": + hashFunction = Hashing.crc32(); + break; + default: + throw new DataValidationException("Unknown checksum algorithm!"); + } + + return hashFunction.hashBytes(data.array()).toString(); + } + + @Override public Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId) { log.trace("Executing findFirmwareById [{}]", firmwareId); @@ -217,11 +243,6 @@ public class BaseFirmwareService implements FirmwareService { throw new DataValidationException("Firmware content type should be specified!"); } - ByteBuffer data = firmware.getData(); - if (data == null || !data.hasArray() || data.array().length == 0) { - throw new DataValidationException("Firmware data should be specified!"); - } - if (StringUtils.isEmpty(firmware.getChecksumAlgorithm())) { throw new DataValidationException("Firmware checksum algorithm should be specified!"); } @@ -229,22 +250,7 @@ public class BaseFirmwareService implements FirmwareService { throw new DataValidationException("Firmware checksum should be specified!"); } - HashFunction hashFunction; - switch (firmware.getChecksumAlgorithm()) { - case "sha256": - hashFunction = Hashing.sha256(); - break; - case "md5": - hashFunction = Hashing.md5(); - break; - case "crc32": - hashFunction = Hashing.crc32(); - break; - default: - throw new DataValidationException("Unknown checksum algorithm!"); - } - - String currentChecksum = hashFunction.hashBytes(data.array()).toString(); + String currentChecksum = generateChecksum(firmware.getChecksumAlgorithm(), firmware.getData()); if (!currentChecksum.equals(firmware.getChecksum())) { throw new DataValidationException("Wrong firmware file!"); diff --git a/ui-ngx/src/app/core/http/firmware.service.ts b/ui-ngx/src/app/core/http/firmware.service.ts index 7bf42fb49e..60d16d6bdf 100644 --- a/ui-ngx/src/app/core/http/firmware.service.ts +++ b/ui-ngx/src/app/core/http/firmware.service.ts @@ -20,7 +20,7 @@ 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 { Firmware, FirmwareInfo } from '@shared/models/firmware.models'; +import { ChecksumAlgorithm, Firmware, FirmwareInfo } from '@shared/models/firmware.models'; import { catchError, map, mergeMap } from 'rxjs/operators'; import { deepClone, isDefinedAndNotNull } from '@core/utils'; @@ -100,16 +100,16 @@ export class FirmwareService { return this.http.post('/api/firmware', firmware, defaultHttpOptionsFromConfig(config)); } - public uploadFirmwareFile(firmwareId: string, file: File, checksumAlgorithm?: string, + 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}`; - if (checksumAlgorithm && checksum) { - url += `?checksumAlgorithm=${checksumAlgorithm}&checksum=${checksum}`; + 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)); diff --git a/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.html b/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.html index 2911802a75..21a5ad327e 100644 --- a/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.html +++ b/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.html @@ -72,7 +72,6 @@ firmware.checksum-algorithm - {{ checksumAlgorithmTranslationMap.get(checksumAlgorithm) }} @@ -80,11 +79,7 @@ firmware.checksum - - - {{ 'firmware.checksum-required' | translate }} - +
diff --git a/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.ts b/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.ts index 8ffef239b4..5e3c26dfee 100644 --- a/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.ts +++ b/ui-ngx/src/app/modules/home/pages/firmware/firmwares.component.ts @@ -23,7 +23,6 @@ import { EntityTableConfig } from '@home/models/entity/entities-table-config.mod import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { EntityComponent } from '@home/components/entity/entity.component'; import { ChecksumAlgorithm, ChecksumAlgorithmTranslationMap, Firmware } from '@shared/models/firmware.models'; -import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators'; import { ActionNotificationShow } from '@core/notification/notification.actions'; @Component({ @@ -45,26 +44,6 @@ export class FirmwaresComponent extends EntityComponent implements OnI super(store, fb, entityValue, entitiesTableConfigValue); } - ngOnInit() { - super.ngOnInit(); - if (this.isAdd) { - this.entityForm.get('checksumAlgorithm').valueChanges.pipe( - map(algorithm => !!algorithm), - distinctUntilChanged(), - takeUntil(this.destroy$) - ).subscribe( - setAlgorithm => { - if (setAlgorithm) { - this.entityForm.get('checksum').setValidators([Validators.maxLength(1020), Validators.required]); - } else { - this.entityForm.get('checksum').clearValidators(); - } - this.entityForm.get('checksum').updateValueAndValidity({emitEvent: false}); - } - ); - } - } - ngOnDestroy() { super.ngOnDestroy(); this.destroy$.next(); @@ -83,7 +62,7 @@ export class FirmwaresComponent extends EntityComponent implements OnI const form = this.fb.group({ title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]], version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]], - checksumAlgorithm: [entity ? entity.checksumAlgorithm : null], + checksumAlgorithm: [entity && entity.checksumAlgorithm ? entity.checksumAlgorithm : ChecksumAlgorithm.SHA256], checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)], additionalInfo: this.fb.group( { diff --git a/ui-ngx/src/app/shared/models/firmware.models.ts b/ui-ngx/src/app/shared/models/firmware.models.ts index 65dd1761bf..147901a0cc 100644 --- a/ui-ngx/src/app/shared/models/firmware.models.ts +++ b/ui-ngx/src/app/shared/models/firmware.models.ts @@ -38,8 +38,8 @@ export interface FirmwareInfo extends BaseData { version?: string; hasData?: boolean; fileName: string; - checksum?: ChecksumAlgorithm; - checksumAlgorithm?: string; + checksum?: string; + checksumAlgorithm: ChecksumAlgorithm; contentType: string; dataSize?: number; additionalInfo?: any;