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 9b3caf7a79..6728120163 100644 --- a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java +++ b/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.controller; -import com.google.common.hash.Hashing; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.io.ByteArrayResource; @@ -35,6 +34,7 @@ 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; @@ -53,6 +53,7 @@ import java.nio.ByteBuffer; 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) @@ -125,9 +126,10 @@ 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(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); @@ -141,18 +143,19 @@ 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(); + 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(data)); - firmware.setDataSize((long) data.length); + 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; diff --git a/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java b/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java index ed9f8a9eaf..9720cd2097 100644 --- a/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java @@ -297,7 +297,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService { attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), TITLE), firmware.getTitle()))); attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), VERSION), firmware.getVersion()))); attributes.add(new BaseAttributeKvEntry(ts, new LongDataEntry(getAttributeKey(firmware.getType(), SIZE), firmware.getDataSize()))); - attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), CHECKSUM_ALGORITHM), firmware.getChecksumAlgorithm()))); + attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), CHECKSUM_ALGORITHM), firmware.getChecksumAlgorithm().name()))); attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), CHECKSUM), firmware.getChecksum()))); telemetryService.saveAndNotify(tenantId, deviceId, DataConstants.SHARED_SCOPE, attributes, new FutureCallback<>() { 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 980f8303f2..eeaafbd777 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java @@ -18,6 +18,7 @@ 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; @@ -25,12 +26,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(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data); + Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId); FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java index 9b00e9b256..33b529e303 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java @@ -19,6 +19,7 @@ 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.id.DeviceProfileId; import org.thingsboard.server.common.data.id.FirmwareId; @@ -39,7 +40,7 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo private boolean hasData; private String fileName; private String contentType; - private String checksumAlgorithm; + private ChecksumAlgorithm checksumAlgorithm; private String checksum; private Long dataSize; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/MqttTopics.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/MqttTopics.java index 7b634bffdc..2b1aba3c0f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/MqttTopics.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/MqttTopics.java @@ -82,7 +82,8 @@ public class MqttTopics { public static final String DEVICE_FIRMWARE_REQUEST_TOPIC_PATTERN = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + REQUEST + "/" + REQUEST_ID_PATTERN + CHUNK + CHUNK_PATTERN; public static final String DEVICE_FIRMWARE_RESPONSES_TOPIC = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + RESPONSE + "/" + SUB_TOPIC + CHUNK + SUB_TOPIC; public static final String DEVICE_FIRMWARE_ERROR_TOPIC = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + ERROR; - public static final String DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT = BASE_DEVICE_API_TOPIC_V2 + "/%s" + RESPONSE + "/"+ "%s" + CHUNK + "%d"; + + public static final String DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT = BASE_DEVICE_API_TOPIC_V2 + "/%s" + RESPONSE + "/%s" + CHUNK + "%d"; public static final String DEVICE_SOFTWARE_REQUEST_TOPIC_PATTERN = BASE_DEVICE_API_TOPIC_V2 + SOFTWARE + REQUEST + "/" + REQUEST_ID_PATTERN + CHUNK + CHUNK_PATTERN; public static final String DEVICE_SOFTWARE_RESPONSES_TOPIC = BASE_DEVICE_API_TOPIC_V2 + SOFTWARE + RESPONSE + "/" + SUB_TOPIC + CHUNK + SUB_TOPIC; 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/firmware/ChecksumAlgorithm.java new file mode 100644 index 0000000000..3998482e35 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/firmware/ChecksumAlgorithm.java @@ -0,0 +1,26 @@ +/** + * 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.common.data.firmware; + +public enum ChecksumAlgorithm { + MD5, + SHA256, + SHA384, + SHA512, + CRC32, + MURMUR3_32, + MURMUR3_128 +} 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 bb1311429c..7d50ea2f7d 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 @@ -468,9 +468,6 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement deviceSessionCtx.getPayloadAdaptor() .convertToPublish(deviceSessionCtx, firmwareChunk, requestId, chunk, type) .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/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 dbda48d15d..a9d7b3e2ea 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 @@ -44,7 +44,7 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; -import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT; /** @@ -156,7 +156,7 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { @Override public Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) { - return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk)); + return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk)); } public static JsonElement validateJsonPayload(UUID sessionId, ByteBuf payloadData) throws AdaptorException { 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 29df08e9c3..08a2f9abe3 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 @@ -39,7 +39,7 @@ import org.thingsboard.server.transport.mqtt.session.MqttDeviceAwareSessionConte import java.util.Optional; -import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT; @Component @Slf4j @@ -169,7 +169,7 @@ public class ProtoMqttAdaptor implements MqttTransportAdaptor { @Override public Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) throws AdaptorException { - return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk)); + return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk)); } @Override 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 6ac3df8292..2e0d5c03b6 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 @@ -31,6 +31,9 @@ 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; @@ -43,7 +46,11 @@ 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; @@ -110,6 +117,36 @@ public class BaseFirmwareService implements FirmwareService { } } + @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); @@ -210,34 +247,16 @@ 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())) { + 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!"); } - 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; - String currentChecksum = hashFunction.hashBytes(data.array()).toString(); + currentChecksum = generateChecksum(firmware.getChecksumAlgorithm(), firmware.getData()); if (!currentChecksum.equals(firmware.getChecksum())) { throw new DataValidationException("Wrong firmware file!"); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java index 4f3aded716..e16d0417e4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareEntity.java @@ -21,6 +21,7 @@ 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.id.DeviceProfileId; import org.thingsboard.server.common.data.id.FirmwareId; @@ -82,8 +83,9 @@ public class FirmwareEntity extends BaseSqlEntity implements SearchTex @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN) private String contentType; + @Enumerated(EnumType.STRING) @Column(name = FIRMWARE_CHECKSUM_ALGORITHM_COLUMN) - private String checksumAlgorithm; + private ChecksumAlgorithm checksumAlgorithm; @Column(name = FIRMWARE_CHECKSUM_COLUMN) private String checksum; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java index bb62db5ea4..93a6e83f25 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/FirmwareInfoEntity.java @@ -22,6 +22,7 @@ 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.id.DeviceProfileId; import org.thingsboard.server.common.data.id.FirmwareId; @@ -81,8 +82,9 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN) private String contentType; + @Enumerated(EnumType.STRING) @Column(name = FIRMWARE_CHECKSUM_ALGORITHM_COLUMN) - private String checksumAlgorithm; + private ChecksumAlgorithm checksumAlgorithm; @Column(name = FIRMWARE_CHECKSUM_COLUMN) private String checksum; @@ -123,7 +125,7 @@ public class FirmwareInfoEntity extends BaseSqlEntity implements S } public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, UUID deviceProfileId, FirmwareType type, String title, String version, - String fileName, String contentType, String checksumAlgorithm, String checksum, Long dataSize, + String fileName, String contentType, ChecksumAlgorithm checksumAlgorithm, String checksum, Long dataSize, Object additionalInfo, boolean hasData) { this.id = id; this.createdTime = createdTime; 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 d5587e9929..5516cb6181 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 @@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.firmware.FirmwareType; +import org.thingsboard.server.common.data.firmware.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; @@ -106,7 +107,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { firmware.setVersion("v1.0"); firmware.setFileName("test.txt"); firmware.setContentType("text/plain"); - firmware.setChecksumAlgorithm("sha256"); + firmware.setChecksumAlgorithm(ChecksumAlgorithm.SHA256); firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); firmware.setData(ByteBuffer.wrap(new byte[]{1})); Firmware savedFirmware = firmwareService.saveFirmware(firmware); 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 7567e6b6d8..587fce1ed5 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 @@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.Firmware; 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.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -196,7 +197,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { firmware.setVersion("v1.0"); firmware.setFileName("test.txt"); firmware.setContentType("text/plain"); - firmware.setChecksumAlgorithm("sha256"); + firmware.setChecksumAlgorithm(ChecksumAlgorithm.SHA256); firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); firmware.setData(ByteBuffer.wrap(new byte[]{1})); Firmware savedFirmware = firmwareService.saveFirmware(firmware); @@ -230,7 +231,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { firmware.setVersion("v1.0"); firmware.setFileName("test.txt"); firmware.setContentType("text/plain"); - firmware.setChecksumAlgorithm("sha256"); + firmware.setChecksumAlgorithm(ChecksumAlgorithm.SHA256); firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); firmware.setData(ByteBuffer.wrap(new byte[]{1})); Firmware savedFirmware = firmwareService.saveFirmware(firmware); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java index 06a2b7084f..bd9e0ed372 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseFirmwareServiceTest.java @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.FirmwareInfo; import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.firmware.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; @@ -47,7 +48,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { private static final String FILE_NAME = "filename.txt"; private static final String VERSION = "v1.0"; private static final String CONTENT_TYPE = "text/plain"; - private static final String CHECKSUM_ALGORITHM = "sha256"; + private static final ChecksumAlgorithm CHECKSUM_ALGORITHM = ChecksumAlgorithm.SHA256; private static final String CHECKSUM = "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"; private static final ByteBuffer DATA = ByteBuffer.wrap(new byte[]{1}); diff --git a/ui-ngx/src/app/core/http/firmware.service.ts b/ui-ngx/src/app/core/http/firmware.service.ts index 8c3249aee6..f0b7e7d75e 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, FirmwareType } from '@shared/models/firmware.models'; +import { ChecksumAlgorithm, Firmware, FirmwareInfo, FirmwareType } from '@shared/models/firmware.models'; import { catchError, map, mergeMap } from 'rxjs/operators'; import { deepClone, isDefinedAndNotNull } from '@core/utils'; @@ -101,16 +101,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 cba515f1d8..b608604d2f 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 @@ -89,7 +89,6 @@ - {{ checksumAlgorithmTranslationMap.get(checksumAlgorithm) }} @@ -97,11 +96,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 adfd2050c7..e2283a588f 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 @@ -29,7 +29,6 @@ import { FirmwareType, FirmwareTypeTranslationMap } from '@shared/models/firmware.models'; -import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators'; import { ActionNotificationShow } from '@core/notification/notification.actions'; @Component({ @@ -53,26 +52,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(); @@ -93,7 +72,7 @@ export class FirmwaresComponent extends EntityComponent implements OnI version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]], type: [entity?.type ? entity.type : FirmwareType.FIRMWARE, [Validators.required]], deviceProfileId: [entity ? entity.deviceProfileId : null], - 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 57c95c3c9a..2b74cb41ca 100644 --- a/ui-ngx/src/app/shared/models/firmware.models.ts +++ b/ui-ngx/src/app/shared/models/firmware.models.ts @@ -20,16 +20,24 @@ import { FirmwareId } from '@shared/models/id/firmware-id'; import { DeviceProfileId } from '@shared/models/id/device-profile-id'; export enum ChecksumAlgorithm { - MD5 = 'md5', - SHA256 = 'sha256', - CRC32 = 'crc32' + MD5 = 'MD5', + SHA256 = 'SHA256', + SHA384 = 'SHA384', + SHA512 = 'SHA512', + CRC32 = 'CRC32', + MURMUR3_32 = 'MURMUR3_32', + MURMUR3_128 = 'MURMUR3_128' } export const ChecksumAlgorithmTranslationMap = new Map( [ [ChecksumAlgorithm.MD5, 'MD5'], [ChecksumAlgorithm.SHA256, 'SHA-256'], - [ChecksumAlgorithm.CRC32, 'CRC-32'] + [ChecksumAlgorithm.SHA384, 'SHA-384'], + [ChecksumAlgorithm.SHA512, 'SHA-512'], + [ChecksumAlgorithm.CRC32, 'CRC-32'], + [ChecksumAlgorithm.MURMUR3_32, 'MURMUR3-32'], + [ChecksumAlgorithm.MURMUR3_128, 'MURMUR3-128'] ] );