Delete OTA update packages of device profile with cascade when this profile is deleted
This commit is contained in:
parent
35528e687a
commit
f51a66b585
27
application/src/main/data/upgrade/3.3.3/schema_update.sql
Normal file
27
application/src/main/data/upgrade/3.3.3/schema_update.sql
Normal file
@ -0,0 +1,27 @@
|
||||
--
|
||||
-- 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.
|
||||
--
|
||||
|
||||
DO
|
||||
$$
|
||||
BEGIN
|
||||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'fk_device_profile_ota_package') THEN
|
||||
ALTER TABLE ota_package
|
||||
ADD CONSTRAINT fk_device_profile_ota_package
|
||||
FOREIGN KEY (device_profile_id) REFERENCES device_profile (id)
|
||||
ON DELETE CASCADE;
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
@ -216,6 +216,9 @@ public class ThingsboardInstallService {
|
||||
dataUpdateService.updateData("3.3.2");
|
||||
log.info("Updating system data...");
|
||||
systemDataLoaderService.updateSystemWidgets();
|
||||
case "3.3.3":
|
||||
log.info("Upgrading ThingsBoard from version 3.3.3 to 3.4.0 ...");
|
||||
databaseEntitiesUpgradeService.upgradeDatabase("3.3.3");
|
||||
break;
|
||||
|
||||
//TODO update CacheCleanupService on the next version upgrade
|
||||
|
||||
@ -488,6 +488,18 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
|
||||
log.error("Failed updating schema!!!", e);
|
||||
}
|
||||
break;
|
||||
case "3.3.3":
|
||||
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
|
||||
log.info("Updating schema...");
|
||||
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.3.3", SCHEMA_UPDATE_SQL);
|
||||
loadSql(schemaUpdateFile, conn);
|
||||
log.info("Updating schema settings...");
|
||||
conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3004000;");
|
||||
log.info("Schema updated");
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to update schema", e);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion);
|
||||
}
|
||||
|
||||
@ -51,7 +51,4 @@ public interface OtaPackageService {
|
||||
void deleteOtaPackagesByTenantId(TenantId tenantId);
|
||||
|
||||
long sumDataSizeByTenantId(TenantId tenantId);
|
||||
|
||||
boolean existsByDeviceProfileId(DeviceProfileId deviceProfileId);
|
||||
|
||||
}
|
||||
|
||||
@ -218,9 +218,6 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
|
||||
if (deviceProfile != null && deviceProfile.isDefault()) {
|
||||
throw new DataValidationException("Deletion of Default Device Profile is prohibited!");
|
||||
}
|
||||
if (otaPackageService.existsByDeviceProfileId(deviceProfileId)) {
|
||||
throw new DataValidationException("The device profile is referenced by OTA update package");
|
||||
}
|
||||
this.removeDeviceProfile(tenantId, deviceProfile);
|
||||
}
|
||||
|
||||
|
||||
@ -223,11 +223,6 @@ public class BaseOtaPackageService implements OtaPackageService {
|
||||
return otaPackageDao.sumDataSizeByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByDeviceProfileId(DeviceProfileId deviceProfileId) {
|
||||
return otaPackageDao.existsByDeviceProfileId(deviceProfileId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteOtaPackagesByTenantId(TenantId tenantId) {
|
||||
log.trace("Executing deleteOtaPackagesByTenantId, tenantId [{}]", tenantId);
|
||||
|
||||
@ -16,14 +16,11 @@
|
||||
package org.thingsboard.server.dao.ota;
|
||||
|
||||
import org.thingsboard.server.common.data.OtaPackage;
|
||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.dao.Dao;
|
||||
import org.thingsboard.server.dao.TenantEntityDao;
|
||||
import org.thingsboard.server.dao.TenantEntityWithDataDao;
|
||||
|
||||
public interface OtaPackageDao extends Dao<OtaPackage>, TenantEntityWithDataDao {
|
||||
Long sumDataSizeByTenantId(TenantId tenantId);
|
||||
|
||||
boolean existsByDeviceProfileId(DeviceProfileId deviceProfileId);
|
||||
|
||||
}
|
||||
|
||||
@ -20,7 +20,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.OtaPackage;
|
||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.dao.ota.OtaPackageDao;
|
||||
import org.thingsboard.server.dao.model.sql.OtaPackageEntity;
|
||||
@ -49,10 +48,4 @@ public class JpaOtaPackageDao extends JpaAbstractSearchTextDao<OtaPackageEntity,
|
||||
public Long sumDataSizeByTenantId(TenantId tenantId) {
|
||||
return otaPackageRepository.sumDataSizeByTenantId(tenantId.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByDeviceProfileId(DeviceProfileId deviceProfileId) {
|
||||
return otaPackageRepository.existsByDeviceProfileId(deviceProfileId.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,13 +19,11 @@ import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.thingsboard.server.dao.model.sql.OtaPackageEntity;
|
||||
import org.thingsboard.server.dao.model.sql.OtaPackageInfoEntity;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface OtaPackageRepository extends CrudRepository<OtaPackageEntity, UUID> {
|
||||
@Query(value = "SELECT COALESCE(SUM(ota.data_size), 0) FROM ota_package ota WHERE ota.tenant_id = :tenantId AND ota.data IS NOT NULL", nativeQuery = true)
|
||||
Long sumDataSizeByTenantId(@Param("tenantId") UUID tenantId);
|
||||
|
||||
boolean existsByDeviceProfileId(UUID deviceProfileId);
|
||||
|
||||
}
|
||||
|
||||
@ -211,7 +211,6 @@ CREATE TABLE IF NOT EXISTS ota_package (
|
||||
additional_info varchar,
|
||||
search_text varchar(255),
|
||||
CONSTRAINT ota_package_tenant_title_version_unq_key UNIQUE (tenant_id, title, version)
|
||||
-- CONSTRAINT fk_device_profile_firmware FOREIGN KEY (device_profile_id) REFERENCES device_profile(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS device_profile (
|
||||
@ -241,6 +240,11 @@ CREATE TABLE IF NOT EXISTS device_profile (
|
||||
CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES ota_package(id)
|
||||
);
|
||||
|
||||
ALTER TABLE ota_package
|
||||
ADD CONSTRAINT fk_device_profile_ota_package
|
||||
FOREIGN KEY (device_profile_id) REFERENCES device_profile (id)
|
||||
ON DELETE CASCADE;
|
||||
|
||||
-- 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,
|
||||
|
||||
@ -31,8 +31,8 @@ import org.thingsboard.server.common.data.DeviceProfileInfo;
|
||||
import org.thingsboard.server.common.data.DeviceTransportType;
|
||||
import org.thingsboard.server.common.data.OtaPackage;
|
||||
import org.thingsboard.server.common.data.Tenant;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||
@ -45,7 +45,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
|
||||
|
||||
public abstract class BaseDeviceProfileServiceTest extends AbstractServiceTest {
|
||||
@ -254,16 +254,19 @@ public abstract class BaseDeviceProfileServiceTest extends AbstractServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDeviceProfileWithExistingOta() {
|
||||
public void testDeleteDeviceProfileWithExistingOta_cascadeDelete() {
|
||||
DeviceProfile deviceProfile = this.createDeviceProfile(tenantId, "Device Profile");
|
||||
DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile);
|
||||
deviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile);
|
||||
OtaPackage otaPackage = constructDefaultOtaPackage(tenantId, deviceProfile.getId());
|
||||
otaPackage = otaPackageService.saveOtaPackage(otaPackage);
|
||||
|
||||
OtaPackage otaPackage = constructDefaultOtaPackage(tenantId, savedDeviceProfile.getId());
|
||||
otaPackageService.saveOtaPackage(otaPackage);
|
||||
assertThat(deviceProfileService.findDeviceProfileById(tenantId, deviceProfile.getId())).isNotNull();
|
||||
assertThat(otaPackageService.findOtaPackageById(tenantId, otaPackage.getId())).isNotNull();
|
||||
|
||||
assertThrows("The device profile is referenced by OTA update package", DataValidationException.class, () -> {
|
||||
deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId());
|
||||
});
|
||||
deviceProfileService.deleteDeviceProfile(tenantId, deviceProfile.getId());
|
||||
|
||||
assertThat(deviceProfileService.findDeviceProfileById(tenantId, deviceProfile.getId())).isNull();
|
||||
assertThat(otaPackageService.findOtaPackageById(tenantId, otaPackage.getId())).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -487,9 +487,6 @@ public abstract class BaseOtaPackageServiceTest extends AbstractServiceTest {
|
||||
thrown.expectMessage("The otaPackage referenced by the device profile cannot be deleted!");
|
||||
otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId());
|
||||
} finally {
|
||||
savedDeviceProfile.setFirmwareId(null);
|
||||
deviceProfileService.saveDeviceProfile(savedDeviceProfile);
|
||||
otaPackageService.deleteOtaPackage(tenantId, savedFirmware.getId());
|
||||
deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
--PostgreSQL specific truncate to fit constraints
|
||||
TRUNCATE TABLE device_credentials, device, device_profile, rule_node_state, rule_node, rule_chain;
|
||||
TRUNCATE TABLE device_credentials, device, device_profile, ota_package, rule_node_state, rule_node, rule_chain;
|
||||
@ -1,6 +1,6 @@
|
||||
TRUNCATE TABLE device_credentials;
|
||||
TRUNCATE TABLE device;
|
||||
TRUNCATE TABLE device_profile;
|
||||
TRUNCATE TABLE device_profile CASCADE;
|
||||
TRUNCATE TABLE rule_node_state;
|
||||
TRUNCATE TABLE rule_node;
|
||||
TRUNCATE TABLE rule_chain;
|
||||
Loading…
x
Reference in New Issue
Block a user