package org.zstack.network.l3; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.header.network.l3.*; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.NetworkUtils; import java.util.List; public class FirstAvailableIpAllocatorStrategy extends AbstractIpAllocatorStrategy{ private static final CLogger logger = Utils.getLogger(FirstAvailableIpAllocatorStrategy.class); static final IpAllocatorType type = new IpAllocatorType(L3NetworkConstant.FIRST_AVAILABLE_IP_ALLOCATOR_STRATEGY); @Override public IpAllocatorType getType() { return type; } private String allocateIp(IpRangeVO vo) { List<Long> used = l3NwMgr.getUsedIpInRange(vo.getUuid()); String ret = NetworkUtils.findFirstAvailableIpv4Address(vo.getStartIp(), vo.getEndIp(), used.toArray(new Long[used.size()])); return ret; } @Override public UsedIpInventory allocateIp(IpAllocateMessage msg) { if (msg.getRequiredIp() != null) { return allocateRequiredIp(msg); } SimpleQuery<IpRangeVO> query = dbf.createQuery(IpRangeVO.class); query.add(IpRangeVO_.l3NetworkUuid, Op.EQ, msg.getL3NetworkUuid()); List<IpRangeVO> ranges = query.list(); do { String ip = null; IpRangeVO tr = null; for (IpRangeVO r : ranges) { if (l3NwMgr.isIpRangeFull(r)) { logger.debug(String.format("Ip range[uuid:%s, name: %s] is exhausted, try next one", r.getUuid(), r.getName())); continue; } ip = allocateIp(r); tr = r; if (ip != null) { break; } } if (ip == null) { /* No available ip in ranges */ return null; } UsedIpInventory inv = l3NwMgr.reserveIp(IpRangeInventory.valueOf(tr), ip); if (inv != null) { return inv; } } while (true); } }