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; | ... | ... |
... | ... | @@ -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 | ... | ... |