/** * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. * * This software is licensed under the GNU General Public License v3 or later. * * It is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ package com.cloud.vm.dao; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import javax.ejb.Local; import org.apache.log4j.Logger; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.Attribute; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicVO; import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine.State; @Local(value={UserVmDao.class}) public class UserVmDaoImpl extends GenericDaoBase implements UserVmDao { public static final Logger s_logger = Logger.getLogger(UserVmDaoImpl.class); protected final SearchBuilder AccountPodSearch; protected final SearchBuilder AccountDataCenterSearch; protected final SearchBuilder AccountSearch; protected final SearchBuilder HostSearch; protected final SearchBuilder LastHostSearch; protected final SearchBuilder HostUpSearch; protected final SearchBuilder HostRunningSearch; protected final SearchBuilder StateChangeSearch; protected final SearchBuilder AccountHostSearch; protected final SearchBuilder DestroySearch; protected SearchBuilder AccountDataCenterVirtualSearch; protected GenericSearchBuilder CountByAccountPod; protected GenericSearchBuilder PodsHavingVmsForAccount; protected SearchBuilder UserVmSearch; protected final Attribute _updateTimeAttr; private static final String LIST_PODS_HAVING_VMS_FOR_ACCOUNT = "SELECT pod_id FROM cloud.vm_instance WHERE data_center_id = ? AND account_id = ? AND pod_id IS NOT NULL AND state = 'Running' OR state = 'Stopped' " + "GROUP BY pod_id HAVING count(id) > 0 ORDER BY count(id) DESC"; protected final UserVmDetailsDaoImpl _detailsDao = ComponentLocator.inject(UserVmDetailsDaoImpl.class); protected UserVmDaoImpl() { AccountSearch = createSearchBuilder(); AccountSearch.and("account", AccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountSearch.done(); HostSearch = createSearchBuilder(); HostSearch.and("host", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ); HostSearch.done(); LastHostSearch = createSearchBuilder(); LastHostSearch.and("lastHost", LastHostSearch.entity().getLastHostId(), SearchCriteria.Op.EQ); LastHostSearch.and("state", LastHostSearch.entity().getState(), SearchCriteria.Op.EQ); LastHostSearch.done(); HostUpSearch = createSearchBuilder(); HostUpSearch.and("host", HostUpSearch.entity().getHostId(), SearchCriteria.Op.EQ); HostUpSearch.and("states", HostUpSearch.entity().getState(), SearchCriteria.Op.NIN); HostUpSearch.done(); HostRunningSearch = createSearchBuilder(); HostRunningSearch.and("host", HostRunningSearch.entity().getHostId(), SearchCriteria.Op.EQ); HostRunningSearch.and("state", HostRunningSearch.entity().getState(), SearchCriteria.Op.EQ); HostRunningSearch.done(); AccountPodSearch = createSearchBuilder(); AccountPodSearch.and("account", AccountPodSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountPodSearch.and("pod", AccountPodSearch.entity().getPodId(), SearchCriteria.Op.EQ); AccountPodSearch.done(); AccountDataCenterSearch = createSearchBuilder(); AccountDataCenterSearch.and("account", AccountDataCenterSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountDataCenterSearch.and("dc", AccountDataCenterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); AccountDataCenterSearch.done(); StateChangeSearch = createSearchBuilder(); StateChangeSearch.and("id", StateChangeSearch.entity().getId(), SearchCriteria.Op.EQ); StateChangeSearch.and("states", StateChangeSearch.entity().getState(), SearchCriteria.Op.EQ); StateChangeSearch.and("host", StateChangeSearch.entity().getHostId(), SearchCriteria.Op.EQ); StateChangeSearch.and("update", StateChangeSearch.entity().getUpdated(), SearchCriteria.Op.EQ); StateChangeSearch.done(); DestroySearch = createSearchBuilder(); DestroySearch.and("state", DestroySearch.entity().getState(), SearchCriteria.Op.IN); DestroySearch.and("updateTime", DestroySearch.entity().getUpdateTime(), SearchCriteria.Op.LT); DestroySearch.done(); AccountHostSearch = createSearchBuilder(); AccountHostSearch.and("accountId", AccountHostSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountHostSearch.and("hostId", AccountHostSearch.entity().getHostId(), SearchCriteria.Op.EQ); AccountHostSearch.done(); CountByAccountPod = createSearchBuilder(Long.class); CountByAccountPod.select(null, Func.COUNT, null); CountByAccountPod.and("account", CountByAccountPod.entity().getAccountId(), SearchCriteria.Op.EQ); CountByAccountPod.and("pod", CountByAccountPod.entity().getPodId(), SearchCriteria.Op.EQ); CountByAccountPod.done(); _updateTimeAttr = _allAttributes.get("updateTime"); assert _updateTimeAttr != null : "Couldn't get this updateTime attribute"; } @Override public List listByAccountAndPod(long accountId, long podId) { SearchCriteria sc = AccountPodSearch.create(); sc.setParameters("account", accountId); sc.setParameters("pod", podId); return listIncludingRemovedBy(sc); } @Override public List listByAccountAndDataCenter(long accountId, long dcId) { SearchCriteria sc = AccountDataCenterSearch.create(); sc.setParameters("account", accountId); sc.setParameters("dc", dcId); return listIncludingRemovedBy(sc); } @Override public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData) { UserVmVO vo = createForUpdate(); vo.setDisplayName(displayName); vo.setHaEnabled(enable); vo.setGuestOSId(osTypeId); vo.setUserData(userData); update(id, vo); } @Override public List findDestroyedVms(Date date) { SearchCriteria sc = DestroySearch.create(); sc.setParameters("state", State.Destroyed, State.Expunging, State.Error); sc.setParameters("updateTime", date); return listBy(sc); } @Override public List listByAccountId(long id) { SearchCriteria sc = AccountSearch.create(); sc.setParameters("account", id); return listBy(sc); } @Override public List listByHostId(Long id) { SearchCriteria sc = HostSearch.create(); sc.setParameters("host", id); return listBy(sc); } @Override public List listUpByHostId(Long hostId) { SearchCriteria sc = HostUpSearch.create(); sc.setParameters("host", hostId); sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging}); return listBy(sc); } @Override public List listRunningByHostId(long hostId) { SearchCriteria sc = HostRunningSearch.create(); sc.setParameters("host", hostId); sc.setParameters("state", State.Running); return listBy(sc); } @Override public List listVirtualNetworkInstancesByAcctAndZone(long accountId, long dcId, long networkId) { if (AccountDataCenterVirtualSearch == null) { NicDao _nicDao = ComponentLocator.getLocator("management-server").getDao(NicDao.class); SearchBuilder nicSearch = _nicDao.createSearchBuilder(); nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); nicSearch.and("ip4Address", nicSearch.entity().getIp4Address(), SearchCriteria.Op.NNULL); AccountDataCenterVirtualSearch = createSearchBuilder(); AccountDataCenterVirtualSearch.and("account", AccountDataCenterVirtualSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountDataCenterVirtualSearch.and("dc", AccountDataCenterVirtualSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); AccountDataCenterVirtualSearch.join("nicSearch", nicSearch, AccountDataCenterVirtualSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); AccountDataCenterVirtualSearch.done(); } SearchCriteria sc = AccountDataCenterVirtualSearch.create(); sc.setParameters("account", accountId); sc.setParameters("dc", dcId); sc.setJoinParameters("nicSearch", "networkId", networkId); return listBy(sc); } @Override public List listByNetworkId(long networkId) { if (UserVmSearch == null) { NicDao _nicDao = ComponentLocator.getLocator("management-server").getDao(NicDao.class); SearchBuilder nicSearch = _nicDao.createSearchBuilder(); nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); nicSearch.and("ip4Address", nicSearch.entity().getIp4Address(), SearchCriteria.Op.NNULL); UserVmSearch = createSearchBuilder(); UserVmSearch.join("nicSearch", nicSearch, UserVmSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); UserVmSearch.done(); } SearchCriteria sc = UserVmSearch.create(); sc.setJoinParameters("nicSearch", "networkId", networkId); return listBy(sc); } @Override public List listByLastHostId(Long hostId) { SearchCriteria sc = LastHostSearch.create(); sc.setParameters("lastHost", hostId); sc.setParameters("state", State.Stopped); return listBy(sc); } @Override public List listByAccountIdAndHostId(long accountId, long hostId) { SearchCriteria sc = AccountHostSearch.create(); sc.setParameters("hostId", hostId); sc.setParameters("accountId", accountId); return listBy(sc); } @Override public void loadDetails(UserVmVO vm) { Map details = _detailsDao.findDetails(vm.getId()); vm.setDetails(details); } @Override public void saveDetails(UserVmVO vm) { Map details = vm.getDetails(); if (details == null) { return; } _detailsDao.persist(vm.getId(), details); } @Override public List listPodIdsHavingVmsforAccount(long zoneId, long accountId){ Transaction txn = Transaction.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); try { String sql = LIST_PODS_HAVING_VMS_FOR_ACCOUNT; pstmt = txn.prepareAutoCloseStatement(sql); pstmt.setLong(1, zoneId); pstmt.setLong(2, accountId); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { result.add(rs.getLong(1)); } return result; } catch (SQLException e) { throw new CloudRuntimeException("DB Exception on: " + LIST_PODS_HAVING_VMS_FOR_ACCOUNT, e); } catch (Throwable e) { throw new CloudRuntimeException("Caught: " + LIST_PODS_HAVING_VMS_FOR_ACCOUNT, e); } } }