Commit 935aab753506e2e5d46718ae458588ef1439e0a7
1 parent
7954f91f
added checksum and checksum algorithm for firmware
Showing
18 changed files
with
511 additions
and
57 deletions
... | ... | @@ -32,10 +32,15 @@ CREATE TABLE IF NOT EXISTS firmware ( |
32 | 32 | created_time bigint NOT NULL, |
33 | 33 | tenant_id uuid NOT NULL, |
34 | 34 | title varchar(255) NOT NULL, |
35 | + version varchar(255) NOT NULL, | |
36 | + file_name varchar(255), | |
37 | + content_type varchar(255), | |
38 | + checksum_algorithm varchar(32), | |
39 | + checksum varchar(1020), | |
40 | + data binary, | |
41 | + additional_info varchar, | |
35 | 42 | search_text varchar(255), |
36 | - file_name varchar(255) NOT NULL, | |
37 | - content_type varchar(255) NOT NULL, | |
38 | - data bytea | |
43 | + CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) | |
39 | 44 | ); |
40 | 45 | |
41 | 46 | ALTER TABLE device_profile | ... | ... |
... | ... | @@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.page.PageData; |
36 | 36 | import org.thingsboard.server.common.data.page.PageLink; |
37 | 37 | import org.thingsboard.server.queue.util.TbCoreComponent; |
38 | 38 | import org.thingsboard.server.service.security.permission.Operation; |
39 | +import org.thingsboard.server.service.security.permission.Resource; | |
39 | 40 | |
40 | 41 | import java.nio.ByteBuffer; |
41 | 42 | |
... | ... | @@ -97,14 +98,36 @@ public class FirmwareController extends BaseController { |
97 | 98 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") |
98 | 99 | @RequestMapping(value = "/firmware", method = RequestMethod.POST) |
99 | 100 | @ResponseBody |
100 | - public Firmware saveFirmware(@RequestParam("title") String title, | |
101 | - @RequestBody MultipartFile firmwareFile) throws ThingsboardException { | |
102 | - checkParameter("title", title); | |
101 | + public FirmwareInfo saveFirmwareInfo(@RequestParam("title") FirmwareInfo firmwareInfo) throws ThingsboardException { | |
102 | + checkEntity(firmwareInfo.getId(), firmwareInfo, Resource.FIRMWARE); | |
103 | 103 | try { |
104 | - checkNotNull(firmwareFile); | |
105 | - Firmware firmware = new Firmware(); | |
104 | + return firmwareService.saveFirmwareInfo(firmwareInfo); | |
105 | + } catch (Exception e) { | |
106 | + throw handleException(e); | |
107 | + } | |
108 | + } | |
109 | + | |
110 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") | |
111 | + @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.POST) | |
112 | + @ResponseBody | |
113 | + public Firmware saveFirmwareData(@PathVariable(FIRMWARE_ID) String strFirmwareId, | |
114 | + @RequestParam String checksum, | |
115 | + @RequestParam String checksumAlgorithm, | |
116 | + @RequestBody MultipartFile firmwareFile) throws ThingsboardException { | |
117 | + checkParameter(FIRMWARE_ID, strFirmwareId); | |
118 | + checkParameter("checksum", checksum); | |
119 | + try { | |
120 | + FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId)); | |
121 | + FirmwareInfo info = checkFirmwareInfoId(firmwareId, Operation.READ); | |
122 | + | |
123 | + Firmware firmware = new Firmware(firmwareId); | |
124 | + firmware.setCreatedTime(info.getCreatedTime()); | |
106 | 125 | firmware.setTenantId(getTenantId()); |
107 | - firmware.setTitle(title); | |
126 | + firmware.setVersion(info.getVersion()); | |
127 | + firmware.setAdditionalInfo(info.getAdditionalInfo()); | |
128 | + | |
129 | + firmware.setChecksumAlgorithm(checksumAlgorithm); | |
130 | + firmware.setChecksum(checksum); | |
108 | 131 | firmware.setFileName(firmwareFile.getOriginalFilename()); |
109 | 132 | firmware.setContentType(firmwareFile.getContentType()); |
110 | 133 | firmware.setData(ByteBuffer.wrap(firmwareFile.getBytes())); | ... | ... |
... | ... | @@ -230,7 +230,6 @@ public class ThingsboardInstallService { |
230 | 230 | systemDataLoaderService.createAdminSettings(); |
231 | 231 | systemDataLoaderService.loadSystemWidgets(); |
232 | 232 | systemDataLoaderService.createOAuth2Templates(); |
233 | - systemDataLoaderService.loadSystemLwm2mResources(); | |
234 | 233 | // systemDataLoaderService.loadSystemPlugins(); |
235 | 234 | // systemDataLoaderService.loadSystemRules(); |
236 | 235 | ... | ... |
... | ... | @@ -22,9 +22,10 @@ import org.thingsboard.server.common.data.id.TenantId; |
22 | 22 | import org.thingsboard.server.common.data.page.PageData; |
23 | 23 | import org.thingsboard.server.common.data.page.PageLink; |
24 | 24 | |
25 | - | |
26 | 25 | public interface FirmwareService { |
27 | 26 | |
27 | + FirmwareInfo saveFirmwareInfo(FirmwareInfo firmwareInfo); | |
28 | + | |
28 | 29 | Firmware saveFirmware(Firmware firmware); |
29 | 30 | |
30 | 31 | Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId); | ... | ... |
... | ... | @@ -27,6 +27,14 @@ public class Firmware extends FirmwareInfo { |
27 | 27 | |
28 | 28 | private static final long serialVersionUID = 3091601761339422546L; |
29 | 29 | |
30 | + private String fileName; | |
31 | + | |
32 | + private String contentType; | |
33 | + | |
34 | + private String checksumAlgorithm; | |
35 | + | |
36 | + private String checksum; | |
37 | + | |
30 | 38 | private transient ByteBuffer data; |
31 | 39 | |
32 | 40 | public Firmware() { |
... | ... | @@ -39,6 +47,10 @@ public class Firmware extends FirmwareInfo { |
39 | 47 | |
40 | 48 | public Firmware(Firmware firmware) { |
41 | 49 | super(firmware); |
50 | + this.fileName = firmware.getFileName(); | |
51 | + this.contentType = firmware.getContentType(); | |
42 | 52 | this.data = firmware.getData(); |
53 | + this.checksumAlgorithm = firmware.getChecksumAlgorithm(); | |
54 | + this.checksum = firmware.getChecksum(); | |
43 | 55 | } |
44 | 56 | } | ... | ... |
... | ... | @@ -24,14 +24,13 @@ import org.thingsboard.server.common.data.id.TenantId; |
24 | 24 | @Slf4j |
25 | 25 | @Data |
26 | 26 | @EqualsAndHashCode(callSuper = true) |
27 | -public class FirmwareInfo extends SearchTextBased<FirmwareId> implements HasTenantId { | |
27 | +public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId> implements HasTenantId { | |
28 | 28 | |
29 | 29 | private static final long serialVersionUID = 3168391583570815419L; |
30 | 30 | |
31 | 31 | private TenantId tenantId; |
32 | 32 | private String title; |
33 | - private String fileName; | |
34 | - private String contentType; | |
33 | + private String version; | |
35 | 34 | |
36 | 35 | public FirmwareInfo() { |
37 | 36 | super(); |
... | ... | @@ -45,8 +44,7 @@ public class FirmwareInfo extends SearchTextBased<FirmwareId> implements HasTena |
45 | 44 | super(firmwareInfo); |
46 | 45 | this.tenantId = firmwareInfo.getTenantId(); |
47 | 46 | this.title = firmwareInfo.getTitle(); |
48 | - this.fileName = firmwareInfo.getFileName(); | |
49 | - this.contentType = firmwareInfo.getContentType(); | |
47 | + this.version = firmwareInfo.getVersion(); | |
50 | 48 | } |
51 | 49 | |
52 | 50 | @Override | ... | ... |
... | ... | @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.DeviceProfileInfo; |
40 | 40 | import org.thingsboard.server.common.data.DeviceProfileProvisionType; |
41 | 41 | import org.thingsboard.server.common.data.DeviceProfileType; |
42 | 42 | import org.thingsboard.server.common.data.DeviceTransportType; |
43 | +import org.thingsboard.server.common.data.Firmware; | |
43 | 44 | import org.thingsboard.server.common.data.Tenant; |
44 | 45 | import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration; |
45 | 46 | import org.thingsboard.server.common.data.device.profile.CoapDeviceTypeConfiguration; |
... | ... | @@ -59,6 +60,7 @@ import org.thingsboard.server.common.data.page.PageData; |
59 | 60 | import org.thingsboard.server.common.data.page.PageLink; |
60 | 61 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
61 | 62 | import org.thingsboard.server.dao.exception.DataValidationException; |
63 | +import org.thingsboard.server.dao.firmware.FirmwareService; | |
62 | 64 | import org.thingsboard.server.dao.service.DataValidator; |
63 | 65 | import org.thingsboard.server.dao.service.PaginatedRemover; |
64 | 66 | import org.thingsboard.server.dao.service.Validator; |
... | ... | @@ -107,6 +109,9 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D |
107 | 109 | @Autowired |
108 | 110 | private CacheManager cacheManager; |
109 | 111 | |
112 | + @Autowired | |
113 | + private FirmwareService firmwareService; | |
114 | + | |
110 | 115 | private final Lock findOrCreateLock = new ReentrantLock(); |
111 | 116 | |
112 | 117 | @Cacheable(cacheNames = DEVICE_PROFILE_CACHE, key = "{#deviceProfileId.id}") |
... | ... | @@ -389,6 +394,15 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D |
389 | 394 | } |
390 | 395 | } |
391 | 396 | |
397 | + if (deviceProfile.getFirmwareId() != null) { | |
398 | + Firmware firmware = firmwareService.findFirmwareById(tenantId, deviceProfile.getFirmwareId()); | |
399 | + if (firmware == null) { | |
400 | + throw new DataValidationException("Can't assign non-existent firmware!"); | |
401 | + } | |
402 | + if (firmware.getData() == null) { | |
403 | + throw new DataValidationException("Can't assign firmware with empty data!"); | |
404 | + } | |
405 | + } | |
392 | 406 | } |
393 | 407 | |
394 | 408 | @Override | ... | ... |
... | ... | @@ -39,6 +39,7 @@ import org.thingsboard.server.common.data.DeviceProfile; |
39 | 39 | import org.thingsboard.server.common.data.EntitySubtype; |
40 | 40 | import org.thingsboard.server.common.data.EntityType; |
41 | 41 | import org.thingsboard.server.common.data.EntityView; |
42 | +import org.thingsboard.server.common.data.Firmware; | |
42 | 43 | import org.thingsboard.server.common.data.Tenant; |
43 | 44 | import org.thingsboard.server.common.data.device.DeviceSearchQuery; |
44 | 45 | import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; |
... | ... | @@ -68,6 +69,7 @@ import org.thingsboard.server.dao.entity.AbstractEntityService; |
68 | 69 | import org.thingsboard.server.dao.entityview.EntityViewService; |
69 | 70 | import org.thingsboard.server.dao.event.EventService; |
70 | 71 | import org.thingsboard.server.dao.exception.DataValidationException; |
72 | +import org.thingsboard.server.dao.firmware.FirmwareService; | |
71 | 73 | import org.thingsboard.server.dao.service.DataValidator; |
72 | 74 | import org.thingsboard.server.dao.service.PaginatedRemover; |
73 | 75 | import org.thingsboard.server.dao.tenant.TbTenantProfileCache; |
... | ... | @@ -128,6 +130,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe |
128 | 130 | @Lazy |
129 | 131 | private TbTenantProfileCache tenantProfileCache; |
130 | 132 | |
133 | + @Autowired | |
134 | + private FirmwareService firmwareService; | |
135 | + | |
131 | 136 | @Override |
132 | 137 | public DeviceInfo findDeviceInfoById(TenantId tenantId, DeviceId deviceId) { |
133 | 138 | log.trace("Executing findDeviceInfoById [{}]", deviceId); |
... | ... | @@ -598,6 +603,16 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe |
598 | 603 | throw new DataValidationException("Can't assign device to customer from different tenant!"); |
599 | 604 | } |
600 | 605 | } |
606 | + | |
607 | + if (device.getFirmwareId() != null) { | |
608 | + Firmware firmware = firmwareService.findFirmwareById(tenantId, device.getFirmwareId()); | |
609 | + if (firmware == null) { | |
610 | + throw new DataValidationException("Can't assign non-existent firmware!"); | |
611 | + } | |
612 | + if (firmware.getData() == null) { | |
613 | + throw new DataValidationException("Can't assign firmware with empty data!"); | |
614 | + } | |
615 | + } | |
601 | 616 | } |
602 | 617 | }; |
603 | 618 | ... | ... |
... | ... | @@ -15,6 +15,8 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.firmware; |
17 | 17 | |
18 | +import com.google.common.hash.HashFunction; | |
19 | +import com.google.common.hash.Hashing; | |
18 | 20 | import lombok.extern.slf4j.Slf4j; |
19 | 21 | import org.apache.commons.lang3.StringUtils; |
20 | 22 | import org.hibernate.exception.ConstraintViolationException; |
... | ... | @@ -54,10 +56,35 @@ public class BaseFirmwareService implements FirmwareService { |
54 | 56 | } |
55 | 57 | |
56 | 58 | @Override |
59 | + public FirmwareInfo saveFirmwareInfo(FirmwareInfo firmwareInfo) { | |
60 | + log.trace("Executing saveFirmwareInfo [{}]", firmwareInfo); | |
61 | + firmwareInfoValidator.validate(firmwareInfo, FirmwareInfo::getTenantId); | |
62 | + try { | |
63 | + return firmwareInfoDao.save(firmwareInfo.getTenantId(), firmwareInfo); | |
64 | + } catch (Exception t) { | |
65 | + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); | |
66 | + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("firmware_tenant_title_version_unq_key")) { | |
67 | + throw new DataValidationException("Firmware with such title and version already exists!"); | |
68 | + } else { | |
69 | + throw t; | |
70 | + } | |
71 | + } | |
72 | + } | |
73 | + | |
74 | + @Override | |
57 | 75 | public Firmware saveFirmware(Firmware firmware) { |
58 | 76 | log.trace("Executing saveFirmware [{}]", firmware); |
59 | - firmwareValidator.validate(firmware, Firmware::getTenantId); | |
60 | - return firmwareDao.save(firmware.getTenantId(), firmware); | |
77 | + firmwareValidator.validate(firmware, FirmwareInfo::getTenantId); | |
78 | + try { | |
79 | + return firmwareDao.save(firmware.getTenantId(), firmware); | |
80 | + } catch (Exception t) { | |
81 | + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); | |
82 | + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("firmware_tenant_title_version_unq_key")) { | |
83 | + throw new DataValidationException("Firmware with such title and version already exists!"); | |
84 | + } else { | |
85 | + throw t; | |
86 | + } | |
87 | + } | |
61 | 88 | } |
62 | 89 | |
63 | 90 | @Override |
... | ... | @@ -107,6 +134,42 @@ public class BaseFirmwareService implements FirmwareService { |
107 | 134 | tenantFirmwareRemover.removeEntities(tenantId, tenantId); |
108 | 135 | } |
109 | 136 | |
137 | + private DataValidator<FirmwareInfo> firmwareInfoValidator = new DataValidator<>() { | |
138 | + | |
139 | + @Override | |
140 | + protected void validateDataImpl(TenantId tenantId, FirmwareInfo firmware) { | |
141 | + if (firmware.getTenantId() == null) { | |
142 | + throw new DataValidationException("Firmware should be assigned to tenant!"); | |
143 | + } else { | |
144 | + Tenant tenant = tenantDao.findById(firmware.getTenantId(), firmware.getTenantId().getId()); | |
145 | + if (tenant == null) { | |
146 | + throw new DataValidationException("Firmware is referencing to non-existent tenant!"); | |
147 | + } | |
148 | + } | |
149 | + | |
150 | + if (StringUtils.isEmpty(firmware.getTitle())) { | |
151 | + throw new DataValidationException("Firmware title should be specified!"); | |
152 | + } | |
153 | + | |
154 | + if (StringUtils.isEmpty(firmware.getVersion())) { | |
155 | + throw new DataValidationException("Firmware version should be specified!"); | |
156 | + } | |
157 | + } | |
158 | + | |
159 | + @Override | |
160 | + protected void validateUpdate(TenantId tenantId, FirmwareInfo firmware) { | |
161 | + FirmwareInfo firmwareOld = firmwareInfoDao.findById(tenantId, firmware.getUuidId()); | |
162 | + | |
163 | + if (!firmwareOld.getTitle().equals(firmware.getTitle())) { | |
164 | + throw new DataValidationException("Updating firmware title is prohibited!"); | |
165 | + } | |
166 | + | |
167 | + if (!firmwareOld.getVersion().equals(firmware.getVersion())) { | |
168 | + throw new DataValidationException("Updating firmware version is prohibited!"); | |
169 | + } | |
170 | + } | |
171 | + }; | |
172 | + | |
110 | 173 | private DataValidator<Firmware> firmwareValidator = new DataValidator<>() { |
111 | 174 | |
112 | 175 | @Override |
... | ... | @@ -123,22 +186,91 @@ public class BaseFirmwareService implements FirmwareService { |
123 | 186 | if (StringUtils.isEmpty(firmware.getTitle())) { |
124 | 187 | throw new DataValidationException("Firmware title should be specified!"); |
125 | 188 | } |
189 | + | |
190 | + if (StringUtils.isEmpty(firmware.getVersion())) { | |
191 | + throw new DataValidationException("Firmware version should be specified!"); | |
192 | + } | |
193 | + | |
126 | 194 | if (StringUtils.isEmpty(firmware.getFileName())) { |
127 | 195 | throw new DataValidationException("Firmware file name should be specified!"); |
128 | 196 | } |
197 | + | |
129 | 198 | if (StringUtils.isEmpty(firmware.getContentType())) { |
130 | 199 | throw new DataValidationException("Firmware content type should be specified!"); |
131 | 200 | } |
201 | + | |
202 | + if (StringUtils.isEmpty(firmware.getChecksum())) { | |
203 | + throw new DataValidationException("Firmware checksum should be specified!"); | |
204 | + } | |
205 | + | |
132 | 206 | ByteBuffer data = firmware.getData(); |
133 | 207 | if (data == null || !data.hasArray() || data.array().length == 0) { |
134 | 208 | throw new DataValidationException("Firmware data should be specified!"); |
135 | 209 | } |
210 | + | |
211 | + if (firmware.getChecksumAlgorithm() != null) { | |
212 | + HashFunction hashFunction; | |
213 | + switch (firmware.getChecksumAlgorithm()) { | |
214 | + case "sha256": | |
215 | + hashFunction = Hashing.sha256(); | |
216 | + break; | |
217 | + case "md5": | |
218 | + hashFunction = Hashing.md5(); | |
219 | + break; | |
220 | + case "crc32": | |
221 | + hashFunction = Hashing.crc32(); | |
222 | + break; | |
223 | + default: | |
224 | + throw new DataValidationException("Unknown checksum algorithm!"); | |
225 | + } | |
226 | + | |
227 | + String currentChecksum = hashFunction.hashBytes(data.array()).toString(); | |
228 | + ; | |
229 | + | |
230 | + if (!currentChecksum.equals(firmware.getChecksum())) { | |
231 | + throw new DataValidationException("Wrong firmware file!"); | |
232 | + } | |
233 | + } | |
234 | + } | |
235 | + | |
236 | + @Override | |
237 | + protected void validateUpdate(TenantId tenantId, Firmware firmware) { | |
238 | + Firmware firmwareOld = firmwareDao.findById(tenantId, firmware.getUuidId()); | |
239 | + | |
240 | + if (!firmwareOld.getTitle().equals(firmware.getTitle())) { | |
241 | + throw new DataValidationException("Updating firmware title is prohibited!"); | |
242 | + } | |
243 | + | |
244 | + if (!firmwareOld.getVersion().equals(firmware.getVersion())) { | |
245 | + throw new DataValidationException("Updating firmware version is prohibited!"); | |
246 | + } | |
247 | + | |
248 | + if (firmwareOld.getFileName() != null && !firmwareOld.getFileName().equals(firmware.getFileName())) { | |
249 | + throw new DataValidationException("Updating firmware file name is prohibited!"); | |
250 | + } | |
251 | + | |
252 | + if (firmwareOld.getContentType() != null && !firmwareOld.getContentType().equals(firmware.getContentType())) { | |
253 | + throw new DataValidationException("Updating firmware content type is prohibited!"); | |
254 | + } | |
255 | + | |
256 | + if (firmwareOld.getChecksumAlgorithm() != null && !firmwareOld.getChecksumAlgorithm().equals(firmware.getChecksumAlgorithm())) { | |
257 | + throw new DataValidationException("Updating firmware content type is prohibited!"); | |
258 | + } | |
259 | + | |
260 | + if (firmwareOld.getChecksum() != null && !firmwareOld.getChecksum().equals(firmware.getChecksum())) { | |
261 | + throw new DataValidationException("Updating firmware content type is prohibited!"); | |
262 | + } | |
263 | + | |
264 | + if (firmwareOld.getData() != null && !firmwareOld.getData().equals(firmware.getData())) { | |
265 | + throw new DataValidationException("Updating firmware data is prohibited!"); | |
266 | + } | |
136 | 267 | } |
137 | 268 | }; |
138 | 269 | |
139 | 270 | private PaginatedRemover<TenantId, FirmwareInfo> tenantFirmwareRemover = |
140 | 271 | new PaginatedRemover<>() { |
141 | 272 | |
273 | + | |
142 | 274 | @Override |
143 | 275 | protected PageData<FirmwareInfo> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) { |
144 | 276 | return firmwareInfoDao.findFirmwareInfoByTenantId(id, pageLink); | ... | ... |
... | ... | @@ -475,9 +475,14 @@ public class ModelConstants { |
475 | 475 | public static final String FIRMWARE_TABLE_NAME = "firmware"; |
476 | 476 | public static final String FIRMWARE_TENANT_ID_COLUMN = TENANT_ID_COLUMN; |
477 | 477 | public static final String FIRMWARE_TITLE_COLUMN = TITLE_PROPERTY; |
478 | + public static final String FIRMWARE_VERSION_COLUMN = "version"; | |
478 | 479 | public static final String FIRMWARE_FILE_NAME_COLUMN = "file_name"; |
479 | 480 | public static final String FIRMWARE_CONTENT_TYPE_COLUMN = "content_type"; |
481 | + public static final String FIRMWARE_CHECKSUM_ALGORITHM_COLUMN = "checksum_algorithm"; | |
482 | + public static final String FIRMWARE_CHECKSUM_COLUMN = "checksum"; | |
480 | 483 | public static final String FIRMWARE_DATA_COLUMN = "data"; |
484 | + public static final String FIRMWARE_ADDITIONAL_INFO_COLUMN = ADDITIONAL_INFO_PROPERTY; | |
485 | + | |
481 | 486 | |
482 | 487 | /** |
483 | 488 | * Cassandra attributes and timeseries constants. | ... | ... |
... | ... | @@ -15,13 +15,18 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.model.sql; |
17 | 17 | |
18 | +import com.fasterxml.jackson.databind.JsonNode; | |
18 | 19 | import lombok.Data; |
19 | 20 | import lombok.EqualsAndHashCode; |
21 | +import org.hibernate.annotations.Type; | |
22 | +import org.hibernate.annotations.TypeDef; | |
20 | 23 | import org.thingsboard.server.common.data.Firmware; |
21 | 24 | import org.thingsboard.server.common.data.id.FirmwareId; |
22 | 25 | import org.thingsboard.server.common.data.id.TenantId; |
23 | 26 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
27 | +import org.thingsboard.server.dao.model.ModelConstants; | |
24 | 28 | import org.thingsboard.server.dao.model.SearchTextEntity; |
29 | +import org.thingsboard.server.dao.util.mapping.JsonStringType; | |
25 | 30 | |
26 | 31 | import javax.persistence.Column; |
27 | 32 | import javax.persistence.Entity; |
... | ... | @@ -29,17 +34,21 @@ import javax.persistence.Table; |
29 | 34 | import java.nio.ByteBuffer; |
30 | 35 | import java.util.UUID; |
31 | 36 | |
37 | +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ALGORITHM_COLUMN; | |
38 | +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_COLUMN; | |
32 | 39 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN; |
33 | 40 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_COLUMN; |
34 | 41 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN; |
35 | 42 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME; |
36 | 43 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN; |
37 | 44 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; |
45 | +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; | |
38 | 46 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; |
39 | 47 | |
40 | 48 | @Data |
41 | 49 | @EqualsAndHashCode(callSuper = true) |
42 | 50 | @Entity |
51 | +@TypeDef(name = "json", typeClass = JsonStringType.class) | |
43 | 52 | @Table(name = FIRMWARE_TABLE_NAME) |
44 | 53 | public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTextEntity<Firmware> { |
45 | 54 | |
... | ... | @@ -49,15 +58,28 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex |
49 | 58 | @Column(name = FIRMWARE_TITLE_COLUMN) |
50 | 59 | private String title; |
51 | 60 | |
61 | + @Column(name = FIRMWARE_VERSION_COLUMN) | |
62 | + private String version; | |
63 | + | |
52 | 64 | @Column(name = FIRMWARE_FILE_NAME_COLUMN) |
53 | 65 | private String fileName; |
54 | 66 | |
55 | 67 | @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN) |
56 | 68 | private String contentType; |
57 | 69 | |
70 | + @Column(name = FIRMWARE_CHECKSUM_ALGORITHM_COLUMN) | |
71 | + private String checksumAlgorithm; | |
72 | + | |
73 | + @Column(name = FIRMWARE_CHECKSUM_COLUMN) | |
74 | + private String checksum; | |
75 | + | |
58 | 76 | @Column(name = FIRMWARE_DATA_COLUMN, columnDefinition = "BINARY") |
59 | 77 | private byte[] data; |
60 | 78 | |
79 | + @Type(type = "json") | |
80 | + @Column(name = ModelConstants.FIRMWARE_ADDITIONAL_INFO_COLUMN) | |
81 | + private JsonNode additionalInfo; | |
82 | + | |
61 | 83 | @Column(name = SEARCH_TEXT_PROPERTY) |
62 | 84 | private String searchText; |
63 | 85 | |
... | ... | @@ -70,9 +92,13 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex |
70 | 92 | this.setUuid(firmware.getUuidId()); |
71 | 93 | this.tenantId = firmware.getTenantId().getId(); |
72 | 94 | this.title = firmware.getTitle(); |
95 | + this.version = firmware.getVersion(); | |
73 | 96 | this.fileName = firmware.getFileName(); |
74 | 97 | this.contentType = firmware.getContentType(); |
98 | + this.checksumAlgorithm = firmware.getChecksumAlgorithm(); | |
99 | + this.checksum = firmware.getChecksum(); | |
75 | 100 | this.data = firmware.getData().array(); |
101 | + this.additionalInfo = firmware.getAdditionalInfo(); | |
76 | 102 | } |
77 | 103 | |
78 | 104 | @Override |
... | ... | @@ -91,9 +117,15 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex |
91 | 117 | firmware.setCreatedTime(createdTime); |
92 | 118 | firmware.setTenantId(new TenantId(tenantId)); |
93 | 119 | firmware.setTitle(title); |
120 | + firmware.setVersion(version); | |
94 | 121 | firmware.setFileName(fileName); |
95 | 122 | firmware.setContentType(contentType); |
96 | - firmware.setData(ByteBuffer.wrap(data)); | |
123 | + firmware.setChecksumAlgorithm(checksumAlgorithm); | |
124 | + firmware.setChecksum(checksum); | |
125 | + if (data != null) { | |
126 | + firmware.setData(ByteBuffer.wrap(data)); | |
127 | + } | |
128 | + firmware.setAdditionalInfo(additionalInfo); | |
97 | 129 | return firmware; |
98 | 130 | } |
99 | 131 | } | ... | ... |
... | ... | @@ -15,29 +15,34 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.dao.model.sql; |
17 | 17 | |
18 | +import com.fasterxml.jackson.databind.JsonNode; | |
18 | 19 | import lombok.Data; |
19 | 20 | import lombok.EqualsAndHashCode; |
21 | +import org.hibernate.annotations.Type; | |
22 | +import org.hibernate.annotations.TypeDef; | |
20 | 23 | import org.thingsboard.server.common.data.FirmwareInfo; |
21 | 24 | import org.thingsboard.server.common.data.id.FirmwareId; |
22 | 25 | import org.thingsboard.server.common.data.id.TenantId; |
23 | 26 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
27 | +import org.thingsboard.server.dao.model.ModelConstants; | |
24 | 28 | import org.thingsboard.server.dao.model.SearchTextEntity; |
29 | +import org.thingsboard.server.dao.util.mapping.JsonStringType; | |
25 | 30 | |
26 | 31 | import javax.persistence.Column; |
27 | 32 | import javax.persistence.Entity; |
28 | 33 | import javax.persistence.Table; |
29 | 34 | import java.util.UUID; |
30 | 35 | |
31 | -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN; | |
32 | -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN; | |
33 | 36 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME; |
34 | 37 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN; |
35 | 38 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; |
39 | +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; | |
36 | 40 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; |
37 | 41 | |
38 | 42 | @Data |
39 | 43 | @EqualsAndHashCode(callSuper = true) |
40 | 44 | @Entity |
45 | +@TypeDef(name = "json", typeClass = JsonStringType.class) | |
41 | 46 | @Table(name = FIRMWARE_TABLE_NAME) |
42 | 47 | public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements SearchTextEntity<FirmwareInfo> { |
43 | 48 | |
... | ... | @@ -47,11 +52,12 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S |
47 | 52 | @Column(name = FIRMWARE_TITLE_COLUMN) |
48 | 53 | private String title; |
49 | 54 | |
50 | - @Column(name = FIRMWARE_FILE_NAME_COLUMN) | |
51 | - private String fileName; | |
55 | + @Column(name = FIRMWARE_VERSION_COLUMN) | |
56 | + private String version; | |
52 | 57 | |
53 | - @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN) | |
54 | - private String contentType; | |
58 | + @Type(type = "json") | |
59 | + @Column(name = ModelConstants.FIRMWARE_ADDITIONAL_INFO_COLUMN) | |
60 | + private JsonNode additionalInfo; | |
55 | 61 | |
56 | 62 | @Column(name = SEARCH_TEXT_PROPERTY) |
57 | 63 | private String searchText; |
... | ... | @@ -65,8 +71,8 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S |
65 | 71 | this.setUuid(firmware.getUuidId()); |
66 | 72 | this.tenantId = firmware.getTenantId().getId(); |
67 | 73 | this.title = firmware.getTitle(); |
68 | - this.fileName = firmware.getFileName(); | |
69 | - this.contentType = firmware.getContentType(); | |
74 | + this.version = firmware.getVersion(); | |
75 | + this.additionalInfo = firmware.getAdditionalInfo(); | |
70 | 76 | } |
71 | 77 | |
72 | 78 | @Override |
... | ... | @@ -85,8 +91,8 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S |
85 | 91 | firmware.setCreatedTime(createdTime); |
86 | 92 | firmware.setTenantId(new TenantId(tenantId)); |
87 | 93 | firmware.setTitle(title); |
88 | - firmware.setFileName(fileName); | |
89 | - firmware.setContentType(contentType); | |
94 | + firmware.setVersion(version); | |
95 | + firmware.setAdditionalInfo(additionalInfo); | |
90 | 96 | return firmware; |
91 | 97 | } |
92 | 98 | } | ... | ... |
... | ... | @@ -162,10 +162,15 @@ CREATE TABLE IF NOT EXISTS firmware ( |
162 | 162 | created_time bigint NOT NULL, |
163 | 163 | tenant_id uuid NOT NULL, |
164 | 164 | title varchar(255) NOT NULL, |
165 | + version varchar(255) NOT NULL, | |
166 | + file_name varchar(255), | |
167 | + content_type varchar(255), | |
168 | + checksum_algorithm varchar(32), | |
169 | + checksum varchar(1020), | |
170 | + data binary, | |
171 | + additional_info varchar, | |
165 | 172 | search_text varchar(255), |
166 | - file_name varchar(255) NOT NULL, | |
167 | - content_type varchar(255) NOT NULL, | |
168 | - data binary | |
173 | + CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) | |
169 | 174 | ); |
170 | 175 | |
171 | 176 | CREATE TABLE IF NOT EXISTS device_profile ( | ... | ... |
... | ... | @@ -180,10 +180,15 @@ CREATE TABLE IF NOT EXISTS firmware ( |
180 | 180 | created_time bigint NOT NULL, |
181 | 181 | tenant_id uuid NOT NULL, |
182 | 182 | title varchar(255) NOT NULL, |
183 | + version varchar(255) NOT NULL, | |
184 | + file_name varchar(255), | |
185 | + content_type varchar(255), | |
186 | + checksum_algorithm varchar(32), | |
187 | + checksum varchar(1020), | |
188 | + data bytea, | |
189 | + additional_info varchar, | |
183 | 190 | search_text varchar(255), |
184 | - file_name varchar(255) NOT NULL, | |
185 | - content_type varchar(255) NOT NULL, | |
186 | - data bytea | |
191 | + CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) | |
187 | 192 | ); |
188 | 193 | |
189 | 194 | CREATE TABLE IF NOT EXISTS device_profile ( | ... | ... |
... | ... | @@ -24,7 +24,7 @@ import java.util.Arrays; |
24 | 24 | |
25 | 25 | @RunWith(ClasspathSuite.class) |
26 | 26 | @ClassnameFilters({ |
27 | - "org.thingsboard.server.dao.service.sql.FirmwareServiceSqlTest" | |
27 | + "org.thingsboard.server.dao.service.sql.*Test" | |
28 | 28 | }) |
29 | 29 | public class SqlDaoServiceTestSuite { |
30 | 30 | ... | ... |
... | ... | @@ -27,19 +27,19 @@ import org.junit.Test; |
27 | 27 | import org.thingsboard.server.common.data.Device; |
28 | 28 | import org.thingsboard.server.common.data.DeviceProfile; |
29 | 29 | import org.thingsboard.server.common.data.DeviceProfileInfo; |
30 | -import org.thingsboard.server.common.data.DeviceProfileType; | |
31 | 30 | import org.thingsboard.server.common.data.DeviceTransportType; |
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.id.TenantId; |
34 | 34 | import org.thingsboard.server.common.data.page.PageData; |
35 | 35 | import org.thingsboard.server.common.data.page.PageLink; |
36 | 36 | import org.thingsboard.server.dao.exception.DataValidationException; |
37 | 37 | |
38 | +import java.nio.ByteBuffer; | |
38 | 39 | import java.util.ArrayList; |
39 | 40 | import java.util.Collections; |
40 | 41 | import java.util.List; |
41 | 42 | import java.util.concurrent.ExecutionException; |
42 | -import java.util.concurrent.ExecutorService; | |
43 | 43 | import java.util.concurrent.Executors; |
44 | 44 | import java.util.stream.Collectors; |
45 | 45 | |
... | ... | @@ -83,17 +83,48 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
83 | 83 | } |
84 | 84 | |
85 | 85 | @Test |
86 | + public void testSaveDeviceProfileWithFirmware() { | |
87 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); | |
88 | + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | |
89 | + Assert.assertNotNull(savedDeviceProfile); | |
90 | + Assert.assertNotNull(savedDeviceProfile.getId()); | |
91 | + Assert.assertTrue(savedDeviceProfile.getCreatedTime() > 0); | |
92 | + Assert.assertEquals(deviceProfile.getName(), savedDeviceProfile.getName()); | |
93 | + Assert.assertEquals(deviceProfile.getDescription(), savedDeviceProfile.getDescription()); | |
94 | + Assert.assertEquals(deviceProfile.getProfileData(), savedDeviceProfile.getProfileData()); | |
95 | + Assert.assertEquals(deviceProfile.isDefault(), savedDeviceProfile.isDefault()); | |
96 | + Assert.assertEquals(deviceProfile.getDefaultRuleChainId(), savedDeviceProfile.getDefaultRuleChainId()); | |
97 | + | |
98 | + Firmware firmware = new Firmware(); | |
99 | + firmware.setTenantId(tenantId); | |
100 | + firmware.setTitle("my firmware"); | |
101 | + firmware.setVersion("v1.0"); | |
102 | + firmware.setFileName("test.txt"); | |
103 | + firmware.setContentType("text/plain"); | |
104 | + firmware.setChecksumAlgorithm("sha256"); | |
105 | + firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); | |
106 | + firmware.setData(ByteBuffer.wrap(new byte[]{1})); | |
107 | + Firmware savedFirmware = firmwareService.saveFirmware(firmware); | |
108 | + | |
109 | + deviceProfile.setFirmwareId(savedFirmware.getId()); | |
110 | + | |
111 | + deviceProfileService.saveDeviceProfile(savedDeviceProfile); | |
112 | + DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); | |
113 | + Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfile.getName()); | |
114 | + } | |
115 | + | |
116 | + @Test | |
86 | 117 | public void testFindDeviceProfileById() { |
87 | - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | |
118 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); | |
88 | 119 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
89 | 120 | DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); |
90 | 121 | Assert.assertNotNull(foundDeviceProfile); |
91 | 122 | Assert.assertEquals(savedDeviceProfile, foundDeviceProfile); |
92 | - } | |
123 | + } | |
93 | 124 | |
94 | 125 | @Test |
95 | 126 | public void testFindDeviceProfileInfoById() { |
96 | - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | |
127 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); | |
97 | 128 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
98 | 129 | DeviceProfileInfo foundDeviceProfileInfo = deviceProfileService.findDeviceProfileInfoById(tenantId, savedDeviceProfile.getId()); |
99 | 130 | Assert.assertNotNull(foundDeviceProfileInfo); |
... | ... | @@ -124,7 +155,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
124 | 155 | ListeningExecutorService testExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(100)); |
125 | 156 | try { |
126 | 157 | List<ListenableFuture<DeviceProfile>> futures = new ArrayList<>(); |
127 | - for (int i = 0; i < 50; i ++) { | |
158 | + for (int i = 0; i < 50; i++) { | |
128 | 159 | futures.add(testExecutor.submit(() -> deviceProfileService.findOrCreateDeviceProfile(tenantId, "Device Profile 1"))); |
129 | 160 | futures.add(testExecutor.submit(() -> deviceProfileService.findOrCreateDeviceProfile(tenantId, "Device Profile 2"))); |
130 | 161 | } |
... | ... | @@ -138,8 +169,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
138 | 169 | |
139 | 170 | @Test |
140 | 171 | public void testSetDefaultDeviceProfile() { |
141 | - DeviceProfile deviceProfile1 = this.createDeviceProfile(tenantId,"Device Profile 1"); | |
142 | - DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId,"Device Profile 2"); | |
172 | + DeviceProfile deviceProfile1 = this.createDeviceProfile(tenantId, "Device Profile 1"); | |
173 | + DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId, "Device Profile 2"); | |
143 | 174 | |
144 | 175 | DeviceProfile savedDeviceProfile1 = deviceProfileService.saveDeviceProfile(deviceProfile1); |
145 | 176 | DeviceProfile savedDeviceProfile2 = deviceProfileService.saveDeviceProfile(deviceProfile2); |
... | ... | @@ -165,16 +196,16 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
165 | 196 | |
166 | 197 | @Test(expected = DataValidationException.class) |
167 | 198 | public void testSaveDeviceProfileWithSameName() { |
168 | - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | |
199 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); | |
169 | 200 | deviceProfileService.saveDeviceProfile(deviceProfile); |
170 | - DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId,"Device Profile"); | |
201 | + DeviceProfile deviceProfile2 = this.createDeviceProfile(tenantId, "Device Profile"); | |
171 | 202 | deviceProfileService.saveDeviceProfile(deviceProfile2); |
172 | 203 | } |
173 | 204 | |
174 | 205 | @Ignore |
175 | 206 | @Test(expected = DataValidationException.class) |
176 | 207 | public void testChangeDeviceProfileTypeWithExistingDevices() { |
177 | - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | |
208 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); | |
178 | 209 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
179 | 210 | Device device = new Device(); |
180 | 211 | device.setTenantId(tenantId); |
... | ... | @@ -189,7 +220,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
189 | 220 | |
190 | 221 | @Test(expected = DataValidationException.class) |
191 | 222 | public void testChangeDeviceProfileTransportTypeWithExistingDevices() { |
192 | - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | |
223 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); | |
193 | 224 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
194 | 225 | Device device = new Device(); |
195 | 226 | device.setTenantId(tenantId); |
... | ... | @@ -203,7 +234,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
203 | 234 | |
204 | 235 | @Test(expected = DataValidationException.class) |
205 | 236 | public void testDeleteDeviceProfileWithExistingDevice() { |
206 | - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | |
237 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); | |
207 | 238 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
208 | 239 | Device device = new Device(); |
209 | 240 | device.setTenantId(tenantId); |
... | ... | @@ -216,7 +247,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
216 | 247 | |
217 | 248 | @Test |
218 | 249 | public void testDeleteDeviceProfile() { |
219 | - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"); | |
250 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); | |
220 | 251 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
221 | 252 | deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); |
222 | 253 | DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); |
... | ... | @@ -233,8 +264,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
233 | 264 | Assert.assertEquals(1, pageData.getTotalElements()); |
234 | 265 | deviceProfiles.addAll(pageData.getData()); |
235 | 266 | |
236 | - for (int i=0;i<28;i++) { | |
237 | - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"+i); | |
267 | + for (int i = 0; i < 28; i++) { | |
268 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile" + i); | |
238 | 269 | deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile)); |
239 | 270 | } |
240 | 271 | |
... | ... | @@ -275,8 +306,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
275 | 306 | Assert.assertEquals(1, deviceProfilePageData.getTotalElements()); |
276 | 307 | deviceProfiles.addAll(deviceProfilePageData.getData()); |
277 | 308 | |
278 | - for (int i=0;i<28;i++) { | |
279 | - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile"+i); | |
309 | + for (int i = 0; i < 28; i++) { | |
310 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile" + i); | |
280 | 311 | deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile)); |
281 | 312 | } |
282 | 313 | |
... | ... | @@ -297,7 +328,7 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
297 | 328 | |
298 | 329 | List<DeviceProfileInfo> deviceProfileInfos = deviceProfiles.stream() |
299 | 330 | .map(deviceProfile -> new DeviceProfileInfo(deviceProfile.getId(), |
300 | - deviceProfile.getName(), deviceProfile.getType(), deviceProfile.getTransportType())).collect(Collectors.toList()); | |
331 | + deviceProfile.getName(), deviceProfile.getType(), deviceProfile.getTransportType())).collect(Collectors.toList()); | |
301 | 332 | |
302 | 333 | Assert.assertEquals(deviceProfileInfos, loadedDeviceProfileInfos); |
303 | 334 | |
... | ... | @@ -312,4 +343,5 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
312 | 343 | Assert.assertFalse(pageData.hasNext()); |
313 | 344 | Assert.assertEquals(1, pageData.getTotalElements()); |
314 | 345 | } |
346 | + | |
315 | 347 | } | ... | ... |
... | ... | @@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials; |
30 | 30 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
31 | 31 | import org.thingsboard.server.dao.exception.DataValidationException; |
32 | 32 | |
33 | +import java.nio.ByteBuffer; | |
33 | 34 | import java.util.ArrayList; |
34 | 35 | import java.util.Collections; |
35 | 36 | import java.util.List; |
... | ... | @@ -88,6 +89,49 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { |
88 | 89 | |
89 | 90 | deviceService.deleteDevice(tenantId, savedDevice.getId()); |
90 | 91 | } |
92 | + | |
93 | + @Test | |
94 | + public void testSaveDeviceWithFirmware() { | |
95 | + Device device = new Device(); | |
96 | + device.setTenantId(tenantId); | |
97 | + device.setName("My device"); | |
98 | + device.setType("default"); | |
99 | + Device savedDevice = deviceService.saveDevice(device); | |
100 | + | |
101 | + Assert.assertNotNull(savedDevice); | |
102 | + Assert.assertNotNull(savedDevice.getId()); | |
103 | + Assert.assertTrue(savedDevice.getCreatedTime() > 0); | |
104 | + Assert.assertEquals(device.getTenantId(), savedDevice.getTenantId()); | |
105 | + Assert.assertNotNull(savedDevice.getCustomerId()); | |
106 | + Assert.assertEquals(NULL_UUID, savedDevice.getCustomerId().getId()); | |
107 | + Assert.assertEquals(device.getName(), savedDevice.getName()); | |
108 | + | |
109 | + DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, savedDevice.getId()); | |
110 | + Assert.assertNotNull(deviceCredentials); | |
111 | + Assert.assertNotNull(deviceCredentials.getId()); | |
112 | + Assert.assertEquals(savedDevice.getId(), deviceCredentials.getDeviceId()); | |
113 | + Assert.assertEquals(DeviceCredentialsType.ACCESS_TOKEN, deviceCredentials.getCredentialsType()); | |
114 | + Assert.assertNotNull(deviceCredentials.getCredentialsId()); | |
115 | + Assert.assertEquals(20, deviceCredentials.getCredentialsId().length()); | |
116 | + | |
117 | + | |
118 | + Firmware firmware = new Firmware(); | |
119 | + firmware.setTenantId(tenantId); | |
120 | + firmware.setTitle("my firmware"); | |
121 | + firmware.setVersion("v1.0"); | |
122 | + firmware.setFileName("test.txt"); | |
123 | + firmware.setContentType("text/plain"); | |
124 | + firmware.setChecksumAlgorithm("sha256"); | |
125 | + firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); | |
126 | + firmware.setData(ByteBuffer.wrap(new byte[]{1})); | |
127 | + Firmware savedFirmware = firmwareService.saveFirmware(firmware); | |
128 | + | |
129 | + savedDevice.setFirmwareId(savedFirmware.getId()); | |
130 | + | |
131 | + deviceService.saveDevice(savedDevice); | |
132 | + Device foundDevice = deviceService.findDeviceById(tenantId, savedDevice.getId()); | |
133 | + Assert.assertEquals(foundDevice.getName(), savedDevice.getName()); | |
134 | + } | |
91 | 135 | |
92 | 136 | @Test(expected = DataValidationException.class) |
93 | 137 | public void testSaveDeviceWithEmptyName() { | ... | ... |
... | ... | @@ -20,6 +20,7 @@ import org.junit.After; |
20 | 20 | import org.junit.Assert; |
21 | 21 | import org.junit.Before; |
22 | 22 | import org.junit.Test; |
23 | +import org.thingsboard.common.util.JacksonUtil; | |
23 | 24 | import org.thingsboard.server.common.data.Device; |
24 | 25 | import org.thingsboard.server.common.data.DeviceProfile; |
25 | 26 | import org.thingsboard.server.common.data.Firmware; |
... | ... | @@ -39,8 +40,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
39 | 40 | |
40 | 41 | public static final String TITLE = "My firmware"; |
41 | 42 | private static final String FILE_NAME = "filename.txt"; |
43 | + private static final String VERSION = "v1.0"; | |
42 | 44 | private static final String CONTENT_TYPE = "text/plain"; |
43 | - private static final ByteBuffer DATA = ByteBuffer.wrap(new byte[]{0}); | |
45 | + private static final String CHECKSUM_ALGORITHM = "sha256"; | |
46 | + private static final String CHECKSUM = "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"; | |
47 | + private static final ByteBuffer DATA = ByteBuffer.wrap(new byte[]{1}); | |
44 | 48 | |
45 | 49 | private IdComparator<FirmwareInfo> idComparator = new IdComparator<>(); |
46 | 50 | |
... | ... | @@ -65,8 +69,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
65 | 69 | Firmware firmware = new Firmware(); |
66 | 70 | firmware.setTenantId(tenantId); |
67 | 71 | firmware.setTitle(TITLE); |
72 | + firmware.setVersion(VERSION); | |
68 | 73 | firmware.setFileName(FILE_NAME); |
69 | 74 | firmware.setContentType(CONTENT_TYPE); |
75 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
76 | + firmware.setChecksum(CHECKSUM); | |
70 | 77 | firmware.setData(DATA); |
71 | 78 | Firmware savedFirmware = firmwareService.saveFirmware(firmware); |
72 | 79 | |
... | ... | @@ -79,7 +86,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
79 | 86 | Assert.assertEquals(firmware.getContentType(), savedFirmware.getContentType()); |
80 | 87 | Assert.assertEquals(firmware.getData(), savedFirmware.getData()); |
81 | 88 | |
82 | - savedFirmware.setTitle("My new firmware"); | |
89 | + savedFirmware.setAdditionalInfo(JacksonUtil.newObjectNode()); | |
83 | 90 | firmwareService.saveFirmware(savedFirmware); |
84 | 91 | |
85 | 92 | Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, savedFirmware.getId()); |
... | ... | @@ -88,12 +95,52 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
88 | 95 | firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); |
89 | 96 | } |
90 | 97 | |
98 | + @Test | |
99 | + public void testSaveFirmwareInfoAndUpdateWithData() { | |
100 | + FirmwareInfo firmwareInfo = new FirmwareInfo(); | |
101 | + firmwareInfo.setTenantId(tenantId); | |
102 | + firmwareInfo.setTitle(TITLE); | |
103 | + firmwareInfo.setVersion(VERSION); | |
104 | + FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo); | |
105 | + | |
106 | + Assert.assertNotNull(savedFirmwareInfo); | |
107 | + Assert.assertNotNull(savedFirmwareInfo.getId()); | |
108 | + Assert.assertTrue(savedFirmwareInfo.getCreatedTime() > 0); | |
109 | + Assert.assertEquals(firmwareInfo.getTenantId(), savedFirmwareInfo.getTenantId()); | |
110 | + Assert.assertEquals(firmwareInfo.getTitle(), savedFirmwareInfo.getTitle()); | |
111 | + | |
112 | + Firmware firmware = new Firmware(savedFirmwareInfo.getId()); | |
113 | + firmware.setCreatedTime(firmwareInfo.getCreatedTime()); | |
114 | + firmware.setTenantId(tenantId); | |
115 | + firmware.setTitle(TITLE); | |
116 | + firmware.setVersion(VERSION); | |
117 | + firmware.setFileName(FILE_NAME); | |
118 | + firmware.setContentType(CONTENT_TYPE); | |
119 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
120 | + firmware.setChecksum(CHECKSUM); | |
121 | + firmware.setData(DATA); | |
122 | + | |
123 | + firmwareService.saveFirmware(firmware); | |
124 | + | |
125 | + savedFirmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode()); | |
126 | + firmwareService.saveFirmwareInfo(savedFirmwareInfo); | |
127 | + | |
128 | + Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, firmware.getId()); | |
129 | + firmware.setAdditionalInfo(JacksonUtil.newObjectNode()); | |
130 | + Assert.assertEquals(foundFirmware.getTitle(), firmware.getTitle()); | |
131 | + | |
132 | + firmwareService.deleteFirmware(tenantId, savedFirmwareInfo.getId()); | |
133 | + } | |
134 | + | |
91 | 135 | @Test(expected = DataValidationException.class) |
92 | 136 | public void testSaveFirmwareWithEmptyTenant() { |
93 | 137 | Firmware firmware = new Firmware(); |
94 | 138 | firmware.setTitle(TITLE); |
139 | + firmware.setVersion(VERSION); | |
95 | 140 | firmware.setFileName(FILE_NAME); |
96 | 141 | firmware.setContentType(CONTENT_TYPE); |
142 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
143 | + firmware.setChecksum(CHECKSUM); | |
97 | 144 | firmware.setData(DATA); |
98 | 145 | firmwareService.saveFirmware(firmware); |
99 | 146 | } |
... | ... | @@ -102,8 +149,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
102 | 149 | public void testSaveFirmwareWithEmptyTitle() { |
103 | 150 | Firmware firmware = new Firmware(); |
104 | 151 | firmware.setTenantId(tenantId); |
152 | + firmware.setVersion(VERSION); | |
105 | 153 | firmware.setFileName(FILE_NAME); |
106 | 154 | firmware.setContentType(CONTENT_TYPE); |
155 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
156 | + firmware.setChecksum(CHECKSUM); | |
107 | 157 | firmware.setData(DATA); |
108 | 158 | firmwareService.saveFirmware(firmware); |
109 | 159 | } |
... | ... | @@ -113,7 +163,10 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
113 | 163 | Firmware firmware = new Firmware(); |
114 | 164 | firmware.setTenantId(tenantId); |
115 | 165 | firmware.setTitle(TITLE); |
166 | + firmware.setVersion(VERSION); | |
116 | 167 | firmware.setContentType(CONTENT_TYPE); |
168 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
169 | + firmware.setChecksum(CHECKSUM); | |
117 | 170 | firmware.setData(DATA); |
118 | 171 | firmwareService.saveFirmware(firmware); |
119 | 172 | } |
... | ... | @@ -123,7 +176,10 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
123 | 176 | Firmware firmware = new Firmware(); |
124 | 177 | firmware.setTenantId(tenantId); |
125 | 178 | firmware.setTitle(TITLE); |
179 | + firmware.setVersion(VERSION); | |
126 | 180 | firmware.setFileName(FILE_NAME); |
181 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
182 | + firmware.setChecksum(CHECKSUM); | |
127 | 183 | firmware.setData(DATA); |
128 | 184 | firmwareService.saveFirmware(firmware); |
129 | 185 | } |
... | ... | @@ -133,8 +189,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
133 | 189 | Firmware firmware = new Firmware(); |
134 | 190 | firmware.setTenantId(tenantId); |
135 | 191 | firmware.setTitle(TITLE); |
192 | + firmware.setVersion(VERSION); | |
136 | 193 | firmware.setFileName(FILE_NAME); |
137 | 194 | firmware.setContentType(CONTENT_TYPE); |
195 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
196 | + firmware.setChecksum(CHECKSUM); | |
138 | 197 | firmwareService.saveFirmware(firmware); |
139 | 198 | } |
140 | 199 | |
... | ... | @@ -143,21 +202,76 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
143 | 202 | Firmware firmware = new Firmware(); |
144 | 203 | firmware.setTenantId(new TenantId(Uuids.timeBased())); |
145 | 204 | firmware.setTitle(TITLE); |
205 | + firmware.setVersion(VERSION); | |
146 | 206 | firmware.setFileName(FILE_NAME); |
147 | 207 | firmware.setContentType(CONTENT_TYPE); |
208 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
209 | + firmware.setChecksum(CHECKSUM); | |
148 | 210 | firmware.setData(DATA); |
149 | 211 | firmwareService.saveFirmware(firmware); |
150 | 212 | } |
151 | 213 | |
214 | + @Test(expected = DataValidationException.class) | |
215 | + public void testSaveFirmwareWithEmptyChecksum() { | |
216 | + Firmware firmware = new Firmware(); | |
217 | + firmware.setTenantId(new TenantId(Uuids.timeBased())); | |
218 | + firmware.setTitle(TITLE); | |
219 | + firmware.setVersion(VERSION); | |
220 | + firmware.setFileName(FILE_NAME); | |
221 | + firmware.setContentType(CONTENT_TYPE); | |
222 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
223 | + firmware.setData(DATA); | |
224 | + firmwareService.saveFirmware(firmware); | |
225 | + } | |
152 | 226 | |
227 | + @Test(expected = DataValidationException.class) | |
228 | + public void testSaveFirmwareInfoWithExistingTitleAndVersion() { | |
229 | + FirmwareInfo firmwareInfo = new FirmwareInfo(); | |
230 | + firmwareInfo.setTenantId(tenantId); | |
231 | + firmwareInfo.setTitle(TITLE); | |
232 | + firmwareInfo.setVersion(VERSION); | |
233 | + firmwareService.saveFirmwareInfo(firmwareInfo); | |
234 | + | |
235 | + FirmwareInfo newFirmwareInfo = new FirmwareInfo(); | |
236 | + newFirmwareInfo.setTenantId(tenantId); | |
237 | + newFirmwareInfo.setTitle(TITLE); | |
238 | + newFirmwareInfo.setVersion(VERSION); | |
239 | + firmwareService.saveFirmwareInfo(newFirmwareInfo); | |
240 | + } | |
241 | + | |
242 | + @Test(expected = DataValidationException.class) | |
243 | + public void testSaveFirmwareWithExistingTitleAndVersion() { | |
244 | + Firmware firmware = new Firmware(); | |
245 | + firmware.setTenantId(tenantId); | |
246 | + firmware.setTitle(TITLE); | |
247 | + firmware.setVersion(VERSION); | |
248 | + firmware.setFileName(FILE_NAME); | |
249 | + firmware.setContentType(CONTENT_TYPE); | |
250 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
251 | + firmware.setChecksum(CHECKSUM); | |
252 | + firmware.setData(DATA); | |
253 | + firmwareService.saveFirmware(firmware); | |
254 | + | |
255 | + Firmware newFirmware = new Firmware(); | |
256 | + newFirmware.setTenantId(tenantId); | |
257 | + newFirmware.setTitle(TITLE); | |
258 | + newFirmware.setVersion(VERSION); | |
259 | + newFirmware.setFileName(FILE_NAME); | |
260 | + newFirmware.setContentType(CONTENT_TYPE); | |
261 | + newFirmware.setData(DATA); | |
262 | + firmwareService.saveFirmware(newFirmware); | |
263 | + } | |
153 | 264 | |
154 | 265 | @Test(expected = DataValidationException.class) |
155 | 266 | public void testDeleteFirmwareWithReferenceByDevice() { |
156 | 267 | Firmware firmware = new Firmware(); |
157 | 268 | firmware.setTenantId(tenantId); |
158 | 269 | firmware.setTitle(TITLE); |
270 | + firmware.setVersion(VERSION); | |
159 | 271 | firmware.setFileName(FILE_NAME); |
160 | 272 | firmware.setContentType(CONTENT_TYPE); |
273 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
274 | + firmware.setChecksum(CHECKSUM); | |
161 | 275 | firmware.setData(DATA); |
162 | 276 | Firmware savedFirmware = firmwareService.saveFirmware(firmware); |
163 | 277 | |
... | ... | @@ -181,8 +295,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
181 | 295 | Firmware firmware = new Firmware(); |
182 | 296 | firmware.setTenantId(tenantId); |
183 | 297 | firmware.setTitle(TITLE); |
298 | + firmware.setVersion(VERSION); | |
184 | 299 | firmware.setFileName(FILE_NAME); |
185 | 300 | firmware.setContentType(CONTENT_TYPE); |
301 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
302 | + firmware.setChecksum(CHECKSUM); | |
186 | 303 | firmware.setData(DATA); |
187 | 304 | Firmware savedFirmware = firmwareService.saveFirmware(firmware); |
188 | 305 | |
... | ... | @@ -203,8 +320,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
203 | 320 | Firmware firmware = new Firmware(); |
204 | 321 | firmware.setTenantId(tenantId); |
205 | 322 | firmware.setTitle(TITLE); |
323 | + firmware.setVersion(VERSION); | |
206 | 324 | firmware.setFileName(FILE_NAME); |
207 | 325 | firmware.setContentType(CONTENT_TYPE); |
326 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
327 | + firmware.setChecksum(CHECKSUM); | |
208 | 328 | firmware.setData(DATA); |
209 | 329 | Firmware savedFirmware = firmwareService.saveFirmware(firmware); |
210 | 330 | |
... | ... | @@ -219,8 +339,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
219 | 339 | Firmware firmware = new Firmware(); |
220 | 340 | firmware.setTenantId(tenantId); |
221 | 341 | firmware.setTitle(TITLE); |
342 | + firmware.setVersion(VERSION); | |
222 | 343 | firmware.setFileName(FILE_NAME); |
223 | 344 | firmware.setContentType(CONTENT_TYPE); |
345 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
346 | + firmware.setChecksum(CHECKSUM); | |
224 | 347 | firmware.setData(DATA); |
225 | 348 | Firmware savedFirmware = firmwareService.saveFirmware(firmware); |
226 | 349 | |
... | ... | @@ -238,8 +361,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
238 | 361 | Firmware firmware = new Firmware(); |
239 | 362 | firmware.setTenantId(tenantId); |
240 | 363 | firmware.setTitle(TITLE); |
364 | + firmware.setVersion(VERSION + i); | |
241 | 365 | firmware.setFileName(FILE_NAME); |
242 | 366 | firmware.setContentType(CONTENT_TYPE); |
367 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | |
368 | + firmware.setChecksum(CHECKSUM); | |
243 | 369 | firmware.setData(DATA); |
244 | 370 | firmwares.add(new FirmwareInfo(firmwareService.saveFirmware(firmware))); |
245 | 371 | } | ... | ... |