Adding Device Profile ID to the Firmware to make sure user assigns compatible firmware

This commit is contained in:
Andrii Shvaika 2021-04-28 15:31:32 +03:00
commit 29f404acb1
15 changed files with 199 additions and 59 deletions

View File

@ -63,6 +63,7 @@ CREATE TABLE IF NOT EXISTS firmware (
id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY,
created_time bigint NOT NULL, created_time bigint NOT NULL,
tenant_id uuid NOT NULL, tenant_id uuid NOT NULL,
type varchar(32) NOT NULL,
title varchar(255) NOT NULL, title varchar(255) NOT NULL,
version varchar(255) NOT NULL, version varchar(255) NOT NULL,
file_name varchar(255), file_name varchar(255),

View File

@ -16,16 +16,20 @@
package org.thingsboard.server.service.firmware; package org.thingsboard.server.service.firmware;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService;
import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.FirmwareInfo; import org.thingsboard.server.common.data.FirmwareInfo;
import org.thingsboard.server.common.data.firmware.FirmwareKeyUtil;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.FirmwareId; import org.thingsboard.server.common.data.id.FirmwareId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.AttributeKey;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
@ -41,46 +45,42 @@ import org.thingsboard.server.dao.firmware.FirmwareService;
import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.TbQueueProducer;
import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.queue.TbClusterService;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_CHECKSUM; import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM;
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_CHECKSUM_ALGORITHM; import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM_ALGORITHM;
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_SIZE; import static org.thingsboard.server.common.data.firmware.FirmwareKey.SIZE;
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_TITLE; import static org.thingsboard.server.common.data.firmware.FirmwareKey.STATE;
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_VERSION; import static org.thingsboard.server.common.data.firmware.FirmwareKey.TITLE;
import static org.thingsboard.server.common.data.firmware.FirmwareKey.TS;
import static org.thingsboard.server.common.data.firmware.FirmwareKey.VERSION;
import static org.thingsboard.server.common.data.firmware.FirmwareKeyUtil.getAttributeKey;
import static org.thingsboard.server.common.data.firmware.FirmwareKeyUtil.getTargetTelemetryKey;
import static org.thingsboard.server.common.data.firmware.FirmwareKeyUtil.getTelemetryKey;
@Slf4j @Slf4j
@Service @Service
@TbCoreComponent @TbCoreComponent
@RequiredArgsConstructor
public class DefaultFirmwareStateService implements FirmwareStateService { public class DefaultFirmwareStateService implements FirmwareStateService {
private final TbClusterService tbClusterService;
private final FirmwareService firmwareService; private final FirmwareService firmwareService;
private final DeviceService deviceService; private final DeviceService deviceService;
private final DeviceProfileService deviceProfileService; private final DeviceProfileService deviceProfileService;
private final RuleEngineTelemetryService telemetryService; private final RuleEngineTelemetryService telemetryService;
private final TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> fwStateMsgProducer; private final TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> fwStateMsgProducer;
public DefaultFirmwareStateService(FirmwareService firmwareService,
DeviceService deviceService,
DeviceProfileService deviceProfileService,
RuleEngineTelemetryService telemetryService,
TbCoreQueueFactory coreQueueFactory) {
this.firmwareService = firmwareService;
this.deviceService = deviceService;
this.deviceProfileService = deviceProfileService;
this.telemetryService = telemetryService;
this.fwStateMsgProducer = coreQueueFactory.createToFirmwareStateServiceMsgProducer();
}
@Override @Override
public void update(Device device, Device oldDevice) { public void update(Device device, Device oldDevice) {
FirmwareId newFirmwareId = device.getFirmwareId(); FirmwareId newFirmwareId = device.getFirmwareId();
@ -183,10 +183,10 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
fwStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null); fwStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null);
List<TsKvEntry> telemetry = new ArrayList<>(); List<TsKvEntry> telemetry = new ArrayList<>();
telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.TARGET_FIRMWARE_TITLE, firmware.getTitle()))); telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), TITLE), firmware.getTitle())));
telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.TARGET_FIRMWARE_VERSION, firmware.getVersion()))); telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), VERSION), firmware.getVersion())));
telemetry.add(new BasicTsKvEntry(ts, new LongDataEntry(DataConstants.TARGET_FIRMWARE_TS, ts))); telemetry.add(new BasicTsKvEntry(ts, new LongDataEntry(getTargetTelemetryKey(firmware.getType(), TS), ts)));
telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_STATE, FirmwareUpdateStatus.QUEUED.name()))); telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), FirmwareUpdateStatus.QUEUED.name())));
telemetryService.saveAndNotify(tenantId, deviceId, telemetry, new FutureCallback<>() { telemetryService.saveAndNotify(tenantId, deviceId, telemetry, new FutureCallback<>() {
@Override @Override
@ -206,7 +206,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
TenantId tenantId = device.getTenantId(); TenantId tenantId = device.getTenantId();
DeviceId deviceId = device.getId(); DeviceId deviceId = device.getId();
BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(DataConstants.FIRMWARE_STATE, FirmwareUpdateStatus.INITIATED.name())); BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), FirmwareUpdateStatus.INITIATED.name()));
telemetryService.saveAndNotify(tenantId, deviceId, Collections.singletonList(status), new FutureCallback<>() { telemetryService.saveAndNotify(tenantId, deviceId, Collections.singletonList(status), new FutureCallback<>() {
@Override @Override
@ -221,13 +221,12 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
}); });
List<AttributeKvEntry> attributes = new ArrayList<>(); List<AttributeKvEntry> attributes = new ArrayList<>();
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), TITLE), firmware.getTitle())));
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), VERSION), firmware.getVersion())));
attributes.add(new BaseAttributeKvEntry(ts, new LongDataEntry(getAttributeKey(firmware.getType(), SIZE), firmware.getDataSize())));
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), CHECKSUM_ALGORITHM), firmware.getChecksumAlgorithm())));
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(getAttributeKey(firmware.getType(), CHECKSUM), firmware.getChecksum())));
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_TITLE, firmware.getTitle())));
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_VERSION, firmware.getVersion())));
attributes.add(new BaseAttributeKvEntry(ts, new LongDataEntry(FIRMWARE_SIZE, firmware.getDataSize())));
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_CHECKSUM_ALGORITHM, firmware.getChecksumAlgorithm())));
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_CHECKSUM, firmware.getChecksum())));
telemetryService.saveAndNotify(tenantId, deviceId, DataConstants.SHARED_SCOPE, attributes, new FutureCallback<>() { telemetryService.saveAndNotify(tenantId, deviceId, DataConstants.SHARED_SCOPE, attributes, new FutureCallback<>() {
@Override @Override
public void onSuccess(@Nullable Void tmp) { public void onSuccess(@Nullable Void tmp) {
@ -242,12 +241,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
} }
private void remove(Device device) { private void remove(Device device) {
telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, FirmwareKeyUtil.ALL_ATTRIBUTE_KEYS,
Arrays.asList(FIRMWARE_TITLE, FIRMWARE_VERSION, FIRMWARE_SIZE, FIRMWARE_CHECKSUM_ALGORITHM, FIRMWARE_CHECKSUM),
new FutureCallback<>() { new FutureCallback<>() {
@Override @Override
public void onSuccess(@Nullable Void tmp) { public void onSuccess(@Nullable Void tmp) {
log.trace("[{}] Success remove target firmware attributes!", device.getId()); log.trace("[{}] Success remove target firmware attributes!", device.getId());
Set<AttributeKey> keysToNotify = new HashSet<>();
FirmwareKeyUtil.ALL_ATTRIBUTE_KEYS.forEach(key -> keysToNotify.add(new AttributeKey(DataConstants.SHARED_SCOPE, key)));
tbClusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onDelete(device.getTenantId(), device.getId(), keysToNotify), null);
} }
@Override @Override

View File

@ -93,22 +93,7 @@ public class DataConstants {
public static final String USERNAME = "username"; public static final String USERNAME = "username";
public static final String PASSWORD = "password"; public static final String PASSWORD = "password";
//firmware
//telemetry
public static final String CURRENT_FIRMWARE_TITLE = "cur_fw_title";
public static final String CURRENT_FIRMWARE_VERSION = "cur_fw_version";
public static final String TARGET_FIRMWARE_TITLE = "target_fw_title";
public static final String TARGET_FIRMWARE_VERSION = "target_fw_version";
public static final String TARGET_FIRMWARE_TS = "target_fw_ts";
public static final String FIRMWARE_STATE = "fw_state";
//attributes
//telemetry
public static final String FIRMWARE_TITLE = "fw_title";
public static final String FIRMWARE_VERSION = "fw_version";
public static final String FIRMWARE_SIZE = "fw_size";
public static final String FIRMWARE_CHECKSUM = "fw_checksum";
public static final String FIRMWARE_CHECKSUM_ALGORITHM = "fw_checksum_algorithm";
public static final String EDGE_MSG_SOURCE = "edge"; public static final String EDGE_MSG_SOURCE = "edge";
public static final String MSG_SOURCE_KEY = "source"; public static final String MSG_SOURCE_KEY = "source";
} }

View File

@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.firmware.FirmwareType;
import org.thingsboard.server.common.data.id.FirmwareId; import org.thingsboard.server.common.data.id.FirmwareId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -30,6 +31,7 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId>
private static final long serialVersionUID = 3168391583570815419L; private static final long serialVersionUID = 3168391583570815419L;
private TenantId tenantId; private TenantId tenantId;
private FirmwareType type;
private String title; private String title;
private String version; private String version;
private boolean hasData; private boolean hasData;
@ -51,6 +53,7 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId>
public FirmwareInfo(FirmwareInfo firmwareInfo) { public FirmwareInfo(FirmwareInfo firmwareInfo) {
super(firmwareInfo); super(firmwareInfo);
this.tenantId = firmwareInfo.getTenantId(); this.tenantId = firmwareInfo.getTenantId();
this.type = firmwareInfo.getType();
this.title = firmwareInfo.getTitle(); this.title = firmwareInfo.getTitle();
this.version = firmwareInfo.getVersion(); this.version = firmwareInfo.getVersion();
this.hasData = firmwareInfo.isHasData(); this.hasData = firmwareInfo.isHasData();

View File

@ -0,0 +1,30 @@
/**
* Copyright © 2016-2021 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.firmware;
import lombok.Getter;
public enum FirmwareKey {
TITLE("title"), VERSION("version"), TS("ts"), STATE("state"), SIZE("size"), CHECKSUM("checksum"), CHECKSUM_ALGORITHM("checksum_algorithm");
@Getter
private final String value;
FirmwareKey(String value) {
this.value = value;
}
}

View File

@ -0,0 +1,52 @@
/**
* Copyright © 2016-2021 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.firmware;
import java.util.ArrayList;
import java.util.List;
public class FirmwareKeyUtil {
public static final List<String> ALL_ATTRIBUTE_KEYS;
static {
ALL_ATTRIBUTE_KEYS = new ArrayList<>();
for (FirmwareType type : FirmwareType.values()) {
for (FirmwareKey key : FirmwareKey.values()) {
ALL_ATTRIBUTE_KEYS.add(getAttributeKey(type, key));
}
}
}
public static String getAttributeKey(FirmwareType type, FirmwareKey key) {
return type.getKeyPrefix() + "_" + key.getValue();
}
public static String getTargetTelemetryKey(FirmwareType type, FirmwareKey key) {
return getTelemetryKey("target_", type, key);
}
public static String getCurrentTelemetryKey(FirmwareType type, FirmwareKey key) {
return getTelemetryKey("current_", type, key);
}
private static String getTelemetryKey(String prefix, FirmwareType type, FirmwareKey key) {
return prefix + type.getKeyPrefix() + "_" + key.getValue();
}
public static String getTelemetryKey(FirmwareType type, FirmwareKey key) {
return type.getKeyPrefix() + "_" + key.getValue();
}
}

View File

@ -0,0 +1,30 @@
/**
* Copyright © 2016-2021 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.firmware;
import lombok.Getter;
public enum FirmwareType {
FIRMWARE("fw"), SOFTWARE("sw");
@Getter
private final String keyPrefix;
FirmwareType(String keyPrefix) {
this.keyPrefix = keyPrefix;
}
}

View File

@ -363,10 +363,11 @@ message GetFirmwareResponseMsg {
ResponseStatus responseStatus = 1; ResponseStatus responseStatus = 1;
int64 firmwareIdMSB = 2; int64 firmwareIdMSB = 2;
int64 firmwareIdLSB = 3; int64 firmwareIdLSB = 3;
string title = 4; string type = 4;
string version = 5; string title = 5;
string contentType = 6; string version = 6;
string fileName = 7; string contentType = 7;
string fileName = 8;
} }
//Used to report session state to tb-Service and persist this state in the cache on the tb-Service level. //Used to report session state to tb-Service and persist this state in the cache on the tb-Service level.

View File

@ -476,6 +476,7 @@ public class ModelConstants {
*/ */
public static final String FIRMWARE_TABLE_NAME = "firmware"; public static final String FIRMWARE_TABLE_NAME = "firmware";
public static final String FIRMWARE_TENANT_ID_COLUMN = TENANT_ID_COLUMN; public static final String FIRMWARE_TENANT_ID_COLUMN = TENANT_ID_COLUMN;
public static final String FIRMWARE_TYPE_COLUMN = "type";
public static final String FIRMWARE_TITLE_COLUMN = TITLE_PROPERTY; public static final String FIRMWARE_TITLE_COLUMN = TITLE_PROPERTY;
public static final String FIRMWARE_VERSION_COLUMN = "version"; public static final String FIRMWARE_VERSION_COLUMN = "version";
public static final String FIRMWARE_FILE_NAME_COLUMN = "file_name"; public static final String FIRMWARE_FILE_NAME_COLUMN = "file_name";

View File

@ -21,6 +21,7 @@ import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.Firmware;
import org.thingsboard.server.common.data.firmware.FirmwareType;
import org.thingsboard.server.common.data.id.FirmwareId; import org.thingsboard.server.common.data.id.FirmwareId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.BaseSqlEntity;
@ -31,6 +32,8 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Lob; import javax.persistence.Lob;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Table; import javax.persistence.Table;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.UUID; import java.util.UUID;
@ -44,6 +47,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TYPE_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
@ -57,6 +61,10 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex
@Column(name = FIRMWARE_TENANT_ID_COLUMN) @Column(name = FIRMWARE_TENANT_ID_COLUMN)
private UUID tenantId; private UUID tenantId;
@Enumerated(EnumType.STRING)
@Column(name = FIRMWARE_TYPE_COLUMN)
private FirmwareType type;
@Column(name = FIRMWARE_TITLE_COLUMN) @Column(name = FIRMWARE_TITLE_COLUMN)
private String title; private String title;
@ -97,6 +105,7 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex
this.createdTime = firmware.getCreatedTime(); this.createdTime = firmware.getCreatedTime();
this.setUuid(firmware.getUuidId()); this.setUuid(firmware.getUuidId());
this.tenantId = firmware.getTenantId().getId(); this.tenantId = firmware.getTenantId().getId();
this.type = firmware.getType();
this.title = firmware.getTitle(); this.title = firmware.getTitle();
this.version = firmware.getVersion(); this.version = firmware.getVersion();
this.fileName = firmware.getFileName(); this.fileName = firmware.getFileName();
@ -123,6 +132,7 @@ public class FirmwareEntity extends BaseSqlEntity<Firmware> implements SearchTex
Firmware firmware = new Firmware(new FirmwareId(id)); Firmware firmware = new Firmware(new FirmwareId(id));
firmware.setCreatedTime(createdTime); firmware.setCreatedTime(createdTime);
firmware.setTenantId(new TenantId(tenantId)); firmware.setTenantId(new TenantId(tenantId));
firmware.setType(type);
firmware.setTitle(title); firmware.setTitle(title);
firmware.setVersion(version); firmware.setVersion(version);
firmware.setFileName(fileName); firmware.setFileName(fileName);

View File

@ -22,6 +22,7 @@ import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDef;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.FirmwareInfo; import org.thingsboard.server.common.data.FirmwareInfo;
import org.thingsboard.server.common.data.firmware.FirmwareType;
import org.thingsboard.server.common.data.id.FirmwareId; import org.thingsboard.server.common.data.id.FirmwareId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.BaseSqlEntity;
@ -31,6 +32,8 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Transient; import javax.persistence.Transient;
import java.util.UUID; import java.util.UUID;
@ -38,13 +41,12 @@ import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ALGORITHM_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_ALGORITHM_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CHECKSUM_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_CONTENT_TYPE_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_SIZE_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_DATA_SIZE_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_FILE_NAME_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_HAS_DATA_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TABLE_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TENANT_ID_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TITLE_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_TYPE_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.FIRMWARE_VERSION_COLUMN;
import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
@ -58,6 +60,10 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
@Column(name = FIRMWARE_TENANT_ID_COLUMN) @Column(name = FIRMWARE_TENANT_ID_COLUMN)
private UUID tenantId; private UUID tenantId;
@Enumerated(EnumType.STRING)
@Column(name = FIRMWARE_TYPE_COLUMN)
private FirmwareType type;
@Column(name = FIRMWARE_TITLE_COLUMN) @Column(name = FIRMWARE_TITLE_COLUMN)
private String title; private String title;
@ -107,12 +113,13 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
this.additionalInfo = firmware.getAdditionalInfo(); this.additionalInfo = firmware.getAdditionalInfo();
} }
public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, String title, String version, public FirmwareInfoEntity(UUID id, long createdTime, UUID tenantId, String type, String title, String version,
String fileName, String contentType, String checksumAlgorithm, String checksum, Long dataSize, String fileName, String contentType, String checksumAlgorithm, String checksum, Long dataSize,
Object additionalInfo, boolean hasData) { Object additionalInfo, boolean hasData) {
this.id = id; this.id = id;
this.createdTime = createdTime; this.createdTime = createdTime;
this.tenantId = tenantId; this.tenantId = tenantId;
this.type = FirmwareType.valueOf(type);
this.title = title; this.title = title;
this.version = version; this.version = version;
this.fileName = fileName; this.fileName = fileName;
@ -139,6 +146,7 @@ public class FirmwareInfoEntity extends BaseSqlEntity<FirmwareInfo> implements S
FirmwareInfo firmware = new FirmwareInfo(new FirmwareId(id)); FirmwareInfo firmware = new FirmwareInfo(new FirmwareId(id));
firmware.setCreatedTime(createdTime); firmware.setCreatedTime(createdTime);
firmware.setTenantId(new TenantId(tenantId)); firmware.setTenantId(new TenantId(tenantId));
firmware.setType(type);
firmware.setTitle(title); firmware.setTitle(title);
firmware.setVersion(version); firmware.setVersion(version);
firmware.setFileName(fileName); firmware.setFileName(fileName);

View File

@ -25,14 +25,14 @@ import org.thingsboard.server.dao.model.sql.FirmwareInfoEntity;
import java.util.UUID; import java.util.UUID;
public interface FirmwareInfoRepository extends CrudRepository<FirmwareInfoEntity, UUID> { public interface FirmwareInfoRepository extends CrudRepository<FirmwareInfoEntity, UUID> {
@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 " + @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, 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.tenantId = :tenantId " + "f.tenantId = :tenantId " +
"AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))") "AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
Page<FirmwareInfoEntity> findAllByTenantId(@Param("tenantId") UUID tenantId, Page<FirmwareInfoEntity> findAllByTenantId(@Param("tenantId") UUID tenantId,
@Param("searchText") String searchText, @Param("searchText") String searchText,
Pageable pageable); Pageable pageable);
@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 " + @Query("SELECT new FirmwareInfoEntity(f.id, f.createdTime, f.tenantId, 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.tenantId = :tenantId " + "f.tenantId = :tenantId " +
"AND ((f.data IS NOT NULL AND :hasData = true) OR (f.data IS NULL AND :hasData = false ))" + "AND ((f.data IS NOT NULL AND :hasData = true) OR (f.data IS NULL AND :hasData = false ))" +
"AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))") "AND LOWER(f.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")

View File

@ -162,6 +162,7 @@ CREATE TABLE IF NOT EXISTS firmware (
id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY,
created_time bigint NOT NULL, created_time bigint NOT NULL,
tenant_id uuid NOT NULL, tenant_id uuid NOT NULL,
type varchar(32) NOT NULL,
title varchar(255) NOT NULL, title varchar(255) NOT NULL,
version varchar(255) NOT NULL, version varchar(255) NOT NULL,
file_name varchar(255), file_name varchar(255),

View File

@ -45,3 +45,4 @@ CREATE INDEX IF NOT EXISTS idx_asset_type ON asset(tenant_id, type);
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); 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);
CREATE INDEX IF NOT EXISTS idx_audit_log_tenant_id_and_created_time ON audit_log(tenant_id, created_time); CREATE INDEX IF NOT EXISTS idx_audit_log_tenant_id_and_created_time ON audit_log(tenant_id, created_time);

View File

@ -180,6 +180,8 @@ CREATE TABLE IF NOT EXISTS firmware (
id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY,
created_time bigint NOT NULL, created_time bigint NOT NULL,
tenant_id uuid NOT NULL, tenant_id uuid NOT NULL,
device_profile_id uuid NOT NULL,
type varchar(32) NOT NULL,
title varchar(255) NOT NULL, title varchar(255) NOT NULL,
version varchar(255) NOT NULL, version varchar(255) NOT NULL,
file_name varchar(255), file_name varchar(255),
@ -190,7 +192,8 @@ CREATE TABLE IF NOT EXISTS firmware (
data_size bigint, data_size bigint,
additional_info varchar, additional_info varchar,
search_text varchar(255), search_text varchar(255),
CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version),
CONSTRAINT fk_firmware_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id) ON DELETE CASCADE
); );
CREATE TABLE IF NOT EXISTS device_profile ( CREATE TABLE IF NOT EXISTS device_profile (
@ -206,15 +209,26 @@ CREATE TABLE IF NOT EXISTS device_profile (
is_default boolean, is_default boolean,
tenant_id uuid, tenant_id uuid,
firmware_id uuid, firmware_id uuid,
software_id uuid,
default_rule_chain_id uuid, default_rule_chain_id uuid,
default_queue_name varchar(255), default_queue_name varchar(255),
provision_device_key varchar, provision_device_key varchar,
CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key), CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id), CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id),
CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id) CONSTRAINT fk_device_profile_firmware FOREIGN KEY (firmware_id) REFERENCES firmware(id)
CONSTRAINT fk_device_profile_software FOREIGN KEY (software_id) REFERENCES firmware(id)
); );
-- We will use one-to-many relation in the first release and extend this feature in case of user requests
-- CREATE TABLE IF NOT EXISTS device_profile_firmware (
-- device_profile_id uuid NOT NULL,
-- firmware_id uuid NOT NULL,
-- CONSTRAINT device_profile_firmware_unq_key UNIQUE (device_profile_id, firmware_id),
-- CONSTRAINT fk_device_profile_firmware_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id) ON DELETE CASCADE,
-- CONSTRAINT fk_device_profile_firmware_firmware FOREIGN KEY (firmware_id) REFERENCES firmware(id) ON DELETE CASCADE,
-- );
CREATE TABLE IF NOT EXISTS device ( CREATE TABLE IF NOT EXISTS device (
id uuid NOT NULL CONSTRAINT device_pkey PRIMARY KEY, id uuid NOT NULL CONSTRAINT device_pkey PRIMARY KEY,
created_time bigint NOT NULL, created_time bigint NOT NULL,
@ -228,9 +242,11 @@ CREATE TABLE IF NOT EXISTS device (
search_text varchar(255), search_text varchar(255),
tenant_id uuid, tenant_id uuid,
firmware_id uuid, firmware_id uuid,
software_id uuid,
CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name), CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name),
CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id), CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id),
CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id) CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES firmware(id)
CONSTRAINT fk_software_device FOREIGN KEY (software_id) REFERENCES firmware(id)
); );
CREATE TABLE IF NOT EXISTS device_credentials ( CREATE TABLE IF NOT EXISTS device_credentials (