| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| package com.cloud.dc.dao; | |
| import java.sql.PreparedStatement; | |
| import java.sql.ResultSet; | |
| import java.sql.SQLException; | |
| import java.util.ArrayList; | |
| import java.util.List; | |
| import java.util.Map; | |
| import javax.ejb.Local; | |
| import javax.inject.Inject; | |
| import javax.naming.ConfigurationException; | |
| import org.springframework.stereotype.Component; | |
| import com.cloud.dc.AccountVlanMapVO; | |
| import com.cloud.dc.PodVlanMapVO; | |
| import com.cloud.dc.Vlan; | |
| import com.cloud.dc.Vlan.VlanType; | |
| import com.cloud.dc.VlanVO; | |
| import com.cloud.network.dao.IPAddressDao; | |
| import com.cloud.utils.Pair; | |
| import com.cloud.utils.db.DB; | |
| import com.cloud.utils.db.GenericDaoBase; | |
| import com.cloud.utils.db.JoinBuilder; | |
| import com.cloud.utils.db.SearchBuilder; | |
| import com.cloud.utils.db.SearchCriteria; | |
| import com.cloud.utils.db.TransactionLegacy; | |
| import com.cloud.utils.exception.CloudRuntimeException; | |
| @Component | |
| @Local(value = {VlanDao.class}) | |
| public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao { | |
| private final String FindZoneWideVlans = | |
| "SELECT * FROM vlan WHERE data_center_id=? and vlan_type=? and vlan_id!=? and id not in (select vlan_db_id from account_vlan_map)"; | |
| protected SearchBuilder<VlanVO> ZoneVlanIdSearch; | |
| protected SearchBuilder<VlanVO> ZoneSearch; | |
| protected SearchBuilder<VlanVO> ZoneTypeSearch; | |
| protected SearchBuilder<VlanVO> ZoneTypeAllPodsSearch; | |
| protected SearchBuilder<VlanVO> ZoneTypePodSearch; | |
| protected SearchBuilder<VlanVO> ZoneVlanSearch; | |
| protected SearchBuilder<VlanVO> NetworkVlanSearch; | |
| protected SearchBuilder<VlanVO> PhysicalNetworkVlanSearch; | |
| protected SearchBuilder<VlanVO> ZoneWideNonDedicatedVlanSearch; | |
| protected SearchBuilder<VlanVO> VlanGatewaysearch; | |
| protected SearchBuilder<VlanVO> DedicatedVlanSearch; | |
| protected SearchBuilder<AccountVlanMapVO> AccountVlanMapSearch; | |
| @Inject | |
| protected PodVlanMapDao _podVlanMapDao; | |
| @Inject | |
| protected AccountVlanMapDao _accountVlanMapDao; | |
| @Inject | |
| protected IPAddressDao _ipAddressDao; | |
| @Override | |
| public VlanVO findByZoneAndVlanId(long zoneId, String vlanId) { | |
| SearchCriteria<VlanVO> sc = ZoneVlanIdSearch.create(); | |
| sc.setParameters("zoneId", zoneId); | |
| sc.setParameters("vlanId", vlanId); | |
| return findOneBy(sc); | |
| } | |
| @Override | |
| public List<VlanVO> listByZone(long zoneId) { | |
| SearchCriteria<VlanVO> sc = ZoneSearch.create(); | |
| sc.setParameters("zoneId", zoneId); | |
| return listBy(sc); | |
| } | |
| public VlanDaoImpl() { | |
| ZoneVlanIdSearch = createSearchBuilder(); | |
| ZoneVlanIdSearch.and("zoneId", ZoneVlanIdSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); | |
| ZoneVlanIdSearch.and("vlanId", ZoneVlanIdSearch.entity().getVlanTag(), SearchCriteria.Op.EQ); | |
| ZoneVlanIdSearch.done(); | |
| ZoneSearch = createSearchBuilder(); | |
| ZoneSearch.and("zoneId", ZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); | |
| ZoneSearch.done(); | |
| ZoneTypeSearch = createSearchBuilder(); | |
| ZoneTypeSearch.and("zoneId", ZoneTypeSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); | |
| ZoneTypeSearch.and("vlanType", ZoneTypeSearch.entity().getVlanType(), SearchCriteria.Op.EQ); | |
| ZoneTypeSearch.done(); | |
| NetworkVlanSearch = createSearchBuilder(); | |
| NetworkVlanSearch.and("networkOfferingId", NetworkVlanSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); | |
| NetworkVlanSearch.done(); | |
| PhysicalNetworkVlanSearch = createSearchBuilder(); | |
| PhysicalNetworkVlanSearch.and("physicalNetworkId", PhysicalNetworkVlanSearch.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ); | |
| PhysicalNetworkVlanSearch.done(); | |
| VlanGatewaysearch = createSearchBuilder(); | |
| VlanGatewaysearch.and("gateway", VlanGatewaysearch.entity().getVlanGateway(), SearchCriteria.Op.EQ); | |
| VlanGatewaysearch.and("networkid", VlanGatewaysearch.entity().getNetworkId(), SearchCriteria.Op.EQ); | |
| VlanGatewaysearch.done(); | |
| } | |
| @Override | |
| public List<VlanVO> listZoneWideVlans(long zoneId, VlanType vlanType, String vlanId) { | |
| SearchCriteria<VlanVO> sc = ZoneVlanSearch.create(); | |
| sc.setParameters("zoneId", zoneId); | |
| sc.setParameters("vlanId", vlanId); | |
| sc.setParameters("vlanType", vlanType); | |
| return listBy(sc); | |
| } | |
| @Override | |
| public List<VlanVO> listByZoneAndType(long zoneId, VlanType vlanType) { | |
| SearchCriteria<VlanVO> sc = ZoneTypeSearch.create(); | |
| sc.setParameters("zoneId", zoneId); | |
| sc.setParameters("vlanType", vlanType); | |
| return listBy(sc); | |
| } | |
| @Override | |
| public List<VlanVO> listByType(VlanType vlanType) { | |
| SearchCriteria<VlanVO> sc = ZoneTypeSearch.create(); | |
| sc.setParameters("vlanType", vlanType); | |
| return listBy(sc); | |
| } | |
| @Override | |
| public List<VlanVO> listVlansForPod(long podId) { | |
| //FIXME: use a join statement to improve the performance (should be minor since we expect only one or two | |
| List<PodVlanMapVO> vlanMaps = _podVlanMapDao.listPodVlanMapsByPod(podId); | |
| List<VlanVO> result = new ArrayList<VlanVO>(); | |
| for (PodVlanMapVO pvmvo : vlanMaps) { | |
| result.add(findById(pvmvo.getVlanDbId())); | |
| } | |
| return result; | |
| } | |
| @Override | |
| public List<VlanVO> listVlansForPodByType(long podId, VlanType vlanType) { | |
| //FIXME: use a join statement to improve the performance (should be minor since we expect only one or two) | |
| List<PodVlanMapVO> vlanMaps = _podVlanMapDao.listPodVlanMapsByPod(podId); | |
| List<VlanVO> result = new ArrayList<VlanVO>(); | |
| for (PodVlanMapVO pvmvo : vlanMaps) { | |
| VlanVO vlan = findById(pvmvo.getVlanDbId()); | |
| if (vlan.getVlanType() == vlanType) { | |
| result.add(vlan); | |
| } | |
| } | |
| return result; | |
| } | |
| @Override | |
| public List<VlanVO> listVlansForAccountByType(Long zoneId, long accountId, VlanType vlanType) { | |
| //FIXME: use a join statement to improve the performance (should be minor since we expect only one or two) | |
| List<AccountVlanMapVO> vlanMaps = _accountVlanMapDao.listAccountVlanMapsByAccount(accountId); | |
| List<VlanVO> result = new ArrayList<VlanVO>(); | |
| for (AccountVlanMapVO acvmvo : vlanMaps) { | |
| VlanVO vlan = findById(acvmvo.getVlanDbId()); | |
| if (vlan.getVlanType() == vlanType && (zoneId == null || vlan.getDataCenterId() == zoneId)) { | |
| result.add(vlan); | |
| } | |
| } | |
| return result; | |
| } | |
| @Override | |
| public void addToPod(long podId, long vlanDbId) { | |
| PodVlanMapVO pvmvo = new PodVlanMapVO(podId, vlanDbId); | |
| _podVlanMapDao.persist(pvmvo); | |
| } | |
| @Override | |
| public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { | |
| boolean result = super.configure(name, params); | |
| ZoneTypeAllPodsSearch = createSearchBuilder(); | |
| ZoneTypeAllPodsSearch.and("zoneId", ZoneTypeAllPodsSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); | |
| ZoneTypeAllPodsSearch.and("vlanType", ZoneTypeAllPodsSearch.entity().getVlanType(), SearchCriteria.Op.EQ); | |
| SearchBuilder<PodVlanMapVO> PodVlanSearch = _podVlanMapDao.createSearchBuilder(); | |
| PodVlanSearch.and("podId", PodVlanSearch.entity().getPodId(), SearchCriteria.Op.NNULL); | |
| ZoneTypeAllPodsSearch.join("vlan", PodVlanSearch, PodVlanSearch.entity().getVlanDbId(), ZoneTypeAllPodsSearch.entity().getId(), JoinBuilder.JoinType.INNER); | |
| ZoneTypeAllPodsSearch.done(); | |
| PodVlanSearch.done(); | |
| ZoneTypePodSearch = createSearchBuilder(); | |
| ZoneTypePodSearch.and("zoneId", ZoneTypePodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); | |
| ZoneTypePodSearch.and("vlanType", ZoneTypePodSearch.entity().getVlanType(), SearchCriteria.Op.EQ); | |
| SearchBuilder<PodVlanMapVO> PodVlanSearch2 = _podVlanMapDao.createSearchBuilder(); | |
| PodVlanSearch2.and("podId", PodVlanSearch2.entity().getPodId(), SearchCriteria.Op.EQ); | |
| ZoneTypePodSearch.join("vlan", PodVlanSearch2, PodVlanSearch2.entity().getVlanDbId(), ZoneTypePodSearch.entity().getId(), JoinBuilder.JoinType.INNER); | |
| PodVlanSearch2.done(); | |
| ZoneTypePodSearch.done(); | |
| ZoneWideNonDedicatedVlanSearch = createSearchBuilder(); | |
| ZoneWideNonDedicatedVlanSearch.and("zoneId", ZoneWideNonDedicatedVlanSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); | |
| AccountVlanMapSearch = _accountVlanMapDao.createSearchBuilder(); | |
| AccountVlanMapSearch.and("accountId", AccountVlanMapSearch.entity().getAccountId(), SearchCriteria.Op.NULL); | |
| ZoneWideNonDedicatedVlanSearch.join("AccountVlanMapSearch", AccountVlanMapSearch, ZoneWideNonDedicatedVlanSearch.entity().getId(), AccountVlanMapSearch.entity() | |
| .getVlanDbId(), JoinBuilder.JoinType.LEFTOUTER); | |
| ZoneWideNonDedicatedVlanSearch.done(); | |
| AccountVlanMapSearch.done(); | |
| DedicatedVlanSearch = createSearchBuilder(); | |
| AccountVlanMapSearch = _accountVlanMapDao.createSearchBuilder(); | |
| AccountVlanMapSearch.and("accountId", AccountVlanMapSearch.entity().getAccountId(), SearchCriteria.Op.EQ); | |
| DedicatedVlanSearch.join("AccountVlanMapSearch", AccountVlanMapSearch, DedicatedVlanSearch.entity().getId(), AccountVlanMapSearch.entity().getVlanDbId(), | |
| JoinBuilder.JoinType.LEFTOUTER); | |
| DedicatedVlanSearch.done(); | |
| AccountVlanMapSearch.done(); | |
| return result; | |
| } | |
| private VlanVO findNextVlan(long zoneId, Vlan.VlanType vlanType) { | |
| List<VlanVO> allVlans = listByZoneAndType(zoneId, vlanType); | |
| List<VlanVO> emptyVlans = new ArrayList<VlanVO>(); | |
| List<VlanVO> fullVlans = new ArrayList<VlanVO>(); | |
| // Try to find a VLAN that is partially allocated | |
| for (VlanVO vlan : allVlans) { | |
| long vlanDbId = vlan.getId(); | |
| int countOfAllocatedIps = _ipAddressDao.countIPs(zoneId, vlanDbId, true); | |
| int countOfAllIps = _ipAddressDao.countIPs(zoneId, vlanDbId, false); | |
| if ((countOfAllocatedIps > 0) && (countOfAllocatedIps < countOfAllIps)) { | |
| return vlan; | |
| } else if (countOfAllocatedIps == 0) { | |
| emptyVlans.add(vlan); | |
| } else if (countOfAllocatedIps == countOfAllIps) { | |
| fullVlans.add(vlan); | |
| } | |
| } | |
| if (emptyVlans.isEmpty()) { | |
| return null; | |
| } | |
| // Try to find an empty VLAN with the same tag/subnet as a VLAN that is full | |
| for (VlanVO fullVlan : fullVlans) { | |
| for (VlanVO emptyVlan : emptyVlans) { | |
| if (fullVlan.getVlanTag().equals(emptyVlan.getVlanTag()) && fullVlan.getVlanGateway().equals(emptyVlan.getVlanGateway()) && | |
| fullVlan.getVlanNetmask().equals(emptyVlan.getVlanNetmask())) { | |
| return emptyVlan; | |
| } | |
| } | |
| } | |
| // Return a random empty VLAN | |
| return emptyVlans.get(0); | |
| } | |
| @Override | |
| public boolean zoneHasDirectAttachUntaggedVlans(long zoneId) { | |
| SearchCriteria<VlanVO> sc = ZoneTypeAllPodsSearch.create(); | |
| sc.setParameters("zoneId", zoneId); | |
| sc.setParameters("vlanType", VlanType.DirectAttached); | |
| return listIncludingRemovedBy(sc).size() > 0; | |
| } | |
| public Pair<String, VlanVO> assignPodDirectAttachIpAddress(long zoneId, long podId, long accountId, long domainId) { | |
| SearchCriteria<VlanVO> sc = ZoneTypePodSearch.create(); | |
| sc.setParameters("zoneId", zoneId); | |
| sc.setParameters("vlanType", VlanType.DirectAttached); | |
| sc.setJoinParameters("vlan", "podId", podId); | |
| VlanVO vlan = findOneIncludingRemovedBy(sc); | |
| if (vlan == null) { | |
| return null; | |
| } | |
| return null; | |
| // String ipAddress = _ipAddressDao.assignIpAddress(accountId, domainId, vlan.getId(), false).getAddress(); | |
| // if (ipAddress == null) { | |
| // return null; | |
| // } | |
| // return new Pair<String, VlanVO>(ipAddress, vlan); | |
| } | |
| @Override | |
| @DB | |
| public List<VlanVO> searchForZoneWideVlans(long dcId, String vlanType, String vlanId) { | |
| StringBuilder sql = new StringBuilder(FindZoneWideVlans); | |
| TransactionLegacy txn = TransactionLegacy.currentTxn(); | |
| PreparedStatement pstmt = null; | |
| try { | |
| pstmt = txn.prepareAutoCloseStatement(sql.toString()); | |
| pstmt.setLong(1, dcId); | |
| pstmt.setString(2, vlanType); | |
| pstmt.setString(3, vlanId); | |
| ResultSet rs = pstmt.executeQuery(); | |
| List<VlanVO> zoneWideVlans = new ArrayList<VlanVO>(); | |
| while (rs.next()) { | |
| zoneWideVlans.add(toEntityBean(rs, false)); | |
| } | |
| return zoneWideVlans; | |
| } catch (SQLException e) { | |
| throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); | |
| } | |
| } | |
| @Override | |
| public List<VlanVO> listVlansByNetworkId(long networkOfferingId) { | |
| SearchCriteria<VlanVO> sc = NetworkVlanSearch.create(); | |
| sc.setParameters("networkOfferingId", networkOfferingId); | |
| return listBy(sc); | |
| } | |
| @Override | |
| public List<VlanVO> listVlansByNetworkIdAndGateway(long networkid, String gateway) { | |
| SearchCriteria<VlanVO> sc = VlanGatewaysearch.create(); | |
| sc.setParameters("networkid", networkid); | |
| sc.setParameters("gateway", gateway); | |
| return listBy(sc); | |
| } | |
| @Override | |
| public List<VlanVO> listVlansByPhysicalNetworkId(long physicalNetworkId) { | |
| SearchCriteria<VlanVO> sc = PhysicalNetworkVlanSearch.create(); | |
| sc.setParameters("physicalNetworkId", physicalNetworkId); | |
| return listBy(sc); | |
| } | |
| @Override | |
| public List<VlanVO> listZoneWideNonDedicatedVlans(long zoneId) { | |
| SearchCriteria<VlanVO> sc = ZoneWideNonDedicatedVlanSearch.create(); | |
| sc.setParameters("zoneId", zoneId); | |
| return listBy(sc); | |
| } | |
| @Override | |
| public List<VlanVO> listDedicatedVlans(long accountId) { | |
| SearchCriteria<VlanVO> sc = DedicatedVlanSearch.create(); | |
| sc.setJoinParameters("AccountVlanMapSearch", "accountId", accountId); | |
| return listBy(sc); | |
| } | |
| } |