You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ke...@apache.org on 2013/01/17 23:22:38 UTC

[2/3] System VM can start now with Spring bootstraped management server

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6d155416/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index 592a7ad..561cddc 100755
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -156,2100 +156,2523 @@ import com.cloud.vm.dao.VMInstanceDao;
 
 @Component
 @Local({ ResourceManager.class, ResourceService.class })
-public class ResourceManagerImpl implements ResourceManager, ResourceService, Manager {
-    private static final Logger s_logger = Logger.getLogger(ResourceManagerImpl.class);
-
-    private String                           _name;
-
-    @Inject
-    AccountManager                           _accountMgr;
-    @Inject
-    AgentManager                             _agentMgr;
-    @Inject
-    StorageManager                           _storageMgr;
-    @Inject
-    protected SecondaryStorageVmManager      _secondaryStorageMgr;
-
-    @Inject
-    protected DataCenterDao                  _dcDao;
-    @Inject
-    protected HostPodDao                     _podDao;
-    @Inject
-    protected ClusterDetailsDao              _clusterDetailsDao;
-    @Inject
-    protected ClusterDao                     _clusterDao;
-    @Inject
-    protected CapacityDao 					 _capacityDao;
-    @Inject
-    protected HostDao                        _hostDao;
-    @Inject
-    protected SwiftManager _swiftMgr;
-    @Inject
-    protected S3Manager                      _s3Mgr;
-    @Inject
-    protected HostDetailsDao                 _hostDetailsDao;
-    @Inject
-    protected ConfigurationDao _configDao;
-    @Inject
-    protected HostTagsDao                    _hostTagsDao;    
-    @Inject
-    protected GuestOSCategoryDao             _guestOSCategoryDao;
-    @Inject 
-    protected StoragePoolDao                _storagePoolDao;
-    @Inject
-    protected DataCenterIpAddressDao         _privateIPAddressDao;
-    @Inject
-    protected IPAddressDao                   _publicIPAddressDao;
-    @Inject
-    protected VirtualMachineManager          _vmMgr; 
-    @Inject
-    protected VMInstanceDao                  _vmDao;  
-    @Inject
-    protected HighAvailabilityManager        _haMgr;
-    @Inject 
-    protected StorageService                 _storageSvr;
-    //@com.cloud.utils.component.Inject(adapter = Discoverer.class)
-    @Inject
-    protected List<? extends Discoverer> _discoverers;
-    @Inject
-    protected ClusterManager                 _clusterMgr;
-    @Inject
-    protected StoragePoolHostDao             _storagePoolHostDao;
-
-    // @com.cloud.utils.component.Inject(adapter = PodAllocator.class)
-    @Inject 
-    protected List<PodAllocator> _podAllocators = null;
-
-    @Inject
-    protected VMTemplateDao  _templateDao;
-    @Inject
-    protected ConfigurationManager 			 _configMgr;
-    @Inject
-    protected ClusterVSMMapDao				 _clusterVSMMapDao;
-
-    protected long                           _nodeId  = ManagementServerNode.getManagementServerId();
-
-    protected HashMap<String, ResourceStateAdapter> _resourceStateAdapters = new HashMap<String, ResourceStateAdapter>();
-
-    protected HashMap<Integer, List<ResourceListener>> _lifeCycleListeners = new HashMap<Integer, List<ResourceListener>>();
-    private HypervisorType _defaultSystemVMHypervisor;
-
-    @PostConstruct
-    public void init() {
-        // TODO initialize pod allocators here instead
-    }
-
-    private void insertListener(Integer event, ResourceListener listener) {
-        List<ResourceListener> lst = _lifeCycleListeners.get(event);
-        if (lst == null) {
-            lst = new ArrayList<ResourceListener>();
-            _lifeCycleListeners.put(event, lst);
-        }
-
-        if (lst.contains(listener)) {
-            throw new CloudRuntimeException("Duplicate resource lisener:" + listener.getClass().getSimpleName());
-        }
-
-        lst.add(listener);
-    }
-
-    @Override
-    public void registerResourceEvent(Integer event, ResourceListener listener) {
-        synchronized (_lifeCycleListeners) {
-            if ((event & ResourceListener.EVENT_DISCOVER_BEFORE) != 0) {
-                insertListener(ResourceListener.EVENT_DISCOVER_BEFORE, listener);
-            }
-            if ((event & ResourceListener.EVENT_DISCOVER_AFTER) != 0) {
-                insertListener(ResourceListener.EVENT_DISCOVER_AFTER, listener);
-            }
-            if ((event & ResourceListener.EVENT_DELETE_HOST_BEFORE) != 0) {
-                insertListener(ResourceListener.EVENT_DELETE_HOST_BEFORE, listener);
-            }
-            if ((event & ResourceListener.EVENT_DELETE_HOST_AFTER) != 0) {
-                insertListener(ResourceListener.EVENT_DELETE_HOST_AFTER, listener);
-            }
-            if ((event & ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE) != 0) {
-                insertListener(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE, listener);
-            }
-            if ((event & ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER) != 0) {
-                insertListener(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, listener);
-            }
-            if ((event & ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE) != 0) {
-                insertListener(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, listener);
-            }
-            if ((event & ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER) != 0) {
-                insertListener(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, listener);
-            }
-        }
-    }
-
-    @Override
-    public void unregisterResourceEvent(ResourceListener listener) {
-        synchronized (_lifeCycleListeners) {
-            Iterator it = _lifeCycleListeners.entrySet().iterator();
-            while (it.hasNext()) {
-                Map.Entry<Integer, List<ResourceListener>> items = (Map.Entry<Integer, List<ResourceListener>>)it.next();
-                List<ResourceListener> lst = items.getValue();
-                lst.remove(listener);
-            }
-        }
-    }
-
-    protected void processResourceEvent(Integer event, Object...params) {
-        List<ResourceListener> lst = _lifeCycleListeners.get(event);
-        if (lst == null || lst.size() == 0) {
-            return;
-        }
-
-        String eventName;
-        for (ResourceListener l : lst) {
-            if (event == ResourceListener.EVENT_DISCOVER_BEFORE) {
-                l.processDiscoverEventBefore((Long) params[0], (Long) params[1], (Long) params[2], (URI) params[3], (String) params[4], (String) params[5],
-                        (List<String>) params[6]);
-                eventName = "EVENT_DISCOVER_BEFORE";
-            } else if (event == ResourceListener.EVENT_DISCOVER_AFTER) {
-                l.processDiscoverEventAfter((Map<? extends ServerResource, Map<String, String>>) params[0]);
-                eventName = "EVENT_DISCOVER_AFTER";
-            } else if (event == ResourceListener.EVENT_DELETE_HOST_BEFORE) {
-                l.processDeleteHostEventBefore((HostVO) params[0]);
-                eventName = "EVENT_DELETE_HOST_BEFORE";
-            } else if (event == ResourceListener.EVENT_DELETE_HOST_AFTER) {
-                l.processDeletHostEventAfter((HostVO) params[0]);
-                eventName = "EVENT_DELETE_HOST_AFTER";
-            } else if (event == ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE) {
-                l.processCancelMaintenaceEventBefore((Long) params[0]);
-                eventName = "EVENT_CANCEL_MAINTENANCE_BEFORE";
-            } else if (event == ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER) {
-                l.processCancelMaintenaceEventAfter((Long) params[0]);
-                eventName = "EVENT_CANCEL_MAINTENANCE_AFTER";
-            } else if (event == ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE) {
-                l.processPrepareMaintenaceEventBefore((Long) params[0]);
-                eventName = "EVENT_PREPARE_MAINTENANCE_BEFORE";
-            } else if (event == ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER) {
-                l.processPrepareMaintenaceEventAfter((Long) params[0]);
-                eventName = "EVENT_PREPARE_MAINTENANCE_AFTER";
-            } else {
-                throw new CloudRuntimeException("Unknown resource event:" + event);
-            }
-            s_logger.debug("Sent resource event " + eventName + " to listener " + l.getClass().getSimpleName());
-        }
-
-    }
-
-    @DB
-    @Override
-    public List<? extends Cluster> discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException {
-        long dcId = cmd.getZoneId();
-        long podId = cmd.getPodId();
-        String clusterName = cmd.getClusterName();
-        String url = cmd.getUrl();
-        String username = cmd.getUsername();
-        String password = cmd.getPassword();
-
-        if (url != null) {
-            url = URLDecoder.decode(url);
-        }
-
-        URI uri = null;
-
-        // Check if the zone exists in the system
-        DataCenterVO zone = _dcDao.findById(dcId);
-        if (zone == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Can't find zone by the id specified");
-            ex.addProxyObject(zone, dcId, "dcId");
-            throw ex;
-        }
-
-        Account account = UserContext.current().getCaller();
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) {
-            PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
-            ex.addProxyObject(zone, dcId, "dcId");
-            throw ex;
-        }
-
-        HostPodVO pod = _podDao.findById(podId);
-        if (pod == null) {
-            throw new InvalidParameterValueException("Can't find pod with specified podId " + podId);
-        }
-
-        // Check if the pod exists in the system
-        if (_podDao.findById(podId) == null) {
-            throw new InvalidParameterValueException("Can't find pod by id " + podId);
-        }
-        // check if pod belongs to the zone
-        if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified id doesn't belong to the zone " + dcId);
-            ex.addProxyObject(pod, podId, "podId");
-            ex.addProxyObject(zone, dcId, "dcId");
-            throw ex;
-        }
-
-
-        // Verify cluster information and create a new cluster if needed
-        if (clusterName == null || clusterName.isEmpty()) {
-            throw new InvalidParameterValueException("Please specify cluster name");
-        }
-
-        if (cmd.getHypervisor() == null || cmd.getHypervisor().isEmpty()) {
-            throw new InvalidParameterValueException("Please specify a hypervisor");
-        }
-
-        Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(cmd.getHypervisor());
-        if (hypervisorType == null) {
-            s_logger.error("Unable to resolve " + cmd.getHypervisor() + " to a valid supported hypervisor type");
-            throw new InvalidParameterValueException("Unable to resolve " + cmd.getHypervisor() + " to a supported ");
-        }
-
-        Cluster.ClusterType clusterType = null;
-        if (cmd.getClusterType() != null && !cmd.getClusterType().isEmpty()) {
-            clusterType = Cluster.ClusterType.valueOf(cmd.getClusterType());
-        }
-        if (clusterType == null) {
-            clusterType = Cluster.ClusterType.CloudManaged;
-        }
-
-        Grouping.AllocationState allocationState = null;
-        if (cmd.getAllocationState() != null && !cmd.getAllocationState().isEmpty()) {
-            try {
-                allocationState = Grouping.AllocationState.valueOf(cmd.getAllocationState());
-            } catch (IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve Allocation State '" + cmd.getAllocationState() + "' to a supported state");
-            }
-        }
-        if (allocationState == null) {
-            allocationState = Grouping.AllocationState.Enabled;
-        }
-
-        Discoverer discoverer = getMatchingDiscover(hypervisorType);
-        if (discoverer == null) {
-
-            throw new InvalidParameterValueException("Could not find corresponding resource manager for " + cmd.getHypervisor());
-        }
-
-        List<ClusterVO> result = new ArrayList<ClusterVO>();
-
-        long clusterId = 0;
-        ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
-        cluster.setHypervisorType(cmd.getHypervisor());
-
-        cluster.setClusterType(clusterType);
-        cluster.setAllocationState(allocationState);
-        try {
-            cluster = _clusterDao.persist(cluster);
-        } catch (Exception e) {
-            // no longer tolerate exception during the cluster creation phase
-            CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod and data center with specified ids", e);
-            // Get the pod VO object's table name.
-            ex.addProxyObject(pod, podId, "podId");
-            ex.addProxyObject(zone, dcId, "dcId");
-            throw ex;
-        }
-        clusterId = cluster.getId();
-        result.add(cluster);
-
-        if (clusterType == Cluster.ClusterType.CloudManaged) {
-            return result;
-        }
-
-        // save cluster details for later cluster/host cross-checking
-        Map<String, String> details = new HashMap<String, String>();
-        details.put("url", url);
-        details.put("username", username);
-        details.put("password", password);
-        _clusterDetailsDao.persist(cluster.getId(), details);
-
-
-        boolean success = false;
-        try {
-            try {
-                uri = new URI(UriUtils.encodeURIComponent(url));
-                if (uri.getScheme() == null) {
-                    throw new InvalidParameterValueException("uri.scheme is null " + url + ", add http:// as a prefix");
-                } else if (uri.getScheme().equalsIgnoreCase("http")) {
-                    if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
-                        throw new InvalidParameterValueException("Your host and/or path is wrong.  Make sure it's of the format http://hostname/path");
-                    }
-                }
-            } catch (URISyntaxException e) {
-                throw new InvalidParameterValueException(url + " is not a valid uri");
-            }
-
-            List<HostVO> hosts = new ArrayList<HostVO>();
-            Map<? extends ServerResource, Map<String, String>> resources = null;
-            resources = discoverer.find(dcId, podId, clusterId, uri, username, password, null);
-
-            if (resources != null) {
-                for (Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
-                    ServerResource resource = entry.getKey();
-
-                    // For Hyper-V, we are here means agent have already started and connected to management server
-                    if (hypervisorType == Hypervisor.HypervisorType.Hyperv) {
-                        break;
-                    }
-
-                    HostVO host = (HostVO)createHostAndAgent(resource, entry.getValue(), true, null, false);
-                    if (host != null) {
-                        hosts.add(host);
-                    }
-                    discoverer.postDiscovery(hosts, _nodeId);
-                }
-                s_logger.info("External cluster has been successfully discovered by " + discoverer.getName());
-                success = true;
-                return result;
-            }
-
-            s_logger.warn("Unable to find the server resources at " + url);
-            throw new DiscoveryException("Unable to add the external cluster");
-        } finally {
-            if (!success) {
-                _clusterDetailsDao.deleteDetails(clusterId);
-                _clusterDao.remove(clusterId);
-            }
-        }
-    }
-
-    @Override
-    public Discoverer getMatchingDiscover(Hypervisor.HypervisorType hypervisorType) {
-        for(Discoverer discoverer : _discoverers) {
-            if (discoverer.getHypervisorType() == hypervisorType)
-                return discoverer;
-        }
-        return null;
-    }
-
-    @Override
-    public List<? extends Host> discoverHosts(AddHostCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
-        Long dcId = cmd.getZoneId();
-        Long podId = cmd.getPodId();
-        Long clusterId = cmd.getClusterId();
-        String clusterName = cmd.getClusterName();
-        String url = cmd.getUrl();
-        String username = cmd.getUsername();
-        String password = cmd.getPassword();
-        List<String> hostTags = cmd.getHostTags();
-
-        dcId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), dcId);
-
-        // this is for standalone option
-        if (clusterName == null && clusterId == null) {
-            clusterName = "Standalone-" + url;
-        }
-
-        if (clusterId != null) {
-            ClusterVO cluster = _clusterDao.findById(clusterId);
-            if (cluster == null) {
-                InvalidParameterValueException ex = new InvalidParameterValueException("can not find cluster for specified clusterId");
-                ex.addProxyObject(cluster, clusterId, "clusterId");
-                throw ex;
-            } else {
-                if (cluster.getGuid() == null) {
-                    List<HostVO> hosts = listAllHostsInCluster(clusterId);
-                    if (!hosts.isEmpty()) {
-                        CloudRuntimeException ex = new CloudRuntimeException("Guid is not updated for cluster with specified cluster id; need to wait for hosts in this cluster to come up");
-                        ex.addProxyObject(cluster, clusterId, "clusterId");
-                        throw ex;
-                    }
-                }
-            }
-        }
-
-        return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, cmd.getFullUrlParams());
-    }
-
-    @Override
-    public List<? extends Host> discoverHosts(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
-        Long dcId = cmd.getZoneId();
-        String url = cmd.getUrl();
-        return discoverHostsFull(dcId, null, null, null, url, null, null, "SecondaryStorage", null, null);
-    }
-
-    @Override
-    public Swift discoverSwift(AddSwiftCmd cmd) throws DiscoveryException {
-        return _swiftMgr.addSwift(cmd);
-    }
-
-    @Override
-    public List<SwiftVO> listSwifts(ListSwiftsCmd cmd) {
-        return _swiftMgr.listSwifts(cmd);
-    }
-
-    @Override
-    public S3 discoverS3(final AddS3Cmd cmd) throws DiscoveryException {
-        return this._s3Mgr.addS3(cmd);
-    }
-
-    @Override
-    public List<S3VO> listS3s(final ListS3sCmd cmd) {
-        return this._s3Mgr.listS3s(cmd);
-    }
-
-    private List<HostVO> discoverHostsFull(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisorType, List<String> hostTags,
-            Map<String, String> params) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
-        URI uri = null;
-
-        // Check if the zone exists in the system
-        DataCenterVO zone = _dcDao.findById(dcId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Can't find zone by id " + dcId);
-        }
-
-        Account account = UserContext.current().getCaller();
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) {
-            PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
-            ex.addProxyObject(zone, dcId, "dcId");
-            throw ex;
-        }
-
-
-        // Check if the pod exists in the system
-        if (podId != null) {
-            HostPodVO pod = _podDao.findById(podId);
-            if (pod == null) {
-                throw new InvalidParameterValueException("Can't find pod by id " + podId);
-            }
-            // check if pod belongs to the zone            
-            if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
-                InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified podId" + podId + " doesn't belong to the zone with specified zoneId" + dcId);
-                ex.addProxyObject(pod, podId, "podId");
-                ex.addProxyObject(zone, dcId, "dcId");
-                throw ex;
-            }
-        }
-
-        // Verify cluster information and create a new cluster if needed
-        if (clusterName != null && clusterId != null) {
-            throw new InvalidParameterValueException("Can't specify cluster by both id and name");
-        }
-
-        if (hypervisorType == null || hypervisorType.isEmpty()) {
-            throw new InvalidParameterValueException("Need to specify Hypervisor Type");
-        }
-
-        if ((clusterName != null || clusterId != null) && podId == null) {
-            throw new InvalidParameterValueException("Can't specify cluster without specifying the pod");
-        }
-
-        if (clusterId != null) {
-            if (_clusterDao.findById(clusterId) == null) {
-                throw new InvalidParameterValueException("Can't find cluster by id " + clusterId);
-            }
-
-            if(hypervisorType.equalsIgnoreCase(HypervisorType.VMware.toString())) {
-                // VMware only allows adding host to an existing cluster, as we already have a lot of information
-                // in cluster object, to simplify user input, we will construct neccessary information here
-                Map<String, String> clusterDetails = this._clusterDetailsDao.findDetails(clusterId);
-                username = clusterDetails.get("username");
-                assert(username != null);
-
-                password = clusterDetails.get("password");
-                assert(password != null);
-
-                try {
-                    uri = new URI(UriUtils.encodeURIComponent(url));
-
-                    url = clusterDetails.get("url") + "/" + uri.getHost();
-                } catch (URISyntaxException e) {
-                    throw new InvalidParameterValueException(url + " is not a valid uri");
-                }
-            }
-        }
-
-        if (clusterName != null) {
-            HostPodVO pod = _podDao.findById(podId);
-            if (pod == null) {
-                throw new InvalidParameterValueException("Can't find pod by id " + podId);
-            }
-            ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
-            cluster.setHypervisorType(hypervisorType);
-            try {
-                cluster = _clusterDao.persist(cluster);
-            } catch (Exception e) {
-                cluster = _clusterDao.findBy(clusterName, podId);
-                if (cluster == null) {
-                    CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod with specified podId and data center with specified dcID", e);
-                    ex.addProxyObject(pod, podId, "podId");
-                    ex.addProxyObject(zone, dcId, "dcId");
-                    throw ex;   
-                }
-            }
-            clusterId = cluster.getId();
-        }
-
-        try {
-            uri = new URI(UriUtils.encodeURIComponent(url));
-            if (uri.getScheme() == null) {
-                throw new InvalidParameterValueException("uri.scheme is null " + url + ", add nfs:// as a prefix");
-            } else if (uri.getScheme().equalsIgnoreCase("nfs")) {
-                if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
-                    throw new InvalidParameterValueException("Your host and/or path is wrong.  Make sure it's of the format nfs://hostname/path");
-                }
-            }
-        } catch (URISyntaxException e) {
-            throw new InvalidParameterValueException(url + " is not a valid uri");
-        }
-
-        List<HostVO> hosts = new ArrayList<HostVO>();
-        s_logger.info("Trying to add a new host at " + url + " in data center " + dcId);
-        boolean isHypervisorTypeSupported = false;
-        for ( Discoverer discoverer : _discoverers) {
-            if (params != null) {
-                discoverer.putParam(params);
-            }
-
-            if (!discoverer.matchHypervisor(hypervisorType)) {
-                continue;
-            }
-            isHypervisorTypeSupported = true;
-            Map<? extends ServerResource, Map<String, String>> resources = null;
-
-            processResourceEvent(ResourceListener.EVENT_DISCOVER_BEFORE, dcId, podId, clusterId, uri, username, password, hostTags);
-            try {
-                resources = discoverer.find(dcId, podId, clusterId, uri, username, password, hostTags);
-            } catch(DiscoveryException e) {
-                throw e;
-            } catch (Exception e) {
-                s_logger.info("Exception in host discovery process with discoverer: " + discoverer.getName() + ", skip to another discoverer if there is any");
-            }
-            processResourceEvent(ResourceListener.EVENT_DISCOVER_AFTER, resources);
-
-            if (resources != null) {
-                for (Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
-                    ServerResource resource = entry.getKey();
-                    /*
-                     * For KVM, if we go to here, that means kvm agent is already connected to mgt svr.
-                     */
-                    if (resource instanceof KvmDummyResourceBase) {
-                        Map<String, String> details = entry.getValue();
-                        String guid = details.get("guid");
-                        List<HostVO> kvmHosts = listAllUpAndEnabledHosts(Host.Type.Routing, clusterId, podId, dcId);
-                        for (HostVO host : kvmHosts) {
-                            if (host.getGuid().equalsIgnoreCase(guid)) {
-                                if(hostTags != null){
-                                    if(s_logger.isTraceEnabled()){
-                                        s_logger.trace("Adding Host Tags for KVM host, tags:  :"+hostTags);
-                                    }
-                                    _hostTagsDao.persist(host.getId(), hostTags);
-                                }
-                                hosts.add(host);
-                                return hosts;
-                            }
-                        }
-                        return null;
-                    }
-
-                    HostVO host = (HostVO)createHostAndAgent(resource, entry.getValue(), true, hostTags, false);
-                    if (host != null) {
-                        hosts.add(host);
-                    }
-                    discoverer.postDiscovery(hosts, _nodeId);
-
-                }
-                s_logger.info("server resources successfully discovered by " + discoverer.getName());
-                return hosts;
-            }
-        }
-        if (!isHypervisorTypeSupported) {
-            String msg = "Do not support HypervisorType " + hypervisorType + " for " + url;
-            s_logger.warn(msg);
-            throw new DiscoveryException(msg);
-        }
-        s_logger.warn("Unable to find the server resources at " + url);
-        throw new DiscoveryException("Unable to add the host");
-    }
-
-    @Override
-    public Host getHost(long hostId) {
-        return _hostDao.findById(hostId);
-    }
-
-    @DB
-    protected boolean doDeleteHost(long hostId, boolean isForced, boolean isForceDeleteStorage) {
-        User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId());
-        // Verify that host exists
-        HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist");            
-        }
-        _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), host.getDataCenterId());
-
-        /*
-         * TODO: check current agent status and updateAgentStatus to removed. If it was already removed, that means
-         * someone is deleting host concurrently, return. And consider the situation of CloudStack shutdown during delete.
-         * A global lock?
-         * 
-         */
-        AgentAttache attache = _agentMgr.findAttache(hostId);
-        // Get storage pool host mappings here because they can be removed as a part of handleDisconnect later
-        //TODO: find out the bad boy, what's a buggy logic!
-        List<StoragePoolHostVO> pools = _storagePoolHostDao.listByHostIdIncludingRemoved(hostId);
-
-        ResourceStateAdapter.DeleteHostAnswer answer = (ResourceStateAdapter.DeleteHostAnswer) dispatchToStateAdapters(ResourceStateAdapter.Event.DELETE_HOST, false, host, new Boolean(isForced), new Boolean(isForceDeleteStorage));
-
-        if (answer == null) {
-            throw new CloudRuntimeException("No resource adapter respond to DELETE_HOST event for " + host.getName() + " id = " + hostId + ", hypervisorType is " + host.getHypervisorType() + ", host type is " + host.getType());
-        }
-
-        if (answer.getIsException()) {
-            return false;
-        }
-
-        if (!answer.getIsContinue()) {
-            return true;
-        }
-
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-
-        _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
-        _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
-
-        // delete host details
-        _hostDetailsDao.deleteDetails(hostId);
-
-        host.setGuid(null);
-        Long clusterId = host.getClusterId();
-        host.setClusterId(null);
-        _hostDao.update(host.getId(), host);
-
-        _hostDao.remove(hostId);
-        if (clusterId != null) {
-            List<HostVO> hosts = listAllHostsInCluster(clusterId);
-            if (hosts.size() == 0) {
-                ClusterVO cluster = _clusterDao.findById(clusterId);
-                cluster.setGuid(null);
-                _clusterDao.update(clusterId, cluster);
-            }
-        }
-
-        try {
-            resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId);
-        } catch (NoTransitionException e) {
-            s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
-        }
-
-        // Delete the associated entries in host ref table
-        _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
-
-        // For pool ids you got, delete local storage host entries in pool table where
-        for (StoragePoolHostVO pool : pools) {
-            Long poolId = pool.getPoolId();
-            StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
-            if (storagePool.isLocal() && isForceDeleteStorage) {
-                storagePool.setUuid(null);
-                storagePool.setClusterId(null);
-                _storagePoolDao.update(poolId, storagePool);
-                _storagePoolDao.remove(poolId);
-                s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
-            }
-        }
-
-        // delete the op_host_capacity entry
-        Object[] capacityTypes = { Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY };
-        SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao.createSearchCriteria();
-        hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
-        hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
-        _capacityDao.remove(hostCapacitySC);
-        txn.commit();
-        return true;
-    }
-
-    @Override
-    public boolean deleteHost(long hostId, boolean isForced, boolean isForceDeleteStorage) {
-        try {
-            Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.DeleteHost);
-            if (result != null) {
-                return result;
-            }
-        } catch (AgentUnavailableException e) {
-            return false;
-        }
-
-        return doDeleteHost(hostId, isForced, isForceDeleteStorage);
-    }
-
-    @Override
-    @DB
-    public boolean deleteCluster(DeleteClusterCmd cmd) {
-        Transaction txn = Transaction.currentTxn();
-        try {        	
-            txn.start();
-            ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
-            if (cluster == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Cluster: " + cmd.getId() + " does not even exist.  Delete call is ignored.");
-                }
-                txn.rollback();
-                throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist");
-            }
-
-            Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType();
-
-            List<HostVO> hosts = listAllHostsInCluster(cmd.getId());
-            if (hosts.size() > 0) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove");
-                }
-                txn.rollback();
-                throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts");
-            }
-
-            //don't allow to remove the cluster if it has non-removed storage pools
-            List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
-            if (storagePools.size() > 0) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove");
-                }
-                txn.rollback();
-                throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools");
-            }
-
-            if (_clusterDao.remove(cmd.getId())){
-                _capacityDao.removeBy(null, null, null, cluster.getId(), null);
-                // If this cluster is of type vmware, and if the nexus vswitch global parameter setting is turned
-                // on, remove the row in cluster_vsm_map for this cluster id.
-                if (hypervisorType == HypervisorType.VMware &&
-                        Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
-                    _clusterVSMMapDao.removeByClusterId(cmd.getId());
-                }
-            }
-
-            txn.commit();
-            return true;
-        } catch(CloudRuntimeException e){
-            throw e;
-        } catch (Throwable t) {
-            s_logger.error("Unable to delete cluster: " + cmd.getId(), t);
-            txn.rollback();
-            return false;
-        }
-    }
-
-    @Override
-    @DB
-    public Cluster updateCluster(Cluster clusterToUpdate, String clusterType, String hypervisor, String allocationState, String managedstate) {
-
-        ClusterVO cluster = (ClusterVO) clusterToUpdate;
-        // Verify cluster information and update the cluster if needed
-        boolean doUpdate = false;
-
-        if (hypervisor != null && !hypervisor.isEmpty()) {
-            Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(hypervisor);
-            if (hypervisorType == null) {
-                s_logger.error("Unable to resolve " + hypervisor + " to a valid supported hypervisor type");
-                throw new InvalidParameterValueException("Unable to resolve " + hypervisor + " to a supported type");
-            } else {
-                cluster.setHypervisorType(hypervisor);
-                doUpdate = true;
-            }
-        }
-
-        Cluster.ClusterType newClusterType = null;
-        if (clusterType != null && !clusterType.isEmpty()) {
-            try {
-                newClusterType = Cluster.ClusterType.valueOf(clusterType);
-            } catch (IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type");
-            }
-            if (newClusterType == null) {
-                s_logger.error("Unable to resolve " + clusterType + " to a valid supported cluster type");
-                throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type");
-            } else {
-                cluster.setClusterType(newClusterType);
-                doUpdate = true;
-            }
-        }
-
-        Grouping.AllocationState newAllocationState = null;
-        if (allocationState != null && !allocationState.isEmpty()) {
-            try {
-                newAllocationState = Grouping.AllocationState.valueOf(allocationState);
-            } catch (IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationState + "' to a supported state");
-            }
-            if (newAllocationState == null) {
-                s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State");
-                throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state");
-            } else {
-                _capacityDao.updateCapacityState(null, null, cluster.getId(), null, allocationState);
-                cluster.setAllocationState(newAllocationState);
-                doUpdate = true;
-            }
-        }
-
-        Managed.ManagedState newManagedState = null;
-        Managed.ManagedState oldManagedState = cluster.getManagedState();
-        if (managedstate != null && !managedstate.isEmpty()) {
-            try {
-                newManagedState = Managed.ManagedState.valueOf(managedstate);
-            } catch (IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve Managed State '" + managedstate + "' to a supported state");
-            }
-            if (newManagedState == null) {
-                s_logger.error("Unable to resolve Managed State '" + managedstate + "' to a supported state");
-                throw new InvalidParameterValueException("Unable to resolve Managed State '" + managedstate + "' to a supported state");
-            } else {
-                doUpdate = true;
-            }
-        }
-
-        if (doUpdate) {
-            Transaction txn = Transaction.currentTxn();
-            try {
-                txn.start();
-                _clusterDao.update(cluster.getId(), cluster);
-                txn.commit();               
-            } catch (Exception e) {
-                s_logger.error("Unable to update cluster due to " + e.getMessage(), e);
-                throw new CloudRuntimeException("Failed to update cluster. Please contact Cloud Support.");
-            }
-        }
-
-        if( newManagedState != null && !newManagedState.equals(oldManagedState)) {
-            Transaction txn = Transaction.currentTxn();
-            if( newManagedState.equals(Managed.ManagedState.Unmanaged) ) {
-                boolean success = false;
-                try {
-                    txn.start();
-                    cluster.setManagedState(Managed.ManagedState.PrepareUnmanaged);
-                    _clusterDao.update(cluster.getId(), cluster);
-                    txn.commit();
-                    List<HostVO>  hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());                  
-                    for( HostVO host : hosts ) {
-                        if(host.getType().equals(Host.Type.Routing) && !host.getStatus().equals(Status.Down) &&  !host.getStatus().equals(Status.Disconnected) 
-                                && !host.getStatus().equals(Status.Up) && !host.getStatus().equals(Status.Alert) ) {
-                            String msg = "host " + host.getPrivateIpAddress() + " should not be in " + host.getStatus().toString() + " status";
-                            throw new CloudRuntimeException("PrepareUnmanaged Failed due to " + msg);                                   
-                        }
-                    }
-
-                    for( HostVO host : hosts ) {
-                        if ( host.getStatus().equals(Status.Up )) {
-                            umanageHost(host.getId());
-                        }
-                    }
-                    int retry = 40;
-                    boolean lsuccess = true;
-                    for ( int i = 0; i < retry; i++) {
-                        lsuccess = true;
-                        try {
-                            Thread.sleep(5 * 1000);
-                        } catch (Exception e) {
-                        }
-                        hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId()); 
-                        for( HostVO host : hosts ) {
-                            if ( !host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected) 
-                                    && !host.getStatus().equals(Status.Alert)) {
-                                lsuccess = false;
-                                break;
-                            }
-                        }
-                        if( lsuccess == true ) {
-                            success = true;
-                            break;
-                        }
-                    }
-                    if ( success == false ) {
-                        throw new CloudRuntimeException("PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later "); 
-                    }
-                } finally {
-                    txn.start();
-                    cluster.setManagedState(success? Managed.ManagedState.Unmanaged : Managed.ManagedState.PrepareUnmanagedError);
-                    _clusterDao.update(cluster.getId(), cluster);
-                    txn.commit();
-                }
-            } else if( newManagedState.equals(Managed.ManagedState.Managed)) {               
-                txn.start();
-                cluster.setManagedState(Managed.ManagedState.Managed);
-                _clusterDao.update(cluster.getId(), cluster);
-                txn.commit();
-            }
-
-        }
-
-        return cluster;
-    }
-
-    @Override
-    public Host cancelMaintenance(CancelMaintenanceCmd cmd) {
-        Long hostId = cmd.getId();
-
-        // verify input parameters
-        HostVO host = _hostDao.findById(hostId);
-        if (host == null || host.getRemoved() != null) {
-            throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist");
-        }
-
-        processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE, hostId);
-        boolean success = cancelMaintenance(hostId);
-        processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, hostId);
-        if (!success) {
-            throw new CloudRuntimeException("Internal error cancelling maintenance.");
-        }
-        return host;
-    }
-
-    @Override
-    public Host reconnectHost(ReconnectHostCmd cmd) {
-        Long hostId = cmd.getId();
-
-        HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist");
-        }
-
-        return (_agentMgr.reconnect(hostId) ? host : null);
-    }
-
-    @Override
-    public boolean resourceStateTransitTo(Host host, ResourceState.Event event, long msId) throws NoTransitionException {
-        ResourceState currentState = host.getResourceState();
-        ResourceState nextState = currentState.getNextState(event);
-        if (nextState == null) {
-            throw new NoTransitionException("No next resource state found for current state =" + currentState + " event =" + event);
-        }
-
-        // TO DO - Make it more granular and have better conversion into capacity type
-
-        if(host.getType() == Type.Routing && host.getClusterId() != null){
-            AllocationState capacityState =  _configMgr.findClusterAllocationState(ApiDBUtils.findClusterById(host.getClusterId()));
-            if (capacityState == AllocationState.Enabled && nextState != ResourceState.Enabled){
-                capacityState = AllocationState.Disabled;
-            }
-            _capacityDao.updateCapacityState(null, null, null, host.getId(), capacityState.toString());
-        }
-        return _hostDao.updateResourceState(currentState, event, nextState, host);
-    }
-
-    private boolean doMaintain(final long hostId) {
-        HostVO host = _hostDao.findById(hostId);
-        MaintainAnswer answer = (MaintainAnswer) _agentMgr.easySend(hostId, new MaintainCommand());
-        if (answer == null || !answer.getResult()) {
-            s_logger.warn("Unable to send MaintainCommand to host: " + hostId);
-        }
-
-        try {
-            resourceStateTransitTo(host, ResourceState.Event.AdminAskMaintenace, _nodeId);
-        } catch (NoTransitionException e) {
-            String err = "Cannot transimit resource state of host " + host.getId() + " to " + ResourceState.Maintenance;
-            s_logger.debug(err, e);
-            throw new CloudRuntimeException(err + e.getMessage());
-        }
-
-        _agentMgr.pullAgentToMaintenance(hostId);
-
-        /*TODO: move below to listener */
-        if (host.getType() == Host.Type.Routing) {
-
-            final List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
-            if (vms.size() == 0) {
-                return true;
-            }
-
-            List<HostVO> hosts = listAllUpAndEnabledHosts(Host.Type.Routing, host.getClusterId(), host.getPodId(), host.getDataCenterId());
-            for (final VMInstanceVO vm : vms) {
-                if (hosts == null || hosts.isEmpty() || !answer.getMigrate()) {
-                    // for the last host in this cluster, stop all the VMs
-                    _haMgr.scheduleStop(vm, hostId, WorkType.ForceStop);
-                } else {
-                    _haMgr.scheduleMigration(vm);
-                }
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean maintain(final long hostId) throws AgentUnavailableException {
-        Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.AdminAskMaintenace);
-        if (result != null) {
-            return result;
-        }
-
-        return doMaintain(hostId);
-    }
-
-    @Override
-    public Host maintain(PrepareForMaintenanceCmd cmd) {
-        Long hostId = cmd.getId();
-        HostVO host = _hostDao.findById(hostId);
-
-        if (host == null) {
-            s_logger.debug("Unable to find host " + hostId);
-            throw new InvalidParameterValueException("Unable to find host with ID: " + hostId + ". Please specify a valid host ID.");
-        }
-
-        if (_hostDao.countBy(host.getClusterId(), ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance) > 0) {
-            throw new InvalidParameterValueException("There are other servers in PrepareForMaintenance OR ErrorInMaintenance STATUS in cluster " + host.getClusterId());
-        }
-
-        if (_storageMgr.isLocalStorageActiveOnHost(host.getId())) {
-            throw new InvalidParameterValueException("There are active VMs using the host's local storage pool. Please stop all VMs on this host that use local storage.");
-        }
-
-        try {
-            processResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, hostId);
-            if (maintain(hostId)) {
-                processResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, hostId);
-                return _hostDao.findById(hostId);
-            } else {
-                throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId);
-            }
-        } catch (AgentUnavailableException e) {
-            throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId);
-        }
-    }
-
-    @Override
-    public Host updateHost(UpdateHostCmd cmd) throws NoTransitionException {
-        Long hostId = cmd.getId();
-        Long guestOSCategoryId = cmd.getOsCategoryId();
-
-        // Verify that the host exists
-        HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist");
-        }
-
-        if (cmd.getAllocationState() != null) {
-            ResourceState.Event resourceEvent = ResourceState.Event.toEvent(cmd.getAllocationState());
-            if (resourceEvent != ResourceState.Event.Enable && resourceEvent != ResourceState.Event.Disable) {
-                throw new CloudRuntimeException("Invalid allocation state:" + cmd.getAllocationState() + ", only Enable/Disable are allowed");
-            }
-
-            resourceStateTransitTo(host, resourceEvent, _nodeId);
-        }
-
-        if (guestOSCategoryId != null) {
-            // Verify that the guest OS Category exists
-            if (guestOSCategoryId > 0) {
-                if (_guestOSCategoryDao.findById(guestOSCategoryId) == null) {
-                    throw new InvalidParameterValueException("Please specify a valid guest OS category.");
-                }
-            }
-
-            GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
-            Map<String, String> hostDetails = _hostDetailsDao.findDetails(hostId);
-
-            if (guestOSCategory != null && !GuestOSCategoryVO.CATEGORY_NONE.equalsIgnoreCase(guestOSCategory.getName())) {
-                // Save a new entry for guest.os.category.id
-                hostDetails.put("guest.os.category.id", String.valueOf(guestOSCategory.getId()));
-            } else {
-                // Delete any existing entry for guest.os.category.id
-                hostDetails.remove("guest.os.category.id");
-            }
-            _hostDetailsDao.persist(hostId, hostDetails);
-        }
-
-        List<String> hostTags = cmd.getHostTags();
-        if (hostTags != null) {
-            if(s_logger.isDebugEnabled()){
-                s_logger.debug("Updating Host Tags to :"+hostTags);
-            }
-            _hostTagsDao.persist(hostId, hostTags);
-        }
-
-        String url = cmd.getUrl();
-        if (url != null) {
-            _storageMgr.updateSecondaryStorage(cmd.getId(), cmd.getUrl());
-        }
-
-        HostVO updatedHost = _hostDao.findById(hostId);
-        return updatedHost;
-    }
-
-    @Override
-    public Cluster getCluster(Long clusterId) {
-        return _clusterDao.findById(clusterId);
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-        _defaultSystemVMHypervisor = HypervisorType.getType(_configDao.getValue(Config.SystemVMDefaultHypervisor.toString()));
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    @Override
-    public List<HypervisorType> getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId) {
-        List<HypervisorType> hypervisorTypes = new ArrayList<HypervisorType>();
-
-        List<ClusterVO> clustersForZone = new ArrayList<ClusterVO>();
-        if (podId != null) {
-            clustersForZone = _clusterDao.listByPodId(podId);
-        } else {
-            clustersForZone = _clusterDao.listByZoneId(zoneId);
-        }
-
-        for (ClusterVO cluster : clustersForZone) {
-            HypervisorType hType = cluster.getHypervisorType();
-            if (!forVirtualRouter || (forVirtualRouter && hType != HypervisorType.BareMetal && hType != HypervisorType.Ovm)) {
-                hypervisorTypes.add(hType);
-            }
-        }
-
-        return hypervisorTypes;
-    }
-
-    @Override
-    public HypervisorType getDefaultHypervisor(long zoneId) {
-        HypervisorType defaultHyper = HypervisorType.None;
-        if (_defaultSystemVMHypervisor != HypervisorType.None) {
-            defaultHyper = _defaultSystemVMHypervisor;
-        }
-
-        DataCenterVO dc = _dcDao.findById(zoneId);
-        if (dc == null) {
-            return HypervisorType.None;
-        }
-        _dcDao.loadDetails(dc);
-        String defaultHypervisorInZone = dc.getDetail("defaultSystemVMHypervisorType");
-        if (defaultHypervisorInZone != null) {
-            defaultHyper = HypervisorType.getType(defaultHypervisorInZone);
-        }
-
-        List<VMTemplateVO> systemTemplates = _templateDao.listAllSystemVMTemplates();
-        boolean isValid = false;
-        for (VMTemplateVO template : systemTemplates) {
-            if (template.getHypervisorType() == defaultHyper) {
-                isValid = true;
-                break;
-            }
-        }
-
-        if (isValid) {
-            List<ClusterVO> clusters = _clusterDao.listByDcHyType(zoneId, defaultHyper.toString());
-            if (clusters.size() <= 0) {
-                isValid = false;
-            }
-        }
-
-        if (isValid) {
-            return defaultHyper;
-        } else {
-            return HypervisorType.None;
-        }
-    }
-
-    @Override
-    public HypervisorType getAvailableHypervisor(long zoneId) {
-        HypervisorType defaultHype = getDefaultHypervisor(zoneId);
-        if (defaultHype == HypervisorType.None) {
-            List<HypervisorType> supportedHypes = getSupportedHypervisorTypes(zoneId, false, null);
-            if (supportedHypes.size() > 0) {
-                defaultHype = supportedHypes.get(0);
-            }
-        }
-
-        if (defaultHype == HypervisorType.None) {
-            defaultHype = HypervisorType.Any;
-        }
-        return defaultHype;
-    }
-
-    @Override
-    public void registerResourceStateAdapter(String name, ResourceStateAdapter adapter) {
-        if (_resourceStateAdapters.get(name) != null) {
-            throw new CloudRuntimeException(name + " has registered");
-        }
-
-        synchronized (_resourceStateAdapters) {
-            _resourceStateAdapters.put(name, adapter);
-        }
-    }
-
-    @Override
-    public void unregisterResourceStateAdapter(String name) {
-        synchronized (_resourceStateAdapters) {
-            _resourceStateAdapters.remove(name);
-        }   
-    }
-
-    private Object dispatchToStateAdapters(ResourceStateAdapter.Event event, boolean singleTaker, Object... args) {
-        synchronized (_resourceStateAdapters) {
-            Iterator it = _resourceStateAdapters.entrySet().iterator();
-            Object result = null;
-            while (it.hasNext()) {
-                Map.Entry<String, ResourceStateAdapter> item = (Map.Entry<String, ResourceStateAdapter>) it.next();
-                ResourceStateAdapter adapter = item.getValue();
-
-                String msg = new String("Dispatching resource state event " + event + " to " + item.getKey());
-                s_logger.debug(msg);
-
-                if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED) {
-                    result = adapter.createHostVOForConnectedAgent((HostVO) args[0], (StartupCommand[]) args[1]);
-                    if (result != null && singleTaker) {
-                        break;
-                    }
-                } else if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT) {
-                    result = adapter.createHostVOForDirectConnectAgent((HostVO) args[0], (StartupCommand[]) args[1], (ServerResource) args[2],
-                            (Map<String, String>) args[3], (List<String>) args[4]);
-                    if (result != null && singleTaker) {
-                        break;
-                    }
-                } else if (event == ResourceStateAdapter.Event.DELETE_HOST) {
-                    try {
-                        result = adapter.deleteHost((HostVO) args[0], (Boolean) args[1], (Boolean) args[2]);
-                        if (result != null) {
-                            break;
-                        }
-                    } catch (UnableDeleteHostException e) {
-                        s_logger.debug("Adapter " + adapter.getName() + " says unable to delete host", e);
-                        result = new ResourceStateAdapter.DeleteHostAnswer(false, true);
-                    }
-                } else {
-                    throw new CloudRuntimeException("Unknown resource state event:" + event);
-                }
-            }
-
-            return result;
-        }
-    }
-
-    @Override
-    public void checkCIDR(HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask) throws IllegalArgumentException {
-        if (serverPrivateIP == null) {
-            return;
-        }
-        // Get the CIDR address and CIDR size
-        String cidrAddress = pod.getCidrAddress();
-        long cidrSize = pod.getCidrSize();
-
-        // If the server's private IP address is not in the same subnet as the
-        // pod's CIDR, return false
-        String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize);
-        String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask);
-        if (!cidrSubnet.equals(serverSubnet)) {
-            s_logger.warn("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName()
-                    + " and zone: " + dc.getName());
-            throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: "
-                    + pod.getName() + " and zone: " + dc.getName());
-        }
-
-        // If the server's private netmask is less inclusive than the pod's CIDR
-        // netmask, return false
-        String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
-        long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
-        long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask);
-        if (serverNetmaskNumeric > cidrNetmaskNumeric) {
-            throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: "
-                    + pod.getName() + " and zone: " + dc.getName());
-        }
-
-    }
-
-    private boolean checkCIDR(HostPodVO pod, String serverPrivateIP, String serverPrivateNetmask) {
-        if (serverPrivateIP == null) {
-            return true;
-        }
-        // Get the CIDR address and CIDR size
-        String cidrAddress = pod.getCidrAddress();
-        long cidrSize = pod.getCidrSize();
-
-        // If the server's private IP address is not in the same subnet as the
-        // pod's CIDR, return false
-        String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize);
-        String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask);
-        if (!cidrSubnet.equals(serverSubnet)) {
-            return false;
-        }
-
-        // If the server's private netmask is less inclusive than the pod's CIDR
-        // netmask, return false
-        String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
-        long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
-        long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask);
-        if (serverNetmaskNumeric > cidrNetmaskNumeric) {
-            return false;
-        }
-        return true;
-    }
-
-    protected HostVO createHostVO(StartupCommand[] cmds, ServerResource resource, Map<String, String> details, List<String> hostTags,
-            ResourceStateAdapter.Event stateEvent) {
-        StartupCommand startup = cmds[0];
-        HostVO host = findHostByGuid(startup.getGuid());
-        boolean isNew = false;
-        if (host == null) {
-            host = findHostByGuid(startup.getGuidWithoutResource());
-        }
-        if (host == null) {
-            host = new HostVO(startup.getGuid());
-            isNew = true;
-        }
-
-        String dataCenter = startup.getDataCenter();
-        String pod = startup.getPod();
-        String cluster = startup.getCluster();
-
-        if (pod != null && dataCenter != null && pod.equalsIgnoreCase("default") && dataCenter.equalsIgnoreCase("default")) {
-            List<HostPodVO> pods = _podDao.listAllIncludingRemoved();
-            for (HostPodVO hpv : pods) {
-                if (checkCIDR(hpv, startup.getPrivateIpAddress(), startup.getPrivateNetmask())) {
-                    pod = hpv.getName();
-                    dataCenter = _dcDao.findById(hpv.getDataCenterId()).getName();
-                    break;
-                }
-            }
-        }
-
-        long dcId = -1;
-        DataCenterVO dc = _dcDao.findByName(dataCenter);
-        if (dc == null) {
-            try {
-                dcId = Long.parseLong(dataCenter);
-                dc = _dcDao.findById(dcId);
-            } catch (final NumberFormatException e) {
-            }
-        }
-        if (dc == null) {
-            throw new IllegalArgumentException("Host " + startup.getPrivateIpAddress() + " sent incorrect data center: " + dataCenter);
-        }
-        dcId = dc.getId();
-
-        HostPodVO p = _podDao.findByName(pod, dcId);
-        if (p == null) {
-            try {
-                final long podId = Long.parseLong(pod);
-                p = _podDao.findById(podId);
-            } catch (final NumberFormatException e) {
-            }
-        }
-        /*
-         * ResourceStateAdapter is responsible for throwing Exception if Pod is
-         * null and non-null is required. for example, XcpServerDiscoever.
-         * Others, like PxeServer, ExternalFireware don't require Pod
-         */
-        Long podId = (p == null ? null : p.getId());
-
-        Long clusterId = null;
-        if (cluster != null) {
-            try {
-                clusterId = Long.valueOf(cluster);
-            } catch (NumberFormatException e) {
-                ClusterVO c = _clusterDao.findBy(cluster, podId);
-                if (c == null) {
-                    c = new ClusterVO(dcId, podId, cluster);
-                    c = _clusterDao.persist(c);
-                }
-                clusterId = c.getId();
-            }
-        }
-
-        host.setDataCenterId(dc.getId());
-        host.setPodId(podId);
-        host.setClusterId(clusterId);
-        host.setPrivateIpAddress(startup.getPrivateIpAddress());
-        host.setPrivateNetmask(startup.getPrivateNetmask());
-        host.setPrivateMacAddress(startup.getPrivateMacAddress());
-        host.setPublicIpAddress(startup.getPublicIpAddress());
-        host.setPublicMacAddress(startup.getPublicMacAddress());
-        host.setPublicNetmask(startup.getPublicNetmask());
-        host.setStorageIpAddress(startup.getStorageIpAddress());
-        host.setStorageMacAddress(startup.getStorageMacAddress());
-        host.setStorageNetmask(startup.getStorageNetmask());
-        host.setVersion(startup.getVersion());
-        host.setName(startup.getName());
-        host.setManagementServerId(_nodeId);
-        host.setStorageUrl(startup.getIqn());
-        host.setLastPinged(System.currentTimeMillis() >> 10);
-        host.setHostTags(hostTags);
-        host.setDetails(details);
-        if (startup.getStorageIpAddressDeux() != null) {
-            host.setStorageIpAddressDeux(startup.getStorageIpAddressDeux());
-            host.setStorageMacAddressDeux(startup.getStorageMacAddressDeux());
-            host.setStorageNetmaskDeux(startup.getStorageNetmaskDeux());
-        }
-        if (resource != null) {
-            /* null when agent is connected agent */
-            host.setResource(resource.getClass().getName());
-        }
-
-        host = (HostVO) dispatchToStateAdapters(stateEvent, true, host, cmds, resource, details, hostTags);
-        if (host == null) {
-            throw new CloudRuntimeException("No resource state adapter response");
-        }
-
-        if (isNew) {
-            host = _hostDao.persist(host);
-        } else {
-            _hostDao.update(host.getId(), host);
-        }
-
-        try {
-            resourceStateTransitTo(host, ResourceState.Event.InternalCreated, _nodeId);
-            /* Agent goes to Connecting status */
-            _agentMgr.agentStatusTransitTo(host, Status.Event.AgentConnected, _nodeId);
-        } catch (Exception e) {
-            s_logger.debug("Cannot transmit host " + host.getId() + " to Creating state", e);
-            _agentMgr.agentStatusTransitTo(host, Status.Event.Error, _nodeId);
-            try {
-                resourceStateTransitTo(host, ResourceState.Event.Error, _nodeId);
-            } catch (NoTransitionException e1) {
-                s_logger.debug("Cannot transmit host " + host.getId() + "to Error state", e);
-            }
-        }
-
-        return host;
-    }
-
-    private Host createHostAndAgent(ServerResource resource, Map<String, String> details, boolean old, List<String> hostTags,
-            boolean forRebalance) {
-        HostVO host = null;
-        AgentAttache attache = null;
-        StartupCommand[] cmds = null;
-
-        try {
-            cmds = resource.initialize();
-            if (cmds == null) {
-                s_logger.info("Unable to fully initialize the agent because no StartupCommands are returned");
-                return null;
-            }
-
-            /* Generate a random version in a dev setup situation */
-            if ( this.getClass().getPackage().getImplementationVersion() == null ) {
-                for ( StartupCommand cmd : cmds ) {
-                    if ( cmd.getVersion() == null ) {
-                        cmd.setVersion(Long.toString(System.currentTimeMillis()));
-                    }
-                }
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                new Request(-1l, -1l, cmds, true, false).logD("Startup request from directly connected host: ", true);
-            }
-
-            if (old) {
-                StartupCommand firstCmd = cmds[0];
-                host = findHostByGuid(firstCmd.getGuid());
-                if (host == null) {
-                    host = findHostByGuid(firstCmd.getGuidWithoutResource());
-                }
-                if (host != null && host.getRemoved() == null) {
-                    s_logger.debug("Found the host " + host.getId() + " by guid: " + firstCmd.getGuid() + ", old host reconnected as new");
-                    return null;
-                }
-            }
-
-            host = createHostVO(cmds, resource, details, hostTags, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT);
-            if (host != null) {
-                attache = _agentMgr.handleDirectConnectAgent(host, cmds, resource, forRebalance);
-                /* reload myself from database */
-                host = _hostDao.findById(host.getId());
-            }
-        } catch (Exception e) {
-            s_logger.warn("Unable to connect due to ", e);
-        } finally {
-            if (attache == null) {
-                if (cmds != null) {
-                    resource.disconnected();
-                }
-                //In case of some db errors, we may land with the sitaution that host is null. We need to reload host from db and call disconnect on it so that it will be loaded for reconnection next time
-                HostVO tempHost = host;
-                if(tempHost == null){
-                    if (cmds != null) {
-                        StartupCommand firstCmd = cmds[0];
-                        tempHost = findHostByGuid(firstCmd.getGuid());
-                        if (tempHost == null) {
-                            tempHost = findHostByGuid(firstCmd.getGuidWithoutResource());
-                        }
-                    }
-                }
-
-                if (tempHost != null) {
-                    /* Change agent status to Alert */
-                    _agentMgr.agentStatusTransitTo(tempHost, Status.Event.AgentDisconnected, _nodeId);
-                    /* Don't change resource state here since HostVO is already in database, which means resource state has had an appropriate value*/
-                }
-            }
-        }
-
-        return host;
-    }
-
-    @Override
-    public Host createHostAndAgent(Long hostId, ServerResource resource, Map<String, String> details, boolean old, List<String> hostTags, boolean forRebalance) {
-        _agentMgr.tapLoadingAgents(hostId, TapAgentsAction.Add);
-        Host host = createHostAndAgent(resource, details, old, hostTags, forRebalance);
-        _agentMgr.tapLoadingAgents(hostId, TapAgentsAction.Del);
-        return host;
-    }
-
-    @Override
-    public Host addHost(long zoneId, ServerResource resource, Type hostType, Map<String, String> hostDetails) {
-        // Check if the zone exists in the system
-        if (_dcDao.findById(zoneId) == null) {
-            throw new InvalidParameterValueException("Can't find zone with id " + zoneId);
-        }
-
-        Map<String, String> details = hostDetails;
-        String guid = details.get("guid");
-        List<HostVO> currentHosts = this.listAllUpAndEnabledHostsInOneZoneByType(hostType, zoneId);
-        for (HostVO currentHost : currentHosts) {
-            if (currentHost.getGuid().equals(guid)) {
-                return currentHost;
-            }
-        }
-
-        return createHostAndAgent(resource, hostDetails, true, null, false);
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(StartupCommand[] cmds) {
-        return createHostVO(cmds, null, null, null, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED);
-    }
-
-    private void checkIPConflicts(HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask, String serverPublicIP, String serverPublicNetmask) {
-        // If the server's private IP is the same as is public IP, this host has
-        // a host-only private network. Don't check for conflicts with the
-        // private IP address table.
-        if (serverPrivateIP != serverPublicIP) {
-            if (!_privateIPAddressDao.mark(dc.getId(), pod.getId(), serverPrivateIP)) {
-                // If the server's private IP address is already in the
-                // database, return false
-                List<DataCenterIpAddressVO> existingPrivateIPs = _privateIPAddressDao.listByPodIdDcIdIpAddress(pod.getId(), dc.getId(), serverPrivateIP);
-
-                assert existingPrivateIPs.size() <= 1 : " How can we get more than one ip address with " + serverPrivateIP;
-                if (existingPrivateIPs.size() > 1) {
-                    throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName());
-                }
-                if (existingPrivateIPs.size() == 1) {
-                    DataCenterIpAddressVO vo = existingPrivateIPs.get(0);
-                    if (vo.getInstanceId() != null) {
-                        throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName());
-                    }
-                }
-            }
-        }
-
-        if (serverPublicIP != null && !_publicIPAddressDao.mark(dc.getId(), new Ip(serverPublicIP))) {
-            // If the server's public IP address is already in the database,
-            // return false
-            List<IPAddressVO> existingPublicIPs = _publicIPAddressDao.listByDcIdIpAddress(dc.getId(), serverPublicIP);
-            if (existingPublicIPs.size() > 0) {
-                throw new IllegalArgumentException("The public ip address of the server (" + serverPublicIP + ") is already in use in zone: " + dc.getName());
-            }
-        }
-    }
-
-    @Override
-    public HostVO fillRoutingHostVO(HostVO host, StartupRoutingCommand ssCmd, HypervisorType hyType, Map<String, String> details, List<String> hostTags) {
-        if (host.getPodId() == null) {
-            s_logger.error("Host " + ssCmd.getPrivateIpAddress() + " sent incorrect pod, pod id is null");
-            throw new IllegalArgumentException("Host " + ssCmd.getPrivateIpAddress() + " sent incorrect pod, pod id is null");
-        }
-
-        ClusterVO clusterVO = _clusterDao.findById(host.getClusterId());
-        if (clusterVO.getHypervisorType() != hyType) {
-            throw new IllegalArgumentException("Can't add host whose hypervisor type is: " + hyType + " into cluster: " + clusterVO.getId() + " whose hypervisor type is: "
-                    + clusterVO.getHypervisorType());
-        }
-
-        final Map<String, String> hostDetails = ssCmd.getHostDetails();
-        if (hostDetails != null) {
-            if (details != null) {
-                details.putAll(hostDetails);
-            } else {
-                details = hostDetails;
-            }
-        }
-
-        HostPodVO pod = _podDao.findById(host.getPodId());
-        DataCenterVO dc = _dcDao.findById(host.getDataCenterId());
-        checkIPConflicts(pod, dc, ssCmd.getPrivateIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicNetmask());
-        host.setType(com.cloud.host.Host.Type.Routing);
-        host.setDetails(details);
-        host.setCaps(ssCmd.getCapabilities());
-        host.setCpus(ssCmd.getCpus());
-        host.setTotalMemory(ssCmd.getMemory());
-        host.setSpeed(ssCmd.getSpeed());
-        host.setHypervisorType(hyType);        
-        return host;
-    }
-
-    @Override
-    public void deleteRoutingHost(HostVO host, boolean isForced, boolean forceDestroyStorage) throws UnableDeleteHostException {
-        if (host.getType() != Host.Type.Routing) {
-            throw new CloudRuntimeException("Non-Routing host gets in deleteRoutingHost, id is " + host.getId());
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Deleting Host: " + host.getId() + " Guid:" + host.getGuid());
-        }
-
-        User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId());
-        if (forceDestroyStorage) {
-            // put local storage into mainenance mode, will set all the VMs on
-            // this local storage into stopped state
-            StoragePool storagePool = _storageMgr.findLocalStorageOnHost(host.getId());
-            if (storagePool != null) {
-                if (storagePool.getStatus() == StoragePoolStatus.Up || storagePool.getStatus() == StoragePoolStatus.ErrorInMaintenance) {
-                    try {
-                        storagePool = _storageSvr.preparePrimaryStorageForMaintenance(storagePool.getId());
-                        if (storagePool == null) {
-                            s_logger.debug("Failed to set primary storage into maintenance mode");
-                            throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode");
-                        }
-                    } catch (Exception e) {
-                        s_logger.debug("Failed to set primary storage into maintenance mode, due to: " + e.toString());
-                        throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode, due to: " + e.toString());
-                    }
-                }
-
-                List<VMInstanceVO> vmsOnLocalStorage = _storageMgr.listByStoragePool(storagePool.getId());
-                for (VMInstanceVO vm : vmsOnLocalStorage) {
-                    try {
-                        if (!_vmMgr.destroy(vm, caller, _accountMgr.getAccount(vm.getAccountId()))) {
-                            String errorMsg = "There was an error Destory the vm: " + vm + " as a part of hostDelete id=" + host.getId();
-                            s_logger.warn(errorMsg);
-                            throw new UnableDeleteHostException(errorMsg);
-                        }
-                    } catch (Exception e) {
-                        String errorMsg = "There was an error Destory the vm: " + vm + " as a part of hostDelete id=" + host.getId();
-                        s_logger.debug(errorMsg, e);
-                        throw new UnableDeleteHostException(errorMsg + "," + e.getMessage());
-                    }
-                }
-            }
-        } else {
-            // Check if there are vms running/starting/stopping on this host
-            List<VMInstanceVO> vms = _vmDao.listByHostId(host.getId());
-            if (!vms.isEmpty()) {
-                if (isForced) {
-                    // Stop HA disabled vms and HA enabled vms in Stopping state
-                    // Restart HA enabled vms
-                    for (VMInstanceVO vm : vms) {
-                        if (!vm.isHaEnabled() || vm.getState() == State.Stopping) {
-                            s_logger.debug("Stopping vm: " + vm + " as a part of deleteHost id=" + host.getId());
-                            try {
-                                if (!_vmMgr.advanceStop(vm, true, caller, _accountMgr.getAccount(vm.getAccountId()))) {
-                                    String errorMsg = "There was an error stopping the vm: " + vm + " as a part of hostDelete id=" + host.getId();
-                                    s_logger.warn(errorMsg);
-                                    throw new UnableDeleteHostException(errorMsg);
-                                }
-                            } catch (Exception e) {
-                                String errorMsg = "There was an error stopping the vm: " + vm + " as a part of hostDelete id=" + host.getId();
-                                s_logger.debug(errorMsg, e);
-                                throw new UnableDeleteHostException(errorMsg + "," + e.getMessage());
-                            }
-                        } else if (vm.isHaEnabled() && (vm.getState() == State.Running || vm.getState() == State.Starting)) {
-                            s_logger.debug("Scheduling restart for vm: " + vm + " " + vm.getState() + " on the host id=" + host.getId());
-                            _haMgr.scheduleRestart(vm, false);
-                        }
-                    }
-                } else {
-                    throw new UnableDeleteHostException("Unable to delete the host as there are vms in " + vms.get(0).getState()
-                            + " state using this host and isForced=false specified");
-                }
-            }
-        }
-    }
-
-    private boolean doCancelMaintenance(long hostId) {
-        HostVO host;
-        host = _hostDao.findById(hostId);
-        if (host == null || host.getRemoved() != null) {
-            s_logger.warn("Unable to find host " + hostId);
-            return true;
-        }
-
-        /*TODO: think twice about returning true or throwing out exception, I really prefer to exception that always exposes bugs */
-        if (host.getResourceState() != ResourceState.PrepareForMaintenance && host.getResourceState() != ResourceState.Maintenance && host.getResourceState() != ResourceState.ErrorInMaintenance) {
-            throw new CloudRuntimeException("Cannot perform cancelMaintenance when resource state is " + host.getResourceState() + ", hostId = " + hostId);
-        }
-
-        /*TODO: move to listener */
-        _haMgr.cancelScheduledMigrations(host);
-        List<VMInstanceVO> vms = _haMgr.findTakenMigrationWork();
-        for (VMInstanceVO vm : vms) {
-            if (vm.getHostId() != null && vm.getHostId() == hostId) {
-                s_logger.info("Unable to cancel migration because the vm is being migrated: " + vm);
-                return false;
-            }
-        }
-
-        try {
-            resourceStateTransitTo(host, ResourceState.Event.AdminCancelMaintenance, _nodeId);
-            _agentMgr.pullAgentOutMaintenance(hostId);
-
-            //for kvm, need to log into kvm host, restart cloud-agent
-            if (host.getHypervisorType() == HypervisorType.KVM) {
-                _hostDao.loadDetails(host);
-                String password = host.getDetail("password");
-                String username = host.getDetail("username");
-                if (password == null || username == null) {
-                    s_logger.debug("Can't find password/username");
-                    return false;
-                }
-                com.trilead.ssh2.Connection connection = SSHCmdHelper.acquireAuthorizedConnection(host.getPrivateIpAddress(), 22, username, password);
-                if (connection == null) {
-                    s_logger.debug("Failed to connect to host: " + host.getPrivateIpAddress());
-                    return false;
-                }
-
-                try {
-                    SSHCmdHelper.sshExecuteCmdOneShot(connection, "service cloud-agent restart");
-                } catch (sshException e) {
-                    return false;
-                }
-            }
-
-            return true;
-        } catch (NoTransitionException e) {
-            s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
-            return false;
-        }
-    }
-
-    private boolean cancelMaintenance(long hostId) {
-        try {
-            Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.AdminCancelMaintenance);
-
-            if (result != null) {
-                return result;
-            }
-        } catch (AgentUnavailableException e) {
-            return false;
-        }
-
-        return doCancelMaintenance(hostId);
-    }
-
-    @Override
-    public boolean executeUserRequest(long hostId, ResourceState.Event event) throws AgentUnavailableException {
-        if (event == ResourceState.Event.AdminAskMaintenace) {
-            return doMaintain(hostId);
-        } else if (event == ResourceState.Event.AdminCancelMaintenance) {
-            return doCancelMaintenance(hostId);
-        } else if (event == ResourceState.Event.DeleteHost) {
-            /*TODO: Ask alex why we assume the last two parameters are false*/
-            return doDeleteHost(hostId, false, false);
-        } else if (event == ResourceState.Event.Unmanaged) {
-            return doUmanageHost(hostId);
-        } else if (event == ResourceState.Event.UpdatePassword) {
-            return doUpdateHostPassword(hostId);
-        } else {
-            throw new CloudRuntimeException("Received an resource event we are not handling now, " + event);
-        }
-    }
-
-    private boolean doUmanageHost(long hostId) {
-        HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            s_logger.debug("Cannot find host " + hostId + ", assuming it has been deleted, skip umanage");
-            return true;
-        }
-
-        if (host.getHypervisorType() == HypervisorType.KVM) {
-            MaintainAnswer answer = (MaintainAnswer) _agentMgr.easySend(hostId, new MaintainCommand());
-        }
-
-        _agentMgr.disconnectWithoutInvestigation(hostId, Event.ShutdownRequested);
-        return true;
-    }
-
-
-    @Override
-    public boolean umanageHost(long hostId) {
-        try {
-            Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.Unmanaged);
-
-            if (result != null) {
-                return result;
-            }
-        } catch (AgentUnavailableException e) {
-            return false;
-        }
-
-        return doUmanageHost(hostId);
-    }
-
-    private boolean doUpdateHostPassword(long hostId) {
-        AgentAttache attache = _agentMgr.findAttache(hostId);
-        if (attache == null) {
-            return false;
-        }
-
-        DetailVO nv = _hostDetailsDao.findDetail(hostId, ApiConstants.USERNAME);
-        String username = nv.getValue();
-        nv = _hostDetailsDao.findDetail(hostId, ApiConstants.PASSWORD);
-        String password = nv.getValue();
-        UpdateHostPasswordCommand cmd = new UpdateHostPasswordCommand(username, password);
-        attache.updatePassword(cmd);
-        return true;
-    }
-
-    @Override
-    public boolean updateHostPassword(UpdateHostPasswordCmd cmd) {
-        if (cmd.getClusterId() == null) {
-            // update agent attache password
-            try {
-                Boolean result = _clusterMgr.propagateResourceEvent(cmd.getHostId(), ResourceState.Event.UpdatePassword);
-                if (result != null) {
-                    return result;
-                }
-            } catch (AgentUnavailableException e) {
-            }
-
-            return doUpdateHostPassword(cmd.getHostId());
-        } else {
-            // get agents for the cluster
-            List<HostVO> hosts = this.listAllHostsInCluster(cmd.getClusterId());
-            for (HostVO h : hosts) {
-                try {
-                    /*FIXME: this is a buggy logic, check with alex. Shouldn't return if propagation return non null*/
-                    Boolean result = _clusterMgr.propagateResourceEvent(h.getId(), ResourceState.Event.UpdatePassword);
-                    if (result != null) {
-                        return result;
-                    }
-
-                    doUpdateHostPassword(h.getId());
-                } catch (AgentUnavailableException e) {
-                }
-            }
-
-            return true;
-        }
-    }
-
-    @Override
-    public boolean maintenanceFailed(long hostId) {
-        HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Cant not find host " + hostId);
-            }
-            return false;
-        } else {
-            try {
-                return resourceStateTransitTo(host, ResourceState.Event.UnableToMigrate, _nodeId);
-            } catch (NoTransitionException e) {
-                s_logger.debug("No next resource state for host " + host.getId() + " while current state is " + host.getResourceState() + " with event " + ResourceState.Event.UnableToMigrate, e);
-                return false;
-            }
-        }
-    }
-
-    @Override
-    public List<HostVO> findDirectlyConnectedHosts() {
-        /* The resource column is not null for direct connected resource */
-        SearchCriteriaService<HostVO, HostVO> sc = SearchCriteria2.create(HostVO.class);
-        sc.addAnd(sc.getEntity().getResource(), Op.NNULL);
-        sc.addAnd(sc.getEntity().getResourceState(), Op.NIN, ResourceState.Disabled);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllUpAndEnabledHosts(Type type, Long clusterId, Long podId, long dcId) {
-        SearchCriteriaService<HostVO, HostVO> sc = SearchCriteria2.create(HostVO.class);
-        if (type != null) {
-            sc.addAnd(sc.getEntity().getType(), Op.EQ, type);
-        }
-        if (clusterId != null) {
-            sc.addAnd(sc.getEntity().getClusterId(), Op.EQ, clusterId);
-        }
-        if (podId != null) {
-            sc.addAnd(sc.getEntity().getPodId(), Op.EQ, podId);
-        }
-        sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId);
-        sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up);
-        sc.addAnd(sc.getEntity().getResourceState(), Op.EQ, ResourceState.Enabled);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId) {
-        String haTag = _haMgr.getHaTag();
-        return _hostDao.listAllUpAndEnabledNonHAHosts(type, clusterId, podId, dcId, haTag);
-    }
-
-    @Override
-    public List<HostVO> findHostByGuid(long dcId, String guid) {
-        SearchCriteriaService<HostVO, HostVO> sc = SearchCriteria2.

<TRUNCATED>