Commit b51fee8740223f8bd6172c211d409f30b947ccd0

Authored by YevhenBondarenko
1 parent ba7543d3

created firmware dao

Showing 36 changed files with 1341 additions and 20 deletions
... ... @@ -24,6 +24,7 @@ import lombok.extern.slf4j.Slf4j;
24 24 import org.apache.commons.lang3.StringUtils;
25 25 import org.springframework.beans.factory.annotation.Autowired;
26 26 import org.springframework.beans.factory.annotation.Value;
  27 +import org.springframework.http.MediaType;
27 28 import org.springframework.security.core.Authentication;
28 29 import org.springframework.security.core.context.SecurityContextHolder;
29 30 import org.springframework.web.bind.annotation.ExceptionHandler;
... ... @@ -37,6 +38,8 @@ import org.thingsboard.server.common.data.DeviceProfile;
37 38 import org.thingsboard.server.common.data.EntityType;
38 39 import org.thingsboard.server.common.data.EntityView;
39 40 import org.thingsboard.server.common.data.EntityViewInfo;
  41 +import org.thingsboard.server.common.data.Firmware;
  42 +import org.thingsboard.server.common.data.FirmwareInfo;
40 43 import org.thingsboard.server.common.data.HasName;
41 44 import org.thingsboard.server.common.data.HasTenantId;
42 45 import org.thingsboard.server.common.data.TbResourceInfo;
... ... @@ -61,6 +64,7 @@ import org.thingsboard.server.common.data.id.DeviceProfileId;
61 64 import org.thingsboard.server.common.data.id.EntityId;
62 65 import org.thingsboard.server.common.data.id.EntityIdFactory;
63 66 import org.thingsboard.server.common.data.id.EntityViewId;
  67 +import org.thingsboard.server.common.data.id.FirmwareId;
64 68 import org.thingsboard.server.common.data.id.TbResourceId;
65 69 import org.thingsboard.server.common.data.id.RuleChainId;
66 70 import org.thingsboard.server.common.data.id.RuleNodeId;
... ... @@ -97,6 +101,7 @@ import org.thingsboard.server.dao.device.DeviceService;
97 101 import org.thingsboard.server.dao.entityview.EntityViewService;
98 102 import org.thingsboard.server.dao.exception.DataValidationException;
99 103 import org.thingsboard.server.dao.exception.IncorrectParameterException;
  104 +import org.thingsboard.server.dao.firmware.FirmwareService;
100 105 import org.thingsboard.server.dao.model.ModelConstants;
101 106 import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
102 107 import org.thingsboard.server.dao.oauth2.OAuth2Service;
... ... @@ -233,6 +238,9 @@ public abstract class BaseController {
233 238 protected TbResourceService resourceService;
234 239
235 240 @Autowired
  241 + protected FirmwareService firmwareService;
  242 +
  243 + @Autowired
236 244 protected TbQueueProducerProvider producerProvider;
237 245
238 246 @Autowired
... ... @@ -470,6 +478,9 @@ public abstract class BaseController {
470 478 case TB_RESOURCE:
471 479 checkResourceId(new TbResourceId(entityId.getId()), operation);
472 480 return;
  481 + case FIRMWARE:
  482 + checkFirmwareId(new FirmwareId(entityId.getId()), operation);
  483 + return;
473 484 default:
474 485 throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType());
475 486 }
... ... @@ -701,6 +712,30 @@ public abstract class BaseController {
701 712 }
702 713 }
703 714
  715 + Firmware checkFirmwareId(FirmwareId firmwareId, Operation operation) throws ThingsboardException {
  716 + try {
  717 + validateId(firmwareId, "Incorrect firmwareId " + firmwareId);
  718 + Firmware firmware = firmwareService.findFirmwareById(getCurrentUser().getTenantId(), firmwareId);
  719 + checkNotNull(firmware);
  720 + accessControlService.checkPermission(getCurrentUser(), Resource.TB_RESOURCE, operation, firmwareId, firmware);
  721 + return firmware;
  722 + } catch (Exception e) {
  723 + throw handleException(e, false);
  724 + }
  725 + }
  726 +
  727 + FirmwareInfo checkFirmwareInfoId(FirmwareId firmwareId, Operation operation) throws ThingsboardException {
  728 + try {
  729 + validateId(firmwareId, "Incorrect firmwareId " + firmwareId);
  730 + FirmwareInfo firmwareInfo = firmwareService.findFirmwareInfoById(getCurrentUser().getTenantId(), firmwareId);
  731 + checkNotNull(firmwareInfo);
  732 + accessControlService.checkPermission(getCurrentUser(), Resource.FIRMWARE, operation, firmwareId, firmwareInfo);
  733 + return firmwareInfo;
  734 + } catch (Exception e) {
  735 + throw handleException(e, false);
  736 + }
  737 + }
  738 +
704 739 @SuppressWarnings("unchecked")
705 740 protected <I extends EntityId> I emptyId(EntityType entityType) {
706 741 return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
... ... @@ -924,4 +959,11 @@ public abstract class BaseController {
924 959 }
925 960 }
926 961
  962 + protected MediaType parseMediaType(String contentType) {
  963 + try {
  964 + return MediaType.parseMediaType(contentType);
  965 + } catch (Exception e) {
  966 + return MediaType.APPLICATION_OCTET_STREAM;
  967 + }
  968 + }
927 969 }
... ...
  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.controller;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.springframework.core.io.ByteArrayResource;
  20 +import org.springframework.http.HttpHeaders;
  21 +import org.springframework.http.ResponseEntity;
  22 +import org.springframework.security.access.prepost.PreAuthorize;
  23 +import org.springframework.web.bind.annotation.PathVariable;
  24 +import org.springframework.web.bind.annotation.RequestBody;
  25 +import org.springframework.web.bind.annotation.RequestMapping;
  26 +import org.springframework.web.bind.annotation.RequestMethod;
  27 +import org.springframework.web.bind.annotation.RequestParam;
  28 +import org.springframework.web.bind.annotation.ResponseBody;
  29 +import org.springframework.web.bind.annotation.RestController;
  30 +import org.springframework.web.multipart.MultipartFile;
  31 +import org.thingsboard.server.common.data.Firmware;
  32 +import org.thingsboard.server.common.data.FirmwareInfo;
  33 +import org.thingsboard.server.common.data.exception.ThingsboardException;
  34 +import org.thingsboard.server.common.data.id.FirmwareId;
  35 +import org.thingsboard.server.common.data.page.PageData;
  36 +import org.thingsboard.server.common.data.page.PageLink;
  37 +import org.thingsboard.server.queue.util.TbCoreComponent;
  38 +import org.thingsboard.server.service.security.permission.Operation;
  39 +
  40 +import java.nio.ByteBuffer;
  41 +
  42 +@Slf4j
  43 +@RestController
  44 +@TbCoreComponent
  45 +@RequestMapping("/api")
  46 +public class FirmwareController extends BaseController {
  47 +
  48 + public static final String FIRMWARE_ID = "firmwareId";
  49 +
  50 + @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')")
  51 + @RequestMapping(value = "/firmware/{firmwareId}/download", method = RequestMethod.GET)
  52 + @ResponseBody
  53 + public ResponseEntity<org.springframework.core.io.Resource> downloadFirmware(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException {
  54 + checkParameter(FIRMWARE_ID, strFirmwareId);
  55 + try {
  56 + FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
  57 + Firmware firmware = checkFirmwareId(firmwareId, Operation.READ);
  58 +
  59 + ByteArrayResource resource = new ByteArrayResource(firmware.getData().array());
  60 + return ResponseEntity.ok()
  61 + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + firmware.getFileName())
  62 + .header("x-filename", firmware.getFileName())
  63 + .contentLength(resource.contentLength())
  64 + .contentType(parseMediaType(firmware.getContentType()))
  65 + .body(resource);
  66 + } catch (Exception e) {
  67 + throw handleException(e);
  68 + }
  69 + }
  70 +
  71 + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
  72 + @RequestMapping(value = "/firmware/info/{firmwareId}", method = RequestMethod.GET)
  73 + @ResponseBody
  74 + public FirmwareInfo getFirmwareInfoById(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException {
  75 + checkParameter(FIRMWARE_ID, strFirmwareId);
  76 + try {
  77 + FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
  78 + return checkFirmwareInfoId(firmwareId, Operation.READ);
  79 + } catch (Exception e) {
  80 + throw handleException(e);
  81 + }
  82 + }
  83 +
  84 + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
  85 + @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.GET)
  86 + @ResponseBody
  87 + public Firmware getFirmwareById(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException {
  88 + checkParameter(FIRMWARE_ID, strFirmwareId);
  89 + try {
  90 + FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
  91 + return checkFirmwareId(firmwareId, Operation.READ);
  92 + } catch (Exception e) {
  93 + throw handleException(e);
  94 + }
  95 + }
  96 +
  97 + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
  98 + @RequestMapping(value = "/firmware", method = RequestMethod.POST)
  99 + @ResponseBody
  100 + public Firmware saveFirmware(@RequestParam("title") String title,
  101 + @RequestBody MultipartFile firmwareFile) throws ThingsboardException {
  102 + checkParameter("title", title);
  103 + try {
  104 + checkNotNull(firmwareFile);
  105 + Firmware firmware = new Firmware();
  106 + firmware.setTenantId(getTenantId());
  107 + firmware.setTitle(title);
  108 + firmware.setFileName(firmwareFile.getOriginalFilename());
  109 + firmware.setContentType(firmwareFile.getContentType());
  110 + firmware.setData(ByteBuffer.wrap(firmwareFile.getBytes()));
  111 + return firmwareService.saveFirmware(firmware);
  112 + } catch (Exception e) {
  113 + throw handleException(e);
  114 + }
  115 + }
  116 +
  117 + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
  118 + @RequestMapping(value = "/firmware", method = RequestMethod.GET)
  119 + @ResponseBody
  120 + public PageData<FirmwareInfo> getFirmwares(@RequestParam int pageSize,
  121 + @RequestParam int page,
  122 + @RequestParam(required = false) String textSearch,
  123 + @RequestParam(required = false) String sortProperty,
  124 + @RequestParam(required = false) String sortOrder) throws ThingsboardException {
  125 + try {
  126 + PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
  127 + return checkNotNull(firmwareService.findTenantFirmwaresByTenantId(getTenantId(), pageLink));
  128 + } catch (Exception e) {
  129 + throw handleException(e);
  130 + }
  131 + }
  132 +
  133 + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
  134 + @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.DELETE)
  135 + @ResponseBody
  136 + public void deleteResource(@PathVariable("firmwareId") String strFirmwareId) throws ThingsboardException {
  137 + checkParameter(FIRMWARE_ID, strFirmwareId);
  138 + try {
  139 + FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
  140 + checkFirmwareInfoId(firmwareId, Operation.DELETE);
  141 + firmwareService.deleteFirmware(getTenantId(), firmwareId);
  142 + } catch (Exception e) {
  143 + throw handleException(e);
  144 + }
  145 + }
  146 +
  147 +}
\ No newline at end of file
... ...
... ... @@ -55,12 +55,6 @@ public class TbResourceController extends BaseController {
55 55
56 56 public static final String RESOURCE_ID = "resourceId";
57 57
58   - private final TbResourceService resourceService;
59   -
60   - public TbResourceController(TbResourceService resourceService) {
61   - this.resourceService = resourceService;
62   - }
63   -
64 58 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
65 59 @RequestMapping(value = "/resource/{resourceId}/download", method = RequestMethod.GET)
66 60 @ResponseBody
... ... @@ -187,7 +181,7 @@ public class TbResourceController extends BaseController {
187 181 @RequestMapping(value = "/resource/{resourceId}", method = RequestMethod.DELETE)
188 182 @ResponseBody
189 183 public void deleteResource(@PathVariable("resourceId") String strResourceId) throws ThingsboardException {
190   - checkParameter("resourceId", strResourceId);
  184 + checkParameter(RESOURCE_ID, strResourceId);
191 185 try {
192 186 TbResourceId resourceId = new TbResourceId(toUUID(strResourceId));
193 187 TbResource tbResource = checkResourceId(resourceId, Operation.DELETE);
... ...
... ... @@ -37,7 +37,8 @@ public enum Resource {
37 37 TENANT_PROFILE(EntityType.TENANT_PROFILE),
38 38 DEVICE_PROFILE(EntityType.DEVICE_PROFILE),
39 39 API_USAGE_STATE(EntityType.API_USAGE_STATE),
40   - TB_RESOURCE(EntityType.TB_RESOURCE);
  40 + TB_RESOURCE(EntityType.TB_RESOURCE),
  41 + FIRMWARE(EntityType.FIRMWARE);
41 42
42 43 private final EntityType entityType;
43 44
... ...
... ... @@ -42,6 +42,7 @@ public class TenantAdminPermissions extends AbstractPermissions {
42 42 put(Resource.DEVICE_PROFILE, tenantEntityPermissionChecker);
43 43 put(Resource.API_USAGE_STATE, tenantEntityPermissionChecker);
44 44 put(Resource.TB_RESOURCE, tbResourcePermissionChecker);
  45 + put(Resource.FIRMWARE, tenantEntityPermissionChecker);
45 46 }
46 47
47 48 public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker() {
... ...
  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.dao.firmware;
  17 +
  18 +import org.thingsboard.server.common.data.Firmware;
  19 +import org.thingsboard.server.common.data.FirmwareInfo;
  20 +import org.thingsboard.server.common.data.id.FirmwareId;
  21 +import org.thingsboard.server.common.data.id.TenantId;
  22 +import org.thingsboard.server.common.data.page.PageData;
  23 +import org.thingsboard.server.common.data.page.PageLink;
  24 +
  25 +
  26 +public interface FirmwareService {
  27 +
  28 + Firmware saveFirmware(Firmware firmware);
  29 +
  30 + Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId);
  31 +
  32 + FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId);
  33 +
  34 + PageData<FirmwareInfo> findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink);
  35 +
  36 + void deleteFirmware(TenantId tenantId, FirmwareId firmwareId);
  37 +
  38 + void deleteFirmwaresByTenantId(TenantId tenantId);
  39 +}
... ...
... ... @@ -32,7 +32,7 @@ import java.util.List;
32 32 public interface TbResourceService {
33 33 TbResource saveResource(TbResource resource) throws InvalidDDFFileException, IOException;
34 34
35   - TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId);
  35 + TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceKey);
36 36
37 37 TbResource findResourceById(TenantId tenantId, TbResourceId resourceId);
38 38
... ...
... ... @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.device.data.DeviceData;
23 23 import org.thingsboard.server.common.data.id.CustomerId;
24 24 import org.thingsboard.server.common.data.id.DeviceId;
25 25 import org.thingsboard.server.common.data.id.DeviceProfileId;
  26 +import org.thingsboard.server.common.data.id.FirmwareId;
26 27 import org.thingsboard.server.common.data.id.TenantId;
27 28
28 29 import java.io.ByteArrayInputStream;
... ... @@ -44,6 +45,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
44 45 @JsonIgnore
45 46 private byte[] deviceDataBytes;
46 47
  48 + private FirmwareId firmwareId;
  49 +
47 50 public Device() {
48 51 super();
49 52 }
... ... @@ -61,6 +64,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
61 64 this.label = device.getLabel();
62 65 this.deviceProfileId = device.getDeviceProfileId();
63 66 this.setDeviceData(device.getDeviceData());
  67 + this.firmwareId = device.getFirmwareId();
64 68 }
65 69
66 70 public Device updateDevice(Device device) {
... ... @@ -155,6 +159,14 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
155 159 return getName();
156 160 }
157 161
  162 + public FirmwareId getFirmwareId() {
  163 + return firmwareId;
  164 + }
  165 +
  166 + public void setFirmwareId(FirmwareId firmwareId) {
  167 + this.firmwareId = firmwareId;
  168 + }
  169 +
158 170 @Override
159 171 public String toString() {
160 172 StringBuilder builder = new StringBuilder();
... ... @@ -171,6 +183,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
171 183 builder.append(", deviceProfileId=");
172 184 builder.append(deviceProfileId);
173 185 builder.append(", deviceData=");
  186 + builder.append(firmwareId);
  187 + builder.append(", firmwareId=");
174 188 builder.append(deviceData);
175 189 builder.append(", additionalInfo=");
176 190 builder.append(getAdditionalInfo());
... ...
... ... @@ -22,6 +22,7 @@ import lombok.EqualsAndHashCode;
22 22 import lombok.extern.slf4j.Slf4j;
23 23 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
24 24 import org.thingsboard.server.common.data.id.DeviceProfileId;
  25 +import org.thingsboard.server.common.data.id.FirmwareId;
25 26 import org.thingsboard.server.common.data.id.RuleChainId;
26 27 import org.thingsboard.server.common.data.id.TenantId;
27 28
... ... @@ -49,6 +50,8 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H
49 50 private byte[] profileDataBytes;
50 51 private String provisionDeviceKey;
51 52
  53 + private FirmwareId firmwareId;
  54 +
52 55 public DeviceProfile() {
53 56 super();
54 57 }
... ...
... ... @@ -19,5 +19,5 @@ package org.thingsboard.server.common.data;
19 19 * @author Andrew Shvayka
20 20 */
21 21 public enum EntityType {
22   - TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, API_USAGE_STATE, TB_RESOURCE;
  22 + TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, API_USAGE_STATE, TB_RESOURCE, FIRMWARE;
23 23 }
... ...
  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 org.thingsboard.server.common.data.id.FirmwareId;
  21 +
  22 +import java.nio.ByteBuffer;
  23 +
  24 +@Data
  25 +@EqualsAndHashCode(callSuper = true)
  26 +public class Firmware extends FirmwareInfo {
  27 +
  28 + private static final long serialVersionUID = 3091601761339422546L;
  29 +
  30 + private transient ByteBuffer data;
  31 +
  32 + public Firmware() {
  33 + super();
  34 + }
  35 +
  36 + public Firmware(FirmwareId id) {
  37 + super(id);
  38 + }
  39 +
  40 + public Firmware(Firmware firmware) {
  41 + super(firmware);
  42 + this.data = firmware.getData();
  43 + }
  44 +}
... ...
  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.extern.slf4j.Slf4j;
  21 +import org.thingsboard.server.common.data.id.FirmwareId;
  22 +import org.thingsboard.server.common.data.id.TenantId;
  23 +
  24 +@Slf4j
  25 +@Data
  26 +@EqualsAndHashCode(callSuper = true)
  27 +public class FirmwareInfo extends SearchTextBased<FirmwareId> implements HasTenantId {
  28 +
  29 + private static final long serialVersionUID = 3168391583570815419L;
  30 +
  31 + private TenantId tenantId;
  32 + private String title;
  33 + private String fileName;
  34 + private String contentType;
  35 +
  36 + public FirmwareInfo() {
  37 + super();
  38 + }
  39 +
  40 + public FirmwareInfo(FirmwareId id) {
  41 + super(id);
  42 + }
  43 +
  44 + public FirmwareInfo(FirmwareInfo firmwareInfo) {
  45 + super(firmwareInfo);
  46 + this.tenantId = firmwareInfo.getTenantId();
  47 + this.title = firmwareInfo.getTitle();
  48 + this.fileName = firmwareInfo.getFileName();
  49 + this.contentType = firmwareInfo.getContentType();
  50 + }
  51 +
  52 + @Override
  53 + public String getSearchText() {
  54 + return title;
  55 + }
  56 +}
... ...
... ... @@ -26,6 +26,8 @@ import org.thingsboard.server.common.data.id.TenantId;
26 26 @EqualsAndHashCode(callSuper = true)
27 27 public class TbResourceInfo extends SearchTextBased<TbResourceId> implements HasTenantId {
28 28
  29 + private static final long serialVersionUID = 7282664529021651736L;
  30 +
29 31 private TenantId tenantId;
30 32 private String title;
31 33 private ResourceType resourceType;
... ...
  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.id;
  17 +
  18 +import com.fasterxml.jackson.annotation.JsonCreator;
  19 +import com.fasterxml.jackson.annotation.JsonIgnore;
  20 +import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import org.thingsboard.server.common.data.EntityType;
  22 +
  23 +import java.util.UUID;
  24 +
  25 +public class FirmwareId extends UUIDBased implements EntityId {
  26 +
  27 + private static final long serialVersionUID = 1L;
  28 +
  29 + @JsonCreator
  30 + public FirmwareId(@JsonProperty("id") UUID id) {
  31 + super(id);
  32 + }
  33 +
  34 + public static FirmwareId fromString(String firmwareId) {
  35 + return new FirmwareId(UUID.fromString(firmwareId));
  36 + }
  37 +
  38 + @JsonIgnore
  39 + @Override
  40 + public EntityType getEntityType() {
  41 + return EntityType.FIRMWARE;
  42 + }
  43 +
  44 +}
... ...
  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.dao.firmware;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.apache.commons.lang3.StringUtils;
  20 +import org.hibernate.exception.ConstraintViolationException;
  21 +import org.springframework.stereotype.Service;
  22 +import org.thingsboard.server.common.data.Firmware;
  23 +import org.thingsboard.server.common.data.FirmwareInfo;
  24 +import org.thingsboard.server.common.data.Tenant;
  25 +import org.thingsboard.server.common.data.id.FirmwareId;
  26 +import org.thingsboard.server.common.data.id.TenantId;
  27 +import org.thingsboard.server.common.data.page.PageData;
  28 +import org.thingsboard.server.common.data.page.PageLink;
  29 +import org.thingsboard.server.dao.exception.DataValidationException;
  30 +import org.thingsboard.server.dao.service.DataValidator;
  31 +import org.thingsboard.server.dao.service.PaginatedRemover;
  32 +import org.thingsboard.server.dao.tenant.TenantDao;
  33 +
  34 +import java.nio.ByteBuffer;
  35 +import java.util.Optional;
  36 +
  37 +import static org.thingsboard.server.dao.service.Validator.validateId;
  38 +import static org.thingsboard.server.dao.service.Validator.validatePageLink;
  39 +
  40 +@Service
  41 +@Slf4j
  42 +public class BaseFirmwareService implements FirmwareService {
  43 + public static final String INCORRECT_FIRMWARE_ID = "Incorrect firmwareId ";
  44 + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
  45 +
  46 + private final TenantDao tenantDao;
  47 + private final FirmwareDao firmwareDao;
  48 + private final FirmwareInfoDao firmwareInfoDao;
  49 +
  50 + public BaseFirmwareService(TenantDao tenantDao, FirmwareDao firmwareDao, FirmwareInfoDao firmwareInfoDao) {
  51 + this.tenantDao = tenantDao;
  52 + this.firmwareDao = firmwareDao;
  53 + this.firmwareInfoDao = firmwareInfoDao;
  54 + }
  55 +
  56 + @Override
  57 + public Firmware saveFirmware(Firmware firmware) {
  58 + log.trace("Executing saveFirmware [{}]", firmware);
  59 + firmwareValidator.validate(firmware, Firmware::getTenantId);
  60 + return firmwareDao.save(firmware.getTenantId(), firmware);
  61 + }
  62 +
  63 + @Override
  64 + public Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId) {
  65 + log.trace("Executing findFirmwareById [{}]", firmwareId);
  66 + validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId);
  67 + return firmwareDao.findById(tenantId, firmwareId.getId());
  68 + }
  69 +
  70 + @Override
  71 + public FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId) {
  72 + log.trace("Executing findFirmwareInfoById [{}]", firmwareId);
  73 + validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId);
  74 + return firmwareInfoDao.findById(tenantId, firmwareId.getId());
  75 + }
  76 +
  77 + @Override
  78 + public PageData<FirmwareInfo> findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink) {
  79 + log.trace("Executing findTenantFirmwaresByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink);
  80 + validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
  81 + validatePageLink(pageLink);
  82 + return firmwareInfoDao.findFirmwareInfoByTenantId(tenantId, pageLink);
  83 + }
  84 +
  85 + @Override
  86 + public void deleteFirmware(TenantId tenantId, FirmwareId firmwareId) {
  87 + log.trace("Executing deleteFirmware [{}]", firmwareId);
  88 + validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId);
  89 + try {
  90 + firmwareDao.removeById(tenantId, firmwareId.getId());
  91 + } catch (Exception t) {
  92 + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
  93 + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_firmware_device")) {
  94 + throw new DataValidationException("The firmware referenced by the devices cannot be deleted!");
  95 + } else if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_firmware_device_profile")) {
  96 + throw new DataValidationException("The firmware referenced by the device profile cannot be deleted!");
  97 + } else {
  98 + throw t;
  99 + }
  100 + }
  101 + }
  102 +
  103 + @Override
  104 + public void deleteFirmwaresByTenantId(TenantId tenantId) {
  105 + log.trace("Executing deleteFirmwaresByTenantId, tenantId [{}]", tenantId);
  106 + validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
  107 + tenantFirmwareRemover.removeEntities(tenantId, tenantId);
  108 + }
  109 +
  110 + private DataValidator<Firmware> firmwareValidator = new DataValidator<>() {
  111 +
  112 + @Override
  113 + protected void validateDataImpl(TenantId tenantId, Firmware firmware) {
  114 + if (firmware.getTenantId() == null) {
  115 + throw new DataValidationException("Firmware should be assigned to tenant!");
  116 + } else {
  117 + Tenant tenant = tenantDao.findById(firmware.getTenantId(), firmware.getTenantId().getId());
  118 + if (tenant == null) {
  119 + throw new DataValidationException("Firmware is referencing to non-existent tenant!");
  120 + }
  121 + }
  122 +
  123 + if (StringUtils.isEmpty(firmware.getTitle())) {
  124 + throw new DataValidationException("Firmware title should be specified!");
  125 + }
  126 + if (StringUtils.isEmpty(firmware.getFileName())) {
  127 + throw new DataValidationException("Firmware file name should be specified!");
  128 + }
  129 + if (StringUtils.isEmpty(firmware.getContentType())) {
  130 + throw new DataValidationException("Firmware content type should be specified!");
  131 + }
  132 + ByteBuffer data = firmware.getData();
  133 + if (data == null || !data.hasArray() || data.array().length == 0) {
  134 + throw new DataValidationException("Firmware data should be specified!");
  135 + }
  136 + }
  137 + };
  138 +
  139 + private PaginatedRemover<TenantId, FirmwareInfo> tenantFirmwareRemover =
  140 + new PaginatedRemover<>() {
  141 +
  142 + @Override
  143 + protected PageData<FirmwareInfo> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
  144 + return firmwareInfoDao.findFirmwareInfoByTenantId(id, pageLink);
  145 + }
  146 +
  147 + @Override
  148 + protected void removeEntity(TenantId tenantId, FirmwareInfo entity) {
  149 + deleteFirmware(tenantId, entity.getId());
  150 + }
  151 + };
  152 +
  153 + protected Optional<ConstraintViolationException> extractConstraintViolationException(Exception t) {
  154 + if (t instanceof ConstraintViolationException) {
  155 + return Optional.of((ConstraintViolationException) t);
  156 + } else if (t.getCause() instanceof ConstraintViolationException) {
  157 + return Optional.of((ConstraintViolationException) (t.getCause()));
  158 + } else {
  159 + return Optional.empty();
  160 + }
  161 + }
  162 +}
... ...
  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.dao.firmware;
  17 +
  18 +import org.thingsboard.server.common.data.Firmware;
  19 +import org.thingsboard.server.dao.Dao;
  20 +
  21 +public interface FirmwareDao extends Dao<Firmware> {
  22 +
  23 +}
... ...
  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.dao.firmware;
  17 +
  18 +import org.thingsboard.server.common.data.FirmwareInfo;
  19 +import org.thingsboard.server.common.data.id.TenantId;
  20 +import org.thingsboard.server.common.data.page.PageData;
  21 +import org.thingsboard.server.common.data.page.PageLink;
  22 +import org.thingsboard.server.dao.Dao;
  23 +
  24 +import java.util.UUID;
  25 +
  26 +public interface FirmwareInfoDao extends Dao<FirmwareInfo> {
  27 +
  28 + PageData<FirmwareInfo> findFirmwareInfoByTenantId(TenantId tenantId, PageLink pageLink);
  29 +
  30 +}
... ...
... ... @@ -153,6 +153,7 @@ public class ModelConstants {
153 153 public static final String DEVICE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;
154 154 public static final String DEVICE_DEVICE_PROFILE_ID_PROPERTY = "device_profile_id";
155 155 public static final String DEVICE_DEVICE_DATA_PROPERTY = "device_data";
  156 + public static final String DEVICE_FIRMWARE_ID_PROPERTY = "firmware_id";
156 157
157 158 public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text";
158 159 public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text";
... ... @@ -176,6 +177,7 @@ public class ModelConstants {
176 177 public static final String DEVICE_PROFILE_DEFAULT_RULE_CHAIN_ID_PROPERTY = "default_rule_chain_id";
177 178 public static final String DEVICE_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY = "default_queue_name";
178 179 public static final String DEVICE_PROFILE_PROVISION_DEVICE_KEY = "provision_device_key";
  180 + public static final String DEVICE_PROFILE_FIRMWARE_ID_PROPERTY = "firmware_id";
179 181
180 182 /**
181 183 * Cassandra entityView constants.
... ... @@ -468,6 +470,16 @@ public class ModelConstants {
468 470 public static final String RESOURCE_DATA_COLUMN = "data";
469 471
470 472 /**
  473 + * Firmware constants.
  474 + */
  475 + public static final String FIRMWARE_TABLE_NAME = "firmware";
  476 + public static final String FIRMWARE_TENANT_ID_COLUMN = TENANT_ID_COLUMN;
  477 + public static final String FIRMWARE_TITLE_COLUMN = TITLE_PROPERTY;
  478 + public static final String FIRMWARE_FILE_NAME_COLUMN = "file_name";
  479 + public static final String FIRMWARE_CONTENT_TYPE_COLUMN = "content_type";
  480 + public static final String FIRMWARE_DATA_COLUMN = "data";
  481 +
  482 + /**
471 483 * Cassandra attributes and timeseries constants.
472 484 */
473 485 public static final String ATTRIBUTES_KV_CF = "attributes_kv_cf";
... ...
... ... @@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.device.data.DeviceData;
27 27 import org.thingsboard.server.common.data.id.CustomerId;
28 28 import org.thingsboard.server.common.data.id.DeviceId;
29 29 import org.thingsboard.server.common.data.id.DeviceProfileId;
  30 +import org.thingsboard.server.common.data.id.FirmwareId;
30 31 import org.thingsboard.server.common.data.id.TenantId;
31 32 import org.thingsboard.server.dao.model.BaseSqlEntity;
32 33 import org.thingsboard.server.dao.model.ModelConstants;
... ... @@ -73,6 +74,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti
73 74 @Column(name = ModelConstants.DEVICE_DEVICE_PROFILE_ID_PROPERTY, columnDefinition = "uuid")
74 75 private UUID deviceProfileId;
75 76
  77 + @Column(name = ModelConstants.DEVICE_FIRMWARE_ID_PROPERTY, columnDefinition = "uuid")
  78 + private UUID firmwareId;
  79 +
76 80 @Type(type = "jsonb")
77 81 @Column(name = ModelConstants.DEVICE_DEVICE_DATA_PROPERTY, columnDefinition = "jsonb")
78 82 private JsonNode deviceData;
... ... @@ -95,6 +99,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti
95 99 if (device.getDeviceProfileId() != null) {
96 100 this.deviceProfileId = device.getDeviceProfileId().getId();
97 101 }
  102 + if (device.getFirmwareId() != null) {
  103 + this.firmwareId = device.getFirmwareId().getId();
  104 + }
98 105 this.deviceData = JacksonUtil.convertValue(device.getDeviceData(), ObjectNode.class);
99 106 this.name = device.getName();
100 107 this.type = device.getType();
... ... @@ -114,6 +121,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti
114 121 this.label = deviceEntity.getLabel();
115 122 this.searchText = deviceEntity.getSearchText();
116 123 this.additionalInfo = deviceEntity.getAdditionalInfo();
  124 + this.firmwareId = deviceEntity.getFirmwareId();
117 125 }
118 126
119 127 @Override
... ... @@ -138,6 +146,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti
138 146 if (deviceProfileId != null) {
139 147 device.setDeviceProfileId(new DeviceProfileId(deviceProfileId));
140 148 }
  149 + if (firmwareId != null) {
  150 + device.setFirmwareId(new FirmwareId(firmwareId));
  151 + }
141 152 device.setDeviceData(JacksonUtil.convertValue(deviceData, DeviceData.class));
142 153 device.setName(name);
143 154 device.setType(type);
... ...
... ... @@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.DeviceProfileProvisionType;
27 27 import org.thingsboard.server.common.data.DeviceTransportType;
28 28 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
29 29 import org.thingsboard.server.common.data.id.DeviceProfileId;
  30 +import org.thingsboard.server.common.data.id.FirmwareId;
30 31 import org.thingsboard.server.common.data.id.RuleChainId;
31 32 import org.thingsboard.server.common.data.id.TenantId;
32 33 import org.thingsboard.server.dao.model.BaseSqlEntity;
... ... @@ -89,6 +90,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
89 90 @Column(name=ModelConstants.DEVICE_PROFILE_PROVISION_DEVICE_KEY)
90 91 private String provisionDeviceKey;
91 92
  93 + @Column(name=ModelConstants.DEVICE_PROFILE_FIRMWARE_ID_PROPERTY)
  94 + private UUID firmwareId;
  95 +
92 96 public DeviceProfileEntity() {
93 97 super();
94 98 }
... ... @@ -113,6 +117,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
113 117 }
114 118 this.defaultQueueName = deviceProfile.getDefaultQueueName();
115 119 this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey();
  120 + if (deviceProfile.getFirmwareId() != null) {
  121 + this.firmwareId = deviceProfile.getFirmwareId().getId();
  122 + }
116 123 }
117 124
118 125 @Override
... ... @@ -148,6 +155,11 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
148 155 }
149 156 deviceProfile.setDefaultQueueName(defaultQueueName);
150 157 deviceProfile.setProvisionDeviceKey(provisionDeviceKey);
  158 +
  159 + if (firmwareId != null) {
  160 + deviceProfile.setFirmwareId(new FirmwareId(firmwareId));
  161 + }
  162 +
151 163 return deviceProfile;
152 164 }
153 165 }
... ...
  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.dao.model.sql;
  17 +
  18 +import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +import org.thingsboard.server.common.data.Firmware;
  21 +import org.thingsboard.server.common.data.id.FirmwareId;
  22 +import org.thingsboard.server.common.data.id.TenantId;
  23 +import org.thingsboard.server.dao.model.BaseSqlEntity;
  24 +import org.thingsboard.server.dao.model.SearchTextEntity;
  25 +
  26 +import javax.persistence.Column;
  27 +import javax.persistence.Entity;
  28 +import javax.persistence.Table;
  29 +import java.nio.ByteBuffer;
  30 +import java.util.UUID;
  31 +
  32 +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN;
  33 +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_COLUMN;
  34 +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN;
  35 +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME;
  36 +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN;
  37 +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN;
  38 +import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
  39 +
  40 +@Data
  41 +@EqualsAndHashCode(callSuper = true)
  42 +@Entity
  43 +@Table(name = FIRMWARE_TABLE_NAME)
  44 +public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTextEntity<Firmware> {
  45 +
  46 + @Column(name = FIRMWARE_TENANT_ID_COLUMN)
  47 + private UUID tenantId;
  48 +
  49 + @Column(name = FIRMWARE_TITLE_COLUMN)
  50 + private String title;
  51 +
  52 + @Column(name = FIRMWARE_FILE_NAME_COLUMN)
  53 + private String fileName;
  54 +
  55 + @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN)
  56 + private String contentType;
  57 +
  58 + @Column(name = FIRMWARE_DATA_COLUMN, columnDefinition = "BINARY")
  59 + private byte[] data;
  60 +
  61 + @Column(name = SEARCH_TEXT_PROPERTY)
  62 + private String searchText;
  63 +
  64 + public FirmwareEntity() {
  65 + super();
  66 + }
  67 +
  68 + public FirmwareEntity(Firmware firmware) {
  69 + this.createdTime = firmware.getCreatedTime();
  70 + this.setUuid(firmware.getUuidId());
  71 + this.tenantId = firmware.getTenantId().getId();
  72 + this.title = firmware.getTitle();
  73 + this.fileName = firmware.getFileName();
  74 + this.contentType = firmware.getContentType();
  75 + this.data = firmware.getData().array();
  76 + }
  77 +
  78 + @Override
  79 + public String getSearchTextSource() {
  80 + return title;
  81 + }
  82 +
  83 + @Override
  84 + public void setSearchText(String searchText) {
  85 + this.searchText = searchText;
  86 + }
  87 +
  88 + @Override
  89 + public Firmware toData() {
  90 + Firmware firmware = new Firmware(new FirmwareId(id));
  91 + firmware.setCreatedTime(createdTime);
  92 + firmware.setTenantId(new TenantId(tenantId));
  93 + firmware.setTitle(title);
  94 + firmware.setFileName(fileName);
  95 + firmware.setContentType(contentType);
  96 + firmware.setData(ByteBuffer.wrap(data));
  97 + return firmware;
  98 + }
  99 +}
... ...
  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.dao.model.sql;
  17 +
  18 +import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +import org.thingsboard.server.common.data.FirmwareInfo;
  21 +import org.thingsboard.server.common.data.id.FirmwareId;
  22 +import org.thingsboard.server.common.data.id.TenantId;
  23 +import org.thingsboard.server.dao.model.BaseSqlEntity;
  24 +import org.thingsboard.server.dao.model.SearchTextEntity;
  25 +
  26 +import javax.persistence.Column;
  27 +import javax.persistence.Entity;
  28 +import javax.persistence.Table;
  29 +import java.util.UUID;
  30 +
  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 +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME;
  34 +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN;
  35 +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN;
  36 +import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
  37 +
  38 +@Data
  39 +@EqualsAndHashCode(callSuper = true)
  40 +@Entity
  41 +@Table(name = FIRMWARE_TABLE_NAME)
  42 +public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements SearchTextEntity<FirmwareInfo> {
  43 +
  44 + @Column(name = FIRMWARE_TENANT_ID_COLUMN)
  45 + private UUID tenantId;
  46 +
  47 + @Column(name = FIRMWARE_TITLE_COLUMN)
  48 + private String title;
  49 +
  50 + @Column(name = FIRMWARE_FILE_NAME_COLUMN)
  51 + private String fileName;
  52 +
  53 + @Column(name = FIRMWARE_CONTENT_TYPE_COLUMN)
  54 + private String contentType;
  55 +
  56 + @Column(name = SEARCH_TEXT_PROPERTY)
  57 + private String searchText;
  58 +
  59 + public FirmwareInfoEntity() {
  60 + super();
  61 + }
  62 +
  63 + public FirmwareInfoEntity(FirmwareInfo firmware) {
  64 + this.createdTime = firmware.getCreatedTime();
  65 + this.setUuid(firmware.getUuidId());
  66 + this.tenantId = firmware.getTenantId().getId();
  67 + this.title = firmware.getTitle();
  68 + this.fileName = firmware.getFileName();
  69 + this.contentType = firmware.getContentType();
  70 + }
  71 +
  72 + @Override
  73 + public String getSearchTextSource() {
  74 + return title;
  75 + }
  76 +
  77 + @Override
  78 + public void setSearchText(String searchText) {
  79 + this.searchText = searchText;
  80 + }
  81 +
  82 + @Override
  83 + public FirmwareInfo toData() {
  84 + FirmwareInfo firmware = new FirmwareInfo(new FirmwareId(id));
  85 + firmware.setCreatedTime(createdTime);
  86 + firmware.setTenantId(new TenantId(tenantId));
  87 + firmware.setTitle(title);
  88 + firmware.setFileName(fileName);
  89 + firmware.setContentType(contentType);
  90 + return firmware;
  91 + }
  92 +}
... ...
  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.dao.sql.firmware;
  17 +
  18 +import org.springframework.data.domain.Page;
  19 +import org.springframework.data.domain.Pageable;
  20 +import org.springframework.data.jpa.repository.Query;
  21 +import org.springframework.data.repository.CrudRepository;
  22 +import org.springframework.data.repository.query.Param;
  23 +import org.thingsboard.server.dao.model.sql.FirmwareInfoEntity;
  24 +
  25 +import java.util.UUID;
  26 +
  27 +public interface FirmwareInfoRepository extends CrudRepository<FirmwareInfoEntity, UUID> {
  28 + @Query("SELECT fi FROM FirmwareInfoEntity fi WHERE " +
  29 + "fi.tenantId = :tenantId " +
  30 + "AND LOWER(fi.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
  31 + Page<FirmwareInfoEntity> findAllByTenantId(@Param("tenantId") UUID tenantId,
  32 + @Param("searchText") String searchText,
  33 + Pageable pageable);
  34 +}
... ...
  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.dao.sql.firmware;
  17 +
  18 +import org.springframework.data.repository.CrudRepository;
  19 +import org.thingsboard.server.dao.model.sql.FirmwareEntity;
  20 +
  21 +import java.util.UUID;
  22 +
  23 +public interface FirmwareRepository extends CrudRepository<FirmwareEntity, UUID> {
  24 +}
... ...
  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.dao.sql.firmware;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.data.repository.CrudRepository;
  21 +import org.springframework.stereotype.Component;
  22 +import org.thingsboard.server.common.data.Firmware;
  23 +import org.thingsboard.server.dao.firmware.FirmwareDao;
  24 +import org.thingsboard.server.dao.model.sql.FirmwareEntity;
  25 +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
  26 +
  27 +import java.util.UUID;
  28 +
  29 +@Slf4j
  30 +@Component
  31 +public class JpaFirmwareDao extends JpaAbstractSearchTextDao<FirmwareEntity, Firmware> implements FirmwareDao {
  32 +
  33 + @Autowired
  34 + private FirmwareRepository firmwareRepository;
  35 +
  36 + @Override
  37 + protected Class<FirmwareEntity> getEntityClass() {
  38 + return FirmwareEntity.class;
  39 + }
  40 +
  41 + @Override
  42 + protected CrudRepository<FirmwareEntity, UUID> getCrudRepository() {
  43 + return firmwareRepository;
  44 + }
  45 +
  46 +}
... ...
  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.dao.sql.firmware;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.data.repository.CrudRepository;
  21 +import org.springframework.stereotype.Component;
  22 +import org.thingsboard.server.common.data.FirmwareInfo;
  23 +import org.thingsboard.server.common.data.id.TenantId;
  24 +import org.thingsboard.server.common.data.page.PageData;
  25 +import org.thingsboard.server.common.data.page.PageLink;
  26 +import org.thingsboard.server.dao.DaoUtil;
  27 +import org.thingsboard.server.dao.firmware.FirmwareInfoDao;
  28 +import org.thingsboard.server.dao.model.sql.FirmwareInfoEntity;
  29 +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
  30 +
  31 +import java.util.Objects;
  32 +import java.util.UUID;
  33 +
  34 +@Slf4j
  35 +@Component
  36 +public class JpaFirmwareInfoDao extends JpaAbstractSearchTextDao<FirmwareInfoEntity, FirmwareInfo> implements FirmwareInfoDao {
  37 +
  38 + @Autowired
  39 + private FirmwareInfoRepository firmwareInfoRepository;
  40 +
  41 + @Override
  42 + protected Class<FirmwareInfoEntity> getEntityClass() {
  43 + return FirmwareInfoEntity.class;
  44 + }
  45 +
  46 + @Override
  47 + protected CrudRepository<FirmwareInfoEntity, UUID> getCrudRepository() {
  48 + return firmwareInfoRepository;
  49 + }
  50 +
  51 + @Override
  52 + public PageData<FirmwareInfo> findFirmwareInfoByTenantId(TenantId tenantId, PageLink pageLink) {
  53 + return DaoUtil.toPageData(firmwareInfoRepository
  54 + .findAllByTenantId(
  55 + tenantId.getId(),
  56 + Objects.toString(pageLink.getTextSearch(), ""),
  57 + DaoUtil.toPageable(pageLink)));
  58 + }
  59 +}
... ...
... ... @@ -48,8 +48,6 @@ public interface TbResourceRepository extends CrudRepository<TbResourceEntity, U
48 48 @Param("searchText") String search,
49 49 Pageable pageable);
50 50
51   - void removeAllByTenantId(UUID tenantId);
52   -
53 51 @Query("SELECT tr FROM TbResourceEntity tr " +
54 52 "WHERE tr.resourceType = :resourceType " +
55 53 "AND LOWER(tr.searchText) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
... ...
... ... @@ -157,6 +157,17 @@ CREATE TABLE IF NOT EXISTS rule_node_state (
157 157 CONSTRAINT fk_rule_node_state_node_id FOREIGN KEY (rule_node_id) REFERENCES rule_node(id) ON DELETE CASCADE
158 158 );
159 159
  160 +CREATE TABLE IF NOT EXISTS firmware (
  161 + id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY,
  162 + created_time bigint NOT NULL,
  163 + tenant_id uuid NOT NULL,
  164 + title varchar(255) NOT NULL,
  165 + search_text varchar(255),
  166 + file_name varchar(255) NOT NULL,
  167 + content_type varchar(255) NOT NULL,
  168 + data binary
  169 +);
  170 +
160 171 CREATE TABLE IF NOT EXISTS device_profile (
161 172 id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY,
162 173 created_time bigint NOT NULL,
... ... @@ -169,12 +180,14 @@ CREATE TABLE IF NOT EXISTS device_profile (
169 180 search_text varchar(255),
170 181 is_default boolean,
171 182 tenant_id uuid,
  183 + firmware_id uuid,
172 184 default_rule_chain_id uuid,
173 185 default_queue_name varchar(255),
174 186 provision_device_key varchar,
175 187 CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
176 188 CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
177   - CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id)
  189 + CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id),
  190 + CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id)
178 191 );
179 192
180 193 CREATE TABLE IF NOT EXISTS device (
... ... @@ -189,8 +202,10 @@ CREATE TABLE IF NOT EXISTS device (
189 202 label varchar(255),
190 203 search_text varchar(255),
191 204 tenant_id uuid,
  205 + firmware_id uuid,
192 206 CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name),
193   - CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id)
  207 + CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id),
  208 + CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id)
194 209 );
195 210
196 211 CREATE TABLE IF NOT EXISTS device_credentials (
... ...
... ... @@ -25,7 +25,7 @@ CREATE OR REPLACE PROCEDURE insert_tb_schema_settings()
25 25 $$
26 26 BEGIN
27 27 IF (SELECT COUNT(*) FROM tb_schema_settings) = 0 THEN
28   - INSERT INTO tb_schema_settings (schema_version) VALUES (3002000);
  28 + INSERT INTO tb_schema_settings (schema_version) VALUES (3003000);
29 29 END IF;
30 30 END;
31 31 $$;
... ... @@ -175,6 +175,17 @@ CREATE TABLE IF NOT EXISTS rule_node_state (
175 175 CONSTRAINT fk_rule_node_state_node_id FOREIGN KEY (rule_node_id) REFERENCES rule_node(id) ON DELETE CASCADE
176 176 );
177 177
  178 +CREATE TABLE IF NOT EXISTS firmware (
  179 + id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY,
  180 + created_time bigint NOT NULL,
  181 + tenant_id uuid NOT NULL,
  182 + title varchar(255) NOT NULL,
  183 + search_text varchar(255),
  184 + file_name varchar(255) NOT NULL,
  185 + content_type varchar(255) NOT NULL,
  186 + data bytea
  187 +);
  188 +
178 189 CREATE TABLE IF NOT EXISTS device_profile (
179 190 id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY,
180 191 created_time bigint NOT NULL,
... ... @@ -187,12 +198,14 @@ CREATE TABLE IF NOT EXISTS device_profile (
187 198 search_text varchar(255),
188 199 is_default boolean,
189 200 tenant_id uuid,
  201 + firmware_id uuid,
190 202 default_rule_chain_id uuid,
191 203 default_queue_name varchar(255),
192 204 provision_device_key varchar,
193 205 CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
194 206 CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
195   - CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id)
  207 + CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id),
  208 + CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id)
196 209 );
197 210
198 211 CREATE TABLE IF NOT EXISTS device (
... ... @@ -207,8 +220,10 @@ CREATE TABLE IF NOT EXISTS device (
207 220 label varchar(255),
208 221 search_text varchar(255),
209 222 tenant_id uuid,
  223 + firmware_id uuid,
210 224 CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name),
211   - CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id)
  225 + CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id),
  226 + CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id)
212 227 );
213 228
214 229 CREATE TABLE IF NOT EXISTS device_credentials (
... ...
... ... @@ -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.*SqlTest"
  27 + "org.thingsboard.server.dao.service.sql.FirmwareServiceSqlTest"
28 28 })
29 29 public class SqlDaoServiceTestSuite {
30 30
... ...
... ... @@ -51,6 +51,7 @@ import org.thingsboard.server.dao.device.DeviceService;
51 51 import org.thingsboard.server.dao.entity.EntityService;
52 52 import org.thingsboard.server.dao.entityview.EntityViewService;
53 53 import org.thingsboard.server.dao.event.EventService;
  54 +import org.thingsboard.server.dao.firmware.FirmwareService;
54 55 import org.thingsboard.server.dao.relation.RelationService;
55 56 import org.thingsboard.server.dao.resource.TbResourceService;
56 57 import org.thingsboard.server.dao.rule.RuleChainService;
... ... @@ -146,6 +147,9 @@ public abstract class AbstractServiceTest {
146 147 @Autowired
147 148 protected TbResourceService resourceService;
148 149
  150 + @Autowired
  151 + protected FirmwareService firmwareService;
  152 +
149 153 class IdComparator<D extends HasId> implements Comparator<D> {
150 154 @Override
151 155 public int compare(D o1, D o2) {
... ... @@ -192,7 +196,7 @@ public abstract class AbstractServiceTest {
192 196
193 197 @Bean
194 198 public AuditLogLevelFilter auditLogLevelFilter() {
195   - Map<String,String> mask = new HashMap<>();
  199 + Map<String, String> mask = new HashMap<>();
196 200 for (EntityType entityType : EntityType.values()) {
197 201 mask.put(entityType.name().toLowerCase(), AuditLogLevelMask.RW.name());
198 202 }
... ...
  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.dao.service;
  17 +
  18 +import com.datastax.oss.driver.api.core.uuid.Uuids;
  19 +import org.junit.After;
  20 +import org.junit.Assert;
  21 +import org.junit.Before;
  22 +import org.junit.Test;
  23 +import org.thingsboard.server.common.data.Device;
  24 +import org.thingsboard.server.common.data.DeviceProfile;
  25 +import org.thingsboard.server.common.data.Firmware;
  26 +import org.thingsboard.server.common.data.FirmwareInfo;
  27 +import org.thingsboard.server.common.data.Tenant;
  28 +import org.thingsboard.server.common.data.id.TenantId;
  29 +import org.thingsboard.server.common.data.page.PageData;
  30 +import org.thingsboard.server.common.data.page.PageLink;
  31 +import org.thingsboard.server.dao.exception.DataValidationException;
  32 +
  33 +import java.nio.ByteBuffer;
  34 +import java.util.ArrayList;
  35 +import java.util.Collections;
  36 +import java.util.List;
  37 +
  38 +public abstract class BaseFirmwareServiceTest extends AbstractServiceTest {
  39 +
  40 + public static final String TITLE = "My firmware";
  41 + private static final String FILE_NAME = "filename.txt";
  42 + private static final String CONTENT_TYPE = "text/plain";
  43 + private static final ByteBuffer DATA = ByteBuffer.wrap(new byte[]{0});
  44 +
  45 + private IdComparator<FirmwareInfo> idComparator = new IdComparator<>();
  46 +
  47 + private TenantId tenantId;
  48 +
  49 + @Before
  50 + public void before() {
  51 + Tenant tenant = new Tenant();
  52 + tenant.setTitle("My tenant");
  53 + Tenant savedTenant = tenantService.saveTenant(tenant);
  54 + Assert.assertNotNull(savedTenant);
  55 + tenantId = savedTenant.getId();
  56 + }
  57 +
  58 + @After
  59 + public void after() {
  60 + tenantService.deleteTenant(tenantId);
  61 + }
  62 +
  63 + @Test
  64 + public void testSaveFirmware() {
  65 + Firmware firmware = new Firmware();
  66 + firmware.setTenantId(tenantId);
  67 + firmware.setTitle(TITLE);
  68 + firmware.setFileName(FILE_NAME);
  69 + firmware.setContentType(CONTENT_TYPE);
  70 + firmware.setData(DATA);
  71 + Firmware savedFirmware = firmwareService.saveFirmware(firmware);
  72 +
  73 + Assert.assertNotNull(savedFirmware);
  74 + Assert.assertNotNull(savedFirmware.getId());
  75 + Assert.assertTrue(savedFirmware.getCreatedTime() > 0);
  76 + Assert.assertEquals(firmware.getTenantId(), savedFirmware.getTenantId());
  77 + Assert.assertEquals(firmware.getTitle(), savedFirmware.getTitle());
  78 + Assert.assertEquals(firmware.getFileName(), savedFirmware.getFileName());
  79 + Assert.assertEquals(firmware.getContentType(), savedFirmware.getContentType());
  80 + Assert.assertEquals(firmware.getData(), savedFirmware.getData());
  81 +
  82 + savedFirmware.setTitle("My new firmware");
  83 + firmwareService.saveFirmware(savedFirmware);
  84 +
  85 + Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, savedFirmware.getId());
  86 + Assert.assertEquals(foundFirmware.getTitle(), savedFirmware.getTitle());
  87 +
  88 + firmwareService.deleteFirmware(tenantId, savedFirmware.getId());
  89 + }
  90 +
  91 + @Test(expected = DataValidationException.class)
  92 + public void testSaveFirmwareWithEmptyTenant() {
  93 + Firmware firmware = new Firmware();
  94 + firmware.setTitle(TITLE);
  95 + firmware.setFileName(FILE_NAME);
  96 + firmware.setContentType(CONTENT_TYPE);
  97 + firmware.setData(DATA);
  98 + firmwareService.saveFirmware(firmware);
  99 + }
  100 +
  101 + @Test(expected = DataValidationException.class)
  102 + public void testSaveFirmwareWithEmptyTitle() {
  103 + Firmware firmware = new Firmware();
  104 + firmware.setTenantId(tenantId);
  105 + firmware.setFileName(FILE_NAME);
  106 + firmware.setContentType(CONTENT_TYPE);
  107 + firmware.setData(DATA);
  108 + firmwareService.saveFirmware(firmware);
  109 + }
  110 +
  111 + @Test(expected = DataValidationException.class)
  112 + public void testSaveFirmwareWithEmptyFileName() {
  113 + Firmware firmware = new Firmware();
  114 + firmware.setTenantId(tenantId);
  115 + firmware.setTitle(TITLE);
  116 + firmware.setContentType(CONTENT_TYPE);
  117 + firmware.setData(DATA);
  118 + firmwareService.saveFirmware(firmware);
  119 + }
  120 +
  121 + @Test(expected = DataValidationException.class)
  122 + public void testSaveFirmwareWithEmptyContentType() {
  123 + Firmware firmware = new Firmware();
  124 + firmware.setTenantId(tenantId);
  125 + firmware.setTitle(TITLE);
  126 + firmware.setFileName(FILE_NAME);
  127 + firmware.setData(DATA);
  128 + firmwareService.saveFirmware(firmware);
  129 + }
  130 +
  131 + @Test(expected = DataValidationException.class)
  132 + public void testSaveFirmwareWithEmptyData() {
  133 + Firmware firmware = new Firmware();
  134 + firmware.setTenantId(tenantId);
  135 + firmware.setTitle(TITLE);
  136 + firmware.setFileName(FILE_NAME);
  137 + firmware.setContentType(CONTENT_TYPE);
  138 + firmwareService.saveFirmware(firmware);
  139 + }
  140 +
  141 + @Test(expected = DataValidationException.class)
  142 + public void testSaveFirmwareWithInvalidTenant() {
  143 + Firmware firmware = new Firmware();
  144 + firmware.setTenantId(new TenantId(Uuids.timeBased()));
  145 + firmware.setTitle(TITLE);
  146 + firmware.setFileName(FILE_NAME);
  147 + firmware.setContentType(CONTENT_TYPE);
  148 + firmware.setData(DATA);
  149 + firmwareService.saveFirmware(firmware);
  150 + }
  151 +
  152 +
  153 +
  154 + @Test(expected = DataValidationException.class)
  155 + public void testDeleteFirmwareWithReferenceByDevice() {
  156 + Firmware firmware = new Firmware();
  157 + firmware.setTenantId(tenantId);
  158 + firmware.setTitle(TITLE);
  159 + firmware.setFileName(FILE_NAME);
  160 + firmware.setContentType(CONTENT_TYPE);
  161 + firmware.setData(DATA);
  162 + Firmware savedFirmware = firmwareService.saveFirmware(firmware);
  163 +
  164 + Device device = new Device();
  165 + device.setTenantId(tenantId);
  166 + device.setName("My device");
  167 + device.setType("default");
  168 + device.setFirmwareId(savedFirmware.getId());
  169 + Device savedDevice = deviceService.saveDevice(device);
  170 +
  171 + try {
  172 + firmwareService.deleteFirmware(tenantId, savedFirmware.getId());
  173 + } finally {
  174 + deviceService.deleteDevice(tenantId, savedDevice.getId());
  175 + firmwareService.deleteFirmware(tenantId, savedFirmware.getId());
  176 + }
  177 + }
  178 +
  179 + @Test(expected = DataValidationException.class)
  180 + public void testDeleteFirmwareWithReferenceByDeviceProfile() {
  181 + Firmware firmware = new Firmware();
  182 + firmware.setTenantId(tenantId);
  183 + firmware.setTitle(TITLE);
  184 + firmware.setFileName(FILE_NAME);
  185 + firmware.setContentType(CONTENT_TYPE);
  186 + firmware.setData(DATA);
  187 + Firmware savedFirmware = firmwareService.saveFirmware(firmware);
  188 +
  189 + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile");
  190 + deviceProfile.setFirmwareId(savedFirmware.getId());
  191 + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile);
  192 +
  193 + try {
  194 + firmwareService.deleteFirmware(tenantId, savedFirmware.getId());
  195 + } finally {
  196 + deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId());
  197 + firmwareService.deleteFirmware(tenantId, savedFirmware.getId());
  198 + }
  199 + }
  200 +
  201 + @Test
  202 + public void testFindFirmwareById() {
  203 + Firmware firmware = new Firmware();
  204 + firmware.setTenantId(tenantId);
  205 + firmware.setTitle(TITLE);
  206 + firmware.setFileName(FILE_NAME);
  207 + firmware.setContentType(CONTENT_TYPE);
  208 + firmware.setData(DATA);
  209 + Firmware savedFirmware = firmwareService.saveFirmware(firmware);
  210 +
  211 + Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, savedFirmware.getId());
  212 + Assert.assertNotNull(foundFirmware);
  213 + Assert.assertEquals(savedFirmware, foundFirmware);
  214 + firmwareService.deleteFirmware(tenantId, savedFirmware.getId());
  215 + }
  216 +
  217 + @Test
  218 + public void testDeleteFirmware() {
  219 + Firmware firmware = new Firmware();
  220 + firmware.setTenantId(tenantId);
  221 + firmware.setTitle(TITLE);
  222 + firmware.setFileName(FILE_NAME);
  223 + firmware.setContentType(CONTENT_TYPE);
  224 + firmware.setData(DATA);
  225 + Firmware savedFirmware = firmwareService.saveFirmware(firmware);
  226 +
  227 + Firmware foundFirmware = firmwareService.findFirmwareById(tenantId, savedFirmware.getId());
  228 + Assert.assertNotNull(foundFirmware);
  229 + firmwareService.deleteFirmware(tenantId, savedFirmware.getId());
  230 + foundFirmware = firmwareService.findFirmwareById(tenantId, savedFirmware.getId());
  231 + Assert.assertNull(foundFirmware);
  232 + }
  233 +
  234 + @Test
  235 + public void testFindTenantFirmwaresByTenantId() {
  236 + List<FirmwareInfo> firmwares = new ArrayList<>();
  237 + for (int i = 0; i < 165; i++) {
  238 + Firmware firmware = new Firmware();
  239 + firmware.setTenantId(tenantId);
  240 + firmware.setTitle(TITLE);
  241 + firmware.setFileName(FILE_NAME);
  242 + firmware.setContentType(CONTENT_TYPE);
  243 + firmware.setData(DATA);
  244 + firmwares.add(new FirmwareInfo(firmwareService.saveFirmware(firmware)));
  245 + }
  246 +
  247 + List<FirmwareInfo> loadedFirmwares = new ArrayList<>();
  248 + PageLink pageLink = new PageLink(16);
  249 + PageData<FirmwareInfo> pageData;
  250 + do {
  251 + pageData = firmwareService.findTenantFirmwaresByTenantId(tenantId, pageLink);
  252 + loadedFirmwares.addAll(pageData.getData());
  253 + if (pageData.hasNext()) {
  254 + pageLink = pageLink.nextPageLink();
  255 + }
  256 + } while (pageData.hasNext());
  257 +
  258 + Collections.sort(firmwares, idComparator);
  259 + Collections.sort(loadedFirmwares, idComparator);
  260 +
  261 + Assert.assertEquals(firmwares, loadedFirmwares);
  262 +
  263 + firmwareService.deleteFirmwaresByTenantId(tenantId);
  264 +
  265 + pageLink = new PageLink(31);
  266 + pageData = firmwareService.findTenantFirmwaresByTenantId(tenantId, pageLink);
  267 + Assert.assertFalse(pageData.hasNext());
  268 + Assert.assertTrue(pageData.getData().isEmpty());
  269 + }
  270 +
  271 +}
... ...
  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.dao.service.sql;
  17 +
  18 +import org.thingsboard.server.dao.service.BaseFirmwareServiceTest;
  19 +import org.thingsboard.server.dao.service.DaoSqlTest;
  20 +
  21 +@DaoSqlTest
  22 +public class FirmwareServiceSqlTest extends BaseFirmwareServiceTest {
  23 +}
... ...
... ... @@ -29,4 +29,5 @@ DROP TABLE IF EXISTS oauth2_client_registration_info;
29 29 DROP TABLE IF EXISTS oauth2_client_registration_template;
30 30 DROP TABLE IF EXISTS api_usage_state;
31 31 DROP TABLE IF EXISTS resource;
  32 +DROP TABLE IF EXISTS firmware;
32 33 DROP FUNCTION IF EXISTS to_uuid;
... ...
... ... @@ -30,3 +30,4 @@ DROP TABLE IF EXISTS oauth2_client_registration_info;
30 30 DROP TABLE IF EXISTS oauth2_client_registration_template;
31 31 DROP TABLE IF EXISTS api_usage_state;
32 32 DROP TABLE IF EXISTS resource;
  33 +DROP TABLE IF EXISTS firmware;
... ...
... ... @@ -28,4 +28,6 @@ DROP TABLE IF EXISTS tb_schema_settings;
28 28 DROP TABLE IF EXISTS oauth2_client_registration;
29 29 DROP TABLE IF EXISTS oauth2_client_registration_info;
30 30 DROP TABLE IF EXISTS oauth2_client_registration_template;
31   -DROP TABLE IF EXISTS api_usage_state;
\ No newline at end of file
  31 +DROP TABLE IF EXISTS api_usage_state;
  32 +DROP TABLE IF EXISTS resource;
  33 +DROP TABLE IF EXISTS firmware;
\ No newline at end of file
... ...