package org.zstack.storage.ceph.primary;
import org.springframework.transaction.annotation.Transactional;
import org.zstack.core.config.GlobalConfig;
import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint;
import org.zstack.header.storage.primary.ImageCacheShadowVO;
import org.zstack.header.storage.primary.ImageCacheVO;
import org.zstack.storage.ceph.CephConstants;
import org.zstack.storage.ceph.CephGlobalConfig;
import org.zstack.storage.primary.ImageCacheCleaner;
import org.zstack.utils.Utils;
import org.zstack.utils.logging.CLogger;
import javax.persistence.TypedQuery;
import java.util.List;
/**
* Created by xing5 on 2016/7/23.
*/
public class CephImageCacheCleaner extends ImageCacheCleaner implements ManagementNodeReadyExtensionPoint {
private static final CLogger logger = Utils.getLogger(CephImageCacheCleaner.class);
@Override
protected String getPrimaryStorageType() {
return CephConstants.CEPH_PRIMARY_STORAGE_TYPE;
}
@Override
protected GlobalConfig cleanupIntervalConfig() {
return CephGlobalConfig.IMAGE_CACHE_CLEANUP_INTERVAL;
}
@Transactional
@Override
protected List<ImageCacheShadowVO> createShadowImageCacheVOs(String psUuid) {
List<Long> staleImageCacheIds = getStaleImageCacheIds(psUuid);
if (staleImageCacheIds == null || staleImageCacheIds.isEmpty()) {
return null;
}
String sql = "select ref.imageCacheId from ImageCacheVolumeRefVO ref where ref.imageCacheId in (:ids)";
TypedQuery<Long> refq = dbf.getEntityManager().createQuery(sql, Long.class);
refq.setParameter("ids", staleImageCacheIds);
List<Long> existing = refq.getResultList();
staleImageCacheIds.removeAll(existing);
if (staleImageCacheIds.isEmpty()) {
return null;
}
sql = "select c from ImageCacheVO c where c.id in (:ids)";
TypedQuery<ImageCacheVO> fq = dbf.getEntityManager().createQuery(sql, ImageCacheVO.class);
fq.setParameter("ids", staleImageCacheIds);
List<ImageCacheVO> stale = fq.getResultList();
logger.debug(String.format("found %s stale images in cache on the primary storage[type:%s], they are about to be cleaned up",
stale.size(), getPrimaryStorageType()));
for (ImageCacheVO vo : stale) {
dbf.getEntityManager().persist(new ImageCacheShadowVO(vo));
dbf.getEntityManager().remove(vo);
}
sql = "select s from ImageCacheShadowVO s, PrimaryStorageVO p where p.uuid = s.primaryStorageUuid and p.type = :ptype";
TypedQuery<ImageCacheShadowVO> sq = dbf.getEntityManager().createQuery(sql, ImageCacheShadowVO.class);
sq.setParameter("ptype", getPrimaryStorageType());
return sq.getResultList();
}
@Override
public void managementNodeReady() {
startGC();
}
}