Commit ceb26bbd617a90266c0dc1ac3af0af2125d5d555

Authored by Andrii Shvaika
2 parents 17ae095d a4eb2df8

Merge with master

Showing 19 changed files with 124 additions and 83 deletions
... ... @@ -15,7 +15,6 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
18   -import com.google.common.hash.Hashing;
19 18 import lombok.extern.slf4j.Slf4j;
20 19 import org.apache.commons.lang3.StringUtils;
21 20 import org.springframework.core.io.ByteArrayResource;
... ... @@ -35,6 +34,7 @@ import org.thingsboard.server.common.data.Firmware;
35 34 import org.thingsboard.server.common.data.FirmwareInfo;
36 35 import org.thingsboard.server.common.data.audit.ActionType;
37 36 import org.thingsboard.server.common.data.exception.ThingsboardException;
  37 +import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
38 38 import org.thingsboard.server.common.data.firmware.FirmwareType;
39 39 import org.thingsboard.server.common.data.id.DeviceProfileId;
40 40 import org.thingsboard.server.common.data.id.FirmwareId;
... ... @@ -53,6 +53,7 @@ import java.nio.ByteBuffer;
53 53 public class FirmwareController extends BaseController {
54 54
55 55 public static final String FIRMWARE_ID = "firmwareId";
  56 + public static final String CHECKSUM_ALGORITHM = "checksumAlgorithm";
56 57
57 58 @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')")
58 59 @RequestMapping(value = "/firmware/{firmwareId}/download", method = RequestMethod.GET)
... ... @@ -125,9 +126,10 @@ public class FirmwareController extends BaseController {
125 126 @ResponseBody
126 127 public Firmware saveFirmwareData(@PathVariable(FIRMWARE_ID) String strFirmwareId,
127 128 @RequestParam(required = false) String checksum,
128   - @RequestParam(required = false) String checksumAlgorithm,
  129 + @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr,
129 130 @RequestBody MultipartFile file) throws ThingsboardException {
130 131 checkParameter(FIRMWARE_ID, strFirmwareId);
  132 + checkParameter(CHECKSUM_ALGORITHM, checksumAlgorithmStr);
131 133 try {
132 134 FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
133 135 FirmwareInfo info = checkFirmwareInfoId(firmwareId, Operation.READ);
... ... @@ -141,18 +143,19 @@ public class FirmwareController extends BaseController {
141 143 firmware.setVersion(info.getVersion());
142 144 firmware.setAdditionalInfo(info.getAdditionalInfo());
143 145
144   - byte[] data = file.getBytes();
145   - if (StringUtils.isEmpty(checksumAlgorithm)) {
146   - checksumAlgorithm = "sha256";
147   - checksum = Hashing.sha256().hashBytes(data).toString();
  146 + ChecksumAlgorithm checksumAlgorithm = ChecksumAlgorithm.valueOf(checksumAlgorithmStr.toUpperCase());
  147 +
  148 + byte[] bytes = file.getBytes();
  149 + if (StringUtils.isEmpty(checksum)) {
  150 + checksum = firmwareService.generateChecksum(checksumAlgorithm, ByteBuffer.wrap(bytes));
148 151 }
149 152
150 153 firmware.setChecksumAlgorithm(checksumAlgorithm);
151 154 firmware.setChecksum(checksum);
152 155 firmware.setFileName(file.getOriginalFilename());
153 156 firmware.setContentType(file.getContentType());
154   - firmware.setData(ByteBuffer.wrap(data));
155   - firmware.setDataSize((long) data.length);
  157 + firmware.setData(ByteBuffer.wrap(bytes));
  158 + firmware.setDataSize((long) bytes.length);
156 159 Firmware savedFirmware = firmwareService.saveFirmware(firmware);
157 160 logEntityAction(savedFirmware.getId(), savedFirmware, null, ActionType.UPDATED, null);
158 161 return savedFirmware;
... ...
... ... @@ -297,7 +297,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
297 297 attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), TITLE), firmware.getTitle())));
298 298 attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), VERSION), firmware.getVersion())));
299 299 attributes.add(new BaseAttributeKvEntry(ts, new LongDataEntry(getAttributeKey(firmware.getType(), SIZE), firmware.getDataSize())));
300   - attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), CHECKSUM_ALGORITHM), firmware.getChecksumAlgorithm())));
  300 + attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), CHECKSUM_ALGORITHM), firmware.getChecksumAlgorithm().name())));
301 301 attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), CHECKSUM), firmware.getChecksum())));
302 302
303 303 telemetryService.saveAndNotify(tenantId, deviceId, DataConstants.SHARED_SCOPE, attributes, new FutureCallback<>() {
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.firmware;
18 18 import com.google.common.util.concurrent.ListenableFuture;
19 19 import org.thingsboard.server.common.data.Firmware;
20 20 import org.thingsboard.server.common.data.FirmwareInfo;
  21 +import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
21 22 import org.thingsboard.server.common.data.firmware.FirmwareType;
22 23 import org.thingsboard.server.common.data.id.DeviceProfileId;
23 24 import org.thingsboard.server.common.data.id.FirmwareId;
... ... @@ -25,12 +26,16 @@ import org.thingsboard.server.common.data.id.TenantId;
25 26 import org.thingsboard.server.common.data.page.PageData;
26 27 import org.thingsboard.server.common.data.page.PageLink;
27 28
  29 +import java.nio.ByteBuffer;
  30 +
28 31 public interface FirmwareService {
29 32
30 33 FirmwareInfo saveFirmwareInfo(FirmwareInfo firmwareInfo);
31 34
32 35 Firmware saveFirmware(Firmware firmware);
33 36
  37 + String generateChecksum(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data);
  38 +
34 39 Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId);
35 40
36 41 FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId);
... ...
... ... @@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
19 19 import lombok.Data;
20 20 import lombok.EqualsAndHashCode;
21 21 import lombok.extern.slf4j.Slf4j;
  22 +import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
22 23 import org.thingsboard.server.common.data.firmware.FirmwareType;
23 24 import org.thingsboard.server.common.data.id.DeviceProfileId;
24 25 import org.thingsboard.server.common.data.id.FirmwareId;
... ... @@ -39,7 +40,7 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId>
39 40 private boolean hasData;
40 41 private String fileName;
41 42 private String contentType;
42   - private String checksumAlgorithm;
  43 + private ChecksumAlgorithm checksumAlgorithm;
43 44 private String checksum;
44 45 private Long dataSize;
45 46
... ...
... ... @@ -82,7 +82,8 @@ public class MqttTopics {
82 82 public static final String DEVICE_FIRMWARE_REQUEST_TOPIC_PATTERN = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + REQUEST + "/" + REQUEST_ID_PATTERN + CHUNK + CHUNK_PATTERN;
83 83 public static final String DEVICE_FIRMWARE_RESPONSES_TOPIC = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + RESPONSE + "/" + SUB_TOPIC + CHUNK + SUB_TOPIC;
84 84 public static final String DEVICE_FIRMWARE_ERROR_TOPIC = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + ERROR;
85   - public static final String DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT = BASE_DEVICE_API_TOPIC_V2 + "/%s" + RESPONSE + "/"+ "%s" + CHUNK + "%d";
  85 +
  86 + public static final String DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT = BASE_DEVICE_API_TOPIC_V2 + "/%s" + RESPONSE + "/%s" + CHUNK + "%d";
86 87
87 88 public static final String DEVICE_SOFTWARE_REQUEST_TOPIC_PATTERN = BASE_DEVICE_API_TOPIC_V2 + SOFTWARE + REQUEST + "/" + REQUEST_ID_PATTERN + CHUNK + CHUNK_PATTERN;
88 89 public static final String DEVICE_SOFTWARE_RESPONSES_TOPIC = BASE_DEVICE_API_TOPIC_V2 + SOFTWARE + RESPONSE + "/" + SUB_TOPIC + CHUNK + SUB_TOPIC;
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.common.data.firmware;
  17 +
  18 +public enum ChecksumAlgorithm {
  19 + MD5,
  20 + SHA256,
  21 + SHA384,
  22 + SHA512,
  23 + CRC32,
  24 + MURMUR3_32,
  25 + MURMUR3_128
  26 +}
... ...
... ... @@ -468,9 +468,6 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
468 468 deviceSessionCtx.getPayloadAdaptor()
469 469 .convertToPublish(deviceSessionCtx, firmwareChunk, requestId, chunk, type)
470 470 .ifPresent(deviceSessionCtx.getChannel()::writeAndFlush);
471   - if (firmwareChunk != null && chunkSize != firmwareChunk.length) {
472   - scheduler.schedule(() -> processDisconnect(ctx), 60, TimeUnit.SECONDS);
473   - }
474 471 } catch (Exception e) {
475 472 log.trace("[{}] Failed to send firmware response!", sessionId, e);
476 473 }
... ...
... ... @@ -44,7 +44,7 @@ import java.util.Optional;
44 44 import java.util.Set;
45 45 import java.util.UUID;
46 46
47   -import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT;
  47 +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT;
48 48
49 49
50 50 /**
... ... @@ -156,7 +156,7 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor {
156 156
157 157 @Override
158 158 public Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) {
159   - return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk));
  159 + return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk));
160 160 }
161 161
162 162 public static JsonElement validateJsonPayload(UUID sessionId, ByteBuf payloadData) throws AdaptorException {
... ...
... ... @@ -39,7 +39,7 @@ import org.thingsboard.server.transport.mqtt.session.MqttDeviceAwareSessionConte
39 39
40 40 import java.util.Optional;
41 41
42   -import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT;
  42 +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT;
43 43
44 44 @Component
45 45 @Slf4j
... ... @@ -169,7 +169,7 @@ public class ProtoMqttAdaptor implements MqttTransportAdaptor {
169 169
170 170 @Override
171 171 public Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) throws AdaptorException {
172   - return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk));
  172 + return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk));
173 173 }
174 174
175 175 @Override
... ...
... ... @@ -31,6 +31,9 @@ import org.thingsboard.server.common.data.DeviceProfile;
31 31 import org.thingsboard.server.common.data.Firmware;
32 32 import org.thingsboard.server.common.data.FirmwareInfo;
33 33 import org.thingsboard.server.common.data.Tenant;
  34 +import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
  35 +import org.thingsboard.server.common.data.exception.ThingsboardException;
  36 +import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
34 37 import org.thingsboard.server.common.data.firmware.FirmwareType;
35 38 import org.thingsboard.server.common.data.id.DeviceProfileId;
36 39 import org.thingsboard.server.common.data.id.FirmwareId;
... ... @@ -43,7 +46,11 @@ import org.thingsboard.server.dao.service.DataValidator;
43 46 import org.thingsboard.server.dao.service.PaginatedRemover;
44 47 import org.thingsboard.server.dao.tenant.TenantDao;
45 48
  49 +import java.lang.reflect.InvocationTargetException;
  50 +import java.lang.reflect.Method;
46 51 import java.nio.ByteBuffer;
  52 +import java.util.ArrayList;
  53 +import java.util.Arrays;
47 54 import java.util.Collections;
48 55 import java.util.List;
49 56 import java.util.Optional;
... ... @@ -111,6 +118,36 @@ public class BaseFirmwareService implements FirmwareService {
111 118 }
112 119
113 120 @Override
  121 + public String generateChecksum(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data) {
  122 + if (data == null || !data.hasArray() || data.array().length == 0) {
  123 + throw new DataValidationException("Firmware data should be specified!");
  124 + }
  125 +
  126 + return getHashFunction(checksumAlgorithm).hashBytes(data.array()).toString();
  127 + }
  128 +
  129 + private HashFunction getHashFunction(ChecksumAlgorithm checksumAlgorithm) {
  130 + switch (checksumAlgorithm) {
  131 + case MD5:
  132 + return Hashing.md5();
  133 + case SHA256:
  134 + return Hashing.sha256();
  135 + case SHA384:
  136 + return Hashing.sha384();
  137 + case SHA512:
  138 + return Hashing.sha512();
  139 + case CRC32:
  140 + return Hashing.crc32();
  141 + case MURMUR3_32:
  142 + return Hashing.murmur3_32();
  143 + case MURMUR3_128:
  144 + return Hashing.murmur3_128();
  145 + default:
  146 + throw new DataValidationException("Unknown checksum algorithm!");
  147 + }
  148 + }
  149 +
  150 + @Override
114 151 public Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId) {
115 152 log.trace("Executing findFirmwareById [{}]", firmwareId);
116 153 validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId);
... ... @@ -210,34 +247,16 @@ public class BaseFirmwareService implements FirmwareService {
210 247 throw new DataValidationException("Firmware content type should be specified!");
211 248 }
212 249
213   - ByteBuffer data = firmware.getData();
214   - if (data == null || !data.hasArray() || data.array().length == 0) {
215   - throw new DataValidationException("Firmware data should be specified!");
216   - }
217   -
218   - if (StringUtils.isEmpty(firmware.getChecksumAlgorithm())) {
  250 + if (firmware.getChecksumAlgorithm() == null) {
219 251 throw new DataValidationException("Firmware checksum algorithm should be specified!");
220 252 }
221 253 if (StringUtils.isEmpty(firmware.getChecksum())) {
222 254 throw new DataValidationException("Firmware checksum should be specified!");
223 255 }
224 256
225   - HashFunction hashFunction;
226   - switch (firmware.getChecksumAlgorithm()) {
227   - case "sha256":
228   - hashFunction = Hashing.sha256();
229   - break;
230   - case "md5":
231   - hashFunction = Hashing.md5();
232   - break;
233   - case "crc32":
234   - hashFunction = Hashing.crc32();
235   - break;
236   - default:
237   - throw new DataValidationException("Unknown checksum algorithm!");
238   - }
  257 + String currentChecksum;
239 258
240   - String currentChecksum = hashFunction.hashBytes(data.array()).toString();
  259 + currentChecksum = generateChecksum(firmware.getChecksumAlgorithm(), firmware.getData());
241 260
242 261 if (!currentChecksum.equals(firmware.getChecksum())) {
243 262 throw new DataValidationException("Wrong firmware file!");
... ...
... ... @@ -21,6 +21,7 @@ import lombok.EqualsAndHashCode;
21 21 import org.hibernate.annotations.Type;
22 22 import org.hibernate.annotations.TypeDef;
23 23 import org.thingsboard.server.common.data.Firmware;
  24 +import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
24 25 import org.thingsboard.server.common.data.firmware.FirmwareType;
25 26 import org.thingsboard.server.common.data.id.DeviceProfileId;
26 27 import org.thingsboard.server.common.data.id.FirmwareId;
... ... @@ -82,8 +83,9 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex
82 83 @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN)
83 84 private String contentType;
84 85
  86 + @Enumerated(EnumType.STRING)
85 87 @Column(name = FIRMWARE_CHECKSUM_ALGORITHM_COLUMN)
86   - private String checksumAlgorithm;
  88 + private ChecksumAlgorithm checksumAlgorithm;
87 89
88 90 @Column(name = FIRMWARE_CHECKSUM_COLUMN)
89 91 private String checksum;
... ...
... ... @@ -22,6 +22,7 @@ import org.hibernate.annotations.Type;
22 22 import org.hibernate.annotations.TypeDef;
23 23 import org.thingsboard.common.util.JacksonUtil;
24 24 import org.thingsboard.server.common.data.FirmwareInfo;
  25 +import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
25 26 import org.thingsboard.server.common.data.firmware.FirmwareType;
26 27 import org.thingsboard.server.common.data.id.DeviceProfileId;
27 28 import org.thingsboard.server.common.data.id.FirmwareId;
... ... @@ -81,8 +82,9 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
81 82 @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN)
82 83 private String contentType;
83 84
  85 + @Enumerated(EnumType.STRING)
84 86 @Column(name = FIRMWARE_CHECKSUM_ALGORITHM_COLUMN)
85   - private String checksumAlgorithm;
  87 + private ChecksumAlgorithm checksumAlgorithm;
86 88
87 89 @Column(name = FIRMWARE_CHECKSUM_COLUMN)
88 90 private String checksum;
... ... @@ -123,7 +125,7 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
123 125 }
124 126
125 127 public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, UUID deviceProfileId, FirmwareType type, String title, String version,
126   - String fileName, String contentType, String checksumAlgorithm, String checksum, Long dataSize,
  128 + String fileName, String contentType, ChecksumAlgorithm checksumAlgorithm, String checksum, Long dataSize,
127 129 Object additionalInfo, boolean hasData) {
128 130 this.id = id;
129 131 this.createdTime = createdTime;
... ...
... ... @@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.DeviceTransportType;
31 31 import org.thingsboard.server.common.data.Firmware;
32 32 import org.thingsboard.server.common.data.Tenant;
33 33 import org.thingsboard.server.common.data.firmware.FirmwareType;
  34 +import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
34 35 import org.thingsboard.server.common.data.id.TenantId;
35 36 import org.thingsboard.server.common.data.page.PageData;
36 37 import org.thingsboard.server.common.data.page.PageLink;
... ... @@ -106,7 +107,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
106 107 firmware.setVersion("v1.0");
107 108 firmware.setFileName("test.txt");
108 109 firmware.setContentType("text/plain");
109   - firmware.setChecksumAlgorithm("sha256");
  110 + firmware.setChecksumAlgorithm(ChecksumAlgorithm.SHA256);
110 111 firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a");
111 112 firmware.setData(ByteBuffer.wrap(new byte[]{1}));
112 113 Firmware savedFirmware = firmwareService.saveFirmware(firmware);
... ...
... ... @@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.EntitySubtype;
31 31 import org.thingsboard.server.common.data.Firmware;
32 32 import org.thingsboard.server.common.data.Tenant;
33 33 import org.thingsboard.server.common.data.TenantProfile;
  34 +import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
34 35 import org.thingsboard.server.common.data.id.CustomerId;
35 36 import org.thingsboard.server.common.data.id.TenantId;
36 37 import org.thingsboard.server.common.data.page.PageData;
... ... @@ -196,7 +197,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest {
196 197 firmware.setVersion("v1.0");
197 198 firmware.setFileName("test.txt");
198 199 firmware.setContentType("text/plain");
199   - firmware.setChecksumAlgorithm("sha256");
  200 + firmware.setChecksumAlgorithm(ChecksumAlgorithm.SHA256);
200 201 firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a");
201 202 firmware.setData(ByteBuffer.wrap(new byte[]{1}));
202 203 Firmware savedFirmware = firmwareService.saveFirmware(firmware);
... ... @@ -230,7 +231,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest {
230 231 firmware.setVersion("v1.0");
231 232 firmware.setFileName("test.txt");
232 233 firmware.setContentType("text/plain");
233   - firmware.setChecksumAlgorithm("sha256");
  234 + firmware.setChecksumAlgorithm(ChecksumAlgorithm.SHA256);
234 235 firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a");
235 236 firmware.setData(ByteBuffer.wrap(new byte[]{1}));
236 237 Firmware savedFirmware = firmwareService.saveFirmware(firmware);
... ...
... ... @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.DeviceProfile;
28 28 import org.thingsboard.server.common.data.Firmware;
29 29 import org.thingsboard.server.common.data.FirmwareInfo;
30 30 import org.thingsboard.server.common.data.Tenant;
  31 +import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
31 32 import org.thingsboard.server.common.data.id.DeviceProfileId;
32 33 import org.thingsboard.server.common.data.id.TenantId;
33 34 import org.thingsboard.server.common.data.page.PageData;
... ... @@ -47,7 +48,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest {
47 48 private static final String FILE_NAME = "filename.txt";
48 49 private static final String VERSION = "v1.0";
49 50 private static final String CONTENT_TYPE = "text/plain";
50   - private static final String CHECKSUM_ALGORITHM = "sha256";
  51 + private static final ChecksumAlgorithm CHECKSUM_ALGORITHM = ChecksumAlgorithm.SHA256;
51 52 private static final String CHECKSUM = "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a";
52 53 private static final ByteBuffer DATA = ByteBuffer.wrap(new byte[]{1});
53 54
... ...
... ... @@ -20,7 +20,7 @@ import { PageLink } from '@shared/models/page/page-link';
20 20 import { defaultHttpOptionsFromConfig, defaultHttpUploadOptions, RequestConfig } from '@core/http/http-utils';
21 21 import { Observable } from 'rxjs';
22 22 import { PageData } from '@shared/models/page/page-data';
23   -import { Firmware, FirmwareInfo, FirmwareType } from '@shared/models/firmware.models';
  23 +import { ChecksumAlgorithm, Firmware, FirmwareInfo, FirmwareType } from '@shared/models/firmware.models';
24 24 import { catchError, map, mergeMap } from 'rxjs/operators';
25 25 import { deepClone, isDefinedAndNotNull } from '@core/utils';
26 26
... ... @@ -101,16 +101,16 @@ export class FirmwareService {
101 101 return this.http.post<Firmware>('/api/firmware', firmware, defaultHttpOptionsFromConfig(config));
102 102 }
103 103
104   - public uploadFirmwareFile(firmwareId: string, file: File, checksumAlgorithm?: string,
  104 + public uploadFirmwareFile(firmwareId: string, file: File, checksumAlgorithm: ChecksumAlgorithm,
105 105 checksum?: string, config?: RequestConfig): Observable<any> {
106 106 if (!config) {
107 107 config = {};
108 108 }
109 109 const formData = new FormData();
110 110 formData.append('file', file);
111   - let url = `/api/firmware/${firmwareId}`;
112   - if (checksumAlgorithm && checksum) {
113   - url += `?checksumAlgorithm=${checksumAlgorithm}&checksum=${checksum}`;
  111 + let url = `/api/firmware/${firmwareId}?checksumAlgorithm=${checksumAlgorithm}`;
  112 + if (checksum) {
  113 + url += `&checksum=${checksum}`;
114 114 }
115 115 return this.http.post(url, formData,
116 116 defaultHttpUploadOptions(config.ignoreLoading, config.ignoreErrors, config.resendRequest));
... ...
... ... @@ -89,7 +89,6 @@
89 89 <input *ngIf="!isAdd" matInput type="text" [readonly]="isEdit" [disabled]="!isEdit"
90 90 value="{{ checksumAlgorithmTranslationMap.get(entityForm.get('checksumAlgorithm').value) | translate }}">
91 91 <mat-select formControlName="checksumAlgorithm" *ngIf="isAdd">
92   - <mat-option [value]=null></mat-option>
93 92 <mat-option *ngFor="let checksumAlgorithm of checksumAlgorithms" [value]="checksumAlgorithm">
94 93 {{ checksumAlgorithmTranslationMap.get(checksumAlgorithm) }}
95 94 </mat-option>
... ... @@ -97,11 +96,7 @@
97 96 </mat-form-field>
98 97 <mat-form-field class="mat-block" fxFlex>
99 98 <mat-label translate>firmware.checksum</mat-label>
100   - <input matInput formControlName="checksum" type="text" [readonly]="!isAdd"
101   - [required]="entityForm.get('checksumAlgorithm').value != null">
102   - <mat-error *ngIf="entityForm.get('checksumAlgorithm').hasError('required')">
103   - {{ 'firmware.checksum-required' | translate }}
104   - </mat-error>
  99 + <input matInput formControlName="checksum" type="text" [readonly]="!isAdd">
105 100 </mat-form-field>
106 101 </div>
107 102 <section *ngIf="isAdd" style="padding-top: 8px">
... ...
... ... @@ -29,7 +29,6 @@ import {
29 29 FirmwareType,
30 30 FirmwareTypeTranslationMap
31 31 } from '@shared/models/firmware.models';
32   -import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators';
33 32 import { ActionNotificationShow } from '@core/notification/notification.actions';
34 33
35 34 @Component({
... ... @@ -53,26 +52,6 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI
53 52 super(store, fb, entityValue, entitiesTableConfigValue);
54 53 }
55 54
56   - ngOnInit() {
57   - super.ngOnInit();
58   - if (this.isAdd) {
59   - this.entityForm.get('checksumAlgorithm').valueChanges.pipe(
60   - map(algorithm => !!algorithm),
61   - distinctUntilChanged(),
62   - takeUntil(this.destroy$)
63   - ).subscribe(
64   - setAlgorithm => {
65   - if (setAlgorithm) {
66   - this.entityForm.get('checksum').setValidators([Validators.maxLength(1020), Validators.required]);
67   - } else {
68   - this.entityForm.get('checksum').clearValidators();
69   - }
70   - this.entityForm.get('checksum').updateValueAndValidity({emitEvent: false});
71   - }
72   - );
73   - }
74   - }
75   -
76 55 ngOnDestroy() {
77 56 super.ngOnDestroy();
78 57 this.destroy$.next();
... ... @@ -93,7 +72,7 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI
93 72 version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]],
94 73 type: [entity?.type ? entity.type : FirmwareType.FIRMWARE, [Validators.required]],
95 74 deviceProfileId: [entity ? entity.deviceProfileId : null],
96   - checksumAlgorithm: [entity ? entity.checksumAlgorithm : null],
  75 + checksumAlgorithm: [entity && entity.checksumAlgorithm ? entity.checksumAlgorithm : ChecksumAlgorithm.SHA256],
97 76 checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)],
98 77 additionalInfo: this.fb.group(
99 78 {
... ...
... ... @@ -20,16 +20,24 @@ import { FirmwareId } from '@shared/models/id/firmware-id';
20 20 import { DeviceProfileId } from '@shared/models/id/device-profile-id';
21 21
22 22 export enum ChecksumAlgorithm {
23   - MD5 = 'md5',
24   - SHA256 = 'sha256',
25   - CRC32 = 'crc32'
  23 + MD5 = 'MD5',
  24 + SHA256 = 'SHA256',
  25 + SHA384 = 'SHA384',
  26 + SHA512 = 'SHA512',
  27 + CRC32 = 'CRC32',
  28 + MURMUR3_32 = 'MURMUR3_32',
  29 + MURMUR3_128 = 'MURMUR3_128'
26 30 }
27 31
28 32 export const ChecksumAlgorithmTranslationMap = new Map<ChecksumAlgorithm, string>(
29 33 [
30 34 [ChecksumAlgorithm.MD5, 'MD5'],
31 35 [ChecksumAlgorithm.SHA256, 'SHA-256'],
32   - [ChecksumAlgorithm.CRC32, 'CRC-32']
  36 + [ChecksumAlgorithm.SHA384, 'SHA-384'],
  37 + [ChecksumAlgorithm.SHA512, 'SHA-512'],
  38 + [ChecksumAlgorithm.CRC32, 'CRC-32'],
  39 + [ChecksumAlgorithm.MURMUR3_32, 'MURMUR3-32'],
  40 + [ChecksumAlgorithm.MURMUR3_128, 'MURMUR3-128']
33 41 ]
34 42 );
35 43
... ...