package org.zstack.compute.vm; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.SimpleQuery; import org.zstack.header.core.scheduler.SchedulerVO; import org.zstack.header.identity.AccountResourceRefVO; import org.zstack.header.identity.AccountResourceRefVO_; import org.zstack.header.vm.VmInstanceState; import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.volume.VolumeStatus; import org.zstack.header.volume.VolumeType; import org.zstack.header.volume.VolumeVO; import org.zstack.header.volume.VolumeVO_; import javax.persistence.Tuple; import javax.persistence.TypedQuery; import static org.zstack.utils.CollectionDSL.list; /** * Created by miao on 16-10-9. */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VmQuotaUtil { @Autowired private DatabaseFacade dbf; public class VmQuota { public long totalVmNum; public long runningVmNum; public long runningVmCpuNum; public long runningVmMemorySize; } @Transactional(readOnly = true) public long getUsedDataVolumeCount(String accountUuid) { String sql = "select count(vol)" + " from VolumeVO vol, AccountResourceRefVO ref " + " where vol.type = :vtype" + " and ref.resourceUuid = vol.uuid " + " and ref.accountUuid = :auuid" + " and ref.resourceType = :rtype" + " and vol.status != :status "; TypedQuery<Tuple> volq = dbf.getEntityManager().createQuery(sql, Tuple.class); volq.setParameter("auuid", accountUuid); volq.setParameter("rtype", VolumeVO.class.getSimpleName()); volq.setParameter("vtype", VolumeType.Data); volq.setParameter("status", VolumeStatus.Deleted); Long n = volq.getSingleResult().get(0, Long.class); n = n == null ? 0 : n; return n; } @Transactional(readOnly = true) public long getUsedAllVolumeSize(String accountUuid) { String sql = "select sum(vol.size)" + " from VolumeVO vol, AccountResourceRefVO ref" + " where ref.resourceUuid = vol.uuid" + " and ref.accountUuid = :auuid" + " and ref.resourceType = :rtype"; TypedQuery<Long> vq = dbf.getEntityManager().createQuery(sql, Long.class); vq.setParameter("auuid", accountUuid); vq.setParameter("rtype", VolumeVO.class.getSimpleName()); Long vsize = vq.getSingleResult(); vsize = vsize == null ? 0 : vsize; return vsize; } @Transactional(readOnly = true) public VmQuota getUsedVmCpuMemory(String accountUUid) { VmQuota quota = new VmQuota(); // get running info String sql = "select count(vm), sum(vm.cpuNum), sum(vm.memorySize)" + " from VmInstanceVO vm, AccountResourceRefVO ref" + " where vm.uuid = ref.resourceUuid" + " and ref.accountUuid = :auuid" + " and ref.resourceType = :rtype" + " and vm.state not in (:states)"; TypedQuery<Tuple> q = dbf.getEntityManager().createQuery(sql, Tuple.class); q.setParameter("auuid", accountUUid); q.setParameter("rtype", VmInstanceVO.class.getSimpleName()); q.setParameter("states", list(VmInstanceState.Stopped, VmInstanceState.Destroying, VmInstanceState.Destroyed, VmInstanceState.Created)); Tuple t = q.getSingleResult(); Long vnum = t.get(0, Long.class); quota.runningVmNum = vnum == null ? 0 : vnum; Long cnum = t.get(1, Long.class); quota.runningVmCpuNum = cnum == null ? 0 : cnum; Long msize = t.get(2, Long.class); quota.runningVmMemorySize = msize == null ? 0 : msize; // get total vm String sql2 = "select count(vm)" + " from VmInstanceVO vm, AccountResourceRefVO ref" + " where vm.uuid = ref.resourceUuid" + " and ref.accountUuid = :auuid" + " and ref.resourceType = :rtype" + " and vm.state not in (:states)"; TypedQuery<Long> q2 = dbf.getEntityManager().createQuery(sql2, Long.class); q2.setParameter("auuid", accountUUid); q2.setParameter("rtype", VmInstanceVO.class.getSimpleName()); q2.setParameter("states", list(VmInstanceState.Destroyed)); Long totalVmNum = q2.getSingleResult(); quota.totalVmNum = totalVmNum == null ? 0 : totalVmNum; return quota; } @Transactional(readOnly = true) public long getVmInstanceRootVolumeSize(String vmInstanceUuid) { SimpleQuery<VolumeVO> sq = dbf.createQuery(VolumeVO.class); sq.select(VolumeVO_.size); sq.add(VolumeVO_.type, SimpleQuery.Op.EQ, VolumeType.Root); sq.add(VolumeVO_.vmInstanceUuid, SimpleQuery.Op.EQ, vmInstanceUuid); Long rootVolumeSize = sq.findValue(); rootVolumeSize = rootVolumeSize == null ? 0 : rootVolumeSize; return rootVolumeSize; } public long getUsedSchedulerNum(String accountUuid) { SimpleQuery<AccountResourceRefVO> querySchedulerNum = dbf.createQuery(AccountResourceRefVO.class); querySchedulerNum.add(AccountResourceRefVO_.accountUuid, SimpleQuery.Op.EQ, accountUuid); querySchedulerNum.add(AccountResourceRefVO_.resourceType, SimpleQuery.Op.EQ, SchedulerVO.class.getSimpleName()); return querySchedulerNum.count(); } }