package org.zstack.compute.allocator; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.db.DatabaseFacade; import org.zstack.header.allocator.AbstractHostAllocatorFlow; import org.zstack.header.allocator.HostCapacityOverProvisioningManager; import org.zstack.header.allocator.HostCpuOverProvisioningManager; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HostVO; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import java.util.List; import java.util.stream.Collectors; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class HostCapacityAllocatorFlow extends AbstractHostAllocatorFlow { private static final CLogger logger = Utils.getLogger(HostCapacityAllocatorFlow.class); @Autowired private DatabaseFacade dbf; @Autowired private HostCapacityReserveManager reserveMgr; @Autowired private HostCapacityOverProvisioningManager ratioMgr; @Autowired private HostCpuOverProvisioningManager cpuRatioMgr; private List<HostVO> allocate(List<HostVO> vos, long cpu, long memory) { List<HostVO> ret = vos.stream() .filter(hvo -> hvo.getCapacity().getAvailableCpu() >= cpu && ratioMgr.calculateHostAvailableMemoryByRatio(hvo.getUuid(), hvo.getCapacity().getAvailableMemory()) >= memory) .collect(Collectors.toList()); return ret; } private boolean isNoCpu(int cpu) { return !candidates.stream().anyMatch(vo -> vo.getCapacity().getCpuNum() >= cpu); } private boolean isNoMemory(long mem) { return !candidates.stream().anyMatch(vo -> ratioMgr.calculateHostAvailableMemoryByRatio(vo.getUuid(), vo.getCapacity().getAvailableMemory()) >= mem); } @Override public void allocate() { List<HostVO> ret; if (amITheFirstFlow()) { throw new CloudRuntimeException("HostCapacityAllocatorFlow cannot be the first allocator flow"); } else { ret = allocate(candidates, spec.getCpuCapacity(), spec.getMemoryCapacity()); } ret = reserveMgr.filterOutHostsByReservedCapacity(ret, spec.getCpuCapacity(), spec.getMemoryCapacity()); if (ret.isEmpty()) { fail(String.format("no host having cpu[%s], memory[%s bytes] found", spec.getCpuCapacity(), spec.getMemoryCapacity())); } else { next(ret); } } }