Commit 5ca0e05ab57ae1c0aead5a1956bd16a3f80f1d73
Committed by
GitHub
Merge pull request #4524 from thingsboard/feature/sota
FOTA/SOTA
Showing
66 changed files
with
1239 additions
and
263 deletions
@@ -63,6 +63,8 @@ CREATE TABLE IF NOT EXISTS firmware ( | @@ -63,6 +63,8 @@ CREATE TABLE IF NOT EXISTS firmware ( | ||
63 | id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, | 63 | id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, |
64 | created_time bigint NOT NULL, | 64 | created_time bigint NOT NULL, |
65 | tenant_id uuid NOT NULL, | 65 | tenant_id uuid NOT NULL, |
66 | + device_profile_id uuid, | ||
67 | + type varchar(32) NOT NULL, | ||
66 | title varchar(255) NOT NULL, | 68 | title varchar(255) NOT NULL, |
67 | version varchar(255) NOT NULL, | 69 | version varchar(255) NOT NULL, |
68 | file_name varchar(255), | 70 | file_name varchar(255), |
@@ -77,10 +79,12 @@ CREATE TABLE IF NOT EXISTS firmware ( | @@ -77,10 +79,12 @@ CREATE TABLE IF NOT EXISTS firmware ( | ||
77 | ); | 79 | ); |
78 | 80 | ||
79 | ALTER TABLE device_profile | 81 | ALTER TABLE device_profile |
80 | - ADD COLUMN IF NOT EXISTS firmware_id uuid; | 82 | + ADD COLUMN IF NOT EXISTS firmware_id uuid, |
83 | + ADD COLUMN IF NOT EXISTS software_id uuid; | ||
81 | 84 | ||
82 | ALTER TABLE device | 85 | ALTER TABLE device |
83 | - ADD COLUMN IF NOT EXISTS firmware_id uuid; | 86 | + ADD COLUMN IF NOT EXISTS firmware_id uuid, |
87 | + ADD COLUMN IF NOT EXISTS software_id uuid; | ||
84 | 88 | ||
85 | DO $$ | 89 | DO $$ |
86 | BEGIN | 90 | BEGIN |
@@ -90,11 +94,23 @@ DO $$ | @@ -90,11 +94,23 @@ DO $$ | ||
90 | FOREIGN KEY (firmware_id) REFERENCES firmware(id); | 94 | FOREIGN KEY (firmware_id) REFERENCES firmware(id); |
91 | END IF; | 95 | END IF; |
92 | 96 | ||
97 | + IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device_profile') THEN | ||
98 | + ALTER TABLE device_profile | ||
99 | + ADD CONSTRAINT fk_software_device_profile | ||
100 | + FOREIGN KEY (firmware_id) REFERENCES firmware(id); | ||
101 | + END IF; | ||
102 | + | ||
93 | IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device') THEN | 103 | IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device') THEN |
94 | ALTER TABLE device | 104 | ALTER TABLE device |
95 | ADD CONSTRAINT fk_firmware_device | 105 | ADD CONSTRAINT fk_firmware_device |
96 | FOREIGN KEY (firmware_id) REFERENCES firmware(id); | 106 | FOREIGN KEY (firmware_id) REFERENCES firmware(id); |
97 | END IF; | 107 | END IF; |
108 | + | ||
109 | + IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device') THEN | ||
110 | + ALTER TABLE device | ||
111 | + ADD CONSTRAINT fk_software_device | ||
112 | + FOREIGN KEY (firmware_id) REFERENCES firmware(id); | ||
113 | + END IF; | ||
98 | END; | 114 | END; |
99 | $$; | 115 | $$; |
100 | 116 |
@@ -146,12 +146,16 @@ public class DeviceProfileController extends BaseController { | @@ -146,12 +146,16 @@ public class DeviceProfileController extends BaseController { | ||
146 | checkEntity(deviceProfile.getId(), deviceProfile, Resource.DEVICE_PROFILE); | 146 | checkEntity(deviceProfile.getId(), deviceProfile, Resource.DEVICE_PROFILE); |
147 | 147 | ||
148 | boolean isFirmwareChanged = false; | 148 | boolean isFirmwareChanged = false; |
149 | + boolean isSoftwareChanged = false; | ||
149 | 150 | ||
150 | if (!created) { | 151 | if (!created) { |
151 | DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(getTenantId(), deviceProfile.getId()); | 152 | DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(getTenantId(), deviceProfile.getId()); |
152 | if (!Objects.equals(deviceProfile.getFirmwareId(), oldDeviceProfile.getFirmwareId())) { | 153 | if (!Objects.equals(deviceProfile.getFirmwareId(), oldDeviceProfile.getFirmwareId())) { |
153 | isFirmwareChanged = true; | 154 | isFirmwareChanged = true; |
154 | } | 155 | } |
156 | + if (!Objects.equals(deviceProfile.getSoftwareId(), oldDeviceProfile.getSoftwareId())) { | ||
157 | + isSoftwareChanged = true; | ||
158 | + } | ||
155 | } | 159 | } |
156 | 160 | ||
157 | DeviceProfile savedDeviceProfile = checkNotNull(deviceProfileService.saveDeviceProfile(deviceProfile)); | 161 | DeviceProfile savedDeviceProfile = checkNotNull(deviceProfileService.saveDeviceProfile(deviceProfile)); |
@@ -164,9 +168,8 @@ public class DeviceProfileController extends BaseController { | @@ -164,9 +168,8 @@ public class DeviceProfileController extends BaseController { | ||
164 | null, | 168 | null, |
165 | created ? ActionType.ADDED : ActionType.UPDATED, null); | 169 | created ? ActionType.ADDED : ActionType.UPDATED, null); |
166 | 170 | ||
167 | - if (isFirmwareChanged) { | ||
168 | - firmwareStateService.update(savedDeviceProfile); | ||
169 | - } | 171 | + firmwareStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged); |
172 | + | ||
170 | sendEntityNotificationMsg(getTenantId(), savedDeviceProfile.getId(), | 173 | sendEntityNotificationMsg(getTenantId(), savedDeviceProfile.getId(), |
171 | deviceProfile.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); | 174 | deviceProfile.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); |
172 | return savedDeviceProfile; | 175 | return savedDeviceProfile; |
@@ -35,6 +35,8 @@ import org.thingsboard.server.common.data.Firmware; | @@ -35,6 +35,8 @@ import org.thingsboard.server.common.data.Firmware; | ||
35 | import org.thingsboard.server.common.data.FirmwareInfo; | 35 | import org.thingsboard.server.common.data.FirmwareInfo; |
36 | import org.thingsboard.server.common.data.audit.ActionType; | 36 | import org.thingsboard.server.common.data.audit.ActionType; |
37 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 37 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
38 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
39 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
38 | import org.thingsboard.server.common.data.id.FirmwareId; | 40 | import org.thingsboard.server.common.data.id.FirmwareId; |
39 | import org.thingsboard.server.common.data.page.PageData; | 41 | import org.thingsboard.server.common.data.page.PageData; |
40 | import org.thingsboard.server.common.data.page.PageLink; | 42 | import org.thingsboard.server.common.data.page.PageLink; |
@@ -133,6 +135,8 @@ public class FirmwareController extends BaseController { | @@ -133,6 +135,8 @@ public class FirmwareController extends BaseController { | ||
133 | Firmware firmware = new Firmware(firmwareId); | 135 | Firmware firmware = new Firmware(firmwareId); |
134 | firmware.setCreatedTime(info.getCreatedTime()); | 136 | firmware.setCreatedTime(info.getCreatedTime()); |
135 | firmware.setTenantId(getTenantId()); | 137 | firmware.setTenantId(getTenantId()); |
138 | + firmware.setDeviceProfileId(info.getDeviceProfileId()); | ||
139 | + firmware.setType(info.getType()); | ||
136 | firmware.setTitle(info.getTitle()); | 140 | firmware.setTitle(info.getTitle()); |
137 | firmware.setVersion(info.getVersion()); | 141 | firmware.setVersion(info.getVersion()); |
138 | firmware.setAdditionalInfo(info.getAdditionalInfo()); | 142 | firmware.setAdditionalInfo(info.getAdditionalInfo()); |
@@ -175,17 +179,22 @@ public class FirmwareController extends BaseController { | @@ -175,17 +179,22 @@ public class FirmwareController extends BaseController { | ||
175 | } | 179 | } |
176 | 180 | ||
177 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | 181 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
178 | - @RequestMapping(value = "/firmwares/{hasData}", method = RequestMethod.GET) | 182 | + @RequestMapping(value = "/firmwares/{deviceProfileId}/{type}/{hasData}", method = RequestMethod.GET) |
179 | @ResponseBody | 183 | @ResponseBody |
180 | - public PageData<FirmwareInfo> getFirmwares(@PathVariable("hasData") boolean hasData, | 184 | + public PageData<FirmwareInfo> getFirmwares(@PathVariable("deviceProfileId") String strDeviceProfileId, |
185 | + @PathVariable("type") String strType, | ||
186 | + @PathVariable("hasData") boolean hasData, | ||
181 | @RequestParam int pageSize, | 187 | @RequestParam int pageSize, |
182 | @RequestParam int page, | 188 | @RequestParam int page, |
183 | @RequestParam(required = false) String textSearch, | 189 | @RequestParam(required = false) String textSearch, |
184 | @RequestParam(required = false) String sortProperty, | 190 | @RequestParam(required = false) String sortProperty, |
185 | @RequestParam(required = false) String sortOrder) throws ThingsboardException { | 191 | @RequestParam(required = false) String sortOrder) throws ThingsboardException { |
192 | + checkParameter("deviceProfileId", strDeviceProfileId); | ||
193 | + checkParameter("type", strType); | ||
186 | try { | 194 | try { |
187 | PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); | 195 | PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); |
188 | - return checkNotNull(firmwareService.findTenantFirmwaresByTenantIdAndHasData(getTenantId(), hasData, pageLink)); | 196 | + return checkNotNull(firmwareService.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(getTenantId(), |
197 | + new DeviceProfileId(toUUID(strDeviceProfileId)), FirmwareType.valueOf(strType), hasData, pageLink)); | ||
189 | } catch (Exception e) { | 198 | } catch (Exception e) { |
190 | throw handleException(e); | 199 | throw handleException(e); |
191 | } | 200 | } |
@@ -19,13 +19,17 @@ import com.google.common.util.concurrent.FutureCallback; | @@ -19,13 +19,17 @@ import com.google.common.util.concurrent.FutureCallback; | ||
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | import org.springframework.stereotype.Service; | 20 | import org.springframework.stereotype.Service; |
21 | import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; | 21 | import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; |
22 | +import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; | ||
22 | import org.thingsboard.server.common.data.DataConstants; | 23 | import org.thingsboard.server.common.data.DataConstants; |
23 | import org.thingsboard.server.common.data.Device; | 24 | import org.thingsboard.server.common.data.Device; |
24 | import org.thingsboard.server.common.data.DeviceProfile; | 25 | import org.thingsboard.server.common.data.DeviceProfile; |
25 | import org.thingsboard.server.common.data.FirmwareInfo; | 26 | import org.thingsboard.server.common.data.FirmwareInfo; |
27 | +import org.thingsboard.server.common.data.firmware.FirmwareUtil; | ||
28 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
26 | import org.thingsboard.server.common.data.id.DeviceId; | 29 | import org.thingsboard.server.common.data.id.DeviceId; |
27 | import org.thingsboard.server.common.data.id.FirmwareId; | 30 | import org.thingsboard.server.common.data.id.FirmwareId; |
28 | import org.thingsboard.server.common.data.id.TenantId; | 31 | import org.thingsboard.server.common.data.id.TenantId; |
32 | +import org.thingsboard.server.common.data.kv.AttributeKey; | ||
29 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; | 33 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
30 | import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; | 34 | import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
31 | import org.thingsboard.server.common.data.kv.BasicTsKvEntry; | 35 | import org.thingsboard.server.common.data.kv.BasicTsKvEntry; |
@@ -43,37 +47,49 @@ import org.thingsboard.server.queue.TbQueueProducer; | @@ -43,37 +47,49 @@ import org.thingsboard.server.queue.TbQueueProducer; | ||
43 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 47 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
44 | import org.thingsboard.server.queue.provider.TbCoreQueueFactory; | 48 | import org.thingsboard.server.queue.provider.TbCoreQueueFactory; |
45 | import org.thingsboard.server.queue.util.TbCoreComponent; | 49 | import org.thingsboard.server.queue.util.TbCoreComponent; |
50 | +import org.thingsboard.server.service.queue.TbClusterService; | ||
46 | 51 | ||
47 | import javax.annotation.Nullable; | 52 | import javax.annotation.Nullable; |
48 | import java.util.ArrayList; | 53 | import java.util.ArrayList; |
49 | -import java.util.Arrays; | ||
50 | import java.util.Collections; | 54 | import java.util.Collections; |
55 | +import java.util.HashSet; | ||
51 | import java.util.List; | 56 | import java.util.List; |
57 | +import java.util.Set; | ||
52 | import java.util.UUID; | 58 | import java.util.UUID; |
53 | import java.util.function.Consumer; | 59 | import java.util.function.Consumer; |
54 | - | ||
55 | -import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_CHECKSUM; | ||
56 | -import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_CHECKSUM_ALGORITHM; | ||
57 | -import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_SIZE; | ||
58 | -import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_TITLE; | ||
59 | -import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_VERSION; | 60 | +import java.util.function.Function; |
61 | + | ||
62 | +import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM; | ||
63 | +import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM_ALGORITHM; | ||
64 | +import static org.thingsboard.server.common.data.firmware.FirmwareKey.SIZE; | ||
65 | +import static org.thingsboard.server.common.data.firmware.FirmwareKey.STATE; | ||
66 | +import static org.thingsboard.server.common.data.firmware.FirmwareKey.TITLE; | ||
67 | +import static org.thingsboard.server.common.data.firmware.FirmwareKey.TS; | ||
68 | +import static org.thingsboard.server.common.data.firmware.FirmwareKey.VERSION; | ||
69 | +import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getAttributeKey; | ||
70 | +import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getTargetTelemetryKey; | ||
71 | +import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getTelemetryKey; | ||
72 | +import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; | ||
73 | +import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE; | ||
60 | 74 | ||
61 | @Slf4j | 75 | @Slf4j |
62 | @Service | 76 | @Service |
63 | @TbCoreComponent | 77 | @TbCoreComponent |
64 | public class DefaultFirmwareStateService implements FirmwareStateService { | 78 | public class DefaultFirmwareStateService implements FirmwareStateService { |
65 | 79 | ||
80 | + private final TbClusterService tbClusterService; | ||
66 | private final FirmwareService firmwareService; | 81 | private final FirmwareService firmwareService; |
67 | private final DeviceService deviceService; | 82 | private final DeviceService deviceService; |
68 | private final DeviceProfileService deviceProfileService; | 83 | private final DeviceProfileService deviceProfileService; |
69 | private final RuleEngineTelemetryService telemetryService; | 84 | private final RuleEngineTelemetryService telemetryService; |
70 | private final TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> fwStateMsgProducer; | 85 | private final TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> fwStateMsgProducer; |
71 | 86 | ||
72 | - public DefaultFirmwareStateService(FirmwareService firmwareService, | 87 | + public DefaultFirmwareStateService(TbClusterService tbClusterService, FirmwareService firmwareService, |
73 | DeviceService deviceService, | 88 | DeviceService deviceService, |
74 | DeviceProfileService deviceProfileService, | 89 | DeviceProfileService deviceProfileService, |
75 | RuleEngineTelemetryService telemetryService, | 90 | RuleEngineTelemetryService telemetryService, |
76 | TbCoreQueueFactory coreQueueFactory) { | 91 | TbCoreQueueFactory coreQueueFactory) { |
92 | + this.tbClusterService = tbClusterService; | ||
77 | this.firmwareService = firmwareService; | 93 | this.firmwareService = firmwareService; |
78 | this.deviceService = deviceService; | 94 | this.deviceService = deviceService; |
79 | this.deviceProfileService = deviceProfileService; | 95 | this.deviceProfileService = deviceProfileService; |
@@ -83,6 +99,11 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | @@ -83,6 +99,11 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | ||
83 | 99 | ||
84 | @Override | 100 | @Override |
85 | public void update(Device device, Device oldDevice) { | 101 | public void update(Device device, Device oldDevice) { |
102 | + updateFirmware(device, oldDevice); | ||
103 | + updateSoftware(device, oldDevice); | ||
104 | + } | ||
105 | + | ||
106 | + private void updateFirmware(Device device, Device oldDevice) { | ||
86 | FirmwareId newFirmwareId = device.getFirmwareId(); | 107 | FirmwareId newFirmwareId = device.getFirmwareId(); |
87 | if (newFirmwareId == null) { | 108 | if (newFirmwareId == null) { |
88 | DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId()); | 109 | DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId()); |
@@ -97,35 +118,84 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | @@ -97,35 +118,84 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | ||
97 | } | 118 | } |
98 | if (!newFirmwareId.equals(oldFirmwareId)) { | 119 | if (!newFirmwareId.equals(oldFirmwareId)) { |
99 | // Device was updated and new firmware is different from previous firmware. | 120 | // Device was updated and new firmware is different from previous firmware. |
100 | - send(device.getTenantId(), device.getId(), newFirmwareId, System.currentTimeMillis()); | 121 | + send(device.getTenantId(), device.getId(), newFirmwareId, System.currentTimeMillis(), FIRMWARE); |
101 | } | 122 | } |
102 | } else { | 123 | } else { |
103 | // Device was updated and new firmware is not set. | 124 | // Device was updated and new firmware is not set. |
104 | - remove(device); | 125 | + remove(device, FIRMWARE); |
105 | } | 126 | } |
106 | } else if (newFirmwareId != null) { | 127 | } else if (newFirmwareId != null) { |
107 | // Device was created and firmware is defined. | 128 | // Device was created and firmware is defined. |
108 | - send(device.getTenantId(), device.getId(), newFirmwareId, System.currentTimeMillis()); | 129 | + send(device.getTenantId(), device.getId(), newFirmwareId, System.currentTimeMillis(), FIRMWARE); |
130 | + } | ||
131 | + } | ||
132 | + | ||
133 | + private void updateSoftware(Device device, Device oldDevice) { | ||
134 | + FirmwareId newSoftwareId = device.getSoftwareId(); | ||
135 | + if (newSoftwareId == null) { | ||
136 | + DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId()); | ||
137 | + newSoftwareId = newDeviceProfile.getSoftwareId(); | ||
138 | + } | ||
139 | + if (oldDevice != null) { | ||
140 | + if (newSoftwareId != null) { | ||
141 | + FirmwareId oldSoftwareId = oldDevice.getSoftwareId(); | ||
142 | + if (oldSoftwareId == null) { | ||
143 | + DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(oldDevice.getTenantId(), oldDevice.getDeviceProfileId()); | ||
144 | + oldSoftwareId = oldDeviceProfile.getSoftwareId(); | ||
145 | + } | ||
146 | + if (!newSoftwareId.equals(oldSoftwareId)) { | ||
147 | + // Device was updated and new firmware is different from previous firmware. | ||
148 | + send(device.getTenantId(), device.getId(), newSoftwareId, System.currentTimeMillis(), SOFTWARE); | ||
149 | + } | ||
150 | + } else { | ||
151 | + // Device was updated and new firmware is not set. | ||
152 | + remove(device, SOFTWARE); | ||
153 | + } | ||
154 | + } else if (newSoftwareId != null) { | ||
155 | + // Device was created and firmware is defined. | ||
156 | + send(device.getTenantId(), device.getId(), newSoftwareId, System.currentTimeMillis(), SOFTWARE); | ||
109 | } | 157 | } |
110 | } | 158 | } |
111 | 159 | ||
112 | @Override | 160 | @Override |
113 | - public void update(DeviceProfile deviceProfile) { | 161 | + public void update(DeviceProfile deviceProfile, boolean isFirmwareChanged, boolean isSoftwareChanged) { |
114 | TenantId tenantId = deviceProfile.getTenantId(); | 162 | TenantId tenantId = deviceProfile.getTenantId(); |
115 | 163 | ||
164 | + if (isFirmwareChanged) { | ||
165 | + update(tenantId, deviceProfile, FIRMWARE); | ||
166 | + } | ||
167 | + if (isSoftwareChanged) { | ||
168 | + update(tenantId, deviceProfile, SOFTWARE); | ||
169 | + } | ||
170 | + } | ||
171 | + | ||
172 | + private void update(TenantId tenantId, DeviceProfile deviceProfile, FirmwareType firmwareType) { | ||
173 | + Function<PageLink, PageData<Device>> getDevicesFunction; | ||
116 | Consumer<Device> updateConsumer; | 174 | Consumer<Device> updateConsumer; |
175 | + | ||
176 | + switch (firmwareType) { | ||
177 | + case FIRMWARE: | ||
178 | + getDevicesFunction = pl -> deviceService.findDevicesByTenantIdAndTypeAndEmptyFirmware(tenantId, deviceProfile.getName(), pl); | ||
179 | + break; | ||
180 | + case SOFTWARE: | ||
181 | + getDevicesFunction = pl -> deviceService.findDevicesByTenantIdAndTypeAndEmptySoftware(tenantId, deviceProfile.getName(), pl); | ||
182 | + break; | ||
183 | + default: | ||
184 | + log.warn("Unsupported firmware type: [{}]", firmwareType); | ||
185 | + return; | ||
186 | + } | ||
187 | + | ||
117 | if (deviceProfile.getFirmwareId() != null) { | 188 | if (deviceProfile.getFirmwareId() != null) { |
118 | long ts = System.currentTimeMillis(); | 189 | long ts = System.currentTimeMillis(); |
119 | - updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts); | 190 | + updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts, firmwareType); |
120 | } else { | 191 | } else { |
121 | - updateConsumer = this::remove; | 192 | + updateConsumer = d -> remove(d, firmwareType); |
122 | } | 193 | } |
123 | 194 | ||
124 | PageLink pageLink = new PageLink(100); | 195 | PageLink pageLink = new PageLink(100); |
125 | PageData<Device> pageData; | 196 | PageData<Device> pageData; |
126 | do { | 197 | do { |
127 | - pageData = deviceService.findDevicesByTenantIdAndTypeAndEmptyFirmware(tenantId, deviceProfile.getName(), pageLink); | ||
128 | - | 198 | + pageData = getDevicesFunction.apply(pageLink); |
129 | pageData.getData().forEach(updateConsumer); | 199 | pageData.getData().forEach(updateConsumer); |
130 | 200 | ||
131 | if (pageData.hasNext()) { | 201 | if (pageData.hasNext()) { |
@@ -140,16 +210,17 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | @@ -140,16 +210,17 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | ||
140 | FirmwareId targetFirmwareId = new FirmwareId(new UUID(msg.getFirmwareIdMSB(), msg.getFirmwareIdLSB())); | 210 | FirmwareId targetFirmwareId = new FirmwareId(new UUID(msg.getFirmwareIdMSB(), msg.getFirmwareIdLSB())); |
141 | DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB())); | 211 | DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB())); |
142 | TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB())); | 212 | TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB())); |
213 | + FirmwareType firmwareType = FirmwareType.valueOf(msg.getType()); | ||
143 | long ts = msg.getTs(); | 214 | long ts = msg.getTs(); |
144 | 215 | ||
145 | Device device = deviceService.findDeviceById(tenantId, deviceId); | 216 | Device device = deviceService.findDeviceById(tenantId, deviceId); |
146 | if (device == null) { | 217 | if (device == null) { |
147 | log.warn("[{}] [{}] Device was removed during firmware update msg was queued!", tenantId, deviceId); | 218 | log.warn("[{}] [{}] Device was removed during firmware update msg was queued!", tenantId, deviceId); |
148 | } else { | 219 | } else { |
149 | - FirmwareId currentFirmwareId = device.getFirmwareId(); | ||
150 | - | 220 | + FirmwareId currentFirmwareId = FirmwareUtil.getFirmwareId(device, firmwareType); |
151 | if (currentFirmwareId == null) { | 221 | if (currentFirmwareId == null) { |
152 | - currentFirmwareId = deviceProfileService.findDeviceProfileById(tenantId, device.getDeviceProfileId()).getFirmwareId(); | 222 | + DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(tenantId, device.getDeviceProfileId()); |
223 | + currentFirmwareId = FirmwareUtil.getFirmwareId(deviceProfile, firmwareType); | ||
153 | } | 224 | } |
154 | 225 | ||
155 | if (targetFirmwareId.equals(currentFirmwareId)) { | 226 | if (targetFirmwareId.equals(currentFirmwareId)) { |
@@ -162,7 +233,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | @@ -162,7 +233,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | ||
162 | return isSuccess; | 233 | return isSuccess; |
163 | } | 234 | } |
164 | 235 | ||
165 | - private void send(TenantId tenantId, DeviceId deviceId, FirmwareId firmwareId, long ts) { | 236 | + private void send(TenantId tenantId, DeviceId deviceId, FirmwareId firmwareId, long ts, FirmwareType firmwareType) { |
166 | ToFirmwareStateServiceMsg msg = ToFirmwareStateServiceMsg.newBuilder() | 237 | ToFirmwareStateServiceMsg msg = ToFirmwareStateServiceMsg.newBuilder() |
167 | .setTenantIdMSB(tenantId.getId().getMostSignificantBits()) | 238 | .setTenantIdMSB(tenantId.getId().getMostSignificantBits()) |
168 | .setTenantIdLSB(tenantId.getId().getLeastSignificantBits()) | 239 | .setTenantIdLSB(tenantId.getId().getLeastSignificantBits()) |
@@ -170,6 +241,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | @@ -170,6 +241,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | ||
170 | .setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()) | 241 | .setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()) |
171 | .setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits()) | 242 | .setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits()) |
172 | .setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits()) | 243 | .setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits()) |
244 | + .setType(firmwareType.name()) | ||
173 | .setTs(ts) | 245 | .setTs(ts) |
174 | .build(); | 246 | .build(); |
175 | 247 | ||
@@ -183,10 +255,10 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | @@ -183,10 +255,10 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | ||
183 | fwStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null); | 255 | fwStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null); |
184 | 256 | ||
185 | List<TsKvEntry> telemetry = new ArrayList<>(); | 257 | List<TsKvEntry> telemetry = new ArrayList<>(); |
186 | - telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.TARGET_FIRMWARE_TITLE, firmware.getTitle()))); | ||
187 | - telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.TARGET_FIRMWARE_VERSION, firmware.getVersion()))); | ||
188 | - telemetry.add(new BasicTsKvEntry(ts, new LongDataEntry(DataConstants.TARGET_FIRMWARE_TS, ts))); | ||
189 | - telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_STATE, FirmwareUpdateStatus.QUEUED.name()))); | 258 | + telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), TITLE), firmware.getTitle()))); |
259 | + telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), VERSION), firmware.getVersion()))); | ||
260 | + telemetry.add(new BasicTsKvEntry(ts, new LongDataEntry(getTargetTelemetryKey(firmware.getType(), TS), ts))); | ||
261 | + telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), FirmwareUpdateStatus.QUEUED.name()))); | ||
190 | 262 | ||
191 | telemetryService.saveAndNotify(tenantId, deviceId, telemetry, new FutureCallback<>() { | 263 | telemetryService.saveAndNotify(tenantId, deviceId, telemetry, new FutureCallback<>() { |
192 | @Override | 264 | @Override |
@@ -206,7 +278,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | @@ -206,7 +278,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | ||
206 | TenantId tenantId = device.getTenantId(); | 278 | TenantId tenantId = device.getTenantId(); |
207 | DeviceId deviceId = device.getId(); | 279 | DeviceId deviceId = device.getId(); |
208 | 280 | ||
209 | - BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(DataConstants.FIRMWARE_STATE, FirmwareUpdateStatus.INITIATED.name())); | 281 | + BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), FirmwareUpdateStatus.INITIATED.name())); |
210 | 282 | ||
211 | telemetryService.saveAndNotify(tenantId, deviceId, Collections.singletonList(status), new FutureCallback<>() { | 283 | telemetryService.saveAndNotify(tenantId, deviceId, Collections.singletonList(status), new FutureCallback<>() { |
212 | @Override | 284 | @Override |
@@ -221,13 +293,12 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | @@ -221,13 +293,12 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | ||
221 | }); | 293 | }); |
222 | 294 | ||
223 | List<AttributeKvEntry> attributes = new ArrayList<>(); | 295 | List<AttributeKvEntry> attributes = new ArrayList<>(); |
296 | + attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), TITLE), firmware.getTitle()))); | ||
297 | + attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), VERSION), firmware.getVersion()))); | ||
298 | + attributes.add(new BaseAttributeKvEntry(ts, new LongDataEntry(getAttributeKey(firmware.getType(), SIZE), firmware.getDataSize()))); | ||
299 | + attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), CHECKSUM_ALGORITHM), firmware.getChecksumAlgorithm()))); | ||
300 | + attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), CHECKSUM), firmware.getChecksum()))); | ||
224 | 301 | ||
225 | - attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_TITLE, firmware.getTitle()))); | ||
226 | - attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_VERSION, firmware.getVersion()))); | ||
227 | - | ||
228 | - attributes.add(new BaseAttributeKvEntry(ts, new LongDataEntry(FIRMWARE_SIZE, firmware.getDataSize()))); | ||
229 | - attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_CHECKSUM_ALGORITHM, firmware.getChecksumAlgorithm()))); | ||
230 | - attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_CHECKSUM, firmware.getChecksum()))); | ||
231 | telemetryService.saveAndNotify(tenantId, deviceId, DataConstants.SHARED_SCOPE, attributes, new FutureCallback<>() { | 302 | telemetryService.saveAndNotify(tenantId, deviceId, DataConstants.SHARED_SCOPE, attributes, new FutureCallback<>() { |
232 | @Override | 303 | @Override |
233 | public void onSuccess(@Nullable Void tmp) { | 304 | public void onSuccess(@Nullable Void tmp) { |
@@ -241,13 +312,15 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | @@ -241,13 +312,15 @@ public class DefaultFirmwareStateService implements FirmwareStateService { | ||
241 | }); | 312 | }); |
242 | } | 313 | } |
243 | 314 | ||
244 | - private void remove(Device device) { | ||
245 | - telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, | ||
246 | - Arrays.asList(FIRMWARE_TITLE, FIRMWARE_VERSION, FIRMWARE_SIZE, FIRMWARE_CHECKSUM_ALGORITHM, FIRMWARE_CHECKSUM), | 315 | + private void remove(Device device, FirmwareType firmwareType) { |
316 | + telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, FirmwareUtil.getAttributeKeys(firmwareType), | ||
247 | new FutureCallback<>() { | 317 | new FutureCallback<>() { |
248 | @Override | 318 | @Override |
249 | public void onSuccess(@Nullable Void tmp) { | 319 | public void onSuccess(@Nullable Void tmp) { |
250 | log.trace("[{}] Success remove target firmware attributes!", device.getId()); | 320 | log.trace("[{}] Success remove target firmware attributes!", device.getId()); |
321 | + Set<AttributeKey> keysToNotify = new HashSet<>(); | ||
322 | + FirmwareUtil.ALL_FW_ATTRIBUTE_KEYS.forEach(key -> keysToNotify.add(new AttributeKey(DataConstants.SHARED_SCOPE, key))); | ||
323 | + tbClusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onDelete(device.getTenantId(), device.getId(), keysToNotify), null); | ||
251 | } | 324 | } |
252 | 325 | ||
253 | @Override | 326 | @Override |
@@ -23,7 +23,7 @@ public interface FirmwareStateService { | @@ -23,7 +23,7 @@ public interface FirmwareStateService { | ||
23 | 23 | ||
24 | void update(Device device, Device oldDevice); | 24 | void update(Device device, Device oldDevice); |
25 | 25 | ||
26 | - void update(DeviceProfile deviceProfile); | 26 | + void update(DeviceProfile deviceProfile, boolean isFirmwareChanged, boolean isSoftwareChanged); |
27 | 27 | ||
28 | boolean process(ToFirmwareStateServiceMsg msg); | 28 | boolean process(ToFirmwareStateServiceMsg msg); |
29 | 29 |
@@ -41,6 +41,8 @@ import org.thingsboard.server.common.data.TenantProfile; | @@ -41,6 +41,8 @@ import org.thingsboard.server.common.data.TenantProfile; | ||
41 | import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; | 41 | import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; |
42 | import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData; | 42 | import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData; |
43 | import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; | 43 | import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; |
44 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
45 | +import org.thingsboard.server.common.data.firmware.FirmwareUtil; | ||
44 | import org.thingsboard.server.common.data.id.CustomerId; | 46 | import org.thingsboard.server.common.data.id.CustomerId; |
45 | import org.thingsboard.server.common.data.id.DeviceId; | 47 | import org.thingsboard.server.common.data.id.DeviceId; |
46 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 48 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
@@ -512,16 +514,17 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -512,16 +514,17 @@ public class DefaultTransportApiService implements TransportApiService { | ||
512 | private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.GetFirmwareRequestMsg requestMsg) { | 514 | private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.GetFirmwareRequestMsg requestMsg) { |
513 | TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); | 515 | TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); |
514 | DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); | 516 | DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); |
517 | + FirmwareType firmwareType = FirmwareType.valueOf(requestMsg.getType()); | ||
515 | Device device = deviceService.findDeviceById(tenantId, deviceId); | 518 | Device device = deviceService.findDeviceById(tenantId, deviceId); |
516 | 519 | ||
517 | if (device == null) { | 520 | if (device == null) { |
518 | return getEmptyTransportApiResponseFuture(); | 521 | return getEmptyTransportApiResponseFuture(); |
519 | } | 522 | } |
520 | 523 | ||
521 | - FirmwareId firmwareId = device.getFirmwareId(); | ||
522 | - | 524 | + FirmwareId firmwareId = FirmwareUtil.getFirmwareId(device, firmwareType); |
523 | if (firmwareId == null) { | 525 | if (firmwareId == null) { |
524 | - firmwareId = deviceProfileCache.find(device.getDeviceProfileId()).getFirmwareId(); | 526 | + DeviceProfile deviceProfile = deviceProfileCache.find(device.getDeviceProfileId()); |
527 | + firmwareId = FirmwareUtil.getFirmwareId(deviceProfile, firmwareType); | ||
525 | } | 528 | } |
526 | 529 | ||
527 | TransportProtos.GetFirmwareResponseMsg.Builder builder = TransportProtos.GetFirmwareResponseMsg.newBuilder(); | 530 | TransportProtos.GetFirmwareResponseMsg.Builder builder = TransportProtos.GetFirmwareResponseMsg.newBuilder(); |
@@ -537,6 +540,7 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -537,6 +540,7 @@ public class DefaultTransportApiService implements TransportApiService { | ||
537 | builder.setResponseStatus(TransportProtos.ResponseStatus.SUCCESS); | 540 | builder.setResponseStatus(TransportProtos.ResponseStatus.SUCCESS); |
538 | builder.setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits()); | 541 | builder.setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits()); |
539 | builder.setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits()); | 542 | builder.setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits()); |
543 | + builder.setType(firmwareInfo.getType().name()); | ||
540 | builder.setTitle(firmwareInfo.getTitle()); | 544 | builder.setTitle(firmwareInfo.getTitle()); |
541 | builder.setVersion(firmwareInfo.getVersion()); | 545 | builder.setVersion(firmwareInfo.getVersion()); |
542 | builder.setFileName(firmwareInfo.getFileName()); | 546 | builder.setFileName(firmwareInfo.getFileName()); |
@@ -24,10 +24,13 @@ import org.springframework.mock.web.MockMultipartFile; | @@ -24,10 +24,13 @@ import org.springframework.mock.web.MockMultipartFile; | ||
24 | import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; | 24 | import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; |
25 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; | 25 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; |
26 | import org.thingsboard.common.util.JacksonUtil; | 26 | import org.thingsboard.common.util.JacksonUtil; |
27 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
27 | import org.thingsboard.server.common.data.Firmware; | 28 | import org.thingsboard.server.common.data.Firmware; |
28 | import org.thingsboard.server.common.data.FirmwareInfo; | 29 | import org.thingsboard.server.common.data.FirmwareInfo; |
29 | import org.thingsboard.server.common.data.Tenant; | 30 | import org.thingsboard.server.common.data.Tenant; |
30 | import org.thingsboard.server.common.data.User; | 31 | import org.thingsboard.server.common.data.User; |
32 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
33 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
31 | import org.thingsboard.server.common.data.page.PageData; | 34 | import org.thingsboard.server.common.data.page.PageData; |
32 | import org.thingsboard.server.common.data.page.PageLink; | 35 | import org.thingsboard.server.common.data.page.PageLink; |
33 | import org.thingsboard.server.common.data.security.Authority; | 36 | import org.thingsboard.server.common.data.security.Authority; |
@@ -38,6 +41,7 @@ import java.util.Collections; | @@ -38,6 +41,7 @@ import java.util.Collections; | ||
38 | import java.util.List; | 41 | import java.util.List; |
39 | 42 | ||
40 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | 43 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
44 | +import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; | ||
41 | 45 | ||
42 | public abstract class BaseFirmwareControllerTest extends AbstractControllerTest { | 46 | public abstract class BaseFirmwareControllerTest extends AbstractControllerTest { |
43 | 47 | ||
@@ -53,6 +57,7 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -53,6 +57,7 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
53 | 57 | ||
54 | private Tenant savedTenant; | 58 | private Tenant savedTenant; |
55 | private User tenantAdmin; | 59 | private User tenantAdmin; |
60 | + private DeviceProfileId deviceProfileId; | ||
56 | 61 | ||
57 | @Before | 62 | @Before |
58 | public void beforeTest() throws Exception { | 63 | public void beforeTest() throws Exception { |
@@ -71,6 +76,11 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -71,6 +76,11 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
71 | tenantAdmin.setLastName("Downs"); | 76 | tenantAdmin.setLastName("Downs"); |
72 | 77 | ||
73 | tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); | 78 | tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); |
79 | + | ||
80 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile", null); | ||
81 | + DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); | ||
82 | + Assert.assertNotNull(savedDeviceProfile); | ||
83 | + deviceProfileId = savedDeviceProfile.getId(); | ||
74 | } | 84 | } |
75 | 85 | ||
76 | @After | 86 | @After |
@@ -84,6 +94,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -84,6 +94,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
84 | @Test | 94 | @Test |
85 | public void testSaveFirmware() throws Exception { | 95 | public void testSaveFirmware() throws Exception { |
86 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 96 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
97 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
98 | + firmwareInfo.setType(FIRMWARE); | ||
87 | firmwareInfo.setTitle(TITLE); | 99 | firmwareInfo.setTitle(TITLE); |
88 | firmwareInfo.setVersion(VERSION); | 100 | firmwareInfo.setVersion(VERSION); |
89 | 101 | ||
@@ -107,6 +119,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -107,6 +119,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
107 | @Test | 119 | @Test |
108 | public void testSaveFirmwareData() throws Exception { | 120 | public void testSaveFirmwareData() throws Exception { |
109 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 121 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
122 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
123 | + firmwareInfo.setType(FIRMWARE); | ||
110 | firmwareInfo.setTitle(TITLE); | 124 | firmwareInfo.setTitle(TITLE); |
111 | firmwareInfo.setVersion(VERSION); | 125 | firmwareInfo.setVersion(VERSION); |
112 | 126 | ||
@@ -137,6 +151,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -137,6 +151,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
137 | @Test | 151 | @Test |
138 | public void testUpdateFirmwareFromDifferentTenant() throws Exception { | 152 | public void testUpdateFirmwareFromDifferentTenant() throws Exception { |
139 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 153 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
154 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
155 | + firmwareInfo.setType(FIRMWARE); | ||
140 | firmwareInfo.setTitle(TITLE); | 156 | firmwareInfo.setTitle(TITLE); |
141 | firmwareInfo.setVersion(VERSION); | 157 | firmwareInfo.setVersion(VERSION); |
142 | 158 | ||
@@ -150,6 +166,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -150,6 +166,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
150 | @Test | 166 | @Test |
151 | public void testFindFirmwareInfoById() throws Exception { | 167 | public void testFindFirmwareInfoById() throws Exception { |
152 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 168 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
169 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
170 | + firmwareInfo.setType(FIRMWARE); | ||
153 | firmwareInfo.setTitle(TITLE); | 171 | firmwareInfo.setTitle(TITLE); |
154 | firmwareInfo.setVersion(VERSION); | 172 | firmwareInfo.setVersion(VERSION); |
155 | 173 | ||
@@ -163,6 +181,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -163,6 +181,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
163 | @Test | 181 | @Test |
164 | public void testFindFirmwareById() throws Exception { | 182 | public void testFindFirmwareById() throws Exception { |
165 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 183 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
184 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
185 | + firmwareInfo.setType(FIRMWARE); | ||
166 | firmwareInfo.setTitle(TITLE); | 186 | firmwareInfo.setTitle(TITLE); |
167 | firmwareInfo.setVersion(VERSION); | 187 | firmwareInfo.setVersion(VERSION); |
168 | 188 | ||
@@ -180,6 +200,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -180,6 +200,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
180 | @Test | 200 | @Test |
181 | public void testDeleteFirmware() throws Exception { | 201 | public void testDeleteFirmware() throws Exception { |
182 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 202 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
203 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
204 | + firmwareInfo.setType(FIRMWARE); | ||
183 | firmwareInfo.setTitle(TITLE); | 205 | firmwareInfo.setTitle(TITLE); |
184 | firmwareInfo.setVersion(VERSION); | 206 | firmwareInfo.setVersion(VERSION); |
185 | 207 | ||
@@ -197,6 +219,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -197,6 +219,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
197 | List<FirmwareInfo> firmwares = new ArrayList<>(); | 219 | List<FirmwareInfo> firmwares = new ArrayList<>(); |
198 | for (int i = 0; i < 165; i++) { | 220 | for (int i = 0; i < 165; i++) { |
199 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 221 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
222 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
223 | + firmwareInfo.setType(FIRMWARE); | ||
200 | firmwareInfo.setTitle(TITLE); | 224 | firmwareInfo.setTitle(TITLE); |
201 | firmwareInfo.setVersion(VERSION + i); | 225 | firmwareInfo.setVersion(VERSION + i); |
202 | 226 | ||
@@ -238,6 +262,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -238,6 +262,8 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
238 | 262 | ||
239 | for (int i = 0; i < 165; i++) { | 263 | for (int i = 0; i < 165; i++) { |
240 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 264 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
265 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
266 | + firmwareInfo.setType(FIRMWARE); | ||
241 | firmwareInfo.setTitle(TITLE); | 267 | firmwareInfo.setTitle(TITLE); |
242 | firmwareInfo.setVersion(VERSION + i); | 268 | firmwareInfo.setVersion(VERSION + i); |
243 | 269 | ||
@@ -257,7 +283,7 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -257,7 +283,7 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
257 | PageLink pageLink = new PageLink(24); | 283 | PageLink pageLink = new PageLink(24); |
258 | PageData<FirmwareInfo> pageData; | 284 | PageData<FirmwareInfo> pageData; |
259 | do { | 285 | do { |
260 | - pageData = doGetTypedWithPageLink("/api/firmwares/true?", | 286 | + pageData = doGetTypedWithPageLink("/api/firmwares/" + deviceProfileId.toString() + "/FIRMWARE/true?", |
261 | new TypeReference<>() { | 287 | new TypeReference<>() { |
262 | }, pageLink); | 288 | }, pageLink); |
263 | loadedFirmwaresWithData.addAll(pageData.getData()); | 289 | loadedFirmwaresWithData.addAll(pageData.getData()); |
@@ -269,7 +295,7 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | @@ -269,7 +295,7 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest | ||
269 | List<FirmwareInfo> loadedFirmwaresWithoutData = new ArrayList<>(); | 295 | List<FirmwareInfo> loadedFirmwaresWithoutData = new ArrayList<>(); |
270 | pageLink = new PageLink(24); | 296 | pageLink = new PageLink(24); |
271 | do { | 297 | do { |
272 | - pageData = doGetTypedWithPageLink("/api/firmwares/false?", | 298 | + pageData = doGetTypedWithPageLink("/api/firmwares/" + deviceProfileId.toString() + "/FIRMWARE/false?", |
273 | new TypeReference<>() { | 299 | new TypeReference<>() { |
274 | }, pageLink); | 300 | }, pageLink); |
275 | loadedFirmwaresWithoutData.addAll(pageData.getData()); | 301 | loadedFirmwaresWithoutData.addAll(pageData.getData()); |
@@ -65,6 +65,8 @@ public interface DeviceService { | @@ -65,6 +65,8 @@ public interface DeviceService { | ||
65 | 65 | ||
66 | PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(TenantId tenantId, String type, PageLink pageLink); | 66 | PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(TenantId tenantId, String type, PageLink pageLink); |
67 | 67 | ||
68 | + PageData<Device> findDevicesByTenantIdAndTypeAndEmptySoftware(TenantId tenantId, String type, PageLink pageLink); | ||
69 | + | ||
68 | PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink); | 70 | PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink); |
69 | 71 | ||
70 | PageData<DeviceInfo> findDeviceInfosByTenantIdAndDeviceProfileId(TenantId tenantId, DeviceProfileId deviceProfileId, PageLink pageLink); | 72 | PageData<DeviceInfo> findDeviceInfosByTenantIdAndDeviceProfileId(TenantId tenantId, DeviceProfileId deviceProfileId, PageLink pageLink); |
@@ -18,6 +18,8 @@ package org.thingsboard.server.dao.firmware; | @@ -18,6 +18,8 @@ package org.thingsboard.server.dao.firmware; | ||
18 | import com.google.common.util.concurrent.ListenableFuture; | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | import org.thingsboard.server.common.data.Firmware; | 19 | import org.thingsboard.server.common.data.Firmware; |
20 | import org.thingsboard.server.common.data.FirmwareInfo; | 20 | import org.thingsboard.server.common.data.FirmwareInfo; |
21 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
22 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
21 | import org.thingsboard.server.common.data.id.FirmwareId; | 23 | import org.thingsboard.server.common.data.id.FirmwareId; |
22 | import org.thingsboard.server.common.data.id.TenantId; | 24 | import org.thingsboard.server.common.data.id.TenantId; |
23 | import org.thingsboard.server.common.data.page.PageData; | 25 | import org.thingsboard.server.common.data.page.PageData; |
@@ -37,7 +39,7 @@ public interface FirmwareService { | @@ -37,7 +39,7 @@ public interface FirmwareService { | ||
37 | 39 | ||
38 | PageData<FirmwareInfo> findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink); | 40 | PageData<FirmwareInfo> findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink); |
39 | 41 | ||
40 | - PageData<FirmwareInfo> findTenantFirmwaresByTenantIdAndHasData(TenantId tenantId, boolean hasData, PageLink pageLink); | 42 | + PageData<FirmwareInfo> findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink); |
41 | 43 | ||
42 | void deleteFirmware(TenantId tenantId, FirmwareId firmwareId); | 44 | void deleteFirmware(TenantId tenantId, FirmwareId firmwareId); |
43 | 45 |
@@ -93,22 +93,26 @@ public class DataConstants { | @@ -93,22 +93,26 @@ public class DataConstants { | ||
93 | public static final String USERNAME = "username"; | 93 | public static final String USERNAME = "username"; |
94 | public static final String PASSWORD = "password"; | 94 | public static final String PASSWORD = "password"; |
95 | 95 | ||
96 | - //firmware | ||
97 | - //telemetry | ||
98 | - public static final String CURRENT_FIRMWARE_TITLE = "current_fw_title"; | ||
99 | - public static final String CURRENT_FIRMWARE_VERSION = "current_fw_version"; | ||
100 | - public static final String TARGET_FIRMWARE_TITLE = "target_fw_title"; | ||
101 | - public static final String TARGET_FIRMWARE_VERSION = "target_fw_version"; | ||
102 | - public static final String TARGET_FIRMWARE_TS = "target_fw_ts"; | ||
103 | - public static final String FIRMWARE_STATE = "fw_state"; | ||
104 | - | ||
105 | - //attributes | ||
106 | - //telemetry | ||
107 | - public static final String FIRMWARE_TITLE = "fw_title"; | ||
108 | - public static final String FIRMWARE_VERSION = "fw_version"; | ||
109 | - public static final String FIRMWARE_SIZE = "fw_size"; | ||
110 | - public static final String FIRMWARE_CHECKSUM = "fw_checksum"; | ||
111 | - public static final String FIRMWARE_CHECKSUM_ALGORITHM = "fw_checksum_algorithm"; | 96 | +//<<<<<<< HEAD |
97 | +//======= | ||
98 | +// //firmware | ||
99 | +// //telemetry | ||
100 | +// public static final String CURRENT_FIRMWARE_TITLE = "current_fw_title"; | ||
101 | +// public static final String CURRENT_FIRMWARE_VERSION = "current_fw_version"; | ||
102 | +// public static final String TARGET_FIRMWARE_TITLE = "target_fw_title"; | ||
103 | +// public static final String TARGET_FIRMWARE_VERSION = "target_fw_version"; | ||
104 | +// public static final String TARGET_FIRMWARE_TS = "target_fw_ts"; | ||
105 | +// public static final String FIRMWARE_STATE = "fw_state"; | ||
106 | +// | ||
107 | +// //attributes | ||
108 | +// //telemetry | ||
109 | +// public static final String FIRMWARE_TITLE = "fw_title"; | ||
110 | +// public static final String FIRMWARE_VERSION = "fw_version"; | ||
111 | +// public static final String FIRMWARE_SIZE = "fw_size"; | ||
112 | +// public static final String FIRMWARE_CHECKSUM = "fw_checksum"; | ||
113 | +// public static final String FIRMWARE_CHECKSUM_ALGORITHM = "fw_checksum_algorithm"; | ||
114 | +//>>>>>>> origin/master | ||
112 | public static final String EDGE_MSG_SOURCE = "edge"; | 115 | public static final String EDGE_MSG_SOURCE = "edge"; |
113 | public static final String MSG_SOURCE_KEY = "source"; | 116 | public static final String MSG_SOURCE_KEY = "source"; |
117 | + | ||
114 | } | 118 | } |
@@ -32,7 +32,7 @@ import java.io.IOException; | @@ -32,7 +32,7 @@ import java.io.IOException; | ||
32 | 32 | ||
33 | @EqualsAndHashCode(callSuper = true) | 33 | @EqualsAndHashCode(callSuper = true) |
34 | @Slf4j | 34 | @Slf4j |
35 | -public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasName, HasTenantId, HasCustomerId { | 35 | +public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasName, HasTenantId, HasCustomerId, HasFirmware { |
36 | 36 | ||
37 | private static final long serialVersionUID = 2807343040519543363L; | 37 | private static final long serialVersionUID = 2807343040519543363L; |
38 | 38 | ||
@@ -50,6 +50,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -50,6 +50,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
50 | private byte[] deviceDataBytes; | 50 | private byte[] deviceDataBytes; |
51 | 51 | ||
52 | private FirmwareId firmwareId; | 52 | private FirmwareId firmwareId; |
53 | + private FirmwareId softwareId; | ||
53 | 54 | ||
54 | public Device() { | 55 | public Device() { |
55 | super(); | 56 | super(); |
@@ -69,6 +70,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -69,6 +70,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
69 | this.deviceProfileId = device.getDeviceProfileId(); | 70 | this.deviceProfileId = device.getDeviceProfileId(); |
70 | this.setDeviceData(device.getDeviceData()); | 71 | this.setDeviceData(device.getDeviceData()); |
71 | this.firmwareId = device.getFirmwareId(); | 72 | this.firmwareId = device.getFirmwareId(); |
73 | + this.softwareId = device.getSoftwareId(); | ||
72 | } | 74 | } |
73 | 75 | ||
74 | public Device updateDevice(Device device) { | 76 | public Device updateDevice(Device device) { |
@@ -79,6 +81,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -79,6 +81,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
79 | this.label = device.getLabel(); | 81 | this.label = device.getLabel(); |
80 | this.deviceProfileId = device.getDeviceProfileId(); | 82 | this.deviceProfileId = device.getDeviceProfileId(); |
81 | this.setDeviceData(device.getDeviceData()); | 83 | this.setDeviceData(device.getDeviceData()); |
84 | + this.setFirmwareId(device.getFirmwareId()); | ||
85 | + this.setSoftwareId(device.getSoftwareId()); | ||
82 | return this; | 86 | return this; |
83 | } | 87 | } |
84 | 88 | ||
@@ -171,6 +175,14 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -171,6 +175,14 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
171 | this.firmwareId = firmwareId; | 175 | this.firmwareId = firmwareId; |
172 | } | 176 | } |
173 | 177 | ||
178 | + public FirmwareId getSoftwareId() { | ||
179 | + return softwareId; | ||
180 | + } | ||
181 | + | ||
182 | + public void setSoftwareId(FirmwareId softwareId) { | ||
183 | + this.softwareId = softwareId; | ||
184 | + } | ||
185 | + | ||
174 | @Override | 186 | @Override |
175 | public String toString() { | 187 | public String toString() { |
176 | StringBuilder builder = new StringBuilder(); | 188 | StringBuilder builder = new StringBuilder(); |
@@ -36,7 +36,7 @@ import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalIn | @@ -36,7 +36,7 @@ import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalIn | ||
36 | @Data | 36 | @Data |
37 | @EqualsAndHashCode(callSuper = true) | 37 | @EqualsAndHashCode(callSuper = true) |
38 | @Slf4j | 38 | @Slf4j |
39 | -public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements HasName, HasTenantId { | 39 | +public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements HasName, HasTenantId, HasFirmware { |
40 | 40 | ||
41 | private TenantId tenantId; | 41 | private TenantId tenantId; |
42 | @NoXss | 42 | @NoXss |
@@ -59,6 +59,8 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H | @@ -59,6 +59,8 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H | ||
59 | 59 | ||
60 | private FirmwareId firmwareId; | 60 | private FirmwareId firmwareId; |
61 | 61 | ||
62 | + private FirmwareId softwareId; | ||
63 | + | ||
62 | public DeviceProfile() { | 64 | public DeviceProfile() { |
63 | super(); | 65 | super(); |
64 | } | 66 | } |
@@ -77,6 +79,8 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H | @@ -77,6 +79,8 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H | ||
77 | this.defaultQueueName = deviceProfile.getDefaultQueueName(); | 79 | this.defaultQueueName = deviceProfile.getDefaultQueueName(); |
78 | this.setProfileData(deviceProfile.getProfileData()); | 80 | this.setProfileData(deviceProfile.getProfileData()); |
79 | this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey(); | 81 | this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey(); |
82 | + this.firmwareId = deviceProfile.getFirmwareId(); | ||
83 | + this.softwareId = deviceProfile.getSoftwareId(); | ||
80 | } | 84 | } |
81 | 85 | ||
82 | @Override | 86 | @Override |
@@ -19,6 +19,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | @@ -19,6 +19,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | import lombok.Data; | 19 | import lombok.Data; |
20 | import lombok.EqualsAndHashCode; | 20 | import lombok.EqualsAndHashCode; |
21 | import lombok.extern.slf4j.Slf4j; | 21 | import lombok.extern.slf4j.Slf4j; |
22 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
23 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
22 | import org.thingsboard.server.common.data.id.FirmwareId; | 24 | import org.thingsboard.server.common.data.id.FirmwareId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 25 | import org.thingsboard.server.common.data.id.TenantId; |
24 | 26 | ||
@@ -30,6 +32,8 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId> | @@ -30,6 +32,8 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId> | ||
30 | private static final long serialVersionUID = 3168391583570815419L; | 32 | private static final long serialVersionUID = 3168391583570815419L; |
31 | 33 | ||
32 | private TenantId tenantId; | 34 | private TenantId tenantId; |
35 | + private DeviceProfileId deviceProfileId; | ||
36 | + private FirmwareType type; | ||
33 | private String title; | 37 | private String title; |
34 | private String version; | 38 | private String version; |
35 | private boolean hasData; | 39 | private boolean hasData; |
@@ -51,6 +55,8 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId> | @@ -51,6 +55,8 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId> | ||
51 | public FirmwareInfo(FirmwareInfo firmwareInfo) { | 55 | public FirmwareInfo(FirmwareInfo firmwareInfo) { |
52 | super(firmwareInfo); | 56 | super(firmwareInfo); |
53 | this.tenantId = firmwareInfo.getTenantId(); | 57 | this.tenantId = firmwareInfo.getTenantId(); |
58 | + this.deviceProfileId = firmwareInfo.getDeviceProfileId(); | ||
59 | + this.type = firmwareInfo.getType(); | ||
54 | this.title = firmwareInfo.getTitle(); | 60 | this.title = firmwareInfo.getTitle(); |
55 | this.version = firmwareInfo.getVersion(); | 61 | this.version = firmwareInfo.getVersion(); |
56 | this.hasData = firmwareInfo.isHasData(); | 62 | this.hasData = firmwareInfo.isHasData(); |
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 org.thingsboard.server.common.data.id.FirmwareId; | ||
19 | + | ||
20 | +public interface HasFirmware { | ||
21 | + | ||
22 | + FirmwareId getFirmwareId(); | ||
23 | + | ||
24 | + FirmwareId getSoftwareId(); | ||
25 | +} |
@@ -31,6 +31,7 @@ public class MqttTopics { | @@ -31,6 +31,7 @@ public class MqttTopics { | ||
31 | private static final String SUB_TOPIC = "+"; | 31 | private static final String SUB_TOPIC = "+"; |
32 | private static final String PROVISION = "/provision"; | 32 | private static final String PROVISION = "/provision"; |
33 | private static final String FIRMWARE = "/fw"; | 33 | private static final String FIRMWARE = "/fw"; |
34 | + private static final String SOFTWARE = "/sw"; | ||
34 | private static final String CHUNK = "/chunk/"; | 35 | private static final String CHUNK = "/chunk/"; |
35 | private static final String ERROR = "/error"; | 36 | private static final String ERROR = "/error"; |
36 | 37 | ||
@@ -75,9 +76,17 @@ public class MqttTopics { | @@ -75,9 +76,17 @@ public class MqttTopics { | ||
75 | // v2 topics | 76 | // v2 topics |
76 | public static final String BASE_DEVICE_API_TOPIC_V2 = "v2"; | 77 | public static final String BASE_DEVICE_API_TOPIC_V2 = "v2"; |
77 | 78 | ||
78 | - public static final String DEVICE_FIRMWARE_RESPONSE_TOPIC_PREFIX = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + RESPONSE + "/"; | ||
79 | - public static final String DEVICE_FIRMWARE_RESPONSES_TOPIC = DEVICE_FIRMWARE_RESPONSE_TOPIC_PREFIX + SUB_TOPIC + CHUNK + SUB_TOPIC; | 79 | + public static final String REQUEST_ID_PATTERN = "(?<requestId>\\d+)"; |
80 | + public static final String CHUNK_PATTERN = "(?<chunk>\\d+)"; | ||
81 | + | ||
82 | + public static final String DEVICE_FIRMWARE_REQUEST_TOPIC_PATTERN = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + REQUEST + "/" + REQUEST_ID_PATTERN + CHUNK + CHUNK_PATTERN; | ||
83 | + public static final String DEVICE_FIRMWARE_RESPONSES_TOPIC = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + RESPONSE + "/" + SUB_TOPIC + CHUNK + SUB_TOPIC; | ||
80 | public static final String DEVICE_FIRMWARE_ERROR_TOPIC = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + ERROR; | 84 | public static final String DEVICE_FIRMWARE_ERROR_TOPIC = BASE_DEVICE_API_TOPIC_V2 + FIRMWARE + ERROR; |
85 | + public static final String DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT = BASE_DEVICE_API_TOPIC_V2 + "%s" + RESPONSE + "/"+ "%s" + CHUNK + "%d"; | ||
86 | + | ||
87 | + public static final String DEVICE_SOFTWARE_REQUEST_TOPIC_PATTERN = BASE_DEVICE_API_TOPIC_V2 + SOFTWARE + REQUEST + "/" + REQUEST_ID_PATTERN + CHUNK + CHUNK_PATTERN; | ||
88 | + public static final String DEVICE_SOFTWARE_RESPONSES_TOPIC = BASE_DEVICE_API_TOPIC_V2 + SOFTWARE + RESPONSE + "/" + SUB_TOPIC + CHUNK + SUB_TOPIC; | ||
89 | + public static final String DEVICE_SOFTWARE_ERROR_TOPIC = BASE_DEVICE_API_TOPIC_V2 + SOFTWARE + ERROR; | ||
81 | 90 | ||
82 | private MqttTopics() { | 91 | private MqttTopics() { |
83 | } | 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.common.data.firmware; | ||
17 | + | ||
18 | +import lombok.Getter; | ||
19 | + | ||
20 | +public enum FirmwareKey { | ||
21 | + | ||
22 | + TITLE("title"), VERSION("version"), TS("ts"), STATE("state"), SIZE("size"), CHECKSUM("checksum"), CHECKSUM_ALGORITHM("checksum_algorithm"); | ||
23 | + | ||
24 | + @Getter | ||
25 | + private final String value; | ||
26 | + | ||
27 | + FirmwareKey(String value) { | ||
28 | + this.value = value; | ||
29 | + } | ||
30 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.firmware; | ||
17 | + | ||
18 | +import lombok.Getter; | ||
19 | + | ||
20 | +public enum FirmwareType { | ||
21 | + | ||
22 | + FIRMWARE("fw"), SOFTWARE("sw"); | ||
23 | + | ||
24 | + @Getter | ||
25 | + private final String keyPrefix; | ||
26 | + | ||
27 | + FirmwareType(String keyPrefix) { | ||
28 | + this.keyPrefix = keyPrefix; | ||
29 | + } | ||
30 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.firmware; | ||
17 | + | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
19 | +import org.thingsboard.server.common.data.HasFirmware; | ||
20 | +import org.thingsboard.server.common.data.id.FirmwareId; | ||
21 | + | ||
22 | +import java.util.ArrayList; | ||
23 | +import java.util.Collections; | ||
24 | +import java.util.List; | ||
25 | + | ||
26 | +import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; | ||
27 | +import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE; | ||
28 | + | ||
29 | +@Slf4j | ||
30 | +public class FirmwareUtil { | ||
31 | + | ||
32 | + public static final List<String> ALL_FW_ATTRIBUTE_KEYS; | ||
33 | + | ||
34 | + public static final List<String> ALL_SW_ATTRIBUTE_KEYS; | ||
35 | + | ||
36 | + static { | ||
37 | + ALL_FW_ATTRIBUTE_KEYS = new ArrayList<>(); | ||
38 | + for (FirmwareKey key : FirmwareKey.values()) { | ||
39 | + ALL_FW_ATTRIBUTE_KEYS.add(getAttributeKey(FIRMWARE, key)); | ||
40 | + | ||
41 | + } | ||
42 | + | ||
43 | + ALL_SW_ATTRIBUTE_KEYS = new ArrayList<>(); | ||
44 | + for (FirmwareKey key : FirmwareKey.values()) { | ||
45 | + ALL_SW_ATTRIBUTE_KEYS.add(getAttributeKey(SOFTWARE, key)); | ||
46 | + | ||
47 | + } | ||
48 | + } | ||
49 | + | ||
50 | + public static List<String> getAttributeKeys(FirmwareType firmwareType) { | ||
51 | + switch (firmwareType) { | ||
52 | + case FIRMWARE: | ||
53 | + return ALL_FW_ATTRIBUTE_KEYS; | ||
54 | + case SOFTWARE: | ||
55 | + return ALL_SW_ATTRIBUTE_KEYS; | ||
56 | + } | ||
57 | + return Collections.emptyList(); | ||
58 | + } | ||
59 | + | ||
60 | + public static String getAttributeKey(FirmwareType type, FirmwareKey key) { | ||
61 | + return type.getKeyPrefix() + "_" + key.getValue(); | ||
62 | + } | ||
63 | + | ||
64 | + public static String getTargetTelemetryKey(FirmwareType type, FirmwareKey key) { | ||
65 | + return getTelemetryKey("target_", type, key); | ||
66 | + } | ||
67 | + | ||
68 | + public static String getCurrentTelemetryKey(FirmwareType type, FirmwareKey key) { | ||
69 | + return getTelemetryKey("current_", type, key); | ||
70 | + } | ||
71 | + | ||
72 | + private static String getTelemetryKey(String prefix, FirmwareType type, FirmwareKey key) { | ||
73 | + return prefix + type.getKeyPrefix() + "_" + key.getValue(); | ||
74 | + } | ||
75 | + | ||
76 | + public static String getTelemetryKey(FirmwareType type, FirmwareKey key) { | ||
77 | + return type.getKeyPrefix() + "_" + key.getValue(); | ||
78 | + } | ||
79 | + | ||
80 | + public static FirmwareId getFirmwareId(HasFirmware entity, FirmwareType firmwareType) { | ||
81 | + switch (firmwareType) { | ||
82 | + case FIRMWARE: | ||
83 | + return entity.getFirmwareId(); | ||
84 | + case SOFTWARE: | ||
85 | + return entity.getSoftwareId(); | ||
86 | + default: | ||
87 | + log.warn("Unsupported firmware type: [{}]", firmwareType); | ||
88 | + return null; | ||
89 | + } | ||
90 | + } | ||
91 | +} |
@@ -16,5 +16,5 @@ | @@ -16,5 +16,5 @@ | ||
16 | package org.thingsboard.server.common.msg.session; | 16 | package org.thingsboard.server.common.msg.session; |
17 | 17 | ||
18 | public enum FeatureType { | 18 | public enum FeatureType { |
19 | - ATTRIBUTES, TELEMETRY, RPC, CLAIM, PROVISION, FIRMWARE | 19 | + ATTRIBUTES, TELEMETRY, RPC, CLAIM, PROVISION, FIRMWARE, SOFTWARE |
20 | } | 20 | } |
@@ -32,7 +32,8 @@ public enum SessionMsgType { | @@ -32,7 +32,8 @@ public enum SessionMsgType { | ||
32 | 32 | ||
33 | CLAIM_REQUEST(), | 33 | CLAIM_REQUEST(), |
34 | 34 | ||
35 | - GET_FIRMWARE_REQUEST; | 35 | + GET_FIRMWARE_REQUEST, |
36 | + GET_SOFTWARE_REQUEST; | ||
36 | 37 | ||
37 | private final boolean requiresRulesProcessing; | 38 | private final boolean requiresRulesProcessing; |
38 | 39 |
@@ -388,16 +388,18 @@ message GetFirmwareRequestMsg { | @@ -388,16 +388,18 @@ message GetFirmwareRequestMsg { | ||
388 | int64 deviceIdLSB = 2; | 388 | int64 deviceIdLSB = 2; |
389 | int64 tenantIdMSB = 3; | 389 | int64 tenantIdMSB = 3; |
390 | int64 tenantIdLSB = 4; | 390 | int64 tenantIdLSB = 4; |
391 | + string type = 5; | ||
391 | } | 392 | } |
392 | 393 | ||
393 | message GetFirmwareResponseMsg { | 394 | message GetFirmwareResponseMsg { |
394 | ResponseStatus responseStatus = 1; | 395 | ResponseStatus responseStatus = 1; |
395 | int64 firmwareIdMSB = 2; | 396 | int64 firmwareIdMSB = 2; |
396 | int64 firmwareIdLSB = 3; | 397 | int64 firmwareIdLSB = 3; |
397 | - string title = 4; | ||
398 | - string version = 5; | ||
399 | - string contentType = 6; | ||
400 | - string fileName = 7; | 398 | + string type = 4; |
399 | + string title = 5; | ||
400 | + string version = 6; | ||
401 | + string contentType = 7; | ||
402 | + string fileName = 8; | ||
401 | } | 403 | } |
402 | 404 | ||
403 | //Used to report session state to tb-Service and persist this state in the cache on the tb-Service level. | 405 | //Used to report session state to tb-Service and persist this state in the cache on the tb-Service level. |
@@ -711,4 +713,5 @@ message ToFirmwareStateServiceMsg { | @@ -711,4 +713,5 @@ message ToFirmwareStateServiceMsg { | ||
711 | int64 deviceIdLSB = 5; | 713 | int64 deviceIdLSB = 5; |
712 | int64 firmwareIdMSB = 6; | 714 | int64 firmwareIdMSB = 6; |
713 | int64 firmwareIdLSB = 7; | 715 | int64 firmwareIdLSB = 7; |
716 | + string type = 8; | ||
714 | } | 717 | } |
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java
@@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC | @@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC | ||
43 | import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; | 43 | import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; |
44 | import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; | 44 | import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; |
45 | import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; | 45 | import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; |
46 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
46 | import org.thingsboard.server.common.data.security.DeviceTokenCredentials; | 47 | import org.thingsboard.server.common.data.security.DeviceTokenCredentials; |
47 | import org.thingsboard.server.common.msg.session.FeatureType; | 48 | import org.thingsboard.server.common.msg.session.FeatureType; |
48 | import org.thingsboard.server.common.msg.session.SessionMsgType; | 49 | import org.thingsboard.server.common.msg.session.SessionMsgType; |
@@ -122,6 +123,8 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -122,6 +123,8 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
122 | processRequest(exchange, SessionMsgType.GET_ATTRIBUTES_REQUEST); | 123 | processRequest(exchange, SessionMsgType.GET_ATTRIBUTES_REQUEST); |
123 | } else if (featureType.get() == FeatureType.FIRMWARE) { | 124 | } else if (featureType.get() == FeatureType.FIRMWARE) { |
124 | processRequest(exchange, SessionMsgType.GET_FIRMWARE_REQUEST); | 125 | processRequest(exchange, SessionMsgType.GET_FIRMWARE_REQUEST); |
126 | + } else if (featureType.get() == FeatureType.SOFTWARE) { | ||
127 | + processRequest(exchange, SessionMsgType.GET_SOFTWARE_REQUEST); | ||
125 | } else { | 128 | } else { |
126 | log.trace("Invalid feature type parameter"); | 129 | log.trace("Invalid feature type parameter"); |
127 | exchange.respond(CoAP.ResponseCode.BAD_REQUEST); | 130 | exchange.respond(CoAP.ResponseCode.BAD_REQUEST); |
@@ -326,12 +329,10 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -326,12 +329,10 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
326 | new CoapNoOpCallback(exchange)); | 329 | new CoapNoOpCallback(exchange)); |
327 | break; | 330 | break; |
328 | case GET_FIRMWARE_REQUEST: | 331 | case GET_FIRMWARE_REQUEST: |
329 | - TransportProtos.GetFirmwareRequestMsg requestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() | ||
330 | - .setTenantIdMSB(sessionInfo.getTenantIdMSB()) | ||
331 | - .setTenantIdLSB(sessionInfo.getTenantIdLSB()) | ||
332 | - .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) | ||
333 | - .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()).build(); | ||
334 | - transportContext.getTransportService().process(sessionInfo, requestMsg, new FirmwareCallback(exchange)); | 332 | + getFirmwareCallback(sessionInfo, exchange, FirmwareType.FIRMWARE); |
333 | + break; | ||
334 | + case GET_SOFTWARE_REQUEST: | ||
335 | + getFirmwareCallback(sessionInfo, exchange, FirmwareType.SOFTWARE); | ||
335 | break; | 336 | break; |
336 | } | 337 | } |
337 | } catch (AdaptorException e) { | 338 | } catch (AdaptorException e) { |
@@ -340,6 +341,16 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | @@ -340,6 +341,16 @@ public class CoapTransportResource extends AbstractCoapTransportResource { | ||
340 | } | 341 | } |
341 | } | 342 | } |
342 | 343 | ||
344 | + private void getFirmwareCallback(TransportProtos.SessionInfoProto sessionInfo, CoapExchange exchange, FirmwareType firmwareType) { | ||
345 | + TransportProtos.GetFirmwareRequestMsg requestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() | ||
346 | + .setTenantIdMSB(sessionInfo.getTenantIdMSB()) | ||
347 | + .setTenantIdLSB(sessionInfo.getTenantIdLSB()) | ||
348 | + .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) | ||
349 | + .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) | ||
350 | + .setType(firmwareType.name()).build(); | ||
351 | + transportContext.getTransportService().process(sessionInfo, requestMsg, new FirmwareCallback(exchange)); | ||
352 | + } | ||
353 | + | ||
343 | private TransportProtos.SessionInfoProto lookupAsyncSessionInfo(String token) { | 354 | private TransportProtos.SessionInfoProto lookupAsyncSessionInfo(String token) { |
344 | tokenToNotificationCounterMap.remove(token); | 355 | tokenToNotificationCounterMap.remove(token); |
345 | return tokenToSessionIdMap.remove(token); | 356 | return tokenToSessionIdMap.remove(token); |
@@ -34,6 +34,7 @@ import org.springframework.web.bind.annotation.RequestParam; | @@ -34,6 +34,7 @@ import org.springframework.web.bind.annotation.RequestParam; | ||
34 | import org.springframework.web.bind.annotation.RestController; | 34 | import org.springframework.web.bind.annotation.RestController; |
35 | import org.springframework.web.context.request.async.DeferredResult; | 35 | import org.springframework.web.context.request.async.DeferredResult; |
36 | import org.thingsboard.server.common.data.DeviceTransportType; | 36 | import org.thingsboard.server.common.data.DeviceTransportType; |
37 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
37 | import org.thingsboard.server.common.data.TbTransportService; | 38 | import org.thingsboard.server.common.data.TbTransportService; |
38 | import org.thingsboard.server.common.data.id.DeviceId; | 39 | import org.thingsboard.server.common.data.id.DeviceId; |
39 | import org.thingsboard.server.common.transport.SessionMsgListener; | 40 | import org.thingsboard.server.common.transport.SessionMsgListener; |
@@ -210,8 +211,29 @@ public class DeviceApiController implements TbTransportService { | @@ -210,8 +211,29 @@ public class DeviceApiController implements TbTransportService { | ||
210 | public DeferredResult<ResponseEntity> getFirmware(@PathVariable("deviceToken") String deviceToken, | 211 | public DeferredResult<ResponseEntity> getFirmware(@PathVariable("deviceToken") String deviceToken, |
211 | @RequestParam(value = "title") String title, | 212 | @RequestParam(value = "title") String title, |
212 | @RequestParam(value = "version") String version, | 213 | @RequestParam(value = "version") String version, |
213 | - @RequestParam(value = "chunkSize", required = false, defaultValue = "0") int chunkSize, | 214 | + @RequestParam(value = "size", required = false, defaultValue = "0") int size, |
214 | @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) { | 215 | @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) { |
216 | + return getFirmwareCallback(deviceToken, title, version, size, chunk, FirmwareType.FIRMWARE); | ||
217 | + } | ||
218 | + | ||
219 | + @RequestMapping(value = "/{deviceToken}/software", method = RequestMethod.GET) | ||
220 | + public DeferredResult<ResponseEntity> getSoftware(@PathVariable("deviceToken") String deviceToken, | ||
221 | + @RequestParam(value = "title") String title, | ||
222 | + @RequestParam(value = "version") String version, | ||
223 | + @RequestParam(value = "size", required = false, defaultValue = "0") int size, | ||
224 | + @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) { | ||
225 | + return getFirmwareCallback(deviceToken, title, version, size, chunk, FirmwareType.SOFTWARE); | ||
226 | + } | ||
227 | + | ||
228 | + @RequestMapping(value = "/provision", method = RequestMethod.POST) | ||
229 | + public DeferredResult<ResponseEntity> provisionDevice(@RequestBody String json, HttpServletRequest httpRequest) { | ||
230 | + DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>(); | ||
231 | + transportContext.getTransportService().process(JsonConverter.convertToProvisionRequestMsg(json), | ||
232 | + new DeviceProvisionCallback(responseWriter)); | ||
233 | + return responseWriter; | ||
234 | + } | ||
235 | + | ||
236 | + private DeferredResult<ResponseEntity> getFirmwareCallback(String deviceToken, String title, String version, int size, int chunk, FirmwareType firmwareType) { | ||
215 | DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>(); | 237 | DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>(); |
216 | transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), | 238 | transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), |
217 | new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> { | 239 | new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> { |
@@ -219,20 +241,13 @@ public class DeviceApiController implements TbTransportService { | @@ -219,20 +241,13 @@ public class DeviceApiController implements TbTransportService { | ||
219 | .setTenantIdMSB(sessionInfo.getTenantIdMSB()) | 241 | .setTenantIdMSB(sessionInfo.getTenantIdMSB()) |
220 | .setTenantIdLSB(sessionInfo.getTenantIdLSB()) | 242 | .setTenantIdLSB(sessionInfo.getTenantIdLSB()) |
221 | .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) | 243 | .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) |
222 | - .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()).build(); | ||
223 | - transportContext.getTransportService().process(sessionInfo, requestMsg, new GetFirmwareCallback(responseWriter, title, version, chunkSize, chunk)); | 244 | + .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) |
245 | + .setType(firmwareType.name()).build(); | ||
246 | + transportContext.getTransportService().process(sessionInfo, requestMsg, new GetFirmwareCallback(responseWriter, title, version, size, chunk)); | ||
224 | })); | 247 | })); |
225 | return responseWriter; | 248 | return responseWriter; |
226 | } | 249 | } |
227 | 250 | ||
228 | - @RequestMapping(value = "/provision", method = RequestMethod.POST) | ||
229 | - public DeferredResult<ResponseEntity> provisionDevice(@RequestBody String json, HttpServletRequest httpRequest) { | ||
230 | - DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>(); | ||
231 | - transportContext.getTransportService().process(JsonConverter.convertToProvisionRequestMsg(json), | ||
232 | - new DeviceProvisionCallback(responseWriter)); | ||
233 | - return responseWriter; | ||
234 | - } | ||
235 | - | ||
236 | private static class DeviceAuthCallback implements TransportServiceCallback<ValidateDeviceCredentialsResponse> { | 251 | private static class DeviceAuthCallback implements TransportServiceCallback<ValidateDeviceCredentialsResponse> { |
237 | private final TransportContext transportContext; | 252 | private final TransportContext transportContext; |
238 | private final DeferredResult<ResponseEntity> responseWriter; | 253 | private final DeferredResult<ResponseEntity> responseWriter; |
@@ -41,6 +41,9 @@ import org.thingsboard.common.util.JacksonUtil; | @@ -41,6 +41,9 @@ import org.thingsboard.common.util.JacksonUtil; | ||
41 | import org.thingsboard.server.cache.firmware.FirmwareDataCache; | 41 | import org.thingsboard.server.cache.firmware.FirmwareDataCache; |
42 | import org.thingsboard.server.common.data.Device; | 42 | import org.thingsboard.server.common.data.Device; |
43 | import org.thingsboard.server.common.data.DeviceProfile; | 43 | import org.thingsboard.server.common.data.DeviceProfile; |
44 | +import org.thingsboard.server.common.data.firmware.FirmwareKey; | ||
45 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
46 | +import org.thingsboard.server.common.data.firmware.FirmwareUtil; | ||
44 | import org.thingsboard.server.common.data.id.FirmwareId; | 47 | import org.thingsboard.server.common.data.id.FirmwareId; |
45 | import org.thingsboard.server.common.transport.TransportService; | 48 | import org.thingsboard.server.common.transport.TransportService; |
46 | import org.thingsboard.server.common.transport.TransportServiceCallback; | 49 | import org.thingsboard.server.common.transport.TransportServiceCallback; |
@@ -79,7 +82,6 @@ import java.util.stream.Collectors; | @@ -79,7 +82,6 @@ import java.util.stream.Collectors; | ||
79 | 82 | ||
80 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; | 83 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; |
81 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; | 84 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; |
82 | -import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_VERSION; | ||
83 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; | 85 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; |
84 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; | 86 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
85 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED; | 87 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED; |
@@ -332,7 +334,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -332,7 +334,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
332 | String pathName = tsKvProto.getKv().getKey(); | 334 | String pathName = tsKvProto.getKv().getKey(); |
333 | String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); | 335 | String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); |
334 | Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); | 336 | Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); |
335 | - if (FIRMWARE_VERSION.equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) { | 337 | + if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) { |
336 | this.getInfoFirmwareUpdate(lwM2MClient); | 338 | this.getInfoFirmwareUpdate(lwM2MClient); |
337 | } | 339 | } |
338 | if (pathIdVer != null) { | 340 | if (pathIdVer != null) { |
@@ -358,7 +360,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -358,7 +360,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
358 | msg.getSharedUpdatedList().forEach(tsKvProto -> { | 360 | msg.getSharedUpdatedList().forEach(tsKvProto -> { |
359 | String pathName = tsKvProto.getKv().getKey(); | 361 | String pathName = tsKvProto.getKv().getKey(); |
360 | Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); | 362 | Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); |
361 | - if (FIRMWARE_VERSION.equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) { | 363 | + if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) { |
362 | lwM2MClient.getFrUpdate().setCurrentFwVersion((String) valueNew); | 364 | lwM2MClient.getFrUpdate().setCurrentFwVersion((String) valueNew); |
363 | } | 365 | } |
364 | }); | 366 | }); |
@@ -47,6 +47,7 @@ import org.thingsboard.server.common.data.DeviceProfile; | @@ -47,6 +47,7 @@ import org.thingsboard.server.common.data.DeviceProfile; | ||
47 | import org.thingsboard.server.common.data.DeviceTransportType; | 47 | import org.thingsboard.server.common.data.DeviceTransportType; |
48 | import org.thingsboard.server.common.data.TransportPayloadType; | 48 | import org.thingsboard.server.common.data.TransportPayloadType; |
49 | import org.thingsboard.server.common.data.device.profile.MqttTopics; | 49 | import org.thingsboard.server.common.data.device.profile.MqttTopics; |
50 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
50 | import org.thingsboard.server.common.data.id.FirmwareId; | 51 | import org.thingsboard.server.common.data.id.FirmwareId; |
51 | import org.thingsboard.server.common.msg.EncryptionUtil; | 52 | import org.thingsboard.server.common.msg.EncryptionUtil; |
52 | import org.thingsboard.server.common.msg.tools.TbRateLimitsException; | 53 | import org.thingsboard.server.common.msg.tools.TbRateLimitsException; |
@@ -59,6 +60,7 @@ import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; | @@ -59,6 +60,7 @@ import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; | ||
59 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | 60 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
60 | import org.thingsboard.server.common.transport.service.DefaultTransportService; | 61 | import org.thingsboard.server.common.transport.service.DefaultTransportService; |
61 | import org.thingsboard.server.common.transport.service.SessionMetaData; | 62 | import org.thingsboard.server.common.transport.service.SessionMetaData; |
63 | +import org.thingsboard.server.common.transport.util.SslUtil; | ||
62 | import org.thingsboard.server.gen.transport.TransportProtos; | 64 | import org.thingsboard.server.gen.transport.TransportProtos; |
63 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; | 65 | import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg; |
64 | import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent; | 66 | import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent; |
@@ -68,7 +70,6 @@ import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; | @@ -68,7 +70,6 @@ import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; | ||
68 | import org.thingsboard.server.transport.mqtt.session.DeviceSessionCtx; | 70 | import org.thingsboard.server.transport.mqtt.session.DeviceSessionCtx; |
69 | import org.thingsboard.server.transport.mqtt.session.GatewaySessionHandler; | 71 | import org.thingsboard.server.transport.mqtt.session.GatewaySessionHandler; |
70 | import org.thingsboard.server.transport.mqtt.session.MqttTopicMatcher; | 72 | import org.thingsboard.server.transport.mqtt.session.MqttTopicMatcher; |
71 | -import org.thingsboard.server.common.transport.util.SslUtil; | ||
72 | 73 | ||
73 | import javax.net.ssl.SSLPeerUnverifiedException; | 74 | import javax.net.ssl.SSLPeerUnverifiedException; |
74 | import java.io.IOException; | 75 | import java.io.IOException; |
@@ -97,6 +98,8 @@ import static io.netty.handler.codec.mqtt.MqttMessageType.UNSUBACK; | @@ -97,6 +98,8 @@ import static io.netty.handler.codec.mqtt.MqttMessageType.UNSUBACK; | ||
97 | import static io.netty.handler.codec.mqtt.MqttQoS.AT_LEAST_ONCE; | 98 | import static io.netty.handler.codec.mqtt.MqttQoS.AT_LEAST_ONCE; |
98 | import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE; | 99 | import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE; |
99 | import static io.netty.handler.codec.mqtt.MqttQoS.FAILURE; | 100 | import static io.netty.handler.codec.mqtt.MqttQoS.FAILURE; |
101 | +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_FIRMWARE_REQUEST_TOPIC_PATTERN; | ||
102 | +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_SOFTWARE_REQUEST_TOPIC_PATTERN; | ||
100 | 103 | ||
101 | /** | 104 | /** |
102 | * @author Andrew Shvayka | 105 | * @author Andrew Shvayka |
@@ -104,7 +107,9 @@ import static io.netty.handler.codec.mqtt.MqttQoS.FAILURE; | @@ -104,7 +107,9 @@ import static io.netty.handler.codec.mqtt.MqttQoS.FAILURE; | ||
104 | @Slf4j | 107 | @Slf4j |
105 | public class MqttTransportHandler extends ChannelInboundHandlerAdapter implements GenericFutureListener<Future<? super Void>>, SessionMsgListener { | 108 | public class MqttTransportHandler extends ChannelInboundHandlerAdapter implements GenericFutureListener<Future<? super Void>>, SessionMsgListener { |
106 | 109 | ||
107 | - private static final Pattern FW_PATTERN = Pattern.compile("v2/fw/request/(?<requestId>\\d+)/chunk/(?<chunk>\\d+)"); | 110 | + private static final Pattern FW_REQUEST_PATTERN = Pattern.compile(DEVICE_FIRMWARE_REQUEST_TOPIC_PATTERN); |
111 | + private static final Pattern SW_REQUEST_PATTERN = Pattern.compile(DEVICE_SOFTWARE_REQUEST_TOPIC_PATTERN); | ||
112 | + | ||
108 | 113 | ||
109 | private static final String PAYLOAD_TOO_LARGE = "PAYLOAD_TOO_LARGE"; | 114 | private static final String PAYLOAD_TOO_LARGE = "PAYLOAD_TOO_LARGE"; |
110 | 115 | ||
@@ -314,38 +319,10 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -314,38 +319,10 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
314 | } else if (topicName.equals(MqttTopics.DEVICE_CLAIM_TOPIC)) { | 319 | } else if (topicName.equals(MqttTopics.DEVICE_CLAIM_TOPIC)) { |
315 | TransportProtos.ClaimDeviceMsg claimDeviceMsg = payloadAdaptor.convertToClaimDevice(deviceSessionCtx, mqttMsg); | 320 | TransportProtos.ClaimDeviceMsg claimDeviceMsg = payloadAdaptor.convertToClaimDevice(deviceSessionCtx, mqttMsg); |
316 | transportService.process(deviceSessionCtx.getSessionInfo(), claimDeviceMsg, getPubAckCallback(ctx, msgId, claimDeviceMsg)); | 321 | transportService.process(deviceSessionCtx.getSessionInfo(), claimDeviceMsg, getPubAckCallback(ctx, msgId, claimDeviceMsg)); |
317 | - } else if ((fwMatcher = FW_PATTERN.matcher(topicName)).find()) { | ||
318 | - String payload = mqttMsg.content().toString(UTF8); | ||
319 | - int chunkSize = StringUtils.isNotEmpty(payload) ? Integer.parseInt(payload) : 0; | ||
320 | - String requestId = fwMatcher.group("requestId"); | ||
321 | - int chunk = Integer.parseInt(fwMatcher.group("chunk")); | ||
322 | - | ||
323 | - if (chunkSize > 0) { | ||
324 | - this.fwChunkSizes.put(requestId, chunkSize); | ||
325 | - } else { | ||
326 | - chunkSize = fwChunkSizes.getOrDefault(requestId, 0); | ||
327 | - } | ||
328 | - | ||
329 | - if (chunkSize > context.getMaxPayloadSize()) { | ||
330 | - sendFirmwareError(ctx, PAYLOAD_TOO_LARGE); | ||
331 | - return; | ||
332 | - } | ||
333 | - | ||
334 | - String firmwareId = fwSessions.get(requestId); | ||
335 | - | ||
336 | - if (firmwareId != null) { | ||
337 | - sendFirmware(ctx, mqttMsg.variableHeader().packetId(), firmwareId, requestId, chunkSize, chunk); | ||
338 | - } else { | ||
339 | - TransportProtos.SessionInfoProto sessionInfo = deviceSessionCtx.getSessionInfo(); | ||
340 | - TransportProtos.GetFirmwareRequestMsg getFirmwareRequestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() | ||
341 | - .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) | ||
342 | - .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) | ||
343 | - .setTenantIdMSB(sessionInfo.getTenantIdMSB()) | ||
344 | - .setTenantIdLSB(sessionInfo.getTenantIdLSB()) | ||
345 | - .build(); | ||
346 | - transportService.process(deviceSessionCtx.getSessionInfo(), getFirmwareRequestMsg, | ||
347 | - new FirmwareCallback(ctx, mqttMsg.variableHeader().packetId(), getFirmwareRequestMsg, requestId, chunkSize, chunk)); | ||
348 | - } | 322 | + } else if ((fwMatcher = FW_REQUEST_PATTERN.matcher(topicName)).find()) { |
323 | + getFirmwareCallback(ctx, mqttMsg, msgId, fwMatcher, FirmwareType.FIRMWARE); | ||
324 | + } else if ((fwMatcher = SW_REQUEST_PATTERN.matcher(topicName)).find()) { | ||
325 | + getFirmwareCallback(ctx, mqttMsg, msgId, fwMatcher, FirmwareType.SOFTWARE); | ||
349 | } else { | 326 | } else { |
350 | transportService.reportActivity(deviceSessionCtx.getSessionInfo()); | 327 | transportService.reportActivity(deviceSessionCtx.getSessionInfo()); |
351 | ack(ctx, msgId); | 328 | ack(ctx, msgId); |
@@ -357,6 +334,41 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -357,6 +334,41 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
357 | } | 334 | } |
358 | } | 335 | } |
359 | 336 | ||
337 | + private void getFirmwareCallback(ChannelHandlerContext ctx, MqttPublishMessage mqttMsg, int msgId, Matcher fwMatcher, FirmwareType type) { | ||
338 | + String payload = mqttMsg.content().toString(UTF8); | ||
339 | + int chunkSize = StringUtils.isNotEmpty(payload) ? Integer.parseInt(payload) : 0; | ||
340 | + String requestId = fwMatcher.group("requestId"); | ||
341 | + int chunk = Integer.parseInt(fwMatcher.group("chunk")); | ||
342 | + | ||
343 | + if (chunkSize > 0) { | ||
344 | + this.fwChunkSizes.put(requestId, chunkSize); | ||
345 | + } else { | ||
346 | + chunkSize = fwChunkSizes.getOrDefault(requestId, 0); | ||
347 | + } | ||
348 | + | ||
349 | + if (chunkSize > context.getMaxPayloadSize()) { | ||
350 | + sendFirmwareError(ctx, PAYLOAD_TOO_LARGE); | ||
351 | + return; | ||
352 | + } | ||
353 | + | ||
354 | + String firmwareId = fwSessions.get(requestId); | ||
355 | + | ||
356 | + if (firmwareId != null) { | ||
357 | + sendFirmware(ctx, mqttMsg.variableHeader().packetId(), firmwareId, requestId, chunkSize, chunk, type); | ||
358 | + } else { | ||
359 | + TransportProtos.SessionInfoProto sessionInfo = deviceSessionCtx.getSessionInfo(); | ||
360 | + TransportProtos.GetFirmwareRequestMsg getFirmwareRequestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() | ||
361 | + .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) | ||
362 | + .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) | ||
363 | + .setTenantIdMSB(sessionInfo.getTenantIdMSB()) | ||
364 | + .setTenantIdLSB(sessionInfo.getTenantIdLSB()) | ||
365 | + .setType(type.name()) | ||
366 | + .build(); | ||
367 | + transportService.process(deviceSessionCtx.getSessionInfo(), getFirmwareRequestMsg, | ||
368 | + new FirmwareCallback(ctx, msgId, getFirmwareRequestMsg, requestId, chunkSize, chunk)); | ||
369 | + } | ||
370 | + } | ||
371 | + | ||
360 | private void ack(ChannelHandlerContext ctx, int msgId) { | 372 | private void ack(ChannelHandlerContext ctx, int msgId) { |
361 | if (msgId > 0) { | 373 | if (msgId > 0) { |
362 | ctx.writeAndFlush(createMqttPubAckMsg(msgId)); | 374 | ctx.writeAndFlush(createMqttPubAckMsg(msgId)); |
@@ -435,7 +447,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -435,7 +447,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
435 | if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())) { | 447 | if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())) { |
436 | FirmwareId firmwareId = new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB())); | 448 | FirmwareId firmwareId = new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB())); |
437 | fwSessions.put(requestId, firmwareId.toString()); | 449 | fwSessions.put(requestId, firmwareId.toString()); |
438 | - sendFirmware(ctx, msgId, firmwareId.toString(), requestId, chunkSize, chunk); | 450 | + sendFirmware(ctx, msgId, firmwareId.toString(), requestId, chunkSize, chunk, FirmwareType.valueOf(response.getType())); |
439 | } else { | 451 | } else { |
440 | sendFirmwareError(ctx, response.getResponseStatus().toString()); | 452 | sendFirmwareError(ctx, response.getResponseStatus().toString()); |
441 | } | 453 | } |
@@ -448,13 +460,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -448,13 +460,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
448 | } | 460 | } |
449 | } | 461 | } |
450 | 462 | ||
451 | - private void sendFirmware(ChannelHandlerContext ctx, int msgId, String firmwareId, String requestId, int chunkSize, int chunk) { | 463 | + private void sendFirmware(ChannelHandlerContext ctx, int msgId, String firmwareId, String requestId, int chunkSize, int chunk, FirmwareType type) { |
452 | log.trace("[{}] Send firmware [{}] to device!", sessionId, firmwareId); | 464 | log.trace("[{}] Send firmware [{}] to device!", sessionId, firmwareId); |
453 | ack(ctx, msgId); | 465 | ack(ctx, msgId); |
454 | try { | 466 | try { |
455 | byte[] firmwareChunk = context.getFirmwareDataCache().get(firmwareId, chunkSize, chunk); | 467 | byte[] firmwareChunk = context.getFirmwareDataCache().get(firmwareId, chunkSize, chunk); |
456 | deviceSessionCtx.getPayloadAdaptor() | 468 | deviceSessionCtx.getPayloadAdaptor() |
457 | - .convertToPublish(deviceSessionCtx, firmwareChunk, requestId, chunk) | 469 | + .convertToPublish(deviceSessionCtx, firmwareChunk, requestId, chunk, type) |
458 | .ifPresent(deviceSessionCtx.getChannel()::writeAndFlush); | 470 | .ifPresent(deviceSessionCtx.getChannel()::writeAndFlush); |
459 | if (firmwareChunk != null && chunkSize != firmwareChunk.length) { | 471 | if (firmwareChunk != null && chunkSize != firmwareChunk.length) { |
460 | scheduler.schedule(() -> processDisconnect(ctx), 60, TimeUnit.SECONDS); | 472 | scheduler.schedule(() -> processDisconnect(ctx), 60, TimeUnit.SECONDS); |
@@ -504,6 +516,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -504,6 +516,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
504 | case MqttTopics.DEVICE_PROVISION_RESPONSE_TOPIC: | 516 | case MqttTopics.DEVICE_PROVISION_RESPONSE_TOPIC: |
505 | case MqttTopics.DEVICE_FIRMWARE_RESPONSES_TOPIC: | 517 | case MqttTopics.DEVICE_FIRMWARE_RESPONSES_TOPIC: |
506 | case MqttTopics.DEVICE_FIRMWARE_ERROR_TOPIC: | 518 | case MqttTopics.DEVICE_FIRMWARE_ERROR_TOPIC: |
519 | + case MqttTopics.DEVICE_SOFTWARE_RESPONSES_TOPIC: | ||
520 | + case MqttTopics.DEVICE_SOFTWARE_ERROR_TOPIC: | ||
507 | registerSubQoS(topic, grantedQoSList, reqQoS); | 521 | registerSubQoS(topic, grantedQoSList, reqQoS); |
508 | break; | 522 | break; |
509 | default: | 523 | default: |
@@ -30,6 +30,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -30,6 +30,7 @@ import lombok.extern.slf4j.Slf4j; | ||
30 | import org.springframework.stereotype.Component; | 30 | import org.springframework.stereotype.Component; |
31 | import org.springframework.util.StringUtils; | 31 | import org.springframework.util.StringUtils; |
32 | import org.thingsboard.server.common.data.device.profile.MqttTopics; | 32 | import org.thingsboard.server.common.data.device.profile.MqttTopics; |
33 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
33 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; | 34 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; |
34 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; | 35 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; |
35 | import org.thingsboard.server.gen.transport.TransportProtos; | 36 | import org.thingsboard.server.gen.transport.TransportProtos; |
@@ -43,6 +44,9 @@ import java.util.Optional; | @@ -43,6 +44,9 @@ import java.util.Optional; | ||
43 | import java.util.Set; | 44 | import java.util.Set; |
44 | import java.util.UUID; | 45 | import java.util.UUID; |
45 | 46 | ||
47 | +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT; | ||
48 | + | ||
49 | + | ||
46 | /** | 50 | /** |
47 | * @author Andrew Shvayka | 51 | * @author Andrew Shvayka |
48 | */ | 52 | */ |
@@ -151,8 +155,8 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { | @@ -151,8 +155,8 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { | ||
151 | } | 155 | } |
152 | 156 | ||
153 | @Override | 157 | @Override |
154 | - public Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk) { | ||
155 | - return Optional.of(createMqttPublishMsg(ctx, MqttTopics.DEVICE_FIRMWARE_RESPONSE_TOPIC_PREFIX + requestId + "/chunk/" + chunk, firmwareChunk)); | 158 | + public Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) { |
159 | + return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk)); | ||
156 | } | 160 | } |
157 | 161 | ||
158 | public static JsonElement validateJsonPayload(UUID sessionId, ByteBuf payloadData) throws AdaptorException { | 162 | public static JsonElement validateJsonPayload(UUID sessionId, ByteBuf payloadData) throws AdaptorException { |
@@ -23,6 +23,7 @@ import io.netty.handler.codec.mqtt.MqttMessage; | @@ -23,6 +23,7 @@ import io.netty.handler.codec.mqtt.MqttMessage; | ||
23 | import io.netty.handler.codec.mqtt.MqttMessageType; | 23 | import io.netty.handler.codec.mqtt.MqttMessageType; |
24 | import io.netty.handler.codec.mqtt.MqttPublishMessage; | 24 | import io.netty.handler.codec.mqtt.MqttPublishMessage; |
25 | import io.netty.handler.codec.mqtt.MqttPublishVariableHeader; | 25 | import io.netty.handler.codec.mqtt.MqttPublishVariableHeader; |
26 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
26 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; | 27 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; |
27 | import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; | 28 | import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; |
28 | import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; | 29 | import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; |
@@ -77,7 +78,7 @@ public interface MqttTransportAdaptor { | @@ -77,7 +78,7 @@ public interface MqttTransportAdaptor { | ||
77 | 78 | ||
78 | Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext ctx, ProvisionDeviceResponseMsg provisionResponse) throws AdaptorException; | 79 | Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext ctx, ProvisionDeviceResponseMsg provisionResponse) throws AdaptorException; |
79 | 80 | ||
80 | - Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk) throws AdaptorException; | 81 | + Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) throws AdaptorException; |
81 | 82 | ||
82 | default MqttPublishMessage createMqttPublishMsg(MqttDeviceAwareSessionContext ctx, String topic, byte[] payloadInBytes) { | 83 | default MqttPublishMessage createMqttPublishMsg(MqttDeviceAwareSessionContext ctx, String topic, byte[] payloadInBytes) { |
83 | MqttFixedHeader mqttFixedHeader = | 84 | MqttFixedHeader mqttFixedHeader = |
@@ -28,6 +28,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -28,6 +28,7 @@ import lombok.extern.slf4j.Slf4j; | ||
28 | import org.springframework.stereotype.Component; | 28 | import org.springframework.stereotype.Component; |
29 | import org.springframework.util.StringUtils; | 29 | import org.springframework.util.StringUtils; |
30 | import org.thingsboard.server.common.data.device.profile.MqttTopics; | 30 | import org.thingsboard.server.common.data.device.profile.MqttTopics; |
31 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
31 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; | 32 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; |
32 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; | 33 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; |
33 | import org.thingsboard.server.common.transport.adaptor.ProtoConverter; | 34 | import org.thingsboard.server.common.transport.adaptor.ProtoConverter; |
@@ -38,6 +39,8 @@ import org.thingsboard.server.transport.mqtt.session.MqttDeviceAwareSessionConte | @@ -38,6 +39,8 @@ import org.thingsboard.server.transport.mqtt.session.MqttDeviceAwareSessionConte | ||
38 | 39 | ||
39 | import java.util.Optional; | 40 | import java.util.Optional; |
40 | 41 | ||
42 | +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT; | ||
43 | + | ||
41 | @Component | 44 | @Component |
42 | @Slf4j | 45 | @Slf4j |
43 | public class ProtoMqttAdaptor implements MqttTransportAdaptor { | 46 | public class ProtoMqttAdaptor implements MqttTransportAdaptor { |
@@ -165,8 +168,8 @@ public class ProtoMqttAdaptor implements MqttTransportAdaptor { | @@ -165,8 +168,8 @@ public class ProtoMqttAdaptor implements MqttTransportAdaptor { | ||
165 | } | 168 | } |
166 | 169 | ||
167 | @Override | 170 | @Override |
168 | - public Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk) throws AdaptorException { | ||
169 | - return Optional.of(createMqttPublishMsg(ctx, MqttTopics.DEVICE_FIRMWARE_RESPONSE_TOPIC_PREFIX + requestId + "/" + chunk, firmwareChunk)); | 171 | + public Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) throws AdaptorException { |
172 | + return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk)); | ||
170 | } | 173 | } |
171 | 174 | ||
172 | @Override | 175 | @Override |
@@ -83,6 +83,8 @@ public interface DeviceDao extends Dao<Device>, TenantEntityDao { | @@ -83,6 +83,8 @@ public interface DeviceDao extends Dao<Device>, TenantEntityDao { | ||
83 | 83 | ||
84 | PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(UUID tenantId, String type, PageLink pageLink); | 84 | PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(UUID tenantId, String type, PageLink pageLink); |
85 | 85 | ||
86 | + PageData<Device> findDevicesByTenantIdAndTypeAndEmptySoftware(UUID tenantId, String type, PageLink pageLink); | ||
87 | + | ||
86 | /** | 88 | /** |
87 | * Find device infos by tenantId, type and page link. | 89 | * Find device infos by tenantId, type and page link. |
88 | * | 90 | * |
@@ -56,6 +56,7 @@ import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfilePr | @@ -56,6 +56,7 @@ import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfilePr | ||
56 | import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; | 56 | import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; |
57 | import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; | 57 | import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; |
58 | import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; | 58 | import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; |
59 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
59 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 60 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
60 | import org.thingsboard.server.common.data.id.TenantId; | 61 | import org.thingsboard.server.common.data.id.TenantId; |
61 | import org.thingsboard.server.common.data.page.PageData; | 62 | import org.thingsboard.server.common.data.page.PageData; |
@@ -406,9 +407,31 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | @@ -406,9 +407,31 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D | ||
406 | if (firmware == null) { | 407 | if (firmware == null) { |
407 | throw new DataValidationException("Can't assign non-existent firmware!"); | 408 | throw new DataValidationException("Can't assign non-existent firmware!"); |
408 | } | 409 | } |
410 | + if (!firmware.getType().equals(FirmwareType.FIRMWARE)) { | ||
411 | + throw new DataValidationException("Can't assign firmware with type: " + firmware.getType()); | ||
412 | + } | ||
409 | if (firmware.getData() == null) { | 413 | if (firmware.getData() == null) { |
410 | throw new DataValidationException("Can't assign firmware with empty data!"); | 414 | throw new DataValidationException("Can't assign firmware with empty data!"); |
411 | } | 415 | } |
416 | + if (!firmware.getDeviceProfileId().equals(deviceProfile.getId())) { | ||
417 | + throw new DataValidationException("Can't assign firmware with different deviceProfile!"); | ||
418 | + } | ||
419 | + } | ||
420 | + | ||
421 | + if (deviceProfile.getSoftwareId() != null) { | ||
422 | + Firmware software = firmwareService.findFirmwareById(tenantId, deviceProfile.getSoftwareId()); | ||
423 | + if (software == null) { | ||
424 | + throw new DataValidationException("Can't assign non-existent software!"); | ||
425 | + } | ||
426 | + if (!software.getType().equals(FirmwareType.SOFTWARE)) { | ||
427 | + throw new DataValidationException("Can't assign software with type: " + software.getType()); | ||
428 | + } | ||
429 | + if (software.getData() == null) { | ||
430 | + throw new DataValidationException("Can't assign software with empty data!"); | ||
431 | + } | ||
432 | + if (!software.getDeviceProfileId().equals(deviceProfile.getId())) { | ||
433 | + throw new DataValidationException("Can't assign firmware with different deviceProfile!"); | ||
434 | + } | ||
412 | } | 435 | } |
413 | } | 436 | } |
414 | 437 |
@@ -53,6 +53,7 @@ import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfig | @@ -53,6 +53,7 @@ import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfig | ||
53 | import org.thingsboard.server.common.data.device.data.MqttDeviceTransportConfiguration; | 53 | import org.thingsboard.server.common.data.device.data.MqttDeviceTransportConfiguration; |
54 | import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; | 54 | import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; |
55 | import org.thingsboard.server.common.data.edge.Edge; | 55 | import org.thingsboard.server.common.data.edge.Edge; |
56 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
56 | import org.thingsboard.server.common.data.id.CustomerId; | 57 | import org.thingsboard.server.common.data.id.CustomerId; |
57 | import org.thingsboard.server.common.data.id.DeviceId; | 58 | import org.thingsboard.server.common.data.id.DeviceId; |
58 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 59 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
@@ -361,7 +362,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | @@ -361,7 +362,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | ||
361 | 362 | ||
362 | @Override | 363 | @Override |
363 | public PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(TenantId tenantId, String type, PageLink pageLink) { | 364 | public PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(TenantId tenantId, String type, PageLink pageLink) { |
364 | - log.trace("Executing findDevicesByTenantIdAndType, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink); | 365 | + log.trace("Executing findDevicesByTenantIdAndTypeAndEmptyFirmware, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink); |
365 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | 366 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); |
366 | validateString(type, "Incorrect type " + type); | 367 | validateString(type, "Incorrect type " + type); |
367 | validatePageLink(pageLink); | 368 | validatePageLink(pageLink); |
@@ -369,6 +370,15 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | @@ -369,6 +370,15 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | ||
369 | } | 370 | } |
370 | 371 | ||
371 | @Override | 372 | @Override |
373 | + public PageData<Device> findDevicesByTenantIdAndTypeAndEmptySoftware(TenantId tenantId, String type, PageLink pageLink) { | ||
374 | + log.trace("Executing findDevicesByTenantIdAndTypeAndEmptySoftware, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink); | ||
375 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
376 | + validateString(type, "Incorrect type " + type); | ||
377 | + validatePageLink(pageLink); | ||
378 | + return deviceDao.findDevicesByTenantIdAndTypeAndEmptySoftware(tenantId.getId(), type, pageLink); | ||
379 | + } | ||
380 | + | ||
381 | + @Override | ||
372 | public PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink) { | 382 | public PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink) { |
373 | log.trace("Executing findDeviceInfosByTenantIdAndType, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink); | 383 | log.trace("Executing findDeviceInfosByTenantIdAndType, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink); |
374 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | 384 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); |
@@ -696,9 +706,31 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | @@ -696,9 +706,31 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | ||
696 | if (firmware == null) { | 706 | if (firmware == null) { |
697 | throw new DataValidationException("Can't assign non-existent firmware!"); | 707 | throw new DataValidationException("Can't assign non-existent firmware!"); |
698 | } | 708 | } |
709 | + if (!firmware.getType().equals(FirmwareType.FIRMWARE)) { | ||
710 | + throw new DataValidationException("Can't assign firmware with type: " + firmware.getType()); | ||
711 | + } | ||
699 | if (firmware.getData() == null) { | 712 | if (firmware.getData() == null) { |
700 | throw new DataValidationException("Can't assign firmware with empty data!"); | 713 | throw new DataValidationException("Can't assign firmware with empty data!"); |
701 | } | 714 | } |
715 | + if (!firmware.getDeviceProfileId().equals(device.getDeviceProfileId())) { | ||
716 | + throw new DataValidationException("Can't assign firmware with different deviceProfile!"); | ||
717 | + } | ||
718 | + } | ||
719 | + | ||
720 | + if (device.getSoftwareId() != null) { | ||
721 | + Firmware software = firmwareService.findFirmwareById(tenantId, device.getSoftwareId()); | ||
722 | + if (software == null) { | ||
723 | + throw new DataValidationException("Can't assign non-existent software!"); | ||
724 | + } | ||
725 | + if (!software.getType().equals(FirmwareType.SOFTWARE)) { | ||
726 | + throw new DataValidationException("Can't assign software with type: " + software.getType()); | ||
727 | + } | ||
728 | + if (software.getData() == null) { | ||
729 | + throw new DataValidationException("Can't assign software with empty data!"); | ||
730 | + } | ||
731 | + if (!software.getDeviceProfileId().equals(device.getDeviceProfileId())) { | ||
732 | + throw new DataValidationException("Can't assign firmware with different deviceProfile!"); | ||
733 | + } | ||
702 | } | 734 | } |
703 | } | 735 | } |
704 | }; | 736 | }; |
@@ -27,13 +27,17 @@ import org.springframework.cache.CacheManager; | @@ -27,13 +27,17 @@ import org.springframework.cache.CacheManager; | ||
27 | import org.springframework.cache.annotation.Cacheable; | 27 | import org.springframework.cache.annotation.Cacheable; |
28 | import org.springframework.stereotype.Service; | 28 | import org.springframework.stereotype.Service; |
29 | import org.thingsboard.server.cache.firmware.FirmwareDataCache; | 29 | import org.thingsboard.server.cache.firmware.FirmwareDataCache; |
30 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
30 | import org.thingsboard.server.common.data.Firmware; | 31 | import org.thingsboard.server.common.data.Firmware; |
31 | import org.thingsboard.server.common.data.FirmwareInfo; | 32 | import org.thingsboard.server.common.data.FirmwareInfo; |
32 | import org.thingsboard.server.common.data.Tenant; | 33 | import org.thingsboard.server.common.data.Tenant; |
34 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
35 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
33 | import org.thingsboard.server.common.data.id.FirmwareId; | 36 | import org.thingsboard.server.common.data.id.FirmwareId; |
34 | import org.thingsboard.server.common.data.id.TenantId; | 37 | import org.thingsboard.server.common.data.id.TenantId; |
35 | import org.thingsboard.server.common.data.page.PageData; | 38 | import org.thingsboard.server.common.data.page.PageData; |
36 | import org.thingsboard.server.common.data.page.PageLink; | 39 | import org.thingsboard.server.common.data.page.PageLink; |
40 | +import org.thingsboard.server.dao.device.DeviceProfileDao; | ||
37 | import org.thingsboard.server.dao.exception.DataValidationException; | 41 | import org.thingsboard.server.dao.exception.DataValidationException; |
38 | import org.thingsboard.server.dao.service.DataValidator; | 42 | import org.thingsboard.server.dao.service.DataValidator; |
39 | import org.thingsboard.server.dao.service.PaginatedRemover; | 43 | import org.thingsboard.server.dao.service.PaginatedRemover; |
@@ -56,6 +60,7 @@ public class BaseFirmwareService implements FirmwareService { | @@ -56,6 +60,7 @@ public class BaseFirmwareService implements FirmwareService { | ||
56 | public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; | 60 | public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
57 | 61 | ||
58 | private final TenantDao tenantDao; | 62 | private final TenantDao tenantDao; |
63 | + private final DeviceProfileDao deviceProfileDao; | ||
59 | private final FirmwareDao firmwareDao; | 64 | private final FirmwareDao firmwareDao; |
60 | private final FirmwareInfoDao firmwareInfoDao; | 65 | private final FirmwareInfoDao firmwareInfoDao; |
61 | private final CacheManager cacheManager; | 66 | private final CacheManager cacheManager; |
@@ -124,7 +129,8 @@ public class BaseFirmwareService implements FirmwareService { | @@ -124,7 +129,8 @@ public class BaseFirmwareService implements FirmwareService { | ||
124 | public ListenableFuture<FirmwareInfo> findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId) { | 129 | public ListenableFuture<FirmwareInfo> findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId) { |
125 | log.trace("Executing findFirmwareInfoByIdAsync [{}]", firmwareId); | 130 | log.trace("Executing findFirmwareInfoByIdAsync [{}]", firmwareId); |
126 | validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId); | 131 | validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId); |
127 | - return firmwareInfoDao.findByIdAsync(tenantId, firmwareId.getId()); } | 132 | + return firmwareInfoDao.findByIdAsync(tenantId, firmwareId.getId()); |
133 | + } | ||
128 | 134 | ||
129 | @Override | 135 | @Override |
130 | public PageData<FirmwareInfo> findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink) { | 136 | public PageData<FirmwareInfo> findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink) { |
@@ -135,11 +141,11 @@ public class BaseFirmwareService implements FirmwareService { | @@ -135,11 +141,11 @@ public class BaseFirmwareService implements FirmwareService { | ||
135 | } | 141 | } |
136 | 142 | ||
137 | @Override | 143 | @Override |
138 | - public PageData<FirmwareInfo> findTenantFirmwaresByTenantIdAndHasData(TenantId tenantId, boolean hasData, PageLink pageLink) { | 144 | + public PageData<FirmwareInfo> findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink) { |
139 | log.trace("Executing findTenantFirmwaresByTenantIdAndHasData, tenantId [{}], hasData [{}] pageLink [{}]", tenantId, hasData, pageLink); | 145 | log.trace("Executing findTenantFirmwaresByTenantIdAndHasData, tenantId [{}], hasData [{}] pageLink [{}]", tenantId, hasData, pageLink); |
140 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | 146 | validateId(tenantId, INCORRECT_TENANT_ID + tenantId); |
141 | validatePageLink(pageLink); | 147 | validatePageLink(pageLink); |
142 | - return firmwareInfoDao.findFirmwareInfoByTenantIdAndHasData(tenantId, hasData, pageLink); | 148 | + return firmwareInfoDao.findFirmwareInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, firmwareType, hasData, pageLink); |
143 | } | 149 | } |
144 | 150 | ||
145 | @Override | 151 | @Override |
@@ -157,6 +163,10 @@ public class BaseFirmwareService implements FirmwareService { | @@ -157,6 +163,10 @@ public class BaseFirmwareService implements FirmwareService { | ||
157 | throw new DataValidationException("The firmware referenced by the devices cannot be deleted!"); | 163 | throw new DataValidationException("The firmware referenced by the devices cannot be deleted!"); |
158 | } else if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_firmware_device_profile")) { | 164 | } else if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_firmware_device_profile")) { |
159 | throw new DataValidationException("The firmware referenced by the device profile cannot be deleted!"); | 165 | throw new DataValidationException("The firmware referenced by the device profile cannot be deleted!"); |
166 | + } else if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_software_device")) { | ||
167 | + throw new DataValidationException("The software referenced by the devices cannot be deleted!"); | ||
168 | + } else if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_software_device_profile")) { | ||
169 | + throw new DataValidationException("The software referenced by the device profile cannot be deleted!"); | ||
160 | } else { | 170 | } else { |
161 | throw t; | 171 | throw t; |
162 | } | 172 | } |
@@ -173,29 +183,15 @@ public class BaseFirmwareService implements FirmwareService { | @@ -173,29 +183,15 @@ public class BaseFirmwareService implements FirmwareService { | ||
173 | private DataValidator<FirmwareInfo> firmwareInfoValidator = new DataValidator<>() { | 183 | private DataValidator<FirmwareInfo> firmwareInfoValidator = new DataValidator<>() { |
174 | 184 | ||
175 | @Override | 185 | @Override |
176 | - protected void validateDataImpl(TenantId tenantId, FirmwareInfo firmware) { | ||
177 | - if (firmware.getTenantId() == null) { | ||
178 | - throw new DataValidationException("Firmware should be assigned to tenant!"); | ||
179 | - } else { | ||
180 | - Tenant tenant = tenantDao.findById(firmware.getTenantId(), firmware.getTenantId().getId()); | ||
181 | - if (tenant == null) { | ||
182 | - throw new DataValidationException("Firmware is referencing to non-existent tenant!"); | ||
183 | - } | ||
184 | - } | ||
185 | - | ||
186 | - if (StringUtils.isEmpty(firmware.getTitle())) { | ||
187 | - throw new DataValidationException("Firmware title should be specified!"); | ||
188 | - } | ||
189 | - | ||
190 | - if (StringUtils.isEmpty(firmware.getVersion())) { | ||
191 | - throw new DataValidationException("Firmware version should be specified!"); | ||
192 | - } | 186 | + protected void validateDataImpl(TenantId tenantId, FirmwareInfo firmwareInfo) { |
187 | + validateImpl(firmwareInfo); | ||
193 | } | 188 | } |
194 | 189 | ||
195 | @Override | 190 | @Override |
196 | protected void validateUpdate(TenantId tenantId, FirmwareInfo firmware) { | 191 | protected void validateUpdate(TenantId tenantId, FirmwareInfo firmware) { |
197 | FirmwareInfo firmwareOld = firmwareInfoDao.findById(tenantId, firmware.getUuidId()); | 192 | FirmwareInfo firmwareOld = firmwareInfoDao.findById(tenantId, firmware.getUuidId()); |
198 | 193 | ||
194 | + validateUpdateDeviceProfile(firmware, firmwareOld); | ||
199 | BaseFirmwareService.validateUpdate(firmware, firmwareOld); | 195 | BaseFirmwareService.validateUpdate(firmware, firmwareOld); |
200 | } | 196 | } |
201 | }; | 197 | }; |
@@ -204,22 +200,7 @@ public class BaseFirmwareService implements FirmwareService { | @@ -204,22 +200,7 @@ public class BaseFirmwareService implements FirmwareService { | ||
204 | 200 | ||
205 | @Override | 201 | @Override |
206 | protected void validateDataImpl(TenantId tenantId, Firmware firmware) { | 202 | protected void validateDataImpl(TenantId tenantId, Firmware firmware) { |
207 | - if (firmware.getTenantId() == null) { | ||
208 | - throw new DataValidationException("Firmware should be assigned to tenant!"); | ||
209 | - } else { | ||
210 | - Tenant tenant = tenantDao.findById(firmware.getTenantId(), firmware.getTenantId().getId()); | ||
211 | - if (tenant == null) { | ||
212 | - throw new DataValidationException("Firmware is referencing to non-existent tenant!"); | ||
213 | - } | ||
214 | - } | ||
215 | - | ||
216 | - if (StringUtils.isEmpty(firmware.getTitle())) { | ||
217 | - throw new DataValidationException("Firmware title should be specified!"); | ||
218 | - } | ||
219 | - | ||
220 | - if (StringUtils.isEmpty(firmware.getVersion())) { | ||
221 | - throw new DataValidationException("Firmware version should be specified!"); | ||
222 | - } | 203 | + validateImpl(firmware); |
223 | 204 | ||
224 | if (StringUtils.isEmpty(firmware.getFileName())) { | 205 | if (StringUtils.isEmpty(firmware.getFileName())) { |
225 | throw new DataValidationException("Firmware file name should be specified!"); | 206 | throw new DataValidationException("Firmware file name should be specified!"); |
@@ -267,6 +248,7 @@ public class BaseFirmwareService implements FirmwareService { | @@ -267,6 +248,7 @@ public class BaseFirmwareService implements FirmwareService { | ||
267 | protected void validateUpdate(TenantId tenantId, Firmware firmware) { | 248 | protected void validateUpdate(TenantId tenantId, Firmware firmware) { |
268 | Firmware firmwareOld = firmwareDao.findById(tenantId, firmware.getUuidId()); | 249 | Firmware firmwareOld = firmwareDao.findById(tenantId, firmware.getUuidId()); |
269 | 250 | ||
251 | + validateUpdateDeviceProfile(firmware, firmwareOld); | ||
270 | BaseFirmwareService.validateUpdate(firmware, firmwareOld); | 252 | BaseFirmwareService.validateUpdate(firmware, firmwareOld); |
271 | 253 | ||
272 | if (firmwareOld.getData() != null && !firmwareOld.getData().equals(firmware.getData())) { | 254 | if (firmwareOld.getData() != null && !firmwareOld.getData().equals(firmware.getData())) { |
@@ -275,7 +257,19 @@ public class BaseFirmwareService implements FirmwareService { | @@ -275,7 +257,19 @@ public class BaseFirmwareService implements FirmwareService { | ||
275 | } | 257 | } |
276 | }; | 258 | }; |
277 | 259 | ||
260 | + private void validateUpdateDeviceProfile(FirmwareInfo firmware, FirmwareInfo firmwareOld) { | ||
261 | + if (firmwareOld.getDeviceProfileId() != null && !firmwareOld.getDeviceProfileId().equals(firmware.getDeviceProfileId())) { | ||
262 | + if (firmwareInfoDao.isFirmwareUsed(firmwareOld.getId(), firmware.getType(), firmwareOld.getDeviceProfileId())) { | ||
263 | + throw new DataValidationException("Can`t update deviceProfileId because firmware is already in use!"); | ||
264 | + } | ||
265 | + } | ||
266 | + } | ||
267 | + | ||
278 | private static void validateUpdate(FirmwareInfo firmware, FirmwareInfo firmwareOld) { | 268 | private static void validateUpdate(FirmwareInfo firmware, FirmwareInfo firmwareOld) { |
269 | + if (!firmwareOld.getType().equals(firmware.getType())) { | ||
270 | + throw new DataValidationException("Updating type is prohibited!"); | ||
271 | + } | ||
272 | + | ||
279 | if (!firmwareOld.getTitle().equals(firmware.getTitle())) { | 273 | if (!firmwareOld.getTitle().equals(firmware.getTitle())) { |
280 | throw new DataValidationException("Updating firmware title is prohibited!"); | 274 | throw new DataValidationException("Updating firmware title is prohibited!"); |
281 | } | 275 | } |
@@ -305,6 +299,36 @@ public class BaseFirmwareService implements FirmwareService { | @@ -305,6 +299,36 @@ public class BaseFirmwareService implements FirmwareService { | ||
305 | } | 299 | } |
306 | } | 300 | } |
307 | 301 | ||
302 | + private void validateImpl(FirmwareInfo firmwareInfo) { | ||
303 | + if (firmwareInfo.getTenantId() == null) { | ||
304 | + throw new DataValidationException("Firmware should be assigned to tenant!"); | ||
305 | + } else { | ||
306 | + Tenant tenant = tenantDao.findById(firmwareInfo.getTenantId(), firmwareInfo.getTenantId().getId()); | ||
307 | + if (tenant == null) { | ||
308 | + throw new DataValidationException("Firmware is referencing to non-existent tenant!"); | ||
309 | + } | ||
310 | + } | ||
311 | + | ||
312 | + if (firmwareInfo.getDeviceProfileId() != null) { | ||
313 | + DeviceProfile deviceProfile = deviceProfileDao.findById(firmwareInfo.getTenantId(), firmwareInfo.getDeviceProfileId().getId()); | ||
314 | + if (deviceProfile == null) { | ||
315 | + throw new DataValidationException("Firmware is referencing to non-existent device profile!"); | ||
316 | + } | ||
317 | + } | ||
318 | + | ||
319 | + if (firmwareInfo.getType() == null) { | ||
320 | + throw new DataValidationException("Type should be specified!"); | ||
321 | + } | ||
322 | + | ||
323 | + if (StringUtils.isEmpty(firmwareInfo.getTitle())) { | ||
324 | + throw new DataValidationException("Firmware title should be specified!"); | ||
325 | + } | ||
326 | + | ||
327 | + if (StringUtils.isEmpty(firmwareInfo.getVersion())) { | ||
328 | + throw new DataValidationException("Firmware version should be specified!"); | ||
329 | + } | ||
330 | + } | ||
331 | + | ||
308 | private PaginatedRemover<TenantId, FirmwareInfo> tenantFirmwareRemover = | 332 | private PaginatedRemover<TenantId, FirmwareInfo> tenantFirmwareRemover = |
309 | new PaginatedRemover<>() { | 333 | new PaginatedRemover<>() { |
310 | 334 |
@@ -16,6 +16,9 @@ | @@ -16,6 +16,9 @@ | ||
16 | package org.thingsboard.server.dao.firmware; | 16 | package org.thingsboard.server.dao.firmware; |
17 | 17 | ||
18 | import org.thingsboard.server.common.data.FirmwareInfo; | 18 | import org.thingsboard.server.common.data.FirmwareInfo; |
19 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
20 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
21 | +import org.thingsboard.server.common.data.id.FirmwareId; | ||
19 | import org.thingsboard.server.common.data.id.TenantId; | 22 | import org.thingsboard.server.common.data.id.TenantId; |
20 | import org.thingsboard.server.common.data.page.PageData; | 23 | import org.thingsboard.server.common.data.page.PageData; |
21 | import org.thingsboard.server.common.data.page.PageLink; | 24 | import org.thingsboard.server.common.data.page.PageLink; |
@@ -27,6 +30,8 @@ public interface FirmwareInfoDao extends Dao<FirmwareInfo> { | @@ -27,6 +30,8 @@ public interface FirmwareInfoDao extends Dao<FirmwareInfo> { | ||
27 | 30 | ||
28 | PageData<FirmwareInfo> findFirmwareInfoByTenantId(TenantId tenantId, PageLink pageLink); | 31 | PageData<FirmwareInfo> findFirmwareInfoByTenantId(TenantId tenantId, PageLink pageLink); |
29 | 32 | ||
30 | - PageData<FirmwareInfo> findFirmwareInfoByTenantIdAndHasData(TenantId tenantId, boolean hasData, PageLink pageLink); | 33 | + PageData<FirmwareInfo> findFirmwareInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink); |
34 | + | ||
35 | + boolean isFirmwareUsed(FirmwareId firmwareId, FirmwareType type, DeviceProfileId deviceProfileId); | ||
31 | 36 | ||
32 | } | 37 | } |
@@ -154,6 +154,7 @@ public class ModelConstants { | @@ -154,6 +154,7 @@ public class ModelConstants { | ||
154 | public static final String DEVICE_DEVICE_PROFILE_ID_PROPERTY = "device_profile_id"; | 154 | public static final String DEVICE_DEVICE_PROFILE_ID_PROPERTY = "device_profile_id"; |
155 | public static final String DEVICE_DEVICE_DATA_PROPERTY = "device_data"; | 155 | public static final String DEVICE_DEVICE_DATA_PROPERTY = "device_data"; |
156 | public static final String DEVICE_FIRMWARE_ID_PROPERTY = "firmware_id"; | 156 | public static final String DEVICE_FIRMWARE_ID_PROPERTY = "firmware_id"; |
157 | + public static final String DEVICE_SOFTWARE_ID_PROPERTY = "software_id"; | ||
157 | 158 | ||
158 | public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text"; | 159 | public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text"; |
159 | public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text"; | 160 | public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text"; |
@@ -178,6 +179,7 @@ public class ModelConstants { | @@ -178,6 +179,7 @@ public class ModelConstants { | ||
178 | public static final String DEVICE_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY = "default_queue_name"; | 179 | public static final String DEVICE_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY = "default_queue_name"; |
179 | public static final String DEVICE_PROFILE_PROVISION_DEVICE_KEY = "provision_device_key"; | 180 | public static final String DEVICE_PROFILE_PROVISION_DEVICE_KEY = "provision_device_key"; |
180 | public static final String DEVICE_PROFILE_FIRMWARE_ID_PROPERTY = "firmware_id"; | 181 | public static final String DEVICE_PROFILE_FIRMWARE_ID_PROPERTY = "firmware_id"; |
182 | + public static final String DEVICE_PROFILE_SOFTWARE_ID_PROPERTY = "software_id"; | ||
181 | 183 | ||
182 | /** | 184 | /** |
183 | * Cassandra entityView constants. | 185 | * Cassandra entityView constants. |
@@ -476,6 +478,8 @@ public class ModelConstants { | @@ -476,6 +478,8 @@ public class ModelConstants { | ||
476 | */ | 478 | */ |
477 | public static final String FIRMWARE_TABLE_NAME = "firmware"; | 479 | public static final String FIRMWARE_TABLE_NAME = "firmware"; |
478 | public static final String FIRMWARE_TENANT_ID_COLUMN = TENANT_ID_COLUMN; | 480 | public static final String FIRMWARE_TENANT_ID_COLUMN = TENANT_ID_COLUMN; |
481 | + public static final String FIRMWARE_DEVICE_PROFILE_ID_COLUMN = "device_profile_id"; | ||
482 | + public static final String FIRMWARE_TYPE_COLUMN = "type"; | ||
479 | public static final String FIRMWARE_TITLE_COLUMN = TITLE_PROPERTY; | 483 | public static final String FIRMWARE_TITLE_COLUMN = TITLE_PROPERTY; |
480 | public static final String FIRMWARE_VERSION_COLUMN = "version"; | 484 | public static final String FIRMWARE_VERSION_COLUMN = "version"; |
481 | public static final String FIRMWARE_FILE_NAME_COLUMN = "file_name"; | 485 | public static final String FIRMWARE_FILE_NAME_COLUMN = "file_name"; |
@@ -22,6 +22,7 @@ import lombok.EqualsAndHashCode; | @@ -22,6 +22,7 @@ import lombok.EqualsAndHashCode; | ||
22 | import org.hibernate.annotations.Type; | 22 | import org.hibernate.annotations.Type; |
23 | import org.hibernate.annotations.TypeDef; | 23 | import org.hibernate.annotations.TypeDef; |
24 | import org.hibernate.annotations.TypeDefs; | 24 | import org.hibernate.annotations.TypeDefs; |
25 | +import org.thingsboard.common.util.JacksonUtil; | ||
25 | import org.thingsboard.server.common.data.Device; | 26 | import org.thingsboard.server.common.data.Device; |
26 | import org.thingsboard.server.common.data.device.data.DeviceData; | 27 | import org.thingsboard.server.common.data.device.data.DeviceData; |
27 | import org.thingsboard.server.common.data.id.CustomerId; | 28 | import org.thingsboard.server.common.data.id.CustomerId; |
@@ -32,7 +33,6 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -32,7 +33,6 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
32 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 33 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
33 | import org.thingsboard.server.dao.model.ModelConstants; | 34 | import org.thingsboard.server.dao.model.ModelConstants; |
34 | import org.thingsboard.server.dao.model.SearchTextEntity; | 35 | import org.thingsboard.server.dao.model.SearchTextEntity; |
35 | -import org.thingsboard.common.util.JacksonUtil; | ||
36 | import org.thingsboard.server.dao.util.mapping.JsonBinaryType; | 36 | import org.thingsboard.server.dao.util.mapping.JsonBinaryType; |
37 | import org.thingsboard.server.dao.util.mapping.JsonStringType; | 37 | import org.thingsboard.server.dao.util.mapping.JsonStringType; |
38 | 38 | ||
@@ -43,8 +43,8 @@ import java.util.UUID; | @@ -43,8 +43,8 @@ import java.util.UUID; | ||
43 | @Data | 43 | @Data |
44 | @EqualsAndHashCode(callSuper = true) | 44 | @EqualsAndHashCode(callSuper = true) |
45 | @TypeDefs({ | 45 | @TypeDefs({ |
46 | - @TypeDef(name = "json", typeClass = JsonStringType.class), | ||
47 | - @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) | 46 | + @TypeDef(name = "json", typeClass = JsonStringType.class), |
47 | + @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) | ||
48 | }) | 48 | }) |
49 | @MappedSuperclass | 49 | @MappedSuperclass |
50 | public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEntity<T> implements SearchTextEntity<T> { | 50 | public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEntity<T> implements SearchTextEntity<T> { |
@@ -77,6 +77,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -77,6 +77,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
77 | @Column(name = ModelConstants.DEVICE_FIRMWARE_ID_PROPERTY, columnDefinition = "uuid") | 77 | @Column(name = ModelConstants.DEVICE_FIRMWARE_ID_PROPERTY, columnDefinition = "uuid") |
78 | private UUID firmwareId; | 78 | private UUID firmwareId; |
79 | 79 | ||
80 | + @Column(name = ModelConstants.DEVICE_SOFTWARE_ID_PROPERTY, columnDefinition = "uuid") | ||
81 | + private UUID softwareId; | ||
82 | + | ||
80 | @Type(type = "jsonb") | 83 | @Type(type = "jsonb") |
81 | @Column(name = ModelConstants.DEVICE_DEVICE_DATA_PROPERTY, columnDefinition = "jsonb") | 84 | @Column(name = ModelConstants.DEVICE_DEVICE_DATA_PROPERTY, columnDefinition = "jsonb") |
82 | private JsonNode deviceData; | 85 | private JsonNode deviceData; |
@@ -102,6 +105,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -102,6 +105,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
102 | if (device.getFirmwareId() != null) { | 105 | if (device.getFirmwareId() != null) { |
103 | this.firmwareId = device.getFirmwareId().getId(); | 106 | this.firmwareId = device.getFirmwareId().getId(); |
104 | } | 107 | } |
108 | + if (device.getSoftwareId() != null) { | ||
109 | + this.softwareId = device.getSoftwareId().getId(); | ||
110 | + } | ||
105 | this.deviceData = JacksonUtil.convertValue(device.getDeviceData(), ObjectNode.class); | 111 | this.deviceData = JacksonUtil.convertValue(device.getDeviceData(), ObjectNode.class); |
106 | this.name = device.getName(); | 112 | this.name = device.getName(); |
107 | this.type = device.getType(); | 113 | this.type = device.getType(); |
@@ -122,6 +128,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -122,6 +128,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
122 | this.searchText = deviceEntity.getSearchText(); | 128 | this.searchText = deviceEntity.getSearchText(); |
123 | this.additionalInfo = deviceEntity.getAdditionalInfo(); | 129 | this.additionalInfo = deviceEntity.getAdditionalInfo(); |
124 | this.firmwareId = deviceEntity.getFirmwareId(); | 130 | this.firmwareId = deviceEntity.getFirmwareId(); |
131 | + this.softwareId = deviceEntity.getSoftwareId(); | ||
125 | } | 132 | } |
126 | 133 | ||
127 | @Override | 134 | @Override |
@@ -149,6 +156,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -149,6 +156,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
149 | if (firmwareId != null) { | 156 | if (firmwareId != null) { |
150 | device.setFirmwareId(new FirmwareId(firmwareId)); | 157 | device.setFirmwareId(new FirmwareId(firmwareId)); |
151 | } | 158 | } |
159 | + if (softwareId != null) { | ||
160 | + device.setSoftwareId(new FirmwareId(softwareId)); | ||
161 | + } | ||
152 | device.setDeviceData(JacksonUtil.convertValue(deviceData, DeviceData.class)); | 162 | device.setDeviceData(JacksonUtil.convertValue(deviceData, DeviceData.class)); |
153 | device.setName(name); | 163 | device.setName(name); |
154 | device.setType(type); | 164 | device.setType(type); |
@@ -21,9 +21,10 @@ import lombok.Data; | @@ -21,9 +21,10 @@ import lombok.Data; | ||
21 | import lombok.EqualsAndHashCode; | 21 | import lombok.EqualsAndHashCode; |
22 | import org.hibernate.annotations.Type; | 22 | import org.hibernate.annotations.Type; |
23 | import org.hibernate.annotations.TypeDef; | 23 | import org.hibernate.annotations.TypeDef; |
24 | +import org.thingsboard.common.util.JacksonUtil; | ||
24 | import org.thingsboard.server.common.data.DeviceProfile; | 25 | import org.thingsboard.server.common.data.DeviceProfile; |
25 | -import org.thingsboard.server.common.data.DeviceProfileType; | ||
26 | import org.thingsboard.server.common.data.DeviceProfileProvisionType; | 26 | import org.thingsboard.server.common.data.DeviceProfileProvisionType; |
27 | +import org.thingsboard.server.common.data.DeviceProfileType; | ||
27 | import org.thingsboard.server.common.data.DeviceTransportType; | 28 | import org.thingsboard.server.common.data.DeviceTransportType; |
28 | import org.thingsboard.server.common.data.device.profile.DeviceProfileData; | 29 | import org.thingsboard.server.common.data.device.profile.DeviceProfileData; |
29 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 30 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
@@ -33,7 +34,6 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -33,7 +34,6 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
33 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 34 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
34 | import org.thingsboard.server.dao.model.ModelConstants; | 35 | import org.thingsboard.server.dao.model.ModelConstants; |
35 | import org.thingsboard.server.dao.model.SearchTextEntity; | 36 | import org.thingsboard.server.dao.model.SearchTextEntity; |
36 | -import org.thingsboard.common.util.JacksonUtil; | ||
37 | import org.thingsboard.server.dao.util.mapping.JsonBinaryType; | 37 | import org.thingsboard.server.dao.util.mapping.JsonBinaryType; |
38 | 38 | ||
39 | import javax.persistence.Column; | 39 | import javax.persistence.Column; |
@@ -87,12 +87,15 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | @@ -87,12 +87,15 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | ||
87 | @Column(name = ModelConstants.DEVICE_PROFILE_PROFILE_DATA_PROPERTY, columnDefinition = "jsonb") | 87 | @Column(name = ModelConstants.DEVICE_PROFILE_PROFILE_DATA_PROPERTY, columnDefinition = "jsonb") |
88 | private JsonNode profileData; | 88 | private JsonNode profileData; |
89 | 89 | ||
90 | - @Column(name=ModelConstants.DEVICE_PROFILE_PROVISION_DEVICE_KEY) | 90 | + @Column(name = ModelConstants.DEVICE_PROFILE_PROVISION_DEVICE_KEY) |
91 | private String provisionDeviceKey; | 91 | private String provisionDeviceKey; |
92 | 92 | ||
93 | - @Column(name=ModelConstants.DEVICE_PROFILE_FIRMWARE_ID_PROPERTY) | 93 | + @Column(name = ModelConstants.DEVICE_PROFILE_FIRMWARE_ID_PROPERTY) |
94 | private UUID firmwareId; | 94 | private UUID firmwareId; |
95 | 95 | ||
96 | + @Column(name = ModelConstants.DEVICE_PROFILE_SOFTWARE_ID_PROPERTY) | ||
97 | + private UUID softwareId; | ||
98 | + | ||
96 | public DeviceProfileEntity() { | 99 | public DeviceProfileEntity() { |
97 | super(); | 100 | super(); |
98 | } | 101 | } |
@@ -120,6 +123,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | @@ -120,6 +123,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | ||
120 | if (deviceProfile.getFirmwareId() != null) { | 123 | if (deviceProfile.getFirmwareId() != null) { |
121 | this.firmwareId = deviceProfile.getFirmwareId().getId(); | 124 | this.firmwareId = deviceProfile.getFirmwareId().getId(); |
122 | } | 125 | } |
126 | + if (deviceProfile.getSoftwareId() != null) { | ||
127 | + this.firmwareId = deviceProfile.getSoftwareId().getId(); | ||
128 | + } | ||
123 | } | 129 | } |
124 | 130 | ||
125 | @Override | 131 | @Override |
@@ -160,6 +166,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | @@ -160,6 +166,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl | ||
160 | deviceProfile.setFirmwareId(new FirmwareId(firmwareId)); | 166 | deviceProfile.setFirmwareId(new FirmwareId(firmwareId)); |
161 | } | 167 | } |
162 | 168 | ||
169 | + if (softwareId != null) { | ||
170 | + deviceProfile.setSoftwareId(new FirmwareId(softwareId)); | ||
171 | + } | ||
172 | + | ||
163 | return deviceProfile; | 173 | return deviceProfile; |
164 | } | 174 | } |
165 | } | 175 | } |
@@ -21,6 +21,8 @@ import lombok.EqualsAndHashCode; | @@ -21,6 +21,8 @@ import lombok.EqualsAndHashCode; | ||
21 | import org.hibernate.annotations.Type; | 21 | import org.hibernate.annotations.Type; |
22 | import org.hibernate.annotations.TypeDef; | 22 | import org.hibernate.annotations.TypeDef; |
23 | import org.thingsboard.server.common.data.Firmware; | 23 | import org.thingsboard.server.common.data.Firmware; |
24 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
25 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
24 | import org.thingsboard.server.common.data.id.FirmwareId; | 26 | import org.thingsboard.server.common.data.id.FirmwareId; |
25 | import org.thingsboard.server.common.data.id.TenantId; | 27 | import org.thingsboard.server.common.data.id.TenantId; |
26 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 28 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
@@ -30,6 +32,8 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; | @@ -30,6 +32,8 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; | ||
30 | 32 | ||
31 | import javax.persistence.Column; | 33 | import javax.persistence.Column; |
32 | import javax.persistence.Entity; | 34 | import javax.persistence.Entity; |
35 | +import javax.persistence.EnumType; | ||
36 | +import javax.persistence.Enumerated; | ||
33 | import javax.persistence.Lob; | 37 | import javax.persistence.Lob; |
34 | import javax.persistence.Table; | 38 | import javax.persistence.Table; |
35 | import java.nio.ByteBuffer; | 39 | import java.nio.ByteBuffer; |
@@ -40,10 +44,12 @@ import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ | @@ -40,10 +44,12 @@ import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ | ||
40 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN; | 44 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN; |
41 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_COLUMN; | 45 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_COLUMN; |
42 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_SIZE_COLUMN; | 46 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_SIZE_COLUMN; |
47 | +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DEVICE_PROFILE_ID_COLUMN; | ||
43 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN; | 48 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN; |
44 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME; | 49 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME; |
45 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN; | 50 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN; |
46 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; | 51 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; |
52 | +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TYPE_COLUMN; | ||
47 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; | 53 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; |
48 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; | 54 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; |
49 | 55 | ||
@@ -57,6 +63,13 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex | @@ -57,6 +63,13 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex | ||
57 | @Column(name = FIRMWARE_TENANT_ID_COLUMN) | 63 | @Column(name = FIRMWARE_TENANT_ID_COLUMN) |
58 | private UUID tenantId; | 64 | private UUID tenantId; |
59 | 65 | ||
66 | + @Column(name = FIRMWARE_DEVICE_PROFILE_ID_COLUMN) | ||
67 | + private UUID deviceProfileId; | ||
68 | + | ||
69 | + @Enumerated(EnumType.STRING) | ||
70 | + @Column(name = FIRMWARE_TYPE_COLUMN) | ||
71 | + private FirmwareType type; | ||
72 | + | ||
60 | @Column(name = FIRMWARE_TITLE_COLUMN) | 73 | @Column(name = FIRMWARE_TITLE_COLUMN) |
61 | private String title; | 74 | private String title; |
62 | 75 | ||
@@ -97,6 +110,10 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex | @@ -97,6 +110,10 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex | ||
97 | this.createdTime = firmware.getCreatedTime(); | 110 | this.createdTime = firmware.getCreatedTime(); |
98 | this.setUuid(firmware.getUuidId()); | 111 | this.setUuid(firmware.getUuidId()); |
99 | this.tenantId = firmware.getTenantId().getId(); | 112 | this.tenantId = firmware.getTenantId().getId(); |
113 | + if (firmware.getDeviceProfileId() != null) { | ||
114 | + this.deviceProfileId = firmware.getDeviceProfileId().getId(); | ||
115 | + } | ||
116 | + this.type = firmware.getType(); | ||
100 | this.title = firmware.getTitle(); | 117 | this.title = firmware.getTitle(); |
101 | this.version = firmware.getVersion(); | 118 | this.version = firmware.getVersion(); |
102 | this.fileName = firmware.getFileName(); | 119 | this.fileName = firmware.getFileName(); |
@@ -123,6 +140,10 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex | @@ -123,6 +140,10 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex | ||
123 | Firmware firmware = new Firmware(new FirmwareId(id)); | 140 | Firmware firmware = new Firmware(new FirmwareId(id)); |
124 | firmware.setCreatedTime(createdTime); | 141 | firmware.setCreatedTime(createdTime); |
125 | firmware.setTenantId(new TenantId(tenantId)); | 142 | firmware.setTenantId(new TenantId(tenantId)); |
143 | + if (deviceProfileId != null) { | ||
144 | + firmware.setDeviceProfileId(new DeviceProfileId(deviceProfileId)); | ||
145 | + } | ||
146 | + firmware.setType(type); | ||
126 | firmware.setTitle(title); | 147 | firmware.setTitle(title); |
127 | firmware.setVersion(version); | 148 | firmware.setVersion(version); |
128 | firmware.setFileName(fileName); | 149 | firmware.setFileName(fileName); |
@@ -22,6 +22,8 @@ import org.hibernate.annotations.Type; | @@ -22,6 +22,8 @@ import org.hibernate.annotations.Type; | ||
22 | import org.hibernate.annotations.TypeDef; | 22 | import org.hibernate.annotations.TypeDef; |
23 | import org.thingsboard.common.util.JacksonUtil; | 23 | import org.thingsboard.common.util.JacksonUtil; |
24 | import org.thingsboard.server.common.data.FirmwareInfo; | 24 | import org.thingsboard.server.common.data.FirmwareInfo; |
25 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
26 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
25 | import org.thingsboard.server.common.data.id.FirmwareId; | 27 | import org.thingsboard.server.common.data.id.FirmwareId; |
26 | import org.thingsboard.server.common.data.id.TenantId; | 28 | import org.thingsboard.server.common.data.id.TenantId; |
27 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 29 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
@@ -31,6 +33,8 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; | @@ -31,6 +33,8 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; | ||
31 | 33 | ||
32 | import javax.persistence.Column; | 34 | import javax.persistence.Column; |
33 | import javax.persistence.Entity; | 35 | import javax.persistence.Entity; |
36 | +import javax.persistence.EnumType; | ||
37 | +import javax.persistence.Enumerated; | ||
34 | import javax.persistence.Table; | 38 | import javax.persistence.Table; |
35 | import javax.persistence.Transient; | 39 | import javax.persistence.Transient; |
36 | import java.util.UUID; | 40 | import java.util.UUID; |
@@ -38,13 +42,13 @@ import java.util.UUID; | @@ -38,13 +42,13 @@ import java.util.UUID; | ||
38 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ALGORITHM_COLUMN; | 42 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ALGORITHM_COLUMN; |
39 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_COLUMN; | 43 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_COLUMN; |
40 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN; | 44 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN; |
41 | -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_COLUMN; | ||
42 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_SIZE_COLUMN; | 45 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_SIZE_COLUMN; |
46 | +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DEVICE_PROFILE_ID_COLUMN; | ||
43 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN; | 47 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN; |
44 | -import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_HAS_DATA_PROPERTY; | ||
45 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME; | 48 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME; |
46 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN; | 49 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN; |
47 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; | 50 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; |
51 | +import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TYPE_COLUMN; | ||
48 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; | 52 | import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; |
49 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; | 53 | import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; |
50 | 54 | ||
@@ -58,6 +62,13 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S | @@ -58,6 +62,13 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S | ||
58 | @Column(name = FIRMWARE_TENANT_ID_COLUMN) | 62 | @Column(name = FIRMWARE_TENANT_ID_COLUMN) |
59 | private UUID tenantId; | 63 | private UUID tenantId; |
60 | 64 | ||
65 | + @Column(name = FIRMWARE_DEVICE_PROFILE_ID_COLUMN) | ||
66 | + private UUID deviceProfileId; | ||
67 | + | ||
68 | + @Enumerated(EnumType.STRING) | ||
69 | + @Column(name = FIRMWARE_TYPE_COLUMN) | ||
70 | + private FirmwareType type; | ||
71 | + | ||
61 | @Column(name = FIRMWARE_TITLE_COLUMN) | 72 | @Column(name = FIRMWARE_TITLE_COLUMN) |
62 | private String title; | 73 | private String title; |
63 | 74 | ||
@@ -97,6 +108,10 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S | @@ -97,6 +108,10 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S | ||
97 | this.createdTime = firmware.getCreatedTime(); | 108 | this.createdTime = firmware.getCreatedTime(); |
98 | this.setUuid(firmware.getUuidId()); | 109 | this.setUuid(firmware.getUuidId()); |
99 | this.tenantId = firmware.getTenantId().getId(); | 110 | this.tenantId = firmware.getTenantId().getId(); |
111 | + this.type = firmware.getType(); | ||
112 | + if (firmware.getDeviceProfileId() != null) { | ||
113 | + this.deviceProfileId = firmware.getDeviceProfileId().getId(); | ||
114 | + } | ||
100 | this.title = firmware.getTitle(); | 115 | this.title = firmware.getTitle(); |
101 | this.version = firmware.getVersion(); | 116 | this.version = firmware.getVersion(); |
102 | this.fileName = firmware.getFileName(); | 117 | this.fileName = firmware.getFileName(); |
@@ -107,12 +122,14 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S | @@ -107,12 +122,14 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S | ||
107 | this.additionalInfo = firmware.getAdditionalInfo(); | 122 | this.additionalInfo = firmware.getAdditionalInfo(); |
108 | } | 123 | } |
109 | 124 | ||
110 | - public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, String title, String version, | 125 | + public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, UUID deviceProfileId, FirmwareType type, String title, String version, |
111 | String fileName, String contentType, String checksumAlgorithm, String checksum, Long dataSize, | 126 | String fileName, String contentType, String checksumAlgorithm, String checksum, Long dataSize, |
112 | Object additionalInfo, boolean hasData) { | 127 | Object additionalInfo, boolean hasData) { |
113 | this.id = id; | 128 | this.id = id; |
114 | this.createdTime = createdTime; | 129 | this.createdTime = createdTime; |
115 | this.tenantId = tenantId; | 130 | this.tenantId = tenantId; |
131 | + this.deviceProfileId = deviceProfileId; | ||
132 | + this.type = type; | ||
116 | this.title = title; | 133 | this.title = title; |
117 | this.version = version; | 134 | this.version = version; |
118 | this.fileName = fileName; | 135 | this.fileName = fileName; |
@@ -139,6 +156,10 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S | @@ -139,6 +156,10 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S | ||
139 | FirmwareInfo firmware = new FirmwareInfo(new FirmwareId(id)); | 156 | FirmwareInfo firmware = new FirmwareInfo(new FirmwareId(id)); |
140 | firmware.setCreatedTime(createdTime); | 157 | firmware.setCreatedTime(createdTime); |
141 | firmware.setTenantId(new TenantId(tenantId)); | 158 | firmware.setTenantId(new TenantId(tenantId)); |
159 | + if (deviceProfileId != null) { | ||
160 | + firmware.setDeviceProfileId(new DeviceProfileId(deviceProfileId)); | ||
161 | + } | ||
162 | + firmware.setType(type); | ||
142 | firmware.setTitle(title); | 163 | firmware.setTitle(title); |
143 | firmware.setVersion(version); | 164 | firmware.setVersion(version); |
144 | firmware.setFileName(fileName); | 165 | firmware.setFileName(fileName); |
@@ -104,6 +104,15 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit | @@ -104,6 +104,15 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit | ||
104 | @Param("textSearch") String textSearch, | 104 | @Param("textSearch") String textSearch, |
105 | Pageable pageable); | 105 | Pageable pageable); |
106 | 106 | ||
107 | + @Query("SELECT d FROM DeviceEntity d WHERE d.tenantId = :tenantId " + | ||
108 | + "AND d.type = :type " + | ||
109 | + "AND d.softwareId = null " + | ||
110 | + "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))") | ||
111 | + Page<DeviceEntity> findByTenantIdAndTypeAndSoftwareIdIsNull(@Param("tenantId") UUID tenantId, | ||
112 | + @Param("type") String type, | ||
113 | + @Param("textSearch") String textSearch, | ||
114 | + Pageable pageable); | ||
115 | + | ||
107 | @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " + | 116 | @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " + |
108 | "FROM DeviceEntity d " + | 117 | "FROM DeviceEntity d " + |
109 | "LEFT JOIN CustomerEntity c on c.id = d.customerId " + | 118 | "LEFT JOIN CustomerEntity c on c.id = d.customerId " + |
@@ -165,6 +165,16 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> | @@ -165,6 +165,16 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> | ||
165 | } | 165 | } |
166 | 166 | ||
167 | @Override | 167 | @Override |
168 | + public PageData<Device> findDevicesByTenantIdAndTypeAndEmptySoftware(UUID tenantId, String type, PageLink pageLink) { | ||
169 | + return DaoUtil.toPageData( | ||
170 | + deviceRepository.findByTenantIdAndTypeAndSoftwareIdIsNull( | ||
171 | + tenantId, | ||
172 | + type, | ||
173 | + Objects.toString(pageLink.getTextSearch(), ""), | ||
174 | + DaoUtil.toPageable(pageLink))); | ||
175 | + } | ||
176 | + | ||
177 | + @Override | ||
168 | public PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(UUID tenantId, String type, PageLink pageLink) { | 178 | public PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(UUID tenantId, String type, PageLink pageLink) { |
169 | return DaoUtil.toPageData( | 179 | return DaoUtil.toPageData( |
170 | deviceRepository.findDeviceInfosByTenantIdAndType( | 180 | deviceRepository.findDeviceInfosByTenantIdAndType( |
@@ -20,27 +20,41 @@ import org.springframework.data.domain.Pageable; | @@ -20,27 +20,41 @@ import org.springframework.data.domain.Pageable; | ||
20 | import org.springframework.data.jpa.repository.Query; | 20 | import org.springframework.data.jpa.repository.Query; |
21 | import org.springframework.data.repository.CrudRepository; | 21 | import org.springframework.data.repository.CrudRepository; |
22 | import org.springframework.data.repository.query.Param; | 22 | import org.springframework.data.repository.query.Param; |
23 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
23 | import org.thingsboard.server.dao.model.sql.FirmwareInfoEntity; | 24 | import org.thingsboard.server.dao.model.sql.FirmwareInfoEntity; |
24 | 25 | ||
25 | import java.util.UUID; | 26 | import java.util.UUID; |
26 | 27 | ||
27 | public interface FirmwareInfoRepository extends CrudRepository<FirmwareInfoEntity, UUID> { | 28 | public interface FirmwareInfoRepository extends CrudRepository<FirmwareInfoEntity, UUID> { |
28 | - @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE " + | 29 | + @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.deviceProfileId, f.type, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE " + |
29 | "f.tenantId = :tenantId " + | 30 | "f.tenantId = :tenantId " + |
30 | "AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))") | 31 | "AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))") |
31 | Page<FirmwareInfoEntity> findAllByTenantId(@Param("tenantId") UUID tenantId, | 32 | Page<FirmwareInfoEntity> findAllByTenantId(@Param("tenantId") UUID tenantId, |
32 | @Param("searchText") String searchText, | 33 | @Param("searchText") String searchText, |
33 | Pageable pageable); | 34 | Pageable pageable); |
34 | 35 | ||
35 | - @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE " + | 36 | + @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.deviceProfileId, f.type, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE " + |
36 | "f.tenantId = :tenantId " + | 37 | "f.tenantId = :tenantId " + |
38 | + "AND f.deviceProfileId = :deviceProfileId " + | ||
39 | + "AND f.type = :type " + | ||
37 | "AND ((f.data IS NOT NULL AND :hasData = true) OR (f.data IS NULL AND :hasData = false ))" + | 40 | "AND ((f.data IS NOT NULL AND :hasData = true) OR (f.data IS NULL AND :hasData = false ))" + |
38 | "AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))") | 41 | "AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))") |
39 | - Page<FirmwareInfoEntity> findAllByTenantIdAndHasData(@Param("tenantId") UUID tenantId, | ||
40 | - @Param("hasData") boolean hasData, | ||
41 | - @Param("searchText") String searchText, | ||
42 | - Pageable pageable); | 42 | + Page<FirmwareInfoEntity> findAllByTenantIdAndTypeAndDeviceProfileIdAndHasData(@Param("tenantId") UUID tenantId, |
43 | + @Param("deviceProfileId") UUID deviceProfileId, | ||
44 | + @Param("type") FirmwareType type, | ||
45 | + @Param("hasData") boolean hasData, | ||
46 | + @Param("searchText") String searchText, | ||
47 | + Pageable pageable); | ||
43 | 48 | ||
44 | - @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE f.id = :id") | 49 | + @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, f.deviceProfileId, f.type, f.title, f.version, f.fileName, f.contentType, f.checksumAlgorithm, f.checksum, f.dataSize, f.additionalInfo, f.data IS NOT NULL) FROM FirmwareEntity f WHERE f.id = :id") |
45 | FirmwareInfoEntity findFirmwareInfoById(@Param("id") UUID id); | 50 | FirmwareInfoEntity findFirmwareInfoById(@Param("id") UUID id); |
51 | + | ||
52 | + @Query(value = "SELECT exists(SELECT * " + | ||
53 | + "FROM device_profile AS dp " + | ||
54 | + "LEFT JOIN device AS d ON dp.id = d.device_profile_id " + | ||
55 | + "WHERE dp.id = :deviceProfileId AND " + | ||
56 | + "(('FIRMWARE' = :type AND (dp.firmware_id = :firmwareId OR d.firmware_id = :firmwareId)) " + | ||
57 | + "OR ('SOFTWARE' = :type AND (dp.software_id = :firmwareId or d.software_id = :firmwareId))))", nativeQuery = true) | ||
58 | + boolean isFirmwareUsed(@Param("firmwareId") UUID firmwareId, @Param("deviceProfileId") UUID deviceProfileId, @Param("type") String type); | ||
59 | + | ||
46 | } | 60 | } |
@@ -20,6 +20,9 @@ import org.springframework.beans.factory.annotation.Autowired; | @@ -20,6 +20,9 @@ import org.springframework.beans.factory.annotation.Autowired; | ||
20 | import org.springframework.data.repository.CrudRepository; | 20 | import org.springframework.data.repository.CrudRepository; |
21 | import org.springframework.stereotype.Component; | 21 | import org.springframework.stereotype.Component; |
22 | import org.thingsboard.server.common.data.FirmwareInfo; | 22 | import org.thingsboard.server.common.data.FirmwareInfo; |
23 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
24 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
25 | +import org.thingsboard.server.common.data.id.FirmwareId; | ||
23 | import org.thingsboard.server.common.data.id.TenantId; | 26 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.common.data.page.PageData; | 27 | import org.thingsboard.server.common.data.page.PageData; |
25 | import org.thingsboard.server.common.data.page.PageLink; | 28 | import org.thingsboard.server.common.data.page.PageLink; |
@@ -73,12 +76,19 @@ public class JpaFirmwareInfoDao extends JpaAbstractSearchTextDao<FirmwareInfoEnt | @@ -73,12 +76,19 @@ public class JpaFirmwareInfoDao extends JpaAbstractSearchTextDao<FirmwareInfoEnt | ||
73 | } | 76 | } |
74 | 77 | ||
75 | @Override | 78 | @Override |
76 | - public PageData<FirmwareInfo> findFirmwareInfoByTenantIdAndHasData(TenantId tenantId, boolean hasData, PageLink pageLink) { | 79 | + public PageData<FirmwareInfo> findFirmwareInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink) { |
77 | return DaoUtil.toPageData(firmwareInfoRepository | 80 | return DaoUtil.toPageData(firmwareInfoRepository |
78 | - .findAllByTenantIdAndHasData( | 81 | + .findAllByTenantIdAndTypeAndDeviceProfileIdAndHasData( |
79 | tenantId.getId(), | 82 | tenantId.getId(), |
83 | + deviceProfileId.getId(), | ||
84 | + firmwareType, | ||
80 | hasData, | 85 | hasData, |
81 | Objects.toString(pageLink.getTextSearch(), ""), | 86 | Objects.toString(pageLink.getTextSearch(), ""), |
82 | DaoUtil.toPageable(pageLink))); | 87 | DaoUtil.toPageable(pageLink))); |
83 | } | 88 | } |
89 | + | ||
90 | + @Override | ||
91 | + public boolean isFirmwareUsed(FirmwareId firmwareId, FirmwareType type, DeviceProfileId deviceProfileId) { | ||
92 | + return firmwareInfoRepository.isFirmwareUsed(firmwareId.getId(), deviceProfileId.getId(), type.name()); | ||
93 | + } | ||
84 | } | 94 | } |
@@ -162,6 +162,8 @@ CREATE TABLE IF NOT EXISTS firmware ( | @@ -162,6 +162,8 @@ CREATE TABLE IF NOT EXISTS firmware ( | ||
162 | id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, | 162 | id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, |
163 | created_time bigint NOT NULL, | 163 | created_time bigint NOT NULL, |
164 | tenant_id uuid NOT NULL, | 164 | tenant_id uuid NOT NULL, |
165 | + device_profile_id uuid , | ||
166 | + type varchar(32) NOT NULL, | ||
165 | title varchar(255) NOT NULL, | 167 | title varchar(255) NOT NULL, |
166 | version varchar(255) NOT NULL, | 168 | version varchar(255) NOT NULL, |
167 | file_name varchar(255), | 169 | file_name varchar(255), |
@@ -188,13 +190,15 @@ CREATE TABLE IF NOT EXISTS device_profile ( | @@ -188,13 +190,15 @@ CREATE TABLE IF NOT EXISTS device_profile ( | ||
188 | is_default boolean, | 190 | is_default boolean, |
189 | tenant_id uuid, | 191 | tenant_id uuid, |
190 | firmware_id uuid, | 192 | firmware_id uuid, |
193 | + software_id uuid, | ||
191 | default_rule_chain_id uuid, | 194 | default_rule_chain_id uuid, |
192 | default_queue_name varchar(255), | 195 | default_queue_name varchar(255), |
193 | provision_device_key varchar, | 196 | provision_device_key varchar, |
194 | CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), | 197 | CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), |
195 | CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key), | 198 | CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key), |
196 | CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id), | 199 | CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id), |
197 | - CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id) | 200 | + CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id), |
201 | + CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES firmware(id) | ||
198 | ); | 202 | ); |
199 | 203 | ||
200 | CREATE TABLE IF NOT EXISTS device ( | 204 | CREATE TABLE IF NOT EXISTS device ( |
@@ -210,9 +214,11 @@ CREATE TABLE IF NOT EXISTS device ( | @@ -210,9 +214,11 @@ CREATE TABLE IF NOT EXISTS device ( | ||
210 | search_text varchar(255), | 214 | search_text varchar(255), |
211 | tenant_id uuid, | 215 | tenant_id uuid, |
212 | firmware_id uuid, | 216 | firmware_id uuid, |
217 | + software_id uuid, | ||
213 | CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name), | 218 | CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name), |
214 | CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id), | 219 | CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id), |
215 | - CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id) | 220 | + CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id), |
221 | + CONSTRAINT fk_software_device FOREIGN KEY (software_id) REFERENCES firmware(id) | ||
216 | ); | 222 | ); |
217 | 223 | ||
218 | CREATE TABLE IF NOT EXISTS device_credentials ( | 224 | CREATE TABLE IF NOT EXISTS device_credentials ( |
@@ -45,3 +45,4 @@ CREATE INDEX IF NOT EXISTS idx_asset_type ON asset(tenant_id, type); | @@ -45,3 +45,4 @@ CREATE INDEX IF NOT EXISTS idx_asset_type ON asset(tenant_id, type); | ||
45 | CREATE INDEX IF NOT EXISTS idx_attribute_kv_by_key_and_last_update_ts ON attribute_kv(entity_id, attribute_key, last_update_ts desc); | 45 | CREATE INDEX IF NOT EXISTS idx_attribute_kv_by_key_and_last_update_ts ON attribute_kv(entity_id, attribute_key, last_update_ts desc); |
46 | 46 | ||
47 | CREATE INDEX IF NOT EXISTS idx_audit_log_tenant_id_and_created_time ON audit_log(tenant_id, created_time); | 47 | CREATE INDEX IF NOT EXISTS idx_audit_log_tenant_id_and_created_time ON audit_log(tenant_id, created_time); |
48 | + |
@@ -180,6 +180,8 @@ CREATE TABLE IF NOT EXISTS firmware ( | @@ -180,6 +180,8 @@ CREATE TABLE IF NOT EXISTS firmware ( | ||
180 | id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, | 180 | id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, |
181 | created_time bigint NOT NULL, | 181 | created_time bigint NOT NULL, |
182 | tenant_id uuid NOT NULL, | 182 | tenant_id uuid NOT NULL, |
183 | + device_profile_id uuid , | ||
184 | + type varchar(32) NOT NULL, | ||
183 | title varchar(255) NOT NULL, | 185 | title varchar(255) NOT NULL, |
184 | version varchar(255) NOT NULL, | 186 | version varchar(255) NOT NULL, |
185 | file_name varchar(255), | 187 | file_name varchar(255), |
@@ -191,6 +193,7 @@ CREATE TABLE IF NOT EXISTS firmware ( | @@ -191,6 +193,7 @@ CREATE TABLE IF NOT EXISTS firmware ( | ||
191 | additional_info varchar, | 193 | additional_info varchar, |
192 | search_text varchar(255), | 194 | search_text varchar(255), |
193 | CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) | 195 | CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) |
196 | +-- CONSTRAINT fk_device_profile_firmware FOREIGN KEY (device_profile_id) REFERENCES device_profile(id) ON DELETE CASCADE | ||
194 | ); | 197 | ); |
195 | 198 | ||
196 | CREATE TABLE IF NOT EXISTS device_profile ( | 199 | CREATE TABLE IF NOT EXISTS device_profile ( |
@@ -206,15 +209,26 @@ CREATE TABLE IF NOT EXISTS device_profile ( | @@ -206,15 +209,26 @@ CREATE TABLE IF NOT EXISTS device_profile ( | ||
206 | is_default boolean, | 209 | is_default boolean, |
207 | tenant_id uuid, | 210 | tenant_id uuid, |
208 | firmware_id uuid, | 211 | firmware_id uuid, |
212 | + software_id uuid, | ||
209 | default_rule_chain_id uuid, | 213 | default_rule_chain_id uuid, |
210 | default_queue_name varchar(255), | 214 | default_queue_name varchar(255), |
211 | provision_device_key varchar, | 215 | provision_device_key varchar, |
212 | CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), | 216 | CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), |
213 | CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key), | 217 | CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key), |
214 | CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id), | 218 | CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id), |
215 | - CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id) | 219 | + CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id), |
220 | + CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES firmware(id) | ||
216 | ); | 221 | ); |
217 | 222 | ||
223 | +-- We will use one-to-many relation in the first release and extend this feature in case of user requests | ||
224 | +-- CREATE TABLE IF NOT EXISTS device_profile_firmware ( | ||
225 | +-- device_profile_id uuid NOT NULL, | ||
226 | +-- firmware_id uuid NOT NULL, | ||
227 | +-- CONSTRAINT device_profile_firmware_unq_key UNIQUE (device_profile_id, firmware_id), | ||
228 | +-- CONSTRAINT fk_device_profile_firmware_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id) ON DELETE CASCADE, | ||
229 | +-- CONSTRAINT fk_device_profile_firmware_firmware FOREIGN KEY (firmware_id) REFERENCES firmware(id) ON DELETE CASCADE, | ||
230 | +-- ); | ||
231 | + | ||
218 | CREATE TABLE IF NOT EXISTS device ( | 232 | CREATE TABLE IF NOT EXISTS device ( |
219 | id uuid NOT NULL CONSTRAINT device_pkey PRIMARY KEY, | 233 | id uuid NOT NULL CONSTRAINT device_pkey PRIMARY KEY, |
220 | created_time bigint NOT NULL, | 234 | created_time bigint NOT NULL, |
@@ -228,9 +242,11 @@ CREATE TABLE IF NOT EXISTS device ( | @@ -228,9 +242,11 @@ CREATE TABLE IF NOT EXISTS device ( | ||
228 | search_text varchar(255), | 242 | search_text varchar(255), |
229 | tenant_id uuid, | 243 | tenant_id uuid, |
230 | firmware_id uuid, | 244 | firmware_id uuid, |
245 | + software_id uuid, | ||
231 | CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name), | 246 | CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name), |
232 | CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id), | 247 | CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id), |
233 | - CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id) | 248 | + CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id), |
249 | + CONSTRAINT fk_software_device FOREIGN KEY (software_id) REFERENCES firmware(id) | ||
234 | ); | 250 | ); |
235 | 251 | ||
236 | CREATE TABLE IF NOT EXISTS device_credentials ( | 252 | CREATE TABLE IF NOT EXISTS device_credentials ( |
@@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.DeviceProfileInfo; | @@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.DeviceProfileInfo; | ||
30 | import org.thingsboard.server.common.data.DeviceTransportType; | 30 | import org.thingsboard.server.common.data.DeviceTransportType; |
31 | import org.thingsboard.server.common.data.Firmware; | 31 | import org.thingsboard.server.common.data.Firmware; |
32 | import org.thingsboard.server.common.data.Tenant; | 32 | import org.thingsboard.server.common.data.Tenant; |
33 | +import org.thingsboard.server.common.data.firmware.FirmwareType; | ||
33 | import org.thingsboard.server.common.data.id.TenantId; | 34 | import org.thingsboard.server.common.data.id.TenantId; |
34 | import org.thingsboard.server.common.data.page.PageData; | 35 | import org.thingsboard.server.common.data.page.PageData; |
35 | import org.thingsboard.server.common.data.page.PageLink; | 36 | import org.thingsboard.server.common.data.page.PageLink; |
@@ -43,6 +44,8 @@ import java.util.concurrent.ExecutionException; | @@ -43,6 +44,8 @@ import java.util.concurrent.ExecutionException; | ||
43 | import java.util.concurrent.Executors; | 44 | import java.util.concurrent.Executors; |
44 | import java.util.stream.Collectors; | 45 | import java.util.stream.Collectors; |
45 | 46 | ||
47 | +import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; | ||
48 | + | ||
46 | public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | 49 | public class BaseDeviceProfileServiceTest extends AbstractServiceTest { |
47 | 50 | ||
48 | private IdComparator<DeviceProfile> idComparator = new IdComparator<>(); | 51 | private IdComparator<DeviceProfile> idComparator = new IdComparator<>(); |
@@ -97,6 +100,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | @@ -97,6 +100,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
97 | 100 | ||
98 | Firmware firmware = new Firmware(); | 101 | Firmware firmware = new Firmware(); |
99 | firmware.setTenantId(tenantId); | 102 | firmware.setTenantId(tenantId); |
103 | + firmware.setDeviceProfileId(savedDeviceProfile.getId()); | ||
104 | + firmware.setType(FIRMWARE); | ||
100 | firmware.setTitle("my firmware"); | 105 | firmware.setTitle("my firmware"); |
101 | firmware.setVersion("v1.0"); | 106 | firmware.setVersion("v1.0"); |
102 | firmware.setFileName("test.txt"); | 107 | firmware.setFileName("test.txt"); |
@@ -20,10 +20,13 @@ import org.apache.commons.lang3.RandomStringUtils; | @@ -20,10 +20,13 @@ import org.apache.commons.lang3.RandomStringUtils; | ||
20 | import org.junit.After; | 20 | import org.junit.After; |
21 | import org.junit.Assert; | 21 | import org.junit.Assert; |
22 | import org.junit.Before; | 22 | import org.junit.Before; |
23 | +import org.junit.Rule; | ||
23 | import org.junit.Test; | 24 | import org.junit.Test; |
25 | +import org.junit.rules.ExpectedException; | ||
24 | import org.thingsboard.server.common.data.Customer; | 26 | import org.thingsboard.server.common.data.Customer; |
25 | import org.thingsboard.server.common.data.Device; | 27 | import org.thingsboard.server.common.data.Device; |
26 | import org.thingsboard.server.common.data.DeviceInfo; | 28 | import org.thingsboard.server.common.data.DeviceInfo; |
29 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
27 | import org.thingsboard.server.common.data.EntitySubtype; | 30 | import org.thingsboard.server.common.data.EntitySubtype; |
28 | import org.thingsboard.server.common.data.Firmware; | 31 | import org.thingsboard.server.common.data.Firmware; |
29 | import org.thingsboard.server.common.data.Tenant; | 32 | import org.thingsboard.server.common.data.Tenant; |
@@ -42,6 +45,7 @@ import java.util.ArrayList; | @@ -42,6 +45,7 @@ import java.util.ArrayList; | ||
42 | import java.util.Collections; | 45 | import java.util.Collections; |
43 | import java.util.List; | 46 | import java.util.List; |
44 | 47 | ||
48 | +import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; | ||
45 | import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; | 49 | import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; |
46 | 50 | ||
47 | public abstract class BaseDeviceServiceTest extends AbstractServiceTest { | 51 | public abstract class BaseDeviceServiceTest extends AbstractServiceTest { |
@@ -66,6 +70,9 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { | @@ -66,6 +70,9 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { | ||
66 | tenantProfileService.deleteTenantProfiles(anotherTenantId); | 70 | tenantProfileService.deleteTenantProfiles(anotherTenantId); |
67 | } | 71 | } |
68 | 72 | ||
73 | + @Rule | ||
74 | + public ExpectedException thrown = ExpectedException.none(); | ||
75 | + | ||
69 | @Test | 76 | @Test |
70 | public void testSaveDevicesWithoutMaxDeviceLimit() { | 77 | public void testSaveDevicesWithoutMaxDeviceLimit() { |
71 | Device device = this.saveDevice(tenantId, "My device"); | 78 | Device device = this.saveDevice(tenantId, "My device"); |
@@ -183,6 +190,8 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { | @@ -183,6 +190,8 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { | ||
183 | 190 | ||
184 | Firmware firmware = new Firmware(); | 191 | Firmware firmware = new Firmware(); |
185 | firmware.setTenantId(tenantId); | 192 | firmware.setTenantId(tenantId); |
193 | + firmware.setDeviceProfileId(device.getDeviceProfileId()); | ||
194 | + firmware.setType(FIRMWARE); | ||
186 | firmware.setTitle("my firmware"); | 195 | firmware.setTitle("my firmware"); |
187 | firmware.setVersion("v1.0"); | 196 | firmware.setVersion("v1.0"); |
188 | firmware.setFileName("test.txt"); | 197 | firmware.setFileName("test.txt"); |
@@ -198,6 +207,40 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { | @@ -198,6 +207,40 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest { | ||
198 | Device foundDevice = deviceService.findDeviceById(tenantId, savedDevice.getId()); | 207 | Device foundDevice = deviceService.findDeviceById(tenantId, savedDevice.getId()); |
199 | Assert.assertEquals(foundDevice.getName(), savedDevice.getName()); | 208 | Assert.assertEquals(foundDevice.getName(), savedDevice.getName()); |
200 | } | 209 | } |
210 | + | ||
211 | + @Test | ||
212 | + public void testAssignFirmwareToDeviceWithDifferentDeviceProfile() { | ||
213 | + Device device = new Device(); | ||
214 | + device.setTenantId(tenantId); | ||
215 | + device.setName("My device"); | ||
216 | + device.setType("default"); | ||
217 | + Device savedDevice = deviceService.saveDevice(device); | ||
218 | + | ||
219 | + Assert.assertNotNull(savedDevice); | ||
220 | + | ||
221 | + DeviceProfile deviceProfile = createDeviceProfile(tenantId, "New device Profile"); | ||
222 | + DeviceProfile savedProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | ||
223 | + Assert.assertNotNull(savedProfile); | ||
224 | + | ||
225 | + Firmware firmware = new Firmware(); | ||
226 | + firmware.setTenantId(tenantId); | ||
227 | + firmware.setDeviceProfileId(savedProfile.getId()); | ||
228 | + firmware.setType(FIRMWARE); | ||
229 | + firmware.setTitle("my firmware"); | ||
230 | + firmware.setVersion("v1.0"); | ||
231 | + firmware.setFileName("test.txt"); | ||
232 | + firmware.setContentType("text/plain"); | ||
233 | + firmware.setChecksumAlgorithm("sha256"); | ||
234 | + firmware.setChecksum("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"); | ||
235 | + firmware.setData(ByteBuffer.wrap(new byte[]{1})); | ||
236 | + Firmware savedFirmware = firmwareService.saveFirmware(firmware); | ||
237 | + | ||
238 | + savedDevice.setFirmwareId(savedFirmware.getId()); | ||
239 | + | ||
240 | + thrown.expect(DataValidationException.class); | ||
241 | + thrown.expectMessage("Can't assign firmware with different deviceProfile!"); | ||
242 | + deviceService.saveDevice(savedDevice); | ||
243 | + } | ||
201 | 244 | ||
202 | @Test(expected = DataValidationException.class) | 245 | @Test(expected = DataValidationException.class) |
203 | public void testSaveDeviceWithEmptyName() { | 246 | public void testSaveDeviceWithEmptyName() { |
@@ -19,13 +19,16 @@ import com.datastax.oss.driver.api.core.uuid.Uuids; | @@ -19,13 +19,16 @@ import com.datastax.oss.driver.api.core.uuid.Uuids; | ||
19 | import org.junit.After; | 19 | import org.junit.After; |
20 | import org.junit.Assert; | 20 | import org.junit.Assert; |
21 | import org.junit.Before; | 21 | import org.junit.Before; |
22 | +import org.junit.Rule; | ||
22 | import org.junit.Test; | 23 | import org.junit.Test; |
24 | +import org.junit.rules.ExpectedException; | ||
23 | import org.thingsboard.common.util.JacksonUtil; | 25 | import org.thingsboard.common.util.JacksonUtil; |
24 | import org.thingsboard.server.common.data.Device; | 26 | import org.thingsboard.server.common.data.Device; |
25 | import org.thingsboard.server.common.data.DeviceProfile; | 27 | import org.thingsboard.server.common.data.DeviceProfile; |
26 | import org.thingsboard.server.common.data.Firmware; | 28 | import org.thingsboard.server.common.data.Firmware; |
27 | import org.thingsboard.server.common.data.FirmwareInfo; | 29 | import org.thingsboard.server.common.data.FirmwareInfo; |
28 | import org.thingsboard.server.common.data.Tenant; | 30 | import org.thingsboard.server.common.data.Tenant; |
31 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
29 | import org.thingsboard.server.common.data.id.TenantId; | 32 | import org.thingsboard.server.common.data.id.TenantId; |
30 | import org.thingsboard.server.common.data.page.PageData; | 33 | import org.thingsboard.server.common.data.page.PageData; |
31 | import org.thingsboard.server.common.data.page.PageLink; | 34 | import org.thingsboard.server.common.data.page.PageLink; |
@@ -36,6 +39,8 @@ import java.util.ArrayList; | @@ -36,6 +39,8 @@ import java.util.ArrayList; | ||
36 | import java.util.Collections; | 39 | import java.util.Collections; |
37 | import java.util.List; | 40 | import java.util.List; |
38 | 41 | ||
42 | +import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; | ||
43 | + | ||
39 | public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | 44 | public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { |
40 | 45 | ||
41 | public static final String TITLE = "My firmware"; | 46 | public static final String TITLE = "My firmware"; |
@@ -50,6 +55,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -50,6 +55,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
50 | 55 | ||
51 | private TenantId tenantId; | 56 | private TenantId tenantId; |
52 | 57 | ||
58 | + private DeviceProfileId deviceProfileId; | ||
59 | + | ||
53 | @Before | 60 | @Before |
54 | public void before() { | 61 | public void before() { |
55 | Tenant tenant = new Tenant(); | 62 | Tenant tenant = new Tenant(); |
@@ -57,8 +64,16 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -57,8 +64,16 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
57 | Tenant savedTenant = tenantService.saveTenant(tenant); | 64 | Tenant savedTenant = tenantService.saveTenant(tenant); |
58 | Assert.assertNotNull(savedTenant); | 65 | Assert.assertNotNull(savedTenant); |
59 | tenantId = savedTenant.getId(); | 66 | tenantId = savedTenant.getId(); |
67 | + | ||
68 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); | ||
69 | + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | ||
70 | + Assert.assertNotNull(savedDeviceProfile); | ||
71 | + deviceProfileId = savedDeviceProfile.getId(); | ||
60 | } | 72 | } |
61 | 73 | ||
74 | + @Rule | ||
75 | + public ExpectedException thrown = ExpectedException.none(); | ||
76 | + | ||
62 | @After | 77 | @After |
63 | public void after() { | 78 | public void after() { |
64 | tenantService.deleteTenant(tenantId); | 79 | tenantService.deleteTenant(tenantId); |
@@ -68,6 +83,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -68,6 +83,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
68 | public void testSaveFirmware() { | 83 | public void testSaveFirmware() { |
69 | Firmware firmware = new Firmware(); | 84 | Firmware firmware = new Firmware(); |
70 | firmware.setTenantId(tenantId); | 85 | firmware.setTenantId(tenantId); |
86 | + firmware.setDeviceProfileId(deviceProfileId); | ||
87 | + firmware.setType(FIRMWARE); | ||
71 | firmware.setTitle(TITLE); | 88 | firmware.setTitle(TITLE); |
72 | firmware.setVersion(VERSION); | 89 | firmware.setVersion(VERSION); |
73 | firmware.setFileName(FILE_NAME); | 90 | firmware.setFileName(FILE_NAME); |
@@ -99,6 +116,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -99,6 +116,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
99 | public void testSaveFirmwareInfoAndUpdateWithData() { | 116 | public void testSaveFirmwareInfoAndUpdateWithData() { |
100 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 117 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
101 | firmwareInfo.setTenantId(tenantId); | 118 | firmwareInfo.setTenantId(tenantId); |
119 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
120 | + firmwareInfo.setType(FIRMWARE); | ||
102 | firmwareInfo.setTitle(TITLE); | 121 | firmwareInfo.setTitle(TITLE); |
103 | firmwareInfo.setVersion(VERSION); | 122 | firmwareInfo.setVersion(VERSION); |
104 | FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo); | 123 | FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo); |
@@ -112,6 +131,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -112,6 +131,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
112 | Firmware firmware = new Firmware(savedFirmwareInfo.getId()); | 131 | Firmware firmware = new Firmware(savedFirmwareInfo.getId()); |
113 | firmware.setCreatedTime(firmwareInfo.getCreatedTime()); | 132 | firmware.setCreatedTime(firmwareInfo.getCreatedTime()); |
114 | firmware.setTenantId(tenantId); | 133 | firmware.setTenantId(tenantId); |
134 | + firmware.setDeviceProfileId(deviceProfileId); | ||
135 | + firmware.setType(FIRMWARE); | ||
115 | firmware.setTitle(TITLE); | 136 | firmware.setTitle(TITLE); |
116 | firmware.setVersion(VERSION); | 137 | firmware.setVersion(VERSION); |
117 | firmware.setFileName(FILE_NAME); | 138 | firmware.setFileName(FILE_NAME); |
@@ -135,9 +156,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -135,9 +156,11 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
135 | firmwareService.deleteFirmware(tenantId, savedFirmwareInfo.getId()); | 156 | firmwareService.deleteFirmware(tenantId, savedFirmwareInfo.getId()); |
136 | } | 157 | } |
137 | 158 | ||
138 | - @Test(expected = DataValidationException.class) | 159 | + @Test |
139 | public void testSaveFirmwareWithEmptyTenant() { | 160 | public void testSaveFirmwareWithEmptyTenant() { |
140 | Firmware firmware = new Firmware(); | 161 | Firmware firmware = new Firmware(); |
162 | + firmware.setDeviceProfileId(deviceProfileId); | ||
163 | + firmware.setType(FIRMWARE); | ||
141 | firmware.setTitle(TITLE); | 164 | firmware.setTitle(TITLE); |
142 | firmware.setVersion(VERSION); | 165 | firmware.setVersion(VERSION); |
143 | firmware.setFileName(FILE_NAME); | 166 | firmware.setFileName(FILE_NAME); |
@@ -145,65 +168,108 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -145,65 +168,108 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
145 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | 168 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); |
146 | firmware.setChecksum(CHECKSUM); | 169 | firmware.setChecksum(CHECKSUM); |
147 | firmware.setData(DATA); | 170 | firmware.setData(DATA); |
171 | + | ||
172 | + thrown.expect(DataValidationException.class); | ||
173 | + thrown.expectMessage("Firmware should be assigned to tenant!"); | ||
148 | firmwareService.saveFirmware(firmware); | 174 | firmwareService.saveFirmware(firmware); |
149 | } | 175 | } |
150 | 176 | ||
151 | - @Test(expected = DataValidationException.class) | 177 | + @Test |
178 | + public void testSaveFirmwareWithEmptyType() { | ||
179 | + Firmware firmware = new Firmware(); | ||
180 | + firmware.setTenantId(tenantId); | ||
181 | + firmware.setDeviceProfileId(deviceProfileId); | ||
182 | + firmware.setTitle(TITLE); | ||
183 | + firmware.setVersion(VERSION); | ||
184 | + firmware.setFileName(FILE_NAME); | ||
185 | + firmware.setContentType(CONTENT_TYPE); | ||
186 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | ||
187 | + firmware.setChecksum(CHECKSUM); | ||
188 | + firmware.setData(DATA); | ||
189 | + | ||
190 | + thrown.expect(DataValidationException.class); | ||
191 | + thrown.expectMessage("Type should be specified!"); | ||
192 | + firmwareService.saveFirmware(firmware); | ||
193 | + } | ||
194 | + | ||
195 | + @Test | ||
152 | public void testSaveFirmwareWithEmptyTitle() { | 196 | public void testSaveFirmwareWithEmptyTitle() { |
153 | Firmware firmware = new Firmware(); | 197 | Firmware firmware = new Firmware(); |
154 | firmware.setTenantId(tenantId); | 198 | firmware.setTenantId(tenantId); |
199 | + firmware.setDeviceProfileId(deviceProfileId); | ||
200 | + firmware.setType(FIRMWARE); | ||
155 | firmware.setVersion(VERSION); | 201 | firmware.setVersion(VERSION); |
156 | firmware.setFileName(FILE_NAME); | 202 | firmware.setFileName(FILE_NAME); |
157 | firmware.setContentType(CONTENT_TYPE); | 203 | firmware.setContentType(CONTENT_TYPE); |
158 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | 204 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); |
159 | firmware.setChecksum(CHECKSUM); | 205 | firmware.setChecksum(CHECKSUM); |
160 | firmware.setData(DATA); | 206 | firmware.setData(DATA); |
207 | + | ||
208 | + thrown.expect(DataValidationException.class); | ||
209 | + thrown.expectMessage("Firmware title should be specified!"); | ||
161 | firmwareService.saveFirmware(firmware); | 210 | firmwareService.saveFirmware(firmware); |
162 | } | 211 | } |
163 | 212 | ||
164 | - @Test(expected = DataValidationException.class) | 213 | + @Test |
165 | public void testSaveFirmwareWithEmptyFileName() { | 214 | public void testSaveFirmwareWithEmptyFileName() { |
166 | Firmware firmware = new Firmware(); | 215 | Firmware firmware = new Firmware(); |
167 | firmware.setTenantId(tenantId); | 216 | firmware.setTenantId(tenantId); |
217 | + firmware.setDeviceProfileId(deviceProfileId); | ||
218 | + firmware.setType(FIRMWARE); | ||
168 | firmware.setTitle(TITLE); | 219 | firmware.setTitle(TITLE); |
169 | firmware.setVersion(VERSION); | 220 | firmware.setVersion(VERSION); |
170 | firmware.setContentType(CONTENT_TYPE); | 221 | firmware.setContentType(CONTENT_TYPE); |
171 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | 222 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); |
172 | firmware.setChecksum(CHECKSUM); | 223 | firmware.setChecksum(CHECKSUM); |
173 | firmware.setData(DATA); | 224 | firmware.setData(DATA); |
225 | + | ||
226 | + thrown.expect(DataValidationException.class); | ||
227 | + thrown.expectMessage("Firmware file name should be specified!"); | ||
174 | firmwareService.saveFirmware(firmware); | 228 | firmwareService.saveFirmware(firmware); |
175 | } | 229 | } |
176 | 230 | ||
177 | - @Test(expected = DataValidationException.class) | 231 | + @Test |
178 | public void testSaveFirmwareWithEmptyContentType() { | 232 | public void testSaveFirmwareWithEmptyContentType() { |
179 | Firmware firmware = new Firmware(); | 233 | Firmware firmware = new Firmware(); |
180 | firmware.setTenantId(tenantId); | 234 | firmware.setTenantId(tenantId); |
235 | + firmware.setDeviceProfileId(deviceProfileId); | ||
236 | + firmware.setType(FIRMWARE); | ||
181 | firmware.setTitle(TITLE); | 237 | firmware.setTitle(TITLE); |
182 | firmware.setVersion(VERSION); | 238 | firmware.setVersion(VERSION); |
183 | firmware.setFileName(FILE_NAME); | 239 | firmware.setFileName(FILE_NAME); |
184 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | 240 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); |
185 | firmware.setChecksum(CHECKSUM); | 241 | firmware.setChecksum(CHECKSUM); |
186 | firmware.setData(DATA); | 242 | firmware.setData(DATA); |
243 | + | ||
244 | + thrown.expect(DataValidationException.class); | ||
245 | + thrown.expectMessage("Firmware content type should be specified!"); | ||
187 | firmwareService.saveFirmware(firmware); | 246 | firmwareService.saveFirmware(firmware); |
188 | } | 247 | } |
189 | 248 | ||
190 | - @Test(expected = DataValidationException.class) | 249 | + @Test |
191 | public void testSaveFirmwareWithEmptyData() { | 250 | public void testSaveFirmwareWithEmptyData() { |
192 | Firmware firmware = new Firmware(); | 251 | Firmware firmware = new Firmware(); |
193 | firmware.setTenantId(tenantId); | 252 | firmware.setTenantId(tenantId); |
253 | + firmware.setDeviceProfileId(deviceProfileId); | ||
254 | + firmware.setType(FIRMWARE); | ||
194 | firmware.setTitle(TITLE); | 255 | firmware.setTitle(TITLE); |
195 | firmware.setVersion(VERSION); | 256 | firmware.setVersion(VERSION); |
196 | firmware.setFileName(FILE_NAME); | 257 | firmware.setFileName(FILE_NAME); |
197 | firmware.setContentType(CONTENT_TYPE); | 258 | firmware.setContentType(CONTENT_TYPE); |
198 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | 259 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); |
199 | firmware.setChecksum(CHECKSUM); | 260 | firmware.setChecksum(CHECKSUM); |
261 | + | ||
262 | + thrown.expect(DataValidationException.class); | ||
263 | + thrown.expectMessage("Firmware data should be specified!"); | ||
200 | firmwareService.saveFirmware(firmware); | 264 | firmwareService.saveFirmware(firmware); |
201 | } | 265 | } |
202 | 266 | ||
203 | - @Test(expected = DataValidationException.class) | 267 | + @Test |
204 | public void testSaveFirmwareWithInvalidTenant() { | 268 | public void testSaveFirmwareWithInvalidTenant() { |
205 | Firmware firmware = new Firmware(); | 269 | Firmware firmware = new Firmware(); |
206 | firmware.setTenantId(new TenantId(Uuids.timeBased())); | 270 | firmware.setTenantId(new TenantId(Uuids.timeBased())); |
271 | + firmware.setDeviceProfileId(deviceProfileId); | ||
272 | + firmware.setType(FIRMWARE); | ||
207 | firmware.setTitle(TITLE); | 273 | firmware.setTitle(TITLE); |
208 | firmware.setVersion(VERSION); | 274 | firmware.setVersion(VERSION); |
209 | firmware.setFileName(FILE_NAME); | 275 | firmware.setFileName(FILE_NAME); |
@@ -211,41 +277,77 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -211,41 +277,77 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
211 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | 277 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); |
212 | firmware.setChecksum(CHECKSUM); | 278 | firmware.setChecksum(CHECKSUM); |
213 | firmware.setData(DATA); | 279 | firmware.setData(DATA); |
280 | + | ||
281 | + thrown.expect(DataValidationException.class); | ||
282 | + thrown.expectMessage("Firmware is referencing to non-existent tenant!"); | ||
214 | firmwareService.saveFirmware(firmware); | 283 | firmwareService.saveFirmware(firmware); |
215 | } | 284 | } |
216 | 285 | ||
217 | - @Test(expected = DataValidationException.class) | 286 | + @Test |
287 | + public void testSaveFirmwareWithInvalidDeviceProfileId() { | ||
288 | + Firmware firmware = new Firmware(); | ||
289 | + firmware.setTenantId(tenantId); | ||
290 | + firmware.setDeviceProfileId(new DeviceProfileId(Uuids.timeBased())); | ||
291 | + firmware.setType(FIRMWARE); | ||
292 | + firmware.setTitle(TITLE); | ||
293 | + firmware.setVersion(VERSION); | ||
294 | + firmware.setFileName(FILE_NAME); | ||
295 | + firmware.setContentType(CONTENT_TYPE); | ||
296 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | ||
297 | + firmware.setChecksum(CHECKSUM); | ||
298 | + firmware.setData(DATA); | ||
299 | + | ||
300 | + thrown.expect(DataValidationException.class); | ||
301 | + thrown.expectMessage("Firmware is referencing to non-existent device profile!"); | ||
302 | + firmwareService.saveFirmware(firmware); | ||
303 | + } | ||
304 | + | ||
305 | + @Test | ||
218 | public void testSaveFirmwareWithEmptyChecksum() { | 306 | public void testSaveFirmwareWithEmptyChecksum() { |
219 | Firmware firmware = new Firmware(); | 307 | Firmware firmware = new Firmware(); |
220 | - firmware.setTenantId(new TenantId(Uuids.timeBased())); | 308 | + firmware.setTenantId(tenantId); |
309 | + firmware.setDeviceProfileId(deviceProfileId); | ||
310 | + firmware.setType(FIRMWARE); | ||
221 | firmware.setTitle(TITLE); | 311 | firmware.setTitle(TITLE); |
222 | firmware.setVersion(VERSION); | 312 | firmware.setVersion(VERSION); |
223 | firmware.setFileName(FILE_NAME); | 313 | firmware.setFileName(FILE_NAME); |
224 | firmware.setContentType(CONTENT_TYPE); | 314 | firmware.setContentType(CONTENT_TYPE); |
225 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | 315 | firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); |
226 | firmware.setData(DATA); | 316 | firmware.setData(DATA); |
317 | + | ||
318 | + thrown.expect(DataValidationException.class); | ||
319 | + thrown.expectMessage("Firmware checksum should be specified!"); | ||
227 | firmwareService.saveFirmware(firmware); | 320 | firmwareService.saveFirmware(firmware); |
228 | } | 321 | } |
229 | 322 | ||
230 | - @Test(expected = DataValidationException.class) | 323 | + @Test |
231 | public void testSaveFirmwareInfoWithExistingTitleAndVersion() { | 324 | public void testSaveFirmwareInfoWithExistingTitleAndVersion() { |
232 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 325 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
233 | firmwareInfo.setTenantId(tenantId); | 326 | firmwareInfo.setTenantId(tenantId); |
327 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
328 | + firmwareInfo.setType(FIRMWARE); | ||
234 | firmwareInfo.setTitle(TITLE); | 329 | firmwareInfo.setTitle(TITLE); |
235 | firmwareInfo.setVersion(VERSION); | 330 | firmwareInfo.setVersion(VERSION); |
236 | firmwareService.saveFirmwareInfo(firmwareInfo); | 331 | firmwareService.saveFirmwareInfo(firmwareInfo); |
237 | 332 | ||
238 | FirmwareInfo newFirmwareInfo = new FirmwareInfo(); | 333 | FirmwareInfo newFirmwareInfo = new FirmwareInfo(); |
239 | newFirmwareInfo.setTenantId(tenantId); | 334 | newFirmwareInfo.setTenantId(tenantId); |
335 | + newFirmwareInfo.setDeviceProfileId(deviceProfileId); | ||
336 | + newFirmwareInfo.setType(FIRMWARE); | ||
240 | newFirmwareInfo.setTitle(TITLE); | 337 | newFirmwareInfo.setTitle(TITLE); |
241 | newFirmwareInfo.setVersion(VERSION); | 338 | newFirmwareInfo.setVersion(VERSION); |
339 | + | ||
340 | + thrown.expect(DataValidationException.class); | ||
341 | + thrown.expectMessage("Firmware with such title and version already exists!"); | ||
242 | firmwareService.saveFirmwareInfo(newFirmwareInfo); | 342 | firmwareService.saveFirmwareInfo(newFirmwareInfo); |
243 | } | 343 | } |
244 | 344 | ||
245 | - @Test(expected = DataValidationException.class) | 345 | + @Test |
246 | public void testSaveFirmwareWithExistingTitleAndVersion() { | 346 | public void testSaveFirmwareWithExistingTitleAndVersion() { |
247 | Firmware firmware = new Firmware(); | 347 | Firmware firmware = new Firmware(); |
248 | firmware.setTenantId(tenantId); | 348 | firmware.setTenantId(tenantId); |
349 | + firmware.setDeviceProfileId(deviceProfileId); | ||
350 | + firmware.setType(FIRMWARE); | ||
249 | firmware.setTitle(TITLE); | 351 | firmware.setTitle(TITLE); |
250 | firmware.setVersion(VERSION); | 352 | firmware.setVersion(VERSION); |
251 | firmware.setFileName(FILE_NAME); | 353 | firmware.setFileName(FILE_NAME); |
@@ -257,18 +359,27 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -257,18 +359,27 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
257 | 359 | ||
258 | Firmware newFirmware = new Firmware(); | 360 | Firmware newFirmware = new Firmware(); |
259 | newFirmware.setTenantId(tenantId); | 361 | newFirmware.setTenantId(tenantId); |
362 | + newFirmware.setDeviceProfileId(deviceProfileId); | ||
363 | + newFirmware.setType(FIRMWARE); | ||
260 | newFirmware.setTitle(TITLE); | 364 | newFirmware.setTitle(TITLE); |
261 | newFirmware.setVersion(VERSION); | 365 | newFirmware.setVersion(VERSION); |
262 | newFirmware.setFileName(FILE_NAME); | 366 | newFirmware.setFileName(FILE_NAME); |
263 | newFirmware.setContentType(CONTENT_TYPE); | 367 | newFirmware.setContentType(CONTENT_TYPE); |
368 | + newFirmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | ||
369 | + newFirmware.setChecksum(CHECKSUM); | ||
264 | newFirmware.setData(DATA); | 370 | newFirmware.setData(DATA); |
371 | + | ||
372 | + thrown.expect(DataValidationException.class); | ||
373 | + thrown.expectMessage("Firmware with such title and version already exists!"); | ||
265 | firmwareService.saveFirmware(newFirmware); | 374 | firmwareService.saveFirmware(newFirmware); |
266 | } | 375 | } |
267 | 376 | ||
268 | - @Test(expected = DataValidationException.class) | 377 | + @Test |
269 | public void testDeleteFirmwareWithReferenceByDevice() { | 378 | public void testDeleteFirmwareWithReferenceByDevice() { |
270 | Firmware firmware = new Firmware(); | 379 | Firmware firmware = new Firmware(); |
271 | firmware.setTenantId(tenantId); | 380 | firmware.setTenantId(tenantId); |
381 | + firmware.setDeviceProfileId(deviceProfileId); | ||
382 | + firmware.setType(FIRMWARE); | ||
272 | firmware.setTitle(TITLE); | 383 | firmware.setTitle(TITLE); |
273 | firmware.setVersion(VERSION); | 384 | firmware.setVersion(VERSION); |
274 | firmware.setFileName(FILE_NAME); | 385 | firmware.setFileName(FILE_NAME); |
@@ -281,11 +392,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -281,11 +392,13 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
281 | Device device = new Device(); | 392 | Device device = new Device(); |
282 | device.setTenantId(tenantId); | 393 | device.setTenantId(tenantId); |
283 | device.setName("My device"); | 394 | device.setName("My device"); |
284 | - device.setType("default"); | 395 | + device.setDeviceProfileId(deviceProfileId); |
285 | device.setFirmwareId(savedFirmware.getId()); | 396 | device.setFirmwareId(savedFirmware.getId()); |
286 | Device savedDevice = deviceService.saveDevice(device); | 397 | Device savedDevice = deviceService.saveDevice(device); |
287 | 398 | ||
288 | try { | 399 | try { |
400 | + thrown.expect(DataValidationException.class); | ||
401 | + thrown.expectMessage("The firmware referenced by the devices cannot be deleted!"); | ||
289 | firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); | 402 | firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); |
290 | } finally { | 403 | } finally { |
291 | deviceService.deleteDevice(tenantId, savedDevice.getId()); | 404 | deviceService.deleteDevice(tenantId, savedDevice.getId()); |
@@ -293,10 +406,12 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -293,10 +406,12 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
293 | } | 406 | } |
294 | } | 407 | } |
295 | 408 | ||
296 | - @Test(expected = DataValidationException.class) | ||
297 | - public void testDeleteFirmwareWithReferenceByDeviceProfile() { | 409 | + @Test |
410 | + public void testUpdateDeviceProfileIdWithReferenceByDevice() { | ||
298 | Firmware firmware = new Firmware(); | 411 | Firmware firmware = new Firmware(); |
299 | firmware.setTenantId(tenantId); | 412 | firmware.setTenantId(tenantId); |
413 | + firmware.setDeviceProfileId(deviceProfileId); | ||
414 | + firmware.setType(FIRMWARE); | ||
300 | firmware.setTitle(TITLE); | 415 | firmware.setTitle(TITLE); |
301 | firmware.setVersion(VERSION); | 416 | firmware.setVersion(VERSION); |
302 | firmware.setFileName(FILE_NAME); | 417 | firmware.setFileName(FILE_NAME); |
@@ -306,12 +421,81 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -306,12 +421,81 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
306 | firmware.setData(DATA); | 421 | firmware.setData(DATA); |
307 | Firmware savedFirmware = firmwareService.saveFirmware(firmware); | 422 | Firmware savedFirmware = firmwareService.saveFirmware(firmware); |
308 | 423 | ||
309 | - DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile"); | ||
310 | - deviceProfile.setFirmwareId(savedFirmware.getId()); | 424 | + Device device = new Device(); |
425 | + device.setTenantId(tenantId); | ||
426 | + device.setName("My device"); | ||
427 | + device.setDeviceProfileId(deviceProfileId); | ||
428 | + device.setFirmwareId(savedFirmware.getId()); | ||
429 | + Device savedDevice = deviceService.saveDevice(device); | ||
430 | + | ||
431 | + try { | ||
432 | + thrown.expect(DataValidationException.class); | ||
433 | + thrown.expectMessage("Can`t update deviceProfileId because firmware is already in use!"); | ||
434 | + savedFirmware.setDeviceProfileId(null); | ||
435 | + firmwareService.saveFirmware(savedFirmware); | ||
436 | + } finally { | ||
437 | + deviceService.deleteDevice(tenantId, savedDevice.getId()); | ||
438 | + firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); | ||
439 | + } | ||
440 | + } | ||
441 | + | ||
442 | + @Test | ||
443 | + public void testDeleteFirmwareWithReferenceByDeviceProfile() { | ||
444 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Test Device Profile"); | ||
311 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | 445 | DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); |
312 | 446 | ||
447 | + Firmware firmware = new Firmware(); | ||
448 | + firmware.setTenantId(tenantId); | ||
449 | + firmware.setDeviceProfileId(savedDeviceProfile.getId()); | ||
450 | + firmware.setType(FIRMWARE); | ||
451 | + firmware.setTitle(TITLE); | ||
452 | + firmware.setVersion(VERSION); | ||
453 | + firmware.setFileName(FILE_NAME); | ||
454 | + firmware.setContentType(CONTENT_TYPE); | ||
455 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | ||
456 | + firmware.setChecksum(CHECKSUM); | ||
457 | + firmware.setData(DATA); | ||
458 | + Firmware savedFirmware = firmwareService.saveFirmware(firmware); | ||
459 | + | ||
460 | + savedDeviceProfile.setFirmwareId(savedFirmware.getId()); | ||
461 | + deviceProfileService.saveDeviceProfile(savedDeviceProfile); | ||
462 | + | ||
313 | try { | 463 | try { |
464 | + thrown.expect(DataValidationException.class); | ||
465 | + thrown.expectMessage("The firmware referenced by the device profile cannot be deleted!"); | ||
466 | + firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); | ||
467 | + } finally { | ||
468 | + deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); | ||
314 | firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); | 469 | firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); |
470 | + } | ||
471 | + } | ||
472 | + | ||
473 | + @Test | ||
474 | + public void testUpdateDeviceProfileIdWithReferenceByDeviceProfile() { | ||
475 | + DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Test Device Profile"); | ||
476 | + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | ||
477 | + | ||
478 | + Firmware firmware = new Firmware(); | ||
479 | + firmware.setTenantId(tenantId); | ||
480 | + firmware.setDeviceProfileId(savedDeviceProfile.getId()); | ||
481 | + firmware.setType(FIRMWARE); | ||
482 | + firmware.setTitle(TITLE); | ||
483 | + firmware.setVersion(VERSION); | ||
484 | + firmware.setFileName(FILE_NAME); | ||
485 | + firmware.setContentType(CONTENT_TYPE); | ||
486 | + firmware.setChecksumAlgorithm(CHECKSUM_ALGORITHM); | ||
487 | + firmware.setChecksum(CHECKSUM); | ||
488 | + firmware.setData(DATA); | ||
489 | + Firmware savedFirmware = firmwareService.saveFirmware(firmware); | ||
490 | + | ||
491 | + savedDeviceProfile.setFirmwareId(savedFirmware.getId()); | ||
492 | + deviceProfileService.saveDeviceProfile(savedDeviceProfile); | ||
493 | + | ||
494 | + try { | ||
495 | + thrown.expect(DataValidationException.class); | ||
496 | + thrown.expectMessage("Can`t update deviceProfileId because firmware is already in use!"); | ||
497 | + savedFirmware.setDeviceProfileId(null); | ||
498 | + firmwareService.saveFirmware(savedFirmware); | ||
315 | } finally { | 499 | } finally { |
316 | deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); | 500 | deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); |
317 | firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); | 501 | firmwareService.deleteFirmware(tenantId, savedFirmware.getId()); |
@@ -322,6 +506,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -322,6 +506,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
322 | public void testFindFirmwareById() { | 506 | public void testFindFirmwareById() { |
323 | Firmware firmware = new Firmware(); | 507 | Firmware firmware = new Firmware(); |
324 | firmware.setTenantId(tenantId); | 508 | firmware.setTenantId(tenantId); |
509 | + firmware.setDeviceProfileId(deviceProfileId); | ||
510 | + firmware.setType(FIRMWARE); | ||
325 | firmware.setTitle(TITLE); | 511 | firmware.setTitle(TITLE); |
326 | firmware.setVersion(VERSION); | 512 | firmware.setVersion(VERSION); |
327 | firmware.setFileName(FILE_NAME); | 513 | firmware.setFileName(FILE_NAME); |
@@ -341,6 +527,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -341,6 +527,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
341 | public void testFindFirmwareInfoById() { | 527 | public void testFindFirmwareInfoById() { |
342 | FirmwareInfo firmware = new FirmwareInfo(); | 528 | FirmwareInfo firmware = new FirmwareInfo(); |
343 | firmware.setTenantId(tenantId); | 529 | firmware.setTenantId(tenantId); |
530 | + firmware.setDeviceProfileId(deviceProfileId); | ||
531 | + firmware.setType(FIRMWARE); | ||
344 | firmware.setTitle(TITLE); | 532 | firmware.setTitle(TITLE); |
345 | firmware.setVersion(VERSION); | 533 | firmware.setVersion(VERSION); |
346 | FirmwareInfo savedFirmware = firmwareService.saveFirmwareInfo(firmware); | 534 | FirmwareInfo savedFirmware = firmwareService.saveFirmwareInfo(firmware); |
@@ -355,6 +543,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -355,6 +543,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
355 | public void testDeleteFirmware() { | 543 | public void testDeleteFirmware() { |
356 | Firmware firmware = new Firmware(); | 544 | Firmware firmware = new Firmware(); |
357 | firmware.setTenantId(tenantId); | 545 | firmware.setTenantId(tenantId); |
546 | + firmware.setDeviceProfileId(deviceProfileId); | ||
547 | + firmware.setType(FIRMWARE); | ||
358 | firmware.setTitle(TITLE); | 548 | firmware.setTitle(TITLE); |
359 | firmware.setVersion(VERSION); | 549 | firmware.setVersion(VERSION); |
360 | firmware.setFileName(FILE_NAME); | 550 | firmware.setFileName(FILE_NAME); |
@@ -377,6 +567,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -377,6 +567,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
377 | for (int i = 0; i < 165; i++) { | 567 | for (int i = 0; i < 165; i++) { |
378 | Firmware firmware = new Firmware(); | 568 | Firmware firmware = new Firmware(); |
379 | firmware.setTenantId(tenantId); | 569 | firmware.setTenantId(tenantId); |
570 | + firmware.setDeviceProfileId(deviceProfileId); | ||
571 | + firmware.setType(FIRMWARE); | ||
380 | firmware.setTitle(TITLE); | 572 | firmware.setTitle(TITLE); |
381 | firmware.setVersion(VERSION + i); | 573 | firmware.setVersion(VERSION + i); |
382 | firmware.setFileName(FILE_NAME); | 574 | firmware.setFileName(FILE_NAME); |
@@ -420,6 +612,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -420,6 +612,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
420 | for (int i = 0; i < 165; i++) { | 612 | for (int i = 0; i < 165; i++) { |
421 | FirmwareInfo firmwareInfo = new FirmwareInfo(); | 613 | FirmwareInfo firmwareInfo = new FirmwareInfo(); |
422 | firmwareInfo.setTenantId(tenantId); | 614 | firmwareInfo.setTenantId(tenantId); |
615 | + firmwareInfo.setDeviceProfileId(deviceProfileId); | ||
616 | + firmwareInfo.setType(FIRMWARE); | ||
423 | firmwareInfo.setTitle(TITLE); | 617 | firmwareInfo.setTitle(TITLE); |
424 | firmwareInfo.setVersion(VERSION + i); | 618 | firmwareInfo.setVersion(VERSION + i); |
425 | firmwareInfo.setFileName(FILE_NAME); | 619 | firmwareInfo.setFileName(FILE_NAME); |
@@ -434,7 +628,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -434,7 +628,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
434 | PageLink pageLink = new PageLink(16); | 628 | PageLink pageLink = new PageLink(16); |
435 | PageData<FirmwareInfo> pageData; | 629 | PageData<FirmwareInfo> pageData; |
436 | do { | 630 | do { |
437 | - pageData = firmwareService.findTenantFirmwaresByTenantIdAndHasData(tenantId, false, pageLink); | 631 | + pageData = firmwareService.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, FIRMWARE, false, pageLink); |
438 | loadedFirmwares.addAll(pageData.getData()); | 632 | loadedFirmwares.addAll(pageData.getData()); |
439 | if (pageData.hasNext()) { | 633 | if (pageData.hasNext()) { |
440 | pageLink = pageLink.nextPageLink(); | 634 | pageLink = pageLink.nextPageLink(); |
@@ -450,6 +644,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -450,6 +644,8 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
450 | Firmware firmware = new Firmware(f.getId()); | 644 | Firmware firmware = new Firmware(f.getId()); |
451 | firmware.setCreatedTime(f.getCreatedTime()); | 645 | firmware.setCreatedTime(f.getCreatedTime()); |
452 | firmware.setTenantId(f.getTenantId()); | 646 | firmware.setTenantId(f.getTenantId()); |
647 | + firmware.setDeviceProfileId(deviceProfileId); | ||
648 | + firmware.setType(FIRMWARE); | ||
453 | firmware.setTitle(f.getTitle()); | 649 | firmware.setTitle(f.getTitle()); |
454 | firmware.setVersion(f.getVersion()); | 650 | firmware.setVersion(f.getVersion()); |
455 | firmware.setFileName(FILE_NAME); | 651 | firmware.setFileName(FILE_NAME); |
@@ -465,7 +661,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | @@ -465,7 +661,7 @@ public abstract class BaseFirmwareServiceTest extends AbstractServiceTest { | ||
465 | loadedFirmwares = new ArrayList<>(); | 661 | loadedFirmwares = new ArrayList<>(); |
466 | pageLink = new PageLink(16); | 662 | pageLink = new PageLink(16); |
467 | do { | 663 | do { |
468 | - pageData = firmwareService.findTenantFirmwaresByTenantIdAndHasData(tenantId, true, pageLink); | 664 | + pageData = firmwareService.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, FIRMWARE, true, pageLink); |
469 | loadedFirmwares.addAll(pageData.getData()); | 665 | loadedFirmwares.addAll(pageData.getData()); |
470 | if (pageData.hasNext()) { | 666 | if (pageData.hasNext()) { |
471 | pageLink = pageLink.nextPageLink(); | 667 | pageLink = pageLink.nextPageLink(); |
@@ -361,7 +361,7 @@ export class EntityService { | @@ -361,7 +361,7 @@ export class EntityService { | ||
361 | break; | 361 | break; |
362 | case EntityType.FIRMWARE: | 362 | case EntityType.FIRMWARE: |
363 | pageLink.sortOrder.property = 'title'; | 363 | pageLink.sortOrder.property = 'title'; |
364 | - entitiesObservable = this.firmwareService.getFirmwares(pageLink, true, config); | 364 | + entitiesObservable = this.firmwareService.getFirmwares(pageLink, config); |
365 | break; | 365 | break; |
366 | } | 366 | } |
367 | return entitiesObservable; | 367 | return entitiesObservable; |
@@ -20,7 +20,7 @@ import { PageLink } from '@shared/models/page/page-link'; | @@ -20,7 +20,7 @@ import { PageLink } from '@shared/models/page/page-link'; | ||
20 | import { defaultHttpOptionsFromConfig, defaultHttpUploadOptions, RequestConfig } from '@core/http/http-utils'; | 20 | import { defaultHttpOptionsFromConfig, defaultHttpUploadOptions, RequestConfig } from '@core/http/http-utils'; |
21 | import { Observable } from 'rxjs'; | 21 | import { Observable } from 'rxjs'; |
22 | import { PageData } from '@shared/models/page/page-data'; | 22 | import { PageData } from '@shared/models/page/page-data'; |
23 | -import { Firmware, FirmwareInfo } from '@shared/models/firmware.models'; | 23 | +import { Firmware, FirmwareInfo, FirmwareType } from '@shared/models/firmware.models'; |
24 | import { catchError, map, mergeMap } from 'rxjs/operators'; | 24 | import { catchError, map, mergeMap } from 'rxjs/operators'; |
25 | import { deepClone, isDefinedAndNotNull } from '@core/utils'; | 25 | import { deepClone, isDefinedAndNotNull } from '@core/utils'; |
26 | 26 | ||
@@ -34,12 +34,13 @@ export class FirmwareService { | @@ -34,12 +34,13 @@ export class FirmwareService { | ||
34 | 34 | ||
35 | } | 35 | } |
36 | 36 | ||
37 | - public getFirmwares(pageLink: PageLink, hasData?: boolean, config?: RequestConfig): Observable<PageData<FirmwareInfo>> { | ||
38 | - let url = `/api/firmwares`; | ||
39 | - if (isDefinedAndNotNull(hasData)) { | ||
40 | - url += `/${hasData}`; | ||
41 | - } | ||
42 | - url += `${pageLink.toQuery()}`; | 37 | + public getFirmwares(pageLink: PageLink, config?: RequestConfig): Observable<PageData<FirmwareInfo>> { |
38 | + return this.http.get<PageData<FirmwareInfo>>(`/api/firmwares${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config)); | ||
39 | + } | ||
40 | + | ||
41 | + public getFirmwaresInfoByDeviceProfileId(pageLink: PageLink, deviceProfileId: string, type: FirmwareType, | ||
42 | + hasData = true, config?: RequestConfig): Observable<PageData<FirmwareInfo>> { | ||
43 | + const url = `/api/firmwares/${deviceProfileId}/${type}/${hasData}${pageLink.toQuery()}`; | ||
43 | return this.http.get<PageData<FirmwareInfo>>(url, defaultHttpOptionsFromConfig(config)); | 44 | return this.http.get<PageData<FirmwareInfo>>(url, defaultHttpOptionsFromConfig(config)); |
44 | } | 45 | } |
45 | 46 |
@@ -60,10 +60,6 @@ | @@ -60,10 +60,6 @@ | ||
60 | {{ 'device-profile.type-required' | translate }} | 60 | {{ 'device-profile.type-required' | translate }} |
61 | </mat-error> | 61 | </mat-error> |
62 | </mat-form-field> | 62 | </mat-form-field> |
63 | - <tb-firmware-autocomplete | ||
64 | - [useFullEntityId]="true" | ||
65 | - formControlName="firmwareId"> | ||
66 | - </tb-firmware-autocomplete> | ||
67 | <mat-form-field class="mat-block"> | 63 | <mat-form-field class="mat-block"> |
68 | <mat-label translate>device-profile.description</mat-label> | 64 | <mat-label translate>device-profile.description</mat-label> |
69 | <textarea matInput formControlName="description" rows="2"></textarea> | 65 | <textarea matInput formControlName="description" rows="2"></textarea> |
@@ -108,7 +108,6 @@ export class AddDeviceProfileDialogComponent extends | @@ -108,7 +108,6 @@ export class AddDeviceProfileDialogComponent extends | ||
108 | type: [DeviceProfileType.DEFAULT, [Validators.required]], | 108 | type: [DeviceProfileType.DEFAULT, [Validators.required]], |
109 | defaultRuleChainId: [null, []], | 109 | defaultRuleChainId: [null, []], |
110 | defaultQueueName: ['', []], | 110 | defaultQueueName: ['', []], |
111 | - firmwareId: [null], | ||
112 | description: ['', []] | 111 | description: ['', []] |
113 | } | 112 | } |
114 | ); | 113 | ); |
@@ -187,7 +186,6 @@ export class AddDeviceProfileDialogComponent extends | @@ -187,7 +186,6 @@ export class AddDeviceProfileDialogComponent extends | ||
187 | transportType: this.transportConfigFormGroup.get('transportType').value, | 186 | transportType: this.transportConfigFormGroup.get('transportType').value, |
188 | provisionType: deviceProvisionConfiguration.type, | 187 | provisionType: deviceProvisionConfiguration.type, |
189 | provisionDeviceKey, | 188 | provisionDeviceKey, |
190 | - firmwareId: this.deviceProfileDetailsFormGroup.get('firmwareId').value, | ||
191 | description: this.deviceProfileDetailsFormGroup.get('description').value, | 189 | description: this.deviceProfileDetailsFormGroup.get('description').value, |
192 | profileData: { | 190 | profileData: { |
193 | configuration: createDeviceProfileConfiguration(DeviceProfileType.DEFAULT), | 191 | configuration: createDeviceProfileConfiguration(DeviceProfileType.DEFAULT), |
@@ -65,8 +65,16 @@ | @@ -65,8 +65,16 @@ | ||
65 | </tb-queue-type-list> | 65 | </tb-queue-type-list> |
66 | <tb-firmware-autocomplete | 66 | <tb-firmware-autocomplete |
67 | [useFullEntityId]="true" | 67 | [useFullEntityId]="true" |
68 | + [type]="firmwareTypes.FIRMWARE" | ||
69 | + [deviceProfileId]="deviceProfileId?.id" | ||
68 | formControlName="firmwareId"> | 70 | formControlName="firmwareId"> |
69 | </tb-firmware-autocomplete> | 71 | </tb-firmware-autocomplete> |
72 | + <tb-firmware-autocomplete | ||
73 | + [useFullEntityId]="true" | ||
74 | + [type]="firmwareTypes.SOFTWARE" | ||
75 | + [deviceProfileId]="deviceProfileId?.id" | ||
76 | + formControlName="softwareId"> | ||
77 | + </tb-firmware-autocomplete> | ||
70 | <mat-form-field fxHide class="mat-block"> | 78 | <mat-form-field fxHide class="mat-block"> |
71 | <mat-label translate>device-profile.type</mat-label> | 79 | <mat-label translate>device-profile.type</mat-label> |
72 | <mat-select formControlName="type" required> | 80 | <mat-select formControlName="type" required> |
@@ -40,6 +40,7 @@ import { EntityType } from '@shared/models/entity-type.models'; | @@ -40,6 +40,7 @@ import { EntityType } from '@shared/models/entity-type.models'; | ||
40 | import { RuleChainId } from '@shared/models/id/rule-chain-id'; | 40 | import { RuleChainId } from '@shared/models/id/rule-chain-id'; |
41 | import { ServiceType } from '@shared/models/queue.models'; | 41 | import { ServiceType } from '@shared/models/queue.models'; |
42 | import { EntityId } from '@shared/models/id/entity-id'; | 42 | import { EntityId } from '@shared/models/id/entity-id'; |
43 | +import { FirmwareType } from '@shared/models/firmware.models'; | ||
43 | 44 | ||
44 | @Component({ | 45 | @Component({ |
45 | selector: 'tb-device-profile', | 46 | selector: 'tb-device-profile', |
@@ -69,6 +70,8 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { | @@ -69,6 +70,8 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { | ||
69 | 70 | ||
70 | deviceProfileId: EntityId; | 71 | deviceProfileId: EntityId; |
71 | 72 | ||
73 | + firmwareTypes = FirmwareType; | ||
74 | + | ||
72 | constructor(protected store: Store<AppState>, | 75 | constructor(protected store: Store<AppState>, |
73 | protected translate: TranslateService, | 76 | protected translate: TranslateService, |
74 | @Optional() @Inject('entity') protected entityValue: DeviceProfile, | 77 | @Optional() @Inject('entity') protected entityValue: DeviceProfile, |
@@ -110,6 +113,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { | @@ -110,6 +113,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { | ||
110 | defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []], | 113 | defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []], |
111 | defaultQueueName: [entity ? entity.defaultQueueName : '', []], | 114 | defaultQueueName: [entity ? entity.defaultQueueName : '', []], |
112 | firmwareId: [entity ? entity.firmwareId : null], | 115 | firmwareId: [entity ? entity.firmwareId : null], |
116 | + softwareId: [entity ? entity.softwareId : null], | ||
113 | description: [entity ? entity.description : '', []], | 117 | description: [entity ? entity.description : '', []], |
114 | } | 118 | } |
115 | ); | 119 | ); |
@@ -186,6 +190,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { | @@ -186,6 +190,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { | ||
186 | this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null}, {emitEvent: false}); | 190 | this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null}, {emitEvent: false}); |
187 | this.entityForm.patchValue({defaultQueueName: entity.defaultQueueName}, {emitEvent: false}); | 191 | this.entityForm.patchValue({defaultQueueName: entity.defaultQueueName}, {emitEvent: false}); |
188 | this.entityForm.patchValue({firmwareId: entity.firmwareId}, {emitEvent: false}); | 192 | this.entityForm.patchValue({firmwareId: entity.firmwareId}, {emitEvent: false}); |
193 | + this.entityForm.patchValue({softwareId: entity.softwareId}, {emitEvent: false}); | ||
189 | this.entityForm.patchValue({description: entity.description}, {emitEvent: false}); | 194 | this.entityForm.patchValue({description: entity.description}, {emitEvent: false}); |
190 | } | 195 | } |
191 | 196 |
@@ -48,10 +48,6 @@ | @@ -48,10 +48,6 @@ | ||
48 | <mat-label translate>device.label</mat-label> | 48 | <mat-label translate>device.label</mat-label> |
49 | <input matInput formControlName="label"> | 49 | <input matInput formControlName="label"> |
50 | </mat-form-field> | 50 | </mat-form-field> |
51 | - <tb-firmware-autocomplete | ||
52 | - [useFullEntityId]="true" | ||
53 | - formControlName="firmwareId"> | ||
54 | - </tb-firmware-autocomplete> | ||
55 | <mat-form-field class="mat-block" style="padding-bottom: 14px;"> | 51 | <mat-form-field class="mat-block" style="padding-bottom: 14px;"> |
56 | <mat-label translate>device-profile.transport-type</mat-label> | 52 | <mat-label translate>device-profile.transport-type</mat-label> |
57 | <mat-select formControlName="transportType" required> | 53 | <mat-select formControlName="transportType" required> |
@@ -107,7 +107,6 @@ export class DeviceWizardDialogComponent extends | @@ -107,7 +107,6 @@ export class DeviceWizardDialogComponent extends | ||
107 | this.deviceWizardFormGroup = this.fb.group({ | 107 | this.deviceWizardFormGroup = this.fb.group({ |
108 | name: ['', Validators.required], | 108 | name: ['', Validators.required], |
109 | label: [''], | 109 | label: [''], |
110 | - firmwareId: [null], | ||
111 | gateway: [false], | 110 | gateway: [false], |
112 | overwriteActivityTime: [false], | 111 | overwriteActivityTime: [false], |
113 | transportType: [DeviceTransportType.DEFAULT, Validators.required], | 112 | transportType: [DeviceTransportType.DEFAULT, Validators.required], |
@@ -313,7 +312,6 @@ export class DeviceWizardDialogComponent extends | @@ -313,7 +312,6 @@ export class DeviceWizardDialogComponent extends | ||
313 | const device = { | 312 | const device = { |
314 | name: this.deviceWizardFormGroup.get('name').value, | 313 | name: this.deviceWizardFormGroup.get('name').value, |
315 | label: this.deviceWizardFormGroup.get('label').value, | 314 | label: this.deviceWizardFormGroup.get('label').value, |
316 | - firmwareId: this.deviceWizardFormGroup.get('firmwareId').value, | ||
317 | deviceProfileId: profileId, | 315 | deviceProfileId: profileId, |
318 | additionalInfo: { | 316 | additionalInfo: { |
319 | gateway: this.deviceWizardFormGroup.get('gateway').value, | 317 | gateway: this.deviceWizardFormGroup.get('gateway').value, |
@@ -103,8 +103,16 @@ | @@ -103,8 +103,16 @@ | ||
103 | </mat-form-field> | 103 | </mat-form-field> |
104 | <tb-firmware-autocomplete | 104 | <tb-firmware-autocomplete |
105 | [useFullEntityId]="true" | 105 | [useFullEntityId]="true" |
106 | + [type]="firmwareTypes.FIRMWARE" | ||
107 | + [deviceProfileId]="entityForm.get('deviceProfileId').value?.id" | ||
106 | formControlName="firmwareId"> | 108 | formControlName="firmwareId"> |
107 | </tb-firmware-autocomplete> | 109 | </tb-firmware-autocomplete> |
110 | + <tb-firmware-autocomplete | ||
111 | + [useFullEntityId]="true" | ||
112 | + [type]="firmwareTypes.SOFTWARE" | ||
113 | + [deviceProfileId]="entityForm.get('deviceProfileId').value?.id" | ||
114 | + formControlName="softwareId"> | ||
115 | + </tb-firmware-autocomplete> | ||
108 | <tb-device-data | 116 | <tb-device-data |
109 | formControlName="deviceData" | 117 | formControlName="deviceData" |
110 | required> | 118 | required> |
@@ -34,6 +34,7 @@ import { ActionNotificationShow } from '@core/notification/notification.actions' | @@ -34,6 +34,7 @@ import { ActionNotificationShow } from '@core/notification/notification.actions' | ||
34 | import { TranslateService } from '@ngx-translate/core'; | 34 | import { TranslateService } from '@ngx-translate/core'; |
35 | import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; | 35 | import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; |
36 | import { Subject } from 'rxjs'; | 36 | import { Subject } from 'rxjs'; |
37 | +import { FirmwareType } from '@shared/models/firmware.models'; | ||
37 | 38 | ||
38 | @Component({ | 39 | @Component({ |
39 | selector: 'tb-device', | 40 | selector: 'tb-device', |
@@ -48,6 +49,8 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { | @@ -48,6 +49,8 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { | ||
48 | 49 | ||
49 | deviceScope: 'tenant' | 'customer' | 'customer_user' | 'edge'; | 50 | deviceScope: 'tenant' | 'customer' | 'customer_user' | 'edge'; |
50 | 51 | ||
52 | + firmwareTypes = FirmwareType; | ||
53 | + | ||
51 | constructor(protected store: Store<AppState>, | 54 | constructor(protected store: Store<AppState>, |
52 | protected translate: TranslateService, | 55 | protected translate: TranslateService, |
53 | @Inject('entity') protected entityValue: DeviceInfo, | 56 | @Inject('entity') protected entityValue: DeviceInfo, |
@@ -80,6 +83,7 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { | @@ -80,6 +83,7 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { | ||
80 | name: [entity ? entity.name : '', [Validators.required]], | 83 | name: [entity ? entity.name : '', [Validators.required]], |
81 | deviceProfileId: [entity ? entity.deviceProfileId : null, [Validators.required]], | 84 | deviceProfileId: [entity ? entity.deviceProfileId : null, [Validators.required]], |
82 | firmwareId: [entity ? entity.firmwareId : null], | 85 | firmwareId: [entity ? entity.firmwareId : null], |
86 | + softwareId: [entity ? entity.softwareId : null], | ||
83 | label: [entity ? entity.label : ''], | 87 | label: [entity ? entity.label : ''], |
84 | deviceData: [entity ? entity.deviceData : null, [Validators.required]], | 88 | deviceData: [entity ? entity.deviceData : null, [Validators.required]], |
85 | additionalInfo: this.fb.group( | 89 | additionalInfo: this.fb.group( |
@@ -94,19 +98,19 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { | @@ -94,19 +98,19 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { | ||
94 | } | 98 | } |
95 | 99 | ||
96 | updateForm(entity: DeviceInfo) { | 100 | updateForm(entity: DeviceInfo) { |
97 | - this.entityForm.patchValue({name: entity.name}); | ||
98 | - this.entityForm.patchValue({deviceProfileId: entity.deviceProfileId}); | ||
99 | - this.entityForm.patchValue({firmwareId: entity.firmwareId}); | ||
100 | - this.entityForm.patchValue({label: entity.label}); | ||
101 | - this.entityForm.patchValue({deviceData: entity.deviceData}); | ||
102 | this.entityForm.patchValue({ | 101 | this.entityForm.patchValue({ |
103 | - additionalInfo: | ||
104 | - { | ||
105 | - gateway: entity.additionalInfo ? entity.additionalInfo.gateway : false, | ||
106 | - overwriteActivityTime: entity.additionalInfo ? entity.additionalInfo.overwriteActivityTime : false | ||
107 | - } | 102 | + name: entity.name, |
103 | + deviceProfileId: entity.deviceProfileId, | ||
104 | + firmwareId: entity.firmwareId, | ||
105 | + softwareId: entity.softwareId, | ||
106 | + label: entity.label, | ||
107 | + deviceData: entity.deviceData, | ||
108 | + additionalInfo: { | ||
109 | + gateway: entity.additionalInfo ? entity.additionalInfo.gateway : false, | ||
110 | + overwriteActivityTime: entity.additionalInfo ? entity.additionalInfo.overwriteActivityTime : false, | ||
111 | + description: entity.additionalInfo ? entity.additionalInfo.description : '' | ||
112 | + } | ||
108 | }); | 113 | }); |
109 | - this.entityForm.patchValue({additionalInfo: {description: entity.additionalInfo ? entity.additionalInfo.description : ''}}); | ||
110 | } | 114 | } |
111 | 115 | ||
112 | 116 | ||
@@ -152,6 +156,10 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { | @@ -152,6 +156,10 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> { | ||
152 | this.entityForm.markAsDirty(); | 156 | this.entityForm.markAsDirty(); |
153 | } | 157 | } |
154 | } | 158 | } |
159 | + this.entityForm.patchValue({ | ||
160 | + firmwareId: null, | ||
161 | + softwareId: null | ||
162 | + }); | ||
155 | } | 163 | } |
156 | } | 164 | } |
157 | } | 165 | } |
@@ -21,7 +21,12 @@ import { | @@ -21,7 +21,12 @@ import { | ||
21 | EntityTableColumn, | 21 | EntityTableColumn, |
22 | EntityTableConfig | 22 | EntityTableConfig |
23 | } from '@home/models/entity/entities-table-config.models'; | 23 | } from '@home/models/entity/entities-table-config.models'; |
24 | -import { Firmware, FirmwareInfo } from '@shared/models/firmware.models'; | 24 | +import { |
25 | + ChecksumAlgorithmTranslationMap, | ||
26 | + Firmware, | ||
27 | + FirmwareInfo, | ||
28 | + FirmwareTypeTranslationMap | ||
29 | +} from '@shared/models/firmware.models'; | ||
25 | import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models'; | 30 | import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models'; |
26 | import { TranslateService } from '@ngx-translate/core'; | 31 | import { TranslateService } from '@ngx-translate/core'; |
27 | import { DatePipe } from '@angular/common'; | 32 | import { DatePipe } from '@angular/common'; |
@@ -49,14 +54,17 @@ export class FirmwareTableConfigResolve implements Resolve<EntityTableConfig<Fir | @@ -49,14 +54,17 @@ export class FirmwareTableConfigResolve implements Resolve<EntityTableConfig<Fir | ||
49 | 54 | ||
50 | this.config.columns.push( | 55 | this.config.columns.push( |
51 | new DateEntityTableColumn<FirmwareInfo>('createdTime', 'common.created-time', this.datePipe, '150px'), | 56 | new DateEntityTableColumn<FirmwareInfo>('createdTime', 'common.created-time', this.datePipe, '150px'), |
52 | - new EntityTableColumn<FirmwareInfo>('title', 'firmware.title', '33%'), | ||
53 | - new EntityTableColumn<FirmwareInfo>('version', 'firmware.version', '33%'), | ||
54 | - new EntityTableColumn<FirmwareInfo>('fileName', 'firmware.file-name', '33%'), | 57 | + new EntityTableColumn<FirmwareInfo>('title', 'firmware.title', '25%'), |
58 | + new EntityTableColumn<FirmwareInfo>('version', 'firmware.version', '25%'), | ||
59 | + new EntityTableColumn<FirmwareInfo>('type', 'firmware.type', '25%', entity => { | ||
60 | + return this.translate.instant(FirmwareTypeTranslationMap.get(entity.type)); | ||
61 | + }), | ||
62 | + new EntityTableColumn<FirmwareInfo>('fileName', 'firmware.file-name', '25%'), | ||
55 | new EntityTableColumn<FirmwareInfo>('dataSize', 'firmware.file-size', '70px', entity => { | 63 | new EntityTableColumn<FirmwareInfo>('dataSize', 'firmware.file-size', '70px', entity => { |
56 | return this.fileSize.transform(entity.dataSize || 0); | 64 | return this.fileSize.transform(entity.dataSize || 0); |
57 | }), | 65 | }), |
58 | new EntityTableColumn<FirmwareInfo>('checksum', 'firmware.checksum', '540px', entity => { | 66 | new EntityTableColumn<FirmwareInfo>('checksum', 'firmware.checksum', '540px', entity => { |
59 | - return `${entity.checksumAlgorithm}: ${entity.checksum}`; | 67 | + return `${ChecksumAlgorithmTranslationMap.get(entity.checksumAlgorithm)}: ${entity.checksum}`; |
60 | }, () => ({}), false) | 68 | }, () => ({}), false) |
61 | ); | 69 | ); |
62 | 70 |
@@ -67,10 +67,27 @@ | @@ -67,10 +67,27 @@ | ||
67 | </mat-error> | 67 | </mat-error> |
68 | </mat-form-field> | 68 | </mat-form-field> |
69 | </div> | 69 | </div> |
70 | + <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayout.xs="column"> | ||
71 | + <mat-form-field fxFlex="45"> | ||
72 | + <mat-label translate>firmware.type</mat-label> | ||
73 | + <input *ngIf="!isAdd" matInput type="text" [readonly]="isEdit" [disabled]="!isEdit" | ||
74 | + value="{{ firmwareTypeTranslationMap.get(entityForm.get('type').value) | translate }}"> | ||
75 | + <mat-select formControlName="type" required *ngIf="isAdd"> | ||
76 | + <mat-option *ngFor="let firmwareType of firmwareTypes" [value]="firmwareType"> | ||
77 | + {{ firmwareTypeTranslationMap.get(firmwareType) | translate }} | ||
78 | + </mat-option> | ||
79 | + </mat-select> | ||
80 | + </mat-form-field> | ||
81 | + <tb-device-profile-autocomplete | ||
82 | + formControlName="deviceProfileId" fxFlex | ||
83 | + [editProfileEnabled]="false"> | ||
84 | + </tb-device-profile-autocomplete> | ||
85 | + </div> | ||
70 | <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayoutGap.sm="8px" fxLayout.xs="column" fxLayout.md="column"> | 86 | <div fxLayout="row" fxLayoutGap.gt-xs="8px" fxLayoutGap.sm="8px" fxLayout.xs="column" fxLayout.md="column"> |
71 | <mat-form-field class="mat-block" fxFlex="33"> | 87 | <mat-form-field class="mat-block" fxFlex="33"> |
72 | <mat-label translate>firmware.checksum-algorithm</mat-label> | 88 | <mat-label translate>firmware.checksum-algorithm</mat-label> |
73 | - <input *ngIf="!isAdd" matInput formControlName="checksumAlgorithm" type="text" [readonly]="isEdit"> | 89 | + <input *ngIf="!isAdd" matInput type="text" [readonly]="isEdit" [disabled]="!isEdit" |
90 | + value="{{ checksumAlgorithmTranslationMap.get(entityForm.get('checksumAlgorithm').value) | translate }}"> | ||
74 | <mat-select formControlName="checksumAlgorithm" *ngIf="isAdd"> | 91 | <mat-select formControlName="checksumAlgorithm" *ngIf="isAdd"> |
75 | <mat-option [value]=null></mat-option> | 92 | <mat-option [value]=null></mat-option> |
76 | <mat-option *ngFor="let checksumAlgorithm of checksumAlgorithms" [value]="checksumAlgorithm"> | 93 | <mat-option *ngFor="let checksumAlgorithm of checksumAlgorithms" [value]="checksumAlgorithm"> |
@@ -22,7 +22,13 @@ import { TranslateService } from '@ngx-translate/core'; | @@ -22,7 +22,13 @@ import { TranslateService } from '@ngx-translate/core'; | ||
22 | import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; | 22 | import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; |
23 | import { FormBuilder, FormGroup, Validators } from '@angular/forms'; | 23 | import { FormBuilder, FormGroup, Validators } from '@angular/forms'; |
24 | import { EntityComponent } from '@home/components/entity/entity.component'; | 24 | import { EntityComponent } from '@home/components/entity/entity.component'; |
25 | -import { ChecksumAlgorithm, ChecksumAlgorithmTranslationMap, Firmware } from '@shared/models/firmware.models'; | 25 | +import { |
26 | + ChecksumAlgorithm, | ||
27 | + ChecksumAlgorithmTranslationMap, | ||
28 | + Firmware, | ||
29 | + FirmwareType, | ||
30 | + FirmwareTypeTranslationMap | ||
31 | +} from '@shared/models/firmware.models'; | ||
26 | import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators'; | 32 | import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators'; |
27 | import { ActionNotificationShow } from '@core/notification/notification.actions'; | 33 | import { ActionNotificationShow } from '@core/notification/notification.actions'; |
28 | 34 | ||
@@ -36,6 +42,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI | @@ -36,6 +42,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI | ||
36 | 42 | ||
37 | checksumAlgorithms = Object.values(ChecksumAlgorithm); | 43 | checksumAlgorithms = Object.values(ChecksumAlgorithm); |
38 | checksumAlgorithmTranslationMap = ChecksumAlgorithmTranslationMap; | 44 | checksumAlgorithmTranslationMap = ChecksumAlgorithmTranslationMap; |
45 | + firmwareTypes = Object.values(FirmwareType); | ||
46 | + firmwareTypeTranslationMap = FirmwareTypeTranslationMap; | ||
39 | 47 | ||
40 | constructor(protected store: Store<AppState>, | 48 | constructor(protected store: Store<AppState>, |
41 | protected translate: TranslateService, | 49 | protected translate: TranslateService, |
@@ -83,6 +91,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI | @@ -83,6 +91,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI | ||
83 | const form = this.fb.group({ | 91 | const form = this.fb.group({ |
84 | title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]], | 92 | title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]], |
85 | version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]], | 93 | version: [entity ? entity.version : '', [Validators.required, Validators.maxLength(255)]], |
94 | + type: [entity?.type ? entity.type : FirmwareType.FIRMWARE, [Validators.required]], | ||
95 | + deviceProfileId: [entity ? entity.deviceProfileId : null], | ||
86 | checksumAlgorithm: [entity ? entity.checksumAlgorithm : null], | 96 | checksumAlgorithm: [entity ? entity.checksumAlgorithm : null], |
87 | checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)], | 97 | checksum: [entity ? entity.checksum : '', Validators.maxLength(1020)], |
88 | additionalInfo: this.fb.group( | 98 | additionalInfo: this.fb.group( |
@@ -105,6 +115,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI | @@ -105,6 +115,8 @@ export class FirmwaresComponent extends EntityComponent<Firmware> implements OnI | ||
105 | this.entityForm.patchValue({ | 115 | this.entityForm.patchValue({ |
106 | title: entity.title, | 116 | title: entity.title, |
107 | version: entity.version, | 117 | version: entity.version, |
118 | + type: entity.type, | ||
119 | + deviceProfileId: entity.deviceProfileId, | ||
108 | checksumAlgorithm: entity.checksumAlgorithm, | 120 | checksumAlgorithm: entity.checksumAlgorithm, |
109 | checksum: entity.checksum, | 121 | checksum: entity.checksum, |
110 | fileName: entity.fileName, | 122 | fileName: entity.fileName, |
@@ -37,11 +37,11 @@ | @@ -37,11 +37,11 @@ | ||
37 | <mat-option *ngIf="!(filteredFirmwares | async)?.length" [value]="null" class="tb-not-found"> | 37 | <mat-option *ngIf="!(filteredFirmwares | async)?.length" [value]="null" class="tb-not-found"> |
38 | <div class="tb-not-found-content" (click)="$event.stopPropagation()"> | 38 | <div class="tb-not-found-content" (click)="$event.stopPropagation()"> |
39 | <div *ngIf="!textIsNotEmpty(searchText); else searchNotEmpty"> | 39 | <div *ngIf="!textIsNotEmpty(searchText); else searchNotEmpty"> |
40 | - <span translate>firmware.no-firmware-text</span> | 40 | + <span>{{ notFoundFirmware | translate }}</span> |
41 | </div> | 41 | </div> |
42 | <ng-template #searchNotEmpty> | 42 | <ng-template #searchNotEmpty> |
43 | <span> | 43 | <span> |
44 | - {{ translate.get('firmware.no-firmware-matching', | 44 | + {{ translate.get(notMatchingFirmware, |
45 | {entity: truncate.transform(searchText, true, 6, '...')}) | async }} | 45 | {entity: truncate.transform(searchText, true, 6, '...')}) | async }} |
46 | </span> | 46 | </span> |
47 | </ng-template> | 47 | </ng-template> |
@@ -28,7 +28,7 @@ import { BaseData } from '@shared/models/base-data'; | @@ -28,7 +28,7 @@ import { BaseData } from '@shared/models/base-data'; | ||
28 | import { EntityService } from '@core/http/entity.service'; | 28 | import { EntityService } from '@core/http/entity.service'; |
29 | import { TruncatePipe } from '@shared/pipe/truncate.pipe'; | 29 | import { TruncatePipe } from '@shared/pipe/truncate.pipe'; |
30 | import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; | 30 | import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; |
31 | -import { FirmwareInfo } from '@shared/models/firmware.models'; | 31 | +import { FirmwareInfo, FirmwareType } from '@shared/models/firmware.models'; |
32 | import { FirmwareService } from '@core/http/firmware.service'; | 32 | import { FirmwareService } from '@core/http/firmware.service'; |
33 | import { PageLink } from '@shared/models/page/page-link'; | 33 | import { PageLink } from '@shared/models/page/page-link'; |
34 | import { Direction } from '@shared/models/page/sort-order'; | 34 | import { Direction } from '@shared/models/page/sort-order'; |
@@ -50,6 +50,12 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | @@ -50,6 +50,12 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | ||
50 | modelValue: string | null; | 50 | modelValue: string | null; |
51 | 51 | ||
52 | @Input() | 52 | @Input() |
53 | + type = FirmwareType.FIRMWARE; | ||
54 | + | ||
55 | + @Input() | ||
56 | + deviceProfileId: string; | ||
57 | + | ||
58 | + @Input() | ||
53 | labelText: string; | 59 | labelText: string; |
54 | 60 | ||
55 | @Input() | 61 | @Input() |
@@ -81,6 +87,23 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | @@ -81,6 +87,23 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | ||
81 | 87 | ||
82 | private dirty = false; | 88 | private dirty = false; |
83 | 89 | ||
90 | + private firmwareTypeTranslation = new Map<FirmwareType, any>( | ||
91 | + [ | ||
92 | + [FirmwareType.FIRMWARE, { | ||
93 | + label: 'firmware.firmware', | ||
94 | + required: 'firmware.firmware-required', | ||
95 | + noFound: 'firmware.no-firmware-text', | ||
96 | + noMatching: 'firmware.no-firmware-matching' | ||
97 | + }], | ||
98 | + [FirmwareType.SOFTWARE, { | ||
99 | + label: 'firmware.software', | ||
100 | + required: 'firmware.software-required', | ||
101 | + noFound: 'firmware.no-software-text', | ||
102 | + noMatching: 'firmware.no-software-matching' | ||
103 | + }] | ||
104 | + ] | ||
105 | + ); | ||
106 | + | ||
84 | private propagateChange = (v: any) => { }; | 107 | private propagateChange = (v: any) => { }; |
85 | 108 | ||
86 | constructor(private store: Store<AppState>, | 109 | constructor(private store: Store<AppState>, |
@@ -160,7 +183,7 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | @@ -160,7 +183,7 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | ||
160 | this.entityService.getEntity(EntityType.FIRMWARE, firmwareId, {ignoreLoading: true, ignoreErrors: true}).subscribe( | 183 | this.entityService.getEntity(EntityType.FIRMWARE, firmwareId, {ignoreLoading: true, ignoreErrors: true}).subscribe( |
161 | (entity) => { | 184 | (entity) => { |
162 | this.modelValue = entity.id.id; | 185 | this.modelValue = entity.id.id; |
163 | - this.firmwareFormGroup.get('firmwareId').patchValue(entity, {emitEvent: false}); | 186 | + this.firmwareFormGroup.get('firmwareId').patchValue(entity); |
164 | }, | 187 | }, |
165 | () => { | 188 | () => { |
166 | this.modelValue = null; | 189 | this.modelValue = null; |
@@ -173,6 +196,7 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | @@ -173,6 +196,7 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | ||
173 | } else { | 196 | } else { |
174 | this.modelValue = null; | 197 | this.modelValue = null; |
175 | this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: false}); | 198 | this.firmwareFormGroup.get('firmwareId').patchValue('', {emitEvent: false}); |
199 | + this.propagateChange(null); | ||
176 | } | 200 | } |
177 | } else { | 201 | } else { |
178 | this.modelValue = null; | 202 | this.modelValue = null; |
@@ -209,7 +233,8 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | @@ -209,7 +233,8 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | ||
209 | property: 'title', | 233 | property: 'title', |
210 | direction: Direction.ASC | 234 | direction: Direction.ASC |
211 | }); | 235 | }); |
212 | - return this.firmwareService.getFirmwares(pageLink, true, {ignoreLoading: true}).pipe( | 236 | + return this.firmwareService.getFirmwaresInfoByDeviceProfileId(pageLink, this.deviceProfileId, this.type, |
237 | + true, {ignoreLoading: true}).pipe( | ||
213 | map((data) => data && data.data.length ? data.data : null) | 238 | map((data) => data && data.data.length ? data.data : null) |
214 | ); | 239 | ); |
215 | } | 240 | } |
@@ -223,11 +248,19 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | @@ -223,11 +248,19 @@ export class FirmwareAutocompleteComponent implements ControlValueAccessor, OnIn | ||
223 | } | 248 | } |
224 | 249 | ||
225 | get placeholderText(): string { | 250 | get placeholderText(): string { |
226 | - return this.labelText || 'firmware.firmware'; | 251 | + return this.labelText || this.firmwareTypeTranslation.get(this.type).label; |
227 | } | 252 | } |
228 | 253 | ||
229 | get requiredErrorText(): string { | 254 | get requiredErrorText(): string { |
230 | - return this.requiredText || 'firmware.firmware-required'; | 255 | + return this.requiredText || this.firmwareTypeTranslation.get(this.type).required; |
256 | + } | ||
257 | + | ||
258 | + get notFoundFirmware(): string { | ||
259 | + return this.firmwareTypeTranslation.get(this.type).noFound; | ||
260 | + } | ||
261 | + | ||
262 | + get notMatchingFirmware(): string { | ||
263 | + return this.firmwareTypeTranslation.get(this.type).noMatching; | ||
231 | } | 264 | } |
232 | 265 | ||
233 | firmwareTitleText(firmware: FirmwareInfo): string { | 266 | firmwareTitleText(firmware: FirmwareInfo): string { |
@@ -498,6 +498,7 @@ export interface DeviceProfile extends BaseData<DeviceProfileId> { | @@ -498,6 +498,7 @@ export interface DeviceProfile extends BaseData<DeviceProfileId> { | ||
498 | defaultRuleChainId?: RuleChainId; | 498 | defaultRuleChainId?: RuleChainId; |
499 | defaultQueueName?: string; | 499 | defaultQueueName?: string; |
500 | firmwareId?: FirmwareId; | 500 | firmwareId?: FirmwareId; |
501 | + softwareId?: FirmwareId; | ||
501 | profileData: DeviceProfileData; | 502 | profileData: DeviceProfileData; |
502 | } | 503 | } |
503 | 504 | ||
@@ -558,6 +559,7 @@ export interface Device extends BaseData<DeviceId> { | @@ -558,6 +559,7 @@ export interface Device extends BaseData<DeviceId> { | ||
558 | type: string; | 559 | type: string; |
559 | label: string; | 560 | label: string; |
560 | firmwareId?: FirmwareId; | 561 | firmwareId?: FirmwareId; |
562 | + softwareId?: FirmwareId; | ||
561 | deviceProfileId?: DeviceProfileId; | 563 | deviceProfileId?: DeviceProfileId; |
562 | deviceData?: DeviceData; | 564 | deviceData?: DeviceData; |
563 | additionalInfo?: any; | 565 | additionalInfo?: any; |
@@ -17,6 +17,7 @@ | @@ -17,6 +17,7 @@ | ||
17 | import { BaseData } from '@shared/models/base-data'; | 17 | import { BaseData } from '@shared/models/base-data'; |
18 | import { TenantId } from '@shared/models/id/tenant-id'; | 18 | import { TenantId } from '@shared/models/id/tenant-id'; |
19 | import { FirmwareId } from '@shared/models/id/firmware-id'; | 19 | import { FirmwareId } from '@shared/models/id/firmware-id'; |
20 | +import { DeviceProfileId } from '@shared/models/id/device-profile-id'; | ||
20 | 21 | ||
21 | export enum ChecksumAlgorithm { | 22 | export enum ChecksumAlgorithm { |
22 | MD5 = 'md5', | 23 | MD5 = 'md5', |
@@ -32,14 +33,28 @@ export const ChecksumAlgorithmTranslationMap = new Map<ChecksumAlgorithm, string | @@ -32,14 +33,28 @@ export const ChecksumAlgorithmTranslationMap = new Map<ChecksumAlgorithm, string | ||
32 | ] | 33 | ] |
33 | ); | 34 | ); |
34 | 35 | ||
36 | +export enum FirmwareType { | ||
37 | + FIRMWARE = 'FIRMWARE', | ||
38 | + SOFTWARE = 'SOFTWARE' | ||
39 | +} | ||
40 | + | ||
41 | +export const FirmwareTypeTranslationMap = new Map<FirmwareType, string>( | ||
42 | + [ | ||
43 | + [FirmwareType.FIRMWARE, 'firmware.types.firmware'], | ||
44 | + [FirmwareType.SOFTWARE, 'firmware.types.software'] | ||
45 | + ] | ||
46 | +); | ||
47 | + | ||
35 | export interface FirmwareInfo extends BaseData<FirmwareId> { | 48 | export interface FirmwareInfo extends BaseData<FirmwareId> { |
36 | tenantId?: TenantId; | 49 | tenantId?: TenantId; |
50 | + type: FirmwareType; | ||
51 | + deviceProfileId?: DeviceProfileId; | ||
37 | title?: string; | 52 | title?: string; |
38 | version?: string; | 53 | version?: string; |
39 | hasData?: boolean; | 54 | hasData?: boolean; |
40 | fileName: string; | 55 | fileName: string; |
41 | - checksum?: ChecksumAlgorithm; | ||
42 | - checksumAlgorithm?: string; | 56 | + checksum?: string; |
57 | + checksumAlgorithm?: ChecksumAlgorithm; | ||
43 | contentType: string; | 58 | contentType: string; |
44 | dataSize?: number; | 59 | dataSize?: number; |
45 | additionalInfo?: any; | 60 | additionalInfo?: any; |
@@ -1948,6 +1948,8 @@ | @@ -1948,6 +1948,8 @@ | ||
1948 | "idCopiedMessage": "Firmware Id has been copied to clipboard", | 1948 | "idCopiedMessage": "Firmware Id has been copied to clipboard", |
1949 | "no-firmware-matching": "No firmware matching '{{entity}}' were found.", | 1949 | "no-firmware-matching": "No firmware matching '{{entity}}' were found.", |
1950 | "no-firmware-text": "No firmwares found", | 1950 | "no-firmware-text": "No firmwares found", |
1951 | + "no-software-matching": "No sowtware matching '{{entity}}' were found.", | ||
1952 | + "no-software-text": "No software found", | ||
1951 | "file-name": "File name", | 1953 | "file-name": "File name", |
1952 | "file-size": "File size", | 1954 | "file-size": "File size", |
1953 | "file-size-bytes": "File size in bytes", | 1955 | "file-size-bytes": "File size in bytes", |
@@ -1956,8 +1958,15 @@ | @@ -1956,8 +1958,15 @@ | ||
1956 | "firmware-required": "Firmware is required.", | 1958 | "firmware-required": "Firmware is required.", |
1957 | "search": "Search firmwares", | 1959 | "search": "Search firmwares", |
1958 | "selected-firmware": "{ count, plural, 1 {1 firmware} other {# firmwares} } selected", | 1960 | "selected-firmware": "{ count, plural, 1 {1 firmware} other {# firmwares} } selected", |
1961 | + "software": "Software", | ||
1962 | + "software-required": "Software is required.", | ||
1959 | "title": "Title", | 1963 | "title": "Title", |
1960 | "title-required": "Title is required.", | 1964 | "title-required": "Title is required.", |
1965 | + "type": "Firmware type", | ||
1966 | + "types": { | ||
1967 | + "firmware": "Firmware", | ||
1968 | + "software": "Software" | ||
1969 | + }, | ||
1961 | "version": "Version", | 1970 | "version": "Version", |
1962 | "version-required": "Version is required.", | 1971 | "version-required": "Version is required.", |
1963 | "warning-after-save-no-edit": "Once the firmware is saved, it will not be possible to change the title and version fields." | 1972 | "warning-after-save-no-edit": "Once the firmware is saved, it will not be possible to change the title and version fields." |