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.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.header.allocator.AbstractHostAllocatorFlow; import org.zstack.header.host.HostState; import org.zstack.header.host.HostStatus; import org.zstack.header.host.HostVO; import org.zstack.header.host.HostVO_; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import java.util.ArrayList; import java.util.List; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class HostStateAndHypervisorAllocatorFlow extends AbstractHostAllocatorFlow { private static final CLogger logger = Utils.getLogger(HostStateAndHypervisorAllocatorFlow.class); @Autowired private DatabaseFacade dbf; private List<HostVO> allocate(String hypervisorType) { SimpleQuery<HostVO> query = dbf.createQuery(HostVO.class); query.add(HostVO_.state, Op.EQ, HostState.Enabled); query.add(HostVO_.status, Op.EQ, HostStatus.Connected); if (hypervisorType != null) { query.add(HostVO_.hypervisorType, Op.EQ, hypervisorType); } if (usePagination()) { query.setStart(paginationInfo.getOffset()); query.setLimit(paginationInfo.getLimit()); } return query.list(); } private List<HostVO> allocate(List<HostVO> vos, String hypervisorType) { List<HostVO> lst = new ArrayList<HostVO>(vos.size()); for (HostVO vo : vos) { if (hypervisorType != null && !hypervisorType.equals(vo.getHypervisorType())) { continue; } if (vo.getState() == HostState.Enabled && vo.getStatus() == HostStatus.Connected) { lst.add(vo); } } return lst; } private boolean isNoEnabledHost() { return !candidates.stream().anyMatch(vo -> HostState.Enabled == vo.getState()); } private boolean isNoConnectedHost() { return !candidates.stream().anyMatch(vo -> HostStatus.Connected == vo.getStatus()); } private boolean isNoHypervisor(String hyType) { return !candidates.stream().anyMatch(vo -> hyType.equals(vo.getHypervisorType())); } @Override public void allocate() { List<HostVO> ret; if (amITheFirstFlow()) { ret = allocate(spec.getHypervisorType()); } else { ret = allocate(candidates, spec.getHypervisorType()); } if (ret.isEmpty()) { String error; if (isNoConnectedHost()) { error = String.format("no Connected hosts found in the [%s] candidate hosts", candidates.size()); } else if (isNoEnabledHost()) { error = String.format("no Enabled hosts found in the [%s] candidate hosts", candidates.size()); } else if (isNoHypervisor(spec.getHypervisorType())) { error = String.format("no Enabled hosts found in the [%s] candidate hosts having the hypervisor type [%s]", candidates.size(), spec.getHypervisorType()); } else { StringBuilder sb = new StringBuilder("no host having"); sb.append(String.format(" state=Enabled")); sb.append(String.format(" status=Connected")); if (spec.getHypervisorType() != null) { sb.append(String.format(" hypervisorType=%s", spec.getHypervisorType())); } sb.append(" found"); error = sb.toString(); } fail(error); } else { logger.info(String.format("found [%s] hosts with hypervisor type [%s] are Enabled and Connected", ret.size(), spec.getHypervisorType())); next(ret); } } }