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; | ... | ... |
common/data/src/main/java/org/thingsboard/server/common/data/firmware/ChecksumAlgorithm.java
0 → 100644
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 | ... | ... |