|
|
|
@ -21,10 +21,10 @@ import com.google.common.util.concurrent.ListenableFuture; |
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.hibernate.exception.ConstraintViolationException; |
|
|
|
import org.springframework.cache.Cache; |
|
|
|
import org.springframework.cache.CacheManager; |
|
|
|
import org.springframework.cache.annotation.Cacheable; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.transaction.annotation.Propagation; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
import org.springframework.transaction.event.TransactionalEventListener; |
|
|
|
import org.thingsboard.server.cache.ota.OtaPackageDataCache; |
|
|
|
import org.thingsboard.server.common.data.OtaPackage; |
|
|
|
import org.thingsboard.server.common.data.OtaPackageInfo; |
|
|
|
@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; |
|
|
|
import org.thingsboard.server.common.data.ota.OtaPackageType; |
|
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
|
import org.thingsboard.server.common.data.page.PageLink; |
|
|
|
import org.thingsboard.server.dao.entity.AbstractCachedEntityService; |
|
|
|
import org.thingsboard.server.dao.exception.DataValidationException; |
|
|
|
import org.thingsboard.server.dao.service.DataValidator; |
|
|
|
import org.thingsboard.server.dao.service.PaginatedRemover; |
|
|
|
@ -45,39 +46,44 @@ import java.util.Collections; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Optional; |
|
|
|
|
|
|
|
import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_CACHE; |
|
|
|
import static org.thingsboard.server.dao.service.Validator.validateId; |
|
|
|
import static org.thingsboard.server.dao.service.Validator.validatePageLink; |
|
|
|
|
|
|
|
@Service |
|
|
|
@Slf4j |
|
|
|
@RequiredArgsConstructor |
|
|
|
public class BaseOtaPackageService implements OtaPackageService { |
|
|
|
public class BaseOtaPackageService extends AbstractCachedEntityService<OtaPackageCacheKey, OtaPackageInfo, OtaPackageCacheEvictEvent> implements OtaPackageService { |
|
|
|
public static final String INCORRECT_OTA_PACKAGE_ID = "Incorrect otaPackageId "; |
|
|
|
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
|
|
|
|
|
|
|
private final OtaPackageDao otaPackageDao; |
|
|
|
private final OtaPackageInfoDao otaPackageInfoDao; |
|
|
|
private final CacheManager cacheManager; |
|
|
|
private final OtaPackageDataCache otaPackageDataCache; |
|
|
|
private final DataValidator<OtaPackageInfo> otaPackageInfoValidator; |
|
|
|
private final DataValidator<OtaPackage> otaPackageValidator; |
|
|
|
|
|
|
|
@TransactionalEventListener(classes = OtaPackageCacheEvictEvent.class) |
|
|
|
@Override |
|
|
|
public void handleEvictEvent(OtaPackageCacheEvictEvent event) { |
|
|
|
cache.evict(new OtaPackageCacheKey(event.getId())); |
|
|
|
otaPackageDataCache.evict(event.getId().toString()); |
|
|
|
} |
|
|
|
|
|
|
|
@Transactional(propagation = Propagation.SUPPORTS) |
|
|
|
@Override |
|
|
|
public OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo, boolean isUrl) { |
|
|
|
log.trace("Executing saveOtaPackageInfo [{}]", otaPackageInfo); |
|
|
|
if(isUrl && (StringUtils.isEmpty(otaPackageInfo.getUrl()) || otaPackageInfo.getUrl().trim().length() == 0)) { |
|
|
|
if (isUrl && (StringUtils.isEmpty(otaPackageInfo.getUrl()) || otaPackageInfo.getUrl().trim().length() == 0)) { |
|
|
|
throw new DataValidationException("Ota package URL should be specified!"); |
|
|
|
} |
|
|
|
otaPackageInfoValidator.validate(otaPackageInfo, OtaPackageInfo::getTenantId); |
|
|
|
try { |
|
|
|
OtaPackageId otaPackageId = otaPackageInfo.getId(); |
|
|
|
var result = otaPackageInfoDao.save(otaPackageInfo.getTenantId(), otaPackageInfo); |
|
|
|
if (otaPackageId != null) { |
|
|
|
Cache cache = cacheManager.getCache(OTA_PACKAGE_CACHE); |
|
|
|
cache.evict(toOtaPackageInfoKey(otaPackageId)); |
|
|
|
otaPackageDataCache.evict(otaPackageId.toString()); |
|
|
|
publishEvictEvent(new OtaPackageCacheEvictEvent(otaPackageId)); |
|
|
|
} |
|
|
|
return otaPackageInfoDao.save(otaPackageInfo.getTenantId(), otaPackageInfo); |
|
|
|
return result; |
|
|
|
} catch (Exception t) { |
|
|
|
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); |
|
|
|
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("ota_package_tenant_title_version_unq_key")) { |
|
|
|
@ -88,18 +94,18 @@ public class BaseOtaPackageService implements OtaPackageService { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Transactional(propagation = Propagation.SUPPORTS) |
|
|
|
@Override |
|
|
|
public OtaPackage saveOtaPackage(OtaPackage otaPackage) { |
|
|
|
log.trace("Executing saveOtaPackage [{}]", otaPackage); |
|
|
|
otaPackageValidator.validate(otaPackage, OtaPackageInfo::getTenantId); |
|
|
|
try { |
|
|
|
OtaPackageId otaPackageId = otaPackage.getId(); |
|
|
|
var result = otaPackageDao.save(otaPackage.getTenantId(), otaPackage); |
|
|
|
if (otaPackageId != null) { |
|
|
|
Cache cache = cacheManager.getCache(OTA_PACKAGE_CACHE); |
|
|
|
cache.evict(toOtaPackageInfoKey(otaPackageId)); |
|
|
|
otaPackageDataCache.evict(otaPackageId.toString()); |
|
|
|
publishEvictEvent(new OtaPackageCacheEvictEvent(otaPackageId)); |
|
|
|
} |
|
|
|
return otaPackageDao.save(otaPackage.getTenantId(), otaPackage); |
|
|
|
return result; |
|
|
|
} catch (Exception t) { |
|
|
|
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); |
|
|
|
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("ota_package_tenant_title_version_unq_key")) { |
|
|
|
@ -149,11 +155,11 @@ public class BaseOtaPackageService implements OtaPackageService { |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
@Cacheable(cacheNames = OTA_PACKAGE_CACHE, key = "{#otaPackageId}") |
|
|
|
public OtaPackageInfo findOtaPackageInfoById(TenantId tenantId, OtaPackageId otaPackageId) { |
|
|
|
log.trace("Executing findOtaPackageInfoById [{}]", otaPackageId); |
|
|
|
validateId(otaPackageId, INCORRECT_OTA_PACKAGE_ID + otaPackageId); |
|
|
|
return otaPackageInfoDao.findById(tenantId, otaPackageId.getId()); |
|
|
|
return cache.getAndPutInTransaction(new OtaPackageCacheKey(otaPackageId), |
|
|
|
() -> otaPackageInfoDao.findById(tenantId, otaPackageId.getId()), true); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
@ -179,15 +185,14 @@ public class BaseOtaPackageService implements OtaPackageService { |
|
|
|
return otaPackageInfoDao.findOtaPackageInfoByTenantIdAndDeviceProfileIdAndTypeAndHasData(tenantId, deviceProfileId, otaPackageType, pageLink); |
|
|
|
} |
|
|
|
|
|
|
|
@Transactional(propagation = Propagation.SUPPORTS) |
|
|
|
@Override |
|
|
|
public void deleteOtaPackage(TenantId tenantId, OtaPackageId otaPackageId) { |
|
|
|
log.trace("Executing deleteOtaPackage [{}]", otaPackageId); |
|
|
|
validateId(otaPackageId, INCORRECT_OTA_PACKAGE_ID + otaPackageId); |
|
|
|
try { |
|
|
|
Cache cache = cacheManager.getCache(OTA_PACKAGE_CACHE); |
|
|
|
cache.evict(toOtaPackageInfoKey(otaPackageId)); |
|
|
|
otaPackageDataCache.evict(otaPackageId.toString()); |
|
|
|
otaPackageDao.removeById(tenantId, otaPackageId.getId()); |
|
|
|
publishEvictEvent(new OtaPackageCacheEvictEvent(otaPackageId)); |
|
|
|
} catch (Exception t) { |
|
|
|
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); |
|
|
|
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_firmware_device")) { |
|
|
|
|