Commit 93b0cfec2ffd8073f8dada46928640d03100e179

Authored by Igor Kulikov
Committed by GitHub
2 parents c8158621 2d7ae47f

Merge pull request #4869 from AndrewVolosytnykhThingsboard/ota-service-url-validation

Url validation for Ota Package
... ... @@ -32,12 +32,13 @@ import org.springframework.web.multipart.MultipartFile;
32 32 import org.thingsboard.server.common.data.EntityType;
33 33 import org.thingsboard.server.common.data.OtaPackage;
34 34 import org.thingsboard.server.common.data.OtaPackageInfo;
  35 +import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest;
35 36 import org.thingsboard.server.common.data.audit.ActionType;
36 37 import org.thingsboard.server.common.data.exception.ThingsboardException;
37   -import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
38   -import org.thingsboard.server.common.data.ota.OtaPackageType;
39 38 import org.thingsboard.server.common.data.id.DeviceProfileId;
40 39 import org.thingsboard.server.common.data.id.OtaPackageId;
  40 +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
  41 +import org.thingsboard.server.common.data.ota.OtaPackageType;
41 42 import org.thingsboard.server.common.data.page.PageData;
42 43 import org.thingsboard.server.common.data.page.PageLink;
43 44 import org.thingsboard.server.queue.util.TbCoreComponent;
... ... @@ -109,12 +110,12 @@ public class OtaPackageController extends BaseController {
109 110 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
110 111 @RequestMapping(value = "/otaPackage", method = RequestMethod.POST)
111 112 @ResponseBody
112   - public OtaPackageInfo saveOtaPackageInfo(@RequestBody OtaPackageInfo otaPackageInfo) throws ThingsboardException {
  113 + public OtaPackageInfo saveOtaPackageInfo(@RequestBody SaveOtaPackageInfoRequest otaPackageInfo) throws ThingsboardException {
113 114 boolean created = otaPackageInfo.getId() == null;
114 115 try {
115 116 otaPackageInfo.setTenantId(getTenantId());
116 117 checkEntity(otaPackageInfo.getId(), otaPackageInfo, Resource.OTA_PACKAGE);
117   - OtaPackageInfo savedOtaPackageInfo = otaPackageService.saveOtaPackageInfo(otaPackageInfo);
  118 + OtaPackageInfo savedOtaPackageInfo = otaPackageService.saveOtaPackageInfo(new OtaPackageInfo(otaPackageInfo), otaPackageInfo.isUsesUrl());
118 119 logEntityAction(savedOtaPackageInfo.getId(), savedOtaPackageInfo,
119 120 null, created ? ActionType.ADDED : ActionType.UPDATED, null);
120 121 return savedOtaPackageInfo;
... ...
... ... @@ -27,6 +27,7 @@ import org.thingsboard.common.util.JacksonUtil;
27 27 import org.thingsboard.server.common.data.DeviceProfile;
28 28 import org.thingsboard.server.common.data.OtaPackage;
29 29 import org.thingsboard.server.common.data.OtaPackageInfo;
  30 +import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest;
30 31 import org.thingsboard.server.common.data.Tenant;
31 32 import org.thingsboard.server.common.data.User;
32 33 import org.thingsboard.server.common.data.id.DeviceProfileId;
... ... @@ -92,11 +93,12 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
92 93
93 94 @Test
94 95 public void testSaveFirmware() throws Exception {
95   - OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  96 + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
96 97 firmwareInfo.setDeviceProfileId(deviceProfileId);
97 98 firmwareInfo.setType(FIRMWARE);
98 99 firmwareInfo.setTitle(TITLE);
99 100 firmwareInfo.setVersion(VERSION);
  101 + firmwareInfo.setUsesUrl(false);
100 102
101 103 OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
102 104
... ... @@ -109,7 +111,7 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
109 111
110 112 savedFirmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode());
111 113
112   - save(savedFirmwareInfo);
  114 + save(new SaveOtaPackageInfoRequest(savedFirmwareInfo, false));
113 115
114 116 OtaPackageInfo foundFirmwareInfo = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class);
115 117 Assert.assertEquals(foundFirmwareInfo.getTitle(), savedFirmwareInfo.getTitle());
... ... @@ -117,11 +119,12 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
117 119
118 120 @Test
119 121 public void testSaveFirmwareData() throws Exception {
120   - OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  122 + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
121 123 firmwareInfo.setDeviceProfileId(deviceProfileId);
122 124 firmwareInfo.setType(FIRMWARE);
123 125 firmwareInfo.setTitle(TITLE);
124 126 firmwareInfo.setVersion(VERSION);
  127 + firmwareInfo.setUsesUrl(false);
125 128
126 129 OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
127 130
... ... @@ -134,7 +137,7 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
134 137
135 138 savedFirmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode());
136 139
137   - save(savedFirmwareInfo);
  140 + save(new SaveOtaPackageInfoRequest(savedFirmwareInfo, false));
138 141
139 142 OtaPackageInfo foundFirmwareInfo = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class);
140 143 Assert.assertEquals(foundFirmwareInfo.getTitle(), savedFirmwareInfo.getTitle());
... ... @@ -151,26 +154,31 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
151 154
152 155 @Test
153 156 public void testUpdateFirmwareFromDifferentTenant() throws Exception {
154   - OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  157 + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
155 158 firmwareInfo.setDeviceProfileId(deviceProfileId);
156 159 firmwareInfo.setType(FIRMWARE);
157 160 firmwareInfo.setTitle(TITLE);
158 161 firmwareInfo.setVersion(VERSION);
  162 + firmwareInfo.setUsesUrl(false);
159 163
160 164 OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
161 165
162 166 loginDifferentTenant();
163   - doPost("/api/otaPackage", savedFirmwareInfo, OtaPackageInfo.class, status().isForbidden());
  167 + doPost("/api/otaPackage",
  168 + new SaveOtaPackageInfoRequest(savedFirmwareInfo, false),
  169 + OtaPackageInfo.class,
  170 + status().isForbidden());
164 171 deleteDifferentTenant();
165 172 }
166 173
167 174 @Test
168 175 public void testFindFirmwareInfoById() throws Exception {
169   - OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  176 + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
170 177 firmwareInfo.setDeviceProfileId(deviceProfileId);
171 178 firmwareInfo.setType(FIRMWARE);
172 179 firmwareInfo.setTitle(TITLE);
173 180 firmwareInfo.setVersion(VERSION);
  181 + firmwareInfo.setUsesUrl(false);
174 182
175 183 OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
176 184
... ... @@ -181,11 +189,12 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
181 189
182 190 @Test
183 191 public void testFindFirmwareById() throws Exception {
184   - OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  192 + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
185 193 firmwareInfo.setDeviceProfileId(deviceProfileId);
186 194 firmwareInfo.setType(FIRMWARE);
187 195 firmwareInfo.setTitle(TITLE);
188 196 firmwareInfo.setVersion(VERSION);
  197 + firmwareInfo.setUsesUrl(false);
189 198
190 199 OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
191 200
... ... @@ -201,11 +210,12 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
201 210
202 211 @Test
203 212 public void testDeleteFirmware() throws Exception {
204   - OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  213 + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
205 214 firmwareInfo.setDeviceProfileId(deviceProfileId);
206 215 firmwareInfo.setType(FIRMWARE);
207 216 firmwareInfo.setTitle(TITLE);
208 217 firmwareInfo.setVersion(VERSION);
  218 + firmwareInfo.setUsesUrl(false);
209 219
210 220 OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
211 221
... ... @@ -220,11 +230,12 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
220 230 public void testFindTenantFirmwares() throws Exception {
221 231 List<OtaPackageInfo> otaPackages = new ArrayList<>();
222 232 for (int i = 0; i < 165; i++) {
223   - OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  233 + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
224 234 firmwareInfo.setDeviceProfileId(deviceProfileId);
225 235 firmwareInfo.setType(FIRMWARE);
226 236 firmwareInfo.setTitle(TITLE);
227 237 firmwareInfo.setVersion(VERSION + i);
  238 + firmwareInfo.setUsesUrl(false);
228 239
229 240 OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
230 241
... ... @@ -263,11 +274,12 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
263 274 List<OtaPackageInfo> allOtaPackages = new ArrayList<>();
264 275
265 276 for (int i = 0; i < 165; i++) {
266   - OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  277 + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest();
267 278 firmwareInfo.setDeviceProfileId(deviceProfileId);
268 279 firmwareInfo.setType(FIRMWARE);
269 280 firmwareInfo.setTitle(TITLE);
270 281 firmwareInfo.setVersion(VERSION + i);
  282 + firmwareInfo.setUsesUrl(false);
271 283
272 284 OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
273 285
... ... @@ -316,8 +328,7 @@ public abstract class BaseOtaPackageControllerTest extends AbstractControllerTes
316 328 Assert.assertEquals(allOtaPackages, allLoadedOtaPackages);
317 329 }
318 330
319   -
320   - private OtaPackageInfo save(OtaPackageInfo firmwareInfo) throws Exception {
  331 + private OtaPackageInfo save(SaveOtaPackageInfoRequest firmwareInfo) throws Exception {
321 332 return doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class);
322 333 }
323 334
... ...
... ... @@ -18,11 +18,11 @@ package org.thingsboard.server.dao.ota;
18 18 import com.google.common.util.concurrent.ListenableFuture;
19 19 import org.thingsboard.server.common.data.OtaPackage;
20 20 import org.thingsboard.server.common.data.OtaPackageInfo;
21   -import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
22   -import org.thingsboard.server.common.data.ota.OtaPackageType;
23 21 import org.thingsboard.server.common.data.id.DeviceProfileId;
24 22 import org.thingsboard.server.common.data.id.OtaPackageId;
25 23 import org.thingsboard.server.common.data.id.TenantId;
  24 +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
  25 +import org.thingsboard.server.common.data.ota.OtaPackageType;
26 26 import org.thingsboard.server.common.data.page.PageData;
27 27 import org.thingsboard.server.common.data.page.PageLink;
28 28
... ... @@ -30,7 +30,7 @@ import java.nio.ByteBuffer;
30 30
31 31 public interface OtaPackageService {
32 32
33   - OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo);
  33 + OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo, boolean isUrl);
34 34
35 35 OtaPackage saveOtaPackage(OtaPackage otaPackage);
36 36
... ...
  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;
  17 +
  18 +import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +import lombok.NoArgsConstructor;
  21 +
  22 +@Data
  23 +@EqualsAndHashCode(callSuper = true)
  24 +@NoArgsConstructor
  25 +public class SaveOtaPackageInfoRequest extends OtaPackageInfo{
  26 + boolean usesUrl;
  27 +
  28 + public SaveOtaPackageInfoRequest(OtaPackageInfo otaPackageInfo, boolean usesUrl) {
  29 + super(otaPackageInfo);
  30 + this.usesUrl = usesUrl;
  31 + }
  32 +
  33 + public SaveOtaPackageInfoRequest(SaveOtaPackageInfoRequest saveOtaPackageInfoRequest) {
  34 + super(saveOtaPackageInfoRequest);
  35 + this.usesUrl = saveOtaPackageInfoRequest.isUsesUrl();
  36 + }
  37 +}
... ...
... ... @@ -77,8 +77,11 @@ public class BaseOtaPackageService implements OtaPackageService {
77 77 private TbTenantProfileCache tenantProfileCache;
78 78
79 79 @Override
80   - public OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo) {
  80 + public OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo, boolean isUrl) {
81 81 log.trace("Executing saveOtaPackageInfo [{}]", otaPackageInfo);
  82 + if(isUrl && (StringUtils.isEmpty(otaPackageInfo.getUrl()) || otaPackageInfo.getUrl().trim().length() == 0)) {
  83 + throw new DataValidationException("Ota package URL should be specified!");
  84 + }
82 85 otaPackageInfoValidator.validate(otaPackageInfo, OtaPackageInfo::getTenantId);
83 86 try {
84 87 OtaPackageId otaPackageId = otaPackageInfo.getId();
... ... @@ -277,7 +280,9 @@ public class BaseOtaPackageService implements OtaPackageService {
277 280 throw new DataValidationException("Wrong otaPackage file!");
278 281 }
279 282 } else {
280   - //TODO: validate url
  283 + if(otaPackage.getData() != null) {
  284 + throw new DataValidationException("File can't be saved if URL present!");
  285 + }
281 286 }
282 287 }
283 288
... ... @@ -336,6 +341,10 @@ public class BaseOtaPackageService implements OtaPackageService {
336 341 if (otaPackageOld.getDataSize() != null && !otaPackageOld.getDataSize().equals(otaPackage.getDataSize())) {
337 342 throw new DataValidationException("Updating otaPackage data size is prohibited!");
338 343 }
  344 +
  345 + if(otaPackageOld.getUrl() != null && !otaPackageOld.getUrl().equals(otaPackage.getUrl())) {
  346 + throw new DataValidationException("Updating otaPackage URL is prohibited!");
  347 + }
339 348 }
340 349
341 350 private void validateImpl(OtaPackageInfo otaPackageInfo) {
... ... @@ -366,6 +375,15 @@ public class BaseOtaPackageService implements OtaPackageService {
366 375 if (StringUtils.isEmpty(otaPackageInfo.getVersion())) {
367 376 throw new DataValidationException("OtaPackage version should be specified!");
368 377 }
  378 +
  379 + if(otaPackageInfo.getTitle().length() > 255) {
  380 + throw new DataValidationException("The length of title should be equal or shorter than 255");
  381 + }
  382 +
  383 + if(otaPackageInfo.getVersion().length() > 255) {
  384 + throw new DataValidationException("The length of version should be equal or shorter than 255");
  385 + }
  386 +
369 387 }
370 388
371 389 private PaginatedRemover<TenantId, OtaPackageInfo> tenantOtaPackageRemover =
... ...
... ... @@ -16,6 +16,7 @@
16 16 package org.thingsboard.server.dao.service;
17 17
18 18 import com.datastax.oss.driver.api.core.uuid.Uuids;
  19 +import org.apache.commons.lang3.RandomStringUtils;
19 20 import org.junit.After;
20 21 import org.junit.Assert;
21 22 import org.junit.Before;
... ... @@ -163,7 +164,7 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
163 164 firmware.setVersion(VERSION);
164 165 firmware.setUrl(URL);
165 166 firmware.setDataSize(0L);
166   - OtaPackageInfo savedFirmware = otaPackageService.saveOtaPackageInfo(firmware);
  167 + OtaPackageInfo savedFirmware = otaPackageService.saveOtaPackageInfo(firmware, true);
167 168
168 169 Assert.assertNotNull(savedFirmware);
169 170 Assert.assertNotNull(savedFirmware.getId());
... ... @@ -174,7 +175,7 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
174 175 Assert.assertEquals(firmware.getContentType(), savedFirmware.getContentType());
175 176
176 177 savedFirmware.setAdditionalInfo(JacksonUtil.newObjectNode());
177   - otaPackageService.saveOtaPackageInfo(savedFirmware);
  178 + otaPackageService.saveOtaPackageInfo(savedFirmware, true);
178 179
179 180 OtaPackage foundFirmware = otaPackageService.findOtaPackageById(tenantId, savedFirmware.getId());
180 181 Assert.assertEquals(foundFirmware.getTitle(), savedFirmware.getTitle());
... ... @@ -190,7 +191,7 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
190 191 firmwareInfo.setType(FIRMWARE);
191 192 firmwareInfo.setTitle(TITLE);
192 193 firmwareInfo.setVersion(VERSION);
193   - OtaPackageInfo savedFirmwareInfo = otaPackageService.saveOtaPackageInfo(firmwareInfo);
  194 + OtaPackageInfo savedFirmwareInfo = otaPackageService.saveOtaPackageInfo(firmwareInfo, false);
194 195
195 196 Assert.assertNotNull(savedFirmwareInfo);
196 197 Assert.assertNotNull(savedFirmwareInfo.getId());
... ... @@ -216,7 +217,7 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
216 217
217 218 savedFirmwareInfo = otaPackageService.findOtaPackageInfoById(tenantId, savedFirmwareInfo.getId());
218 219 savedFirmwareInfo.setAdditionalInfo(JacksonUtil.newObjectNode());
219   - otaPackageService.saveOtaPackageInfo(savedFirmwareInfo);
  220 + otaPackageService.saveOtaPackageInfo(savedFirmwareInfo, false);
220 221
221 222 OtaPackage foundFirmware = otaPackageService.findOtaPackageById(tenantId, firmware.getId());
222 223 firmware.setAdditionalInfo(JacksonUtil.newObjectNode());
... ... @@ -399,7 +400,7 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
399 400 firmwareInfo.setType(FIRMWARE);
400 401 firmwareInfo.setTitle(TITLE);
401 402 firmwareInfo.setVersion(VERSION);
402   - otaPackageService.saveOtaPackageInfo(firmwareInfo);
  403 + otaPackageService.saveOtaPackageInfo(firmwareInfo, false);
403 404
404 405 OtaPackageInfo newFirmwareInfo = new OtaPackageInfo();
405 406 newFirmwareInfo.setTenantId(tenantId);
... ... @@ -410,7 +411,7 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
410 411
411 412 thrown.expect(DataValidationException.class);
412 413 thrown.expectMessage("OtaPackage with such title and version already exists!");
413   - otaPackageService.saveOtaPackageInfo(newFirmwareInfo);
  414 + otaPackageService.saveOtaPackageInfo(newFirmwareInfo, false);
414 415 }
415 416
416 417 @Test
... ... @@ -506,7 +507,7 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
506 507 firmware.setType(FIRMWARE);
507 508 firmware.setTitle(TITLE);
508 509 firmware.setVersion(VERSION);
509   - OtaPackageInfo savedFirmware = otaPackageService.saveOtaPackageInfo(firmware);
  510 + OtaPackageInfo savedFirmware = otaPackageService.saveOtaPackageInfo(firmware, false);
510 511
511 512 OtaPackageInfo foundFirmware = otaPackageService.findOtaPackageInfoById(tenantId, savedFirmware.getId());
512 513 Assert.assertNotNull(foundFirmware);
... ... @@ -543,7 +544,7 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
543 544 firmwareWithUrl.setUrl(URL);
544 545 firmwareWithUrl.setDataSize(0L);
545 546
546   - OtaPackageInfo savedFwWithUrl = otaPackageService.saveOtaPackageInfo(firmwareWithUrl);
  547 + OtaPackageInfo savedFwWithUrl = otaPackageService.saveOtaPackageInfo(firmwareWithUrl, true);
547 548 savedFwWithUrl.setHasData(true);
548 549
549 550 firmwares.add(savedFwWithUrl);
... ... @@ -588,7 +589,7 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
588 589 firmwareWithUrl.setUrl(URL);
589 590 firmwareWithUrl.setDataSize(0L);
590 591
591   - OtaPackageInfo savedFwWithUrl = otaPackageService.saveOtaPackageInfo(firmwareWithUrl);
  592 + OtaPackageInfo savedFwWithUrl = otaPackageService.saveOtaPackageInfo(firmwareWithUrl, true);
592 593 savedFwWithUrl.setHasData(true);
593 594
594 595 firmwares.add(savedFwWithUrl);
... ... @@ -627,6 +628,71 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
627 628 Assert.assertTrue(pageData.getData().isEmpty());
628 629 }
629 630
  631 + @Test
  632 + public void testSaveOtaPackageInfoWithBlankAndEmptyUrl() {
  633 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  634 + firmwareInfo.setDeviceProfileId(deviceProfileId);
  635 + firmwareInfo.setType(FIRMWARE);
  636 + firmwareInfo.setTitle(TITLE);
  637 + firmwareInfo.setVersion(VERSION);
  638 + firmwareInfo.setUrl(" ");
  639 + thrown.expect(DataValidationException.class);
  640 + thrown.expectMessage("Ota package URL should be specified!");
  641 + otaPackageService.saveOtaPackageInfo(firmwareInfo, true);
  642 + firmwareInfo.setUrl("");
  643 + otaPackageService.saveOtaPackageInfo(firmwareInfo, true);
  644 + }
  645 +
  646 + @Test
  647 + public void testSaveOtaPackageUrlCantBeUpdated() {
  648 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  649 + firmwareInfo.setDeviceProfileId(deviceProfileId);
  650 + firmwareInfo.setType(FIRMWARE);
  651 + firmwareInfo.setTitle(TITLE);
  652 + firmwareInfo.setVersion(VERSION);
  653 + firmwareInfo.setUrl(URL);
  654 + firmwareInfo.setTenantId(tenantId);
  655 +
  656 + OtaPackageInfo savedFirmwareInfo = otaPackageService.saveOtaPackageInfo(firmwareInfo, true);
  657 +
  658 + thrown.expect(DataValidationException.class);
  659 + thrown.expectMessage("Updating otaPackage URL is prohibited!");
  660 +
  661 + savedFirmwareInfo.setUrl("https://newurl.com");
  662 + otaPackageService.saveOtaPackageInfo(savedFirmwareInfo, true);
  663 + }
  664 +
  665 + @Test
  666 + public void testSaveOtaPackageCantViolateSizeOfTitle() {
  667 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  668 + firmwareInfo.setDeviceProfileId(deviceProfileId);
  669 + firmwareInfo.setType(FIRMWARE);
  670 + firmwareInfo.setTitle(RandomStringUtils.random(257));
  671 + firmwareInfo.setVersion(VERSION);
  672 + firmwareInfo.setUrl(URL);
  673 + firmwareInfo.setTenantId(tenantId);
  674 +
  675 + thrown.expect(DataValidationException.class);
  676 + thrown.expectMessage("The length of title should be equal or shorter than 255");
  677 +
  678 + otaPackageService.saveOtaPackageInfo(firmwareInfo, true);
  679 + }
  680 +
  681 + @Test
  682 + public void testSaveOtaPackageCantViolateSizeOfVersion() {
  683 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
  684 + firmwareInfo.setDeviceProfileId(deviceProfileId);
  685 + firmwareInfo.setType(FIRMWARE);
  686 + firmwareInfo.setUrl(URL);
  687 + firmwareInfo.setTenantId(tenantId);
  688 + firmwareInfo.setTitle(TITLE);
  689 +
  690 + firmwareInfo.setVersion(RandomStringUtils.random(257));
  691 + thrown.expectMessage("The length of version should be equal or shorter than 255");
  692 +
  693 + otaPackageService.saveOtaPackageInfo(firmwareInfo, true);
  694 + }
  695 +
630 696 private OtaPackage createFirmware(TenantId tenantId, String version) {
631 697 OtaPackage firmware = new OtaPackage();
632 698 firmware.setTenantId(tenantId);
... ... @@ -642,5 +708,4 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
642 708 firmware.setDataSize(DATA_SIZE);
643 709 return otaPackageService.saveOtaPackage(firmware);
644 710 }
645   -
646 711 }
... ...
... ... @@ -2977,8 +2977,10 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable {
2977 2977 ).getBody();
2978 2978 }
2979 2979
2980   - public OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo) {
2981   - return restTemplate.postForEntity(baseURL + "/api/otaPackage", otaPackageInfo, OtaPackageInfo.class).getBody();
  2980 + public OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo, boolean isUrl) {
  2981 + Map<String, String> params = new HashMap<>();
  2982 + params.put("isUrl", Boolean.toString(isUrl));
  2983 + return restTemplate.postForEntity(baseURL + "/api/otaPackage?isUrl={isUrl}", otaPackageInfo, OtaPackageInfo.class, params).getBody();
2982 2984 }
2983 2985
2984 2986 public OtaPackageInfo saveOtaPackageData(OtaPackageId otaPackageId, String checkSum, ChecksumAlgorithm checksumAlgorithm, MultipartFile file) throws Exception {
... ...
... ... @@ -93,17 +93,17 @@
93 93 </mat-form-field>
94 94 <section *ngIf="isAdd">
95 95 <div class="mat-caption" style="margin: -8px 0 8px;" translate>ota-update.warning-after-save-no-edit</div>
96   - <mat-radio-group formControlName="resource" fxLayoutGap="16px">
97   - <mat-radio-button value="file">Upload binary file</mat-radio-button>
98   - <mat-radio-button value="url">Use external URL</mat-radio-button>
  96 + <mat-radio-group formControlName="isURL" fxLayoutGap="16px">
  97 + <mat-radio-button [value]="false">Upload binary file</mat-radio-button>
  98 + <mat-radio-button [value]="true">Use external URL</mat-radio-button>
99 99 </mat-radio-group>
100 100 </section>
101   - <section *ngIf="entityForm.get('resource').value === 'file'">
  101 + <section *ngIf="!entityForm.get('isURL').value">
102 102 <section *ngIf="isAdd">
103 103 <tb-file-input
104 104 formControlName="file"
105 105 workFromFileObj="true"
106   - [required]="entityForm.get('resource').value === 'file'"
  106 + [required]="!entityForm.get('isURL').value"
107 107 dropLabel="{{'ota-update.drop-file' | translate}}">
108 108 </tb-file-input>
109 109 <mat-checkbox formControlName="generateChecksum" style="margin-top: 16px">
... ... @@ -143,12 +143,12 @@
143 143 </div>
144 144 </section>
145 145 </section>
146   - <section *ngIf="entityForm.get('resource').value === 'url'" style="margin-top: 8px">
  146 + <section *ngIf="entityForm.get('isURL').value" style="margin-top: 8px">
147 147 <mat-form-field class="mat-block">
148 148 <mat-label translate>ota-update.direct-url</mat-label>
149 149 <input matInput formControlName="url"
150 150 type="text"
151   - [required]="entityForm.get('resource').value === 'url'">
  151 + [required]="entityForm.get('isURL').value">
152 152 <mat-error *ngIf="entityForm.get('url').hasError('required') || entityForm.get('url').hasError('pattern')" translate>
153 153 ota-update.direct-url-required
154 154 </mat-error>
... ...
... ... @@ -56,11 +56,11 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O
56 56
57 57 ngOnInit() {
58 58 super.ngOnInit();
59   - this.entityForm.get('resource').valueChanges.pipe(
  59 + this.entityForm.get('isURL').valueChanges.pipe(
60 60 filter(() => this.isAdd),
61 61 takeUntil(this.destroy$)
62   - ).subscribe((resource) => {
63   - if (resource === 'file') {
  62 + ).subscribe((isURL) => {
  63 + if (isURL === false) {
64 64 this.entityForm.get('url').clearValidators();
65 65 this.entityForm.get('file').setValidators(Validators.required);
66 66 this.entityForm.get('url').updateValueAndValidity({emitEvent: false});
... ... @@ -97,7 +97,7 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O
97 97 checksumAlgorithm: [entity && entity.checksumAlgorithm ? entity.checksumAlgorithm : ChecksumAlgorithm.SHA256],
98 98 checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)],
99 99 url: [entity ? entity.url : ''],
100   - resource: ['file'],
  100 + isURL: [false],
101 101 additionalInfo: this.fb.group(
102 102 {
103 103 description: [entity && entity.additionalInfo ? entity.additionalInfo.description : ''],
... ... @@ -127,7 +127,7 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O
127 127 dataSize: entity.dataSize,
128 128 contentType: entity.contentType,
129 129 url: entity.url,
130   - resource: isNotEmptyStr(entity.url) ? 'url' : 'file',
  130 + isURL: isNotEmptyStr(entity.url),
131 131 additionalInfo: {
132 132 description: entity.additionalInfo ? entity.additionalInfo.description : ''
133 133 }
... ... @@ -172,12 +172,11 @@ export class OtaUpdateComponent extends EntityComponent<OtaPackage> implements O
172 172 }
173 173
174 174 prepareFormValue(formValue: any): any {
175   - if (formValue.resource === 'url') {
  175 + if (formValue.isURL) {
176 176 delete formValue.file;
177 177 } else {
178 178 delete formValue.url;
179 179 }
180   - delete formValue.resource;
181 180 delete formValue.generateChecksum;
182 181 return super.prepareFormValue(formValue);
183 182 }
... ...
... ... @@ -99,6 +99,7 @@ export interface OtaPackageInfo extends BaseData<OtaPackageId> {
99 99 contentType: string;
100 100 dataSize?: number;
101 101 additionalInfo?: any;
  102 + isURL?: boolean;
102 103 }
103 104
104 105 export interface OtaPackage extends OtaPackageInfo {
... ...