Repository: apache/cloudstack
Pull request #10647: Revert "Add the option to filter by host when retrieving of unregistered VMs (#9925)"
Author: login: DaanHoogland
Labels: name: component:vmware
name: component:api
name: component:UI
name: Python
description: Warning... Python code Ahead!
name: component:integration-test
Created: 2025-04-01T15:37:26Z | Merged: 2025-04-24T07:06:57Z

### Description

This PR...
<!--- Describe your changes in DETAIL - And how has behaviour functionally changed. -->

<!-- For new features, provide link to FS, dev ML discussion etc. -->
<!-- In case of bug fix, the expected and actual behaviours, steps to reproduce. -->

<!-- When "Fixes: #<id>" is specified, the issue/PR will automatically be closed when this PR gets merged -->
<!-- For addressing multiple issues/PRs, use multiple "Fixes: #<id>" -->
Fixes: #10634

#9925 caused a regression where under certain circumstances (with more than 100 VMs) console proxy would not work anymore. This has to do with the APIs being used in vmware, that timeout or do not work at all. 

#9782 needs to be reworked as a consequence.

<!--- ******************************************************************************* -->
<!--- NOTE: AUTOMATION USES THE DESCRIPTIONS TO SET LABELS AND PRODUCE DOCUMENTATION. -->
<!--- PLEASE PUT AN 'X' in only **ONE** box -->
<!--- ******************************************************************************* -->

### Types of changes

- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] Enhancement (improves an existing feature and functionality)
- [ ] Cleanup (Code refactoring and cleanup, that may add test cases)
- [ ] build/CI
- [ ] test (unit or integration test code)

### Feature/Enhancement Scale or Bug Severity

#### Feature/Enhancement Scale

- [ ] Major
- [ ] Minor

#### Bug Severity

- [ ] BLOCKER
- [ ] Critical
- [ ] Major
- [ ] Minor
- [ ] Trivial

### Screenshots (if appropriate):

### How Has This Been Tested?

<!-- Please describe in detail how you tested your changes. -->
<!-- Include details of your testing environment, and the tests you ran to -->

#### How did you try to break this feature and the system with this change?

<!-- see how your change affects other areas of the code, etc. -->

<!-- Please read the [CONTRIBUTING](https://github.com/apache/cloudstack/blob/main/CONTRIBUTING.md) document -->



Diff:
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
index efceafd1a3a2..b2042c116a7f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -46,7 +46,6 @@ public class ApiConstants {
     public static final String BACKUP_OFFERING_NAME = "backupofferingname";
     public static final String BACKUP_OFFERING_ID = "backupofferingid";
     public static final String BASE64_IMAGE = "base64image";
-    public static final String BATCH_SIZE = "batchsize";
     public static final String BITS = "bits";
     public static final String BOOTABLE = "bootable";
     public static final String BIND_DN = "binddn";
@@ -438,12 +437,11 @@ public class ApiConstants {
     public static final String STATE = "state";
     public static final String STATS = "stats";
     public static final String STATUS = "status";
+    public static final String STORAGE_TYPE = "storagetype";
+    public static final String STORAGE_POLICY = "storagepolicy";
+    public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
     public static final String STORAGE_CAPABILITIES = "storagecapabilities";
     public static final String STORAGE_CUSTOM_STATS = "storagecustomstats";
-    public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
-    public static final String STORAGE_POLICY = "storagepolicy";
-    public static final String STORAGE_POOL = "storagepool";
-    public static final String STORAGE_TYPE = "storagetype";
     public static final String SUBNET = "subnet";
     public static final String OWNER = "owner";
     public static final String SWAP_OWNER = "swapowner";
@@ -1108,7 +1106,6 @@ public class ApiConstants {
     public static final String PARAMETER_DESCRIPTION_IS_TAG_A_RULE = "Whether the informed tag is a JS interpretable rule or not.";
 
     public static final String NFS_MOUNT_OPTIONS = "nfsmountopts";
-    public static final String VMWARE_DC = "vmwaredc";
 
     /**
      * This enum specifies IO Drivers, each option controls specific policies on I/O.
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java
index cb759d9ab6d0..99aabd889134 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java
@@ -152,7 +152,7 @@ public class HostResponse extends BaseResponseWithAnnotations {
     @Deprecated
     @SerializedName("memoryallocated")
     @Param(description = "the amount of the host's memory currently allocated")
-    private Long memoryAllocated;
+    private long memoryAllocated;
 
     @SerializedName("memoryallocatedpercentage")
     @Param(description = "the amount of the host's memory currently allocated in percentage")
@@ -395,7 +395,7 @@ public void setMemWithOverprovisioning(String memWithOverprovisioning){
         this.memWithOverprovisioning=memWithOverprovisioning;
     }
 
-    public void setMemoryAllocated(Long memoryAllocated) {
+    public void setMemoryAllocated(long memoryAllocated) {
         this.memoryAllocated = memoryAllocated;
     }
 
@@ -659,8 +659,8 @@ public Long getMemoryTotal() {
         return memoryTotal;
     }
 
-    public Long getMemoryAllocated() {
-        return memoryAllocated == null ? 0 : memoryAllocated;
+    public long getMemoryAllocated() {
+        return memoryAllocated;
     }
 
     public void setMemoryAllocatedPercentage(String memoryAllocatedPercentage) {
diff --git a/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java b/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java
index 005eb2a8fd4f..1dfe20a10be2 100644
--- a/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java
+++ b/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java
@@ -47,14 +47,14 @@ public class DynamicRoleBasedAPIAccessChecker extends AdapterBase implements API
     private RoleService roleService;
 
     private List<PluggableService> services;
-    private Map<RoleType, Set<String>> annotationRoleBasedApisMap = new HashMap<>();
+    private Map<RoleType, Set<String>> annotationRoleBasedApisMap = new HashMap<RoleType, Set<String>>();
 
     private static final Logger LOGGER = Logger.getLogger(DynamicRoleBasedAPIAccessChecker.class.getName());
 
     protected DynamicRoleBasedAPIAccessChecker() {
         super();
         for (RoleType roleType : RoleType.values()) {
-            annotationRoleBasedApisMap.put(roleType, new HashSet<>());
+            annotationRoleBasedApisMap.put(roleType, new HashSet<String>());
         }
     }
 
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
index 6bb473536b86..bbac78b879a4 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
@@ -22,15 +22,12 @@
 import com.cloud.dc.VsphereStoragePolicy;
 import com.cloud.exception.DiscoveryException;
 import com.cloud.exception.ResourceInUseException;
-import com.cloud.hypervisor.vmware.mo.HostMO;
 import com.cloud.storage.StoragePool;
-import com.cloud.utils.Pair;
 import com.cloud.utils.component.PluggableService;
 import com.cloud.utils.exception.CloudRuntimeException;
 import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
 import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
 import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcVmsCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcHostsCmd;
 import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
 import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
 import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
@@ -56,7 +53,5 @@ public interface VmwareDatacenterService extends PluggableService {
 
     List<StoragePool> listVsphereStoragePolicyCompatibleStoragePools(ListVsphereStoragePolicyCompatiblePoolsCmd cmd);
 
-    List<HostMO> listHostsInDatacenter(ListVmwareDcHostsCmd cmd);
-
-    Pair<String, List<UnmanagedInstanceTO>> listVMsInDatacenter(ListVmwareDcVmsCmd cmd);
+    List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd cmd);
 }
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index 2d733e8a16cb..61a949f42d3e 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -19,12 +19,10 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
 import java.rmi.RemoteException;
 import java.time.Duration;
 import java.time.Instant;
@@ -45,11 +43,10 @@
 import javax.naming.ConfigurationException;
 import javax.persistence.EntityExistsException;
 
+import com.cloud.hypervisor.vmware.util.VmwareClient;
 import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
 import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
 import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcVmsCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcHostsCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcItems;
 import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
 import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
 import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
@@ -90,7 +87,6 @@
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.ClusterVSMMapVO;
 import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.VmwareDatacenter;
 import com.cloud.dc.VsphereStoragePolicy;
 import com.cloud.dc.VsphereStoragePolicyVO;
 import com.cloud.dc.dao.ClusterDao;
@@ -116,8 +112,7 @@
 import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
 import com.cloud.hypervisor.vmware.LegacyZoneVO;
 import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
-import com.cloud.hypervisor.vmware.util.VmwareClient;
-import com.cloud.hypervisor.vmware.util.VmwareClientException;
+import com.cloud.dc.VmwareDatacenter;
 import com.cloud.hypervisor.vmware.VmwareDatacenterService;
 import com.cloud.dc.VmwareDatacenterVO;
 import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMap;
@@ -170,18 +165,13 @@
 import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SshHelper;
+import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.dao.UserVmCloneSettingDao;
 import com.cloud.vm.dao.VMInstanceDao;
-
-// TODO move these items upstream?
 import com.vmware.pbm.PbmProfile;
 import com.vmware.vim25.AboutInfo;
 import com.vmware.vim25.ManagedObjectReference;
-import com.vmware.vim25.InvalidLocaleFaultMsg;
-import com.vmware.vim25.InvalidLoginFaultMsg;
-import com.vmware.vim25.RuntimeFaultFaultMsg;
-import com.vmware.vim25.InvalidPropertyFaultMsg;
-import org.jetbrains.annotations.NotNull;
 
 public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable {
     private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class);
@@ -257,11 +247,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
     private StorageLayer _storage;
     private final String _privateNetworkVSwitchName = "vSwitch0";
 
-    private final int _portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP;
+    private int _portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP;
     private boolean _fullCloneFlag;
     private boolean _instanceNameFlag;
     private String _serviceConsoleName;
-    private String _managementPortGroupName;
+    private String _managemetPortGroupName;
     private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
     private String _recycleHungWorker = "false";
     private int _additionalPortRangeStart;
@@ -275,7 +265,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
 
     private final Random _rand = new Random(System.currentTimeMillis());
 
-    private static final ScheduledExecutorService templateCleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-FullyClonedTemplateCheck"));
+    private static ScheduledExecutorService templateCleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-FullyClonedTemplateCheck"));;
 
     private final VmwareStorageManager _storageMgr;
     private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
@@ -359,9 +349,9 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
             _serviceConsoleName = "Service Console";
         }
 
-        _managementPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
-        if (_managementPortGroupName == null) {
-            _managementPortGroupName = "Management Network";
+        _managemetPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
+        if (_managemetPortGroupName == null) {
+            _managemetPortGroupName = "Management Network";
         }
 
         _defaultSystemVmNicAdapterType = _configDao.getValue(Config.VmwareSystemVmNicDeviceType.key());
@@ -460,7 +450,7 @@ private void prepareHost(HostMO hostMo, String privateTrafficLabel) throws Excep
 
         s_logger.info("Preparing network on host " + hostMo.getContext().toString() + " for " + privateTrafficLabel);
         VirtualSwitchType vsType = VirtualSwitchType.getType(vSwitchType);
-        //The management network is probably always going to be a physical network with isolation type of vlans, so assume BroadcastDomainType VLAN
+        //The management network is probably always going to be a physical network with islation type of vlans, so assume BroadcastDomainType VLAN
         if (VirtualSwitchType.StandardVirtualSwitch == vsType) {
             HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null, null);
         }
@@ -469,7 +459,7 @@ private void prepareHost(HostMO hostMo, String privateTrafficLabel) throws Excep
             AboutInfo about = hostMo.getHostAboutInfo();
             if (about != null) {
                 String version = about.getApiVersion();
-                if (version != null && (version.equals("4.0") || version.equals("4.1")) ) { // && _portsPerDvPortGroup < DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x)
+                if (version != null && (version.equals("4.0") || version.equals("4.1")) && _portsPerDvPortGroup < DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x) {
                     portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x;
                 }
             }
@@ -492,7 +482,7 @@ private HostMO getOldestExistentHostInCluster(Long clusterId, VmwareContext serv
             }
 
             URI uriForHost = new URI(UriUtils.encodeURIComponent(clusterDetails.get("url") + "/" + host.getName()));
-            morSrcHost = serviceContext.getHostMorByPath(URLDecoder.decode(uriForHost.getPath(), StandardCharsets.UTF_8));
+            morSrcHost = serviceContext.getHostMorByPath(URLDecoder.decode(uriForHost.getPath(), "UTF-8"));
             if (morSrcHost == null) {
                 return null;
             }
@@ -508,18 +498,19 @@ public List<ManagedObjectReference> addHostToPodCluster(VmwareContext serviceCon
             throw new CloudRuntimeException("Invalid serviceContext");
         }
         ManagedObjectReference mor = serviceContext.getHostMorByPath(hostInventoryPath);
-        String privateTrafficLabel;
+        String privateTrafficLabel = null;
         privateTrafficLabel = serviceContext.getStockObject("privateTrafficLabel");
         if (privateTrafficLabel == null) {
             privateTrafficLabel = _privateNetworkVSwitchName;
         }
 
         if (mor != null) {
-            List<ManagedObjectReference> returnedHostList = new ArrayList<>();
+            List<ManagedObjectReference> returnedHostList = new ArrayList<ManagedObjectReference>();
 
             if (mor.getType().equals("ComputeResource")) {
                 List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
-                assert (CollectionUtils.isNullOrEmpty(hosts));
+                assert (hosts != null && hosts.size() > 0);
+
                 // For ESX host, we need to enable host firewall to allow VNC access
                 HostMO hostMo = new HostMO(serviceContext, hosts.get(0));
 
@@ -530,8 +521,8 @@ public List<ManagedObjectReference> addHostToPodCluster(VmwareContext serviceCon
                 List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
                 assert (hosts != null);
 
-                if (!hosts.isEmpty()) {
-                    AboutInfo about = serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product");
+                if (hosts.size() > 0) {
+                    AboutInfo about = (AboutInfo)(serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product"));
                     String version = about.getApiVersion();
                     int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version);
                     if (hosts.size() > maxHostsPerCluster) {
@@ -560,7 +551,7 @@ public List<ManagedObjectReference> addHostToPodCluster(VmwareContext serviceCon
                 returnedHostList.add(mor);
                 return returnedHostList;
             } else {
-                s_logger.error("Unsupported host type " + mor.getType() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath);
+                s_logger.error("Unsupport host type " + mor.getType() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath);
                 return null;
             }
         }
@@ -625,13 +616,13 @@ public String getServiceConsolePortGroupName() {
 
     @Override
     public String getManagementPortGroupName() {
-        return _managementPortGroupName;
+        return _managemetPortGroupName;
     }
 
     @Override
     public String getManagementPortGroupByHost(HostMO hostMo) throws Exception {
         if (hostMo.getHostType() == VmwareHostType.ESXi) {
-            return _managementPortGroupName;
+            return _managemetPortGroupName;
         }
         return _serviceConsoleName;
     }
@@ -641,7 +632,7 @@ public void setupResourceStartupParams(Map<String, Object> params) {
         params.put("vmware.create.full.clone", _fullCloneFlag);
         params.put("vm.instancename.flag", _instanceNameFlag);
         params.put("service.console.name", _serviceConsoleName);
-        params.put("management.portgroup.name", _managementPortGroupName);
+        params.put("management.portgroup.name", _managemetPortGroupName);
         params.put("vmware.root.disk.controller", _rootDiskController);
         params.put("vmware.data.disk.controller", _dataDiskController);
         params.put("vmware.recycle.hung.wokervm", _recycleHungWorker);
@@ -668,25 +659,25 @@ public boolean needRecycle(String workerTag) {
             return false;
         }
 
-        String[] tokens = workerTag.split("-");
+        String tokens[] = workerTag.split("-");
         if (tokens.length != 3) {
             s_logger.error("Invalid worker VM tag " + workerTag);
             return false;
         }
 
         long startTick = Long.parseLong(tokens[0]);
-        long msId = Long.parseLong(tokens[1]);
-        long runId = Long.parseLong(tokens[2]);
+        long msid = Long.parseLong(tokens[1]);
+        long runid = Long.parseLong(tokens[2]);
 
-        if (msHostPeerDao.countStateSeenInPeers(msId, runId, ManagementServerHost.State.Down) > 0) {
+        if (msHostPeerDao.countStateSeenInPeers(msid, runid, ManagementServerHost.State.Down) > 0) {
             if (s_logger.isInfoEnabled())
                 s_logger.info("Worker VM's owner management server node has been detected down from peer nodes, recycle it");
             return true;
         }
 
-        if (runId != clusterManager.getManagementRunId(msId)) {
+        if (runid != clusterManager.getManagementRunId(msid)) {
             if (s_logger.isInfoEnabled())
-                s_logger.info("Worker VM's owner management server has changed runId, recycle it");
+                s_logger.info("Worker VM's owner management server has changed runid, recycle it");
             return true;
         }
 
@@ -721,7 +712,7 @@ public void prepareSecondaryStorageStore(String storageUrl, Long storeId) {
                     File patchFolder = new File(mountPoint + "/systemvm");
                     if (!patchFolder.exists()) {
                         if (!patchFolder.mkdirs()) {
-                            String msg = "Unable to create systemvm folder on secondary storage. location: " + patchFolder;
+                            String msg = "Unable to create systemvm folder on secondary storage. location: " + patchFolder.toString();
                             s_logger.error(msg);
                             throw new CloudRuntimeException(msg);
                         }
@@ -740,7 +731,7 @@ public void prepareSecondaryStorageStore(String storageUrl, Long storeId) {
                         } catch (IOException e) {
                             s_logger.error("Unexpected exception ", e);
 
-                            String msg = "Unable to copy systemvm ISO on secondary storage. src location: " + srcIso + ", dest location: " + destIso;
+                            String msg = "Unable to copy systemvm ISO on secondary storage. src location: " + srcIso.toString() + ", dest location: " + destIso;
                             s_logger.error(msg);
                             throw new CloudRuntimeException(msg);
                         }
@@ -782,8 +773,9 @@ private File getSystemVMPatchIsoFile() {
             isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso");
         }
 
+        assert (isoFile != null);
         if (!isoFile.exists()) {
-            s_logger.error("Unable to locate systemvm.iso in your setup at " + isoFile);
+            s_logger.error("Unable to locate systemvm.iso in your setup at " + isoFile.toString());
         }
         return isoFile;
     }
@@ -798,16 +790,16 @@ public File getSystemVMKeyFile() {
         if (keyFile == null || !keyFile.exists()) {
             keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
         }
-
+        assert (keyFile != null);
         if (!keyFile.exists()) {
-            s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile);
+            s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString());
         }
         return keyFile;
     }
 
     @Override
     public String getMountPoint(String storageUrl, String nfsVersion) {
-        String mountPoint;
+        String mountPoint = null;
         synchronized (_storageMounts) {
             mountPoint = _storageMounts.get(storageUrl);
             if (mountPoint != null) {
@@ -837,7 +829,7 @@ private String setupMountPoint(String parent) {
         String mountPoint = null;
         long mshostId = ManagementServerNode.getManagementServerId();
         for (int i = 0; i < 10; i++) {
-            String mntPt = parent + File.separator + mshostId + "." + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
+            String mntPt = parent + File.separator + String.valueOf(mshostId) + "." + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
             File file = new File(mntPt);
             if (!file.exists()) {
                 if (_storage.mkdir(mntPt)) {
@@ -862,9 +854,10 @@ private void startupCleanup(String parent) {
             for (String mountPoint : mounts) {
                 s_logger.info("umount NFS mount from previous session: " + mountPoint);
 
+                String result = null;
                 Script command = new Script(true, "umount", _timeout, s_logger);
                 command.add(mountPoint);
-                String result = command.execute();
+                result = command.execute();
                 if (result != null) {
                     s_logger.warn("Unable to umount " + mountPoint + " due to " + result);
                 }
@@ -882,7 +875,7 @@ private void shutdownCleanup() {
         for (String mountPoint : _storageMounts.values()) {
             s_logger.info("umount NFS mount: " + mountPoint);
 
-            String result;
+            String result = null;
             Script command = new Script(true, "umount", _timeout, s_logger);
             command.add(mountPoint);
             result = command.execute();
@@ -903,8 +896,8 @@ protected String mount(String path, String parent, String nfsVersion) {
             return null;
         }
 
-        Script script;
-        String result;
+        Script script = null;
+        String result = null;
         Script command = new Script(true, "mount", _timeout, s_logger);
         command.add("-t", "nfs");
         if (nfsVersion != null){
@@ -991,15 +984,40 @@ public void processHostAdded(long hostId) {
 
     @Override
     public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
-        if (cmd != null) {
+        if (cmd instanceof StartupCommand) {
             if (host.getHypervisorType() == HypervisorType.VMware) {
                 updateClusterNativeHAState(host, cmd);
+            } else {
+                return;
             }
         }
     }
 
     protected final static int DEFAULT_DOMR_SSHPORT = 3922;
 
+    protected boolean shutdownRouterVM(DomainRouterVO router) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Try to shutdown router VM " + router.getInstanceName() + " directly.");
+        }
+
+        Pair<Boolean, String> result;
+        try {
+            result = SshHelper.sshExecute(router.getPrivateIpAddress(), DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "poweroff -f");
+
+            if (!result.first()) {
+                s_logger.debug("Unable to shutdown " + router.getInstanceName() + " directly");
+                return false;
+            }
+        } catch (Throwable e) {
+            s_logger.warn("Unable to shutdown router " + router.getInstanceName() + " directly.");
+            return false;
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Shutdown router " + router.getInstanceName() + " successful.");
+        }
+        return true;
+    }
+
     @Override
     public boolean processDisconnect(long agentId, Status state) {
         return false;
@@ -1040,16 +1058,16 @@ public void endExclusiveOperation() {
 
     @Override
     public Pair<Integer, Integer> getAddiionalVncPortRange() {
-        return new Pair<>(_additionalPortRangeStart, _additionalPortRangeSize);
+        return new Pair<Integer, Integer>(_additionalPortRangeStart, _additionalPortRangeSize);
     }
 
     @Override
     public Map<String, String> getNexusVSMCredentialsByClusterId(Long clusterId) {
-        CiscoNexusVSMDeviceVO nexusVSM;
-        ClusterVSMMapVO vsmMapVO;
+        CiscoNexusVSMDeviceVO nexusVSM = null;
+        ClusterVSMMapVO vsmMapVO = null;
 
         vsmMapVO = _vsmMapDao.findByClusterId(clusterId);
-        long vsmId;
+        long vsmId = 0;
         if (vsmMapVO != null) {
             vsmId = vsmMapVO.getVsmId();
             s_logger.info("vsmId is " + vsmId);
@@ -1060,7 +1078,7 @@ public Map<String, String> getNexusVSMCredentialsByClusterId(Long clusterId) {
             return null;
         }
 
-        Map<String, String> nexusVSMCredentials = new HashMap<>();
+        Map<String, String> nexusVSMCredentials = new HashMap<String, String>();
         if (nexusVSM != null) {
             nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr());
             nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName());
@@ -1087,7 +1105,7 @@ public int getVcenterSessionTimeout() {
 
     @Override
     public List<Class<?>> getCommands() {
-        List<Class<?>> cmdList = new ArrayList<>();
+        List<Class<?>> cmdList = new ArrayList<Class<?>>();
         cmdList.add(AddVmwareDcCmd.class);
         cmdList.add(UpdateVmwareDcCmd.class);
         cmdList.add(RemoveVmwareDcCmd.class);
@@ -1096,14 +1114,13 @@ public List<Class<?>> getCommands() {
         cmdList.add(ListVsphereStoragePoliciesCmd.class);
         cmdList.add(ListVsphereStoragePolicyCompatiblePoolsCmd.class);
         cmdList.add(ListVmwareDcVmsCmd.class);
-        cmdList.add(ListVmwareDcHostsCmd.class);
         return cmdList;
     }
 
     @Override
     @DB
     public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException {
-        VmwareDatacenterVO vmwareDc;
+        VmwareDatacenterVO vmwareDc = null;
         Long zoneId = cmd.getZoneId();
         String userName = cmd.getUsername();
         String password = cmd.getPassword();
@@ -1159,10 +1176,10 @@ public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws Resourc
         checkIfDcIsUsed(vCenterHost, vmwareDcName, zoneId);
 
         VmwareContext context = null;
-        DatacenterMO dcMo;
+        DatacenterMO dcMo = null;
         String dcCustomFieldValue;
         boolean addDcCustomFieldDef = false;
-        boolean dcInUse;
+        boolean dcInUse = false;
         String guid;
         ManagedObjectReference dcMor;
         try {
@@ -1195,7 +1212,7 @@ public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws Resourc
                 // Map zone with vmware datacenter
             vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId());
 
-            vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap);
+            vmwareDcZoneMap = vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap);
 
             // Set custom field for this DC
             if (addDcCustomFieldDef) {
@@ -1215,6 +1232,7 @@ public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws Resourc
             if (context != null) {
                 context.close();
             }
+            context = null;
         }
         importVsphereStoragePoliciesInternal(zoneId, vmwareDc.getId());
         return vmwareDc;
@@ -1239,9 +1257,9 @@ VmwareDatacenterVO createOrUpdateDc(String guid, String name, String host, Strin
      * Check if DC is already part of zone
      * In that case vmware_data_center table should have the DC and a dc zone mapping should exist
      *
-     * @param vCenterHost the vcenter appliance hostname
-     * @param vmwareDcName the name of the vmware DC
-     * @param zoneId zone that the DC should be connected to
+     * @param vCenterHost
+     * @param vmwareDcName
+     * @param zoneId
      * @throws ResourceInUseException if the DC can not be used.
      */
     private void checkIfDcIsUsed(String vCenterHost, String vmwareDcName, Long zoneId) throws ResourceInUseException {
@@ -1249,7 +1267,7 @@ private void checkIfDcIsUsed(String vCenterHost, String vmwareDcName, Long zoneI
         vmwareDc = vmwareDcDao.getVmwareDatacenterByGuid(vmwareDcName + "@" + vCenterHost);
         if (vmwareDc != null) {
             VmwareDatacenterZoneMapVO mapping = vmwareDatacenterZoneMapDao.findByVmwareDcId(vmwareDc.getId());
-            if (mapping != null && zoneId == mapping.getZoneId()) {
+            if (mapping != null && Long.compare(zoneId, mapping.getZoneId()) == 0) {
                 throw new ResourceInUseException(String.format("This DC (%s) is already part of other CloudStack zone (%d). Cannot add this DC to more zones.", vmwareDc.getUuid(), zoneId));
             }
         }
@@ -1258,7 +1276,7 @@ private void checkIfDcIsUsed(String vCenterHost, String vmwareDcName, Long zoneI
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "updating VMware datacenter")
     public VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd cmd) {
-        final long zoneId = cmd.getZoneId();
+        final Long zoneId = cmd.getZoneId();
         final String userName = cmd.getUsername();
         final String password = cmd.getPassword();
         final String vCenterHost = cmd.getVcenter();
@@ -1286,7 +1304,7 @@ public VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd cmd) {
         }
         vmwareDc.setGuid(String.format("%s@%s", vmwareDc.getVmwareDatacenterName(), vmwareDc.getVcenterHost()));
 
-        return Transaction.execute(new TransactionCallback<>() {
+        return Transaction.execute(new TransactionCallback<VmwareDatacenter>() {
             @Override
             public VmwareDatacenter doInTransaction(TransactionStatus status) {
                 if (vmwareDcDao.update(vmwareDc.getId(), vmwareDc)) {
@@ -1335,7 +1353,7 @@ public boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws ResourceInUs
         String vCenterHost;
         String userName;
         String password;
-        DatacenterMO dcMo;
+        DatacenterMO dcMo = null;
         final VmwareDatacenterZoneMapVO vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
         // Check if zone is associated with VMware DC
         if (vmwareDcZoneMap == null) {
@@ -1372,9 +1390,11 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
                 throw new DiscoveryException(msg);
             }
 
+            assert (dcMo != null);
+
             // Reset custom field property cloud.zone over this DC
             dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "false");
-            s_logger.info("Successfully reset custom field property cloud.zone over DC " + vmwareDcName);
+            s_logger.info("Sucessfully reset custom field property cloud.zone over DC " + vmwareDcName);
         } catch (Exception e) {
             String msg = "Unable to reset custom field property cloud.zone over DC " + vmwareDcName + " due to : " + VmwareHelper.getExceptionMessage(e);
             s_logger.error(msg);
@@ -1383,6 +1403,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
             if (context != null) {
                 context.close();
             }
+            context = null;
         }
         return true;
     }
@@ -1403,7 +1424,7 @@ private void validateZone(Long zoneId) throws InvalidParameterValueException {
     private void validateZoneWithResources(Long zoneId, String errStr) throws ResourceInUseException {
         // Check if zone has resources? - For now look for clusters
         List<ClusterVO> clusters = clusterDao.listByZoneId(zoneId);
-        if (!CollectionUtils.isNullOrEmpty(clusters)) {
+        if (clusters != null && clusters.size() > 0) {
             // Look for VMware hypervisor.
             for (ClusterVO cluster : clusters) {
                 if (cluster.getHypervisorType().equals(HypervisorType.VMware)) {
@@ -1424,9 +1445,9 @@ public boolean isLegacyZone(long dcId) {
     }
 
     @Override
-    public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException {
+    public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException, InvalidParameterValueException {
         Long zoneId = cmd.getZoneId();
-        List<VmwareDatacenterVO> vmwareDcList = new ArrayList<>();
+        List<VmwareDatacenterVO> vmwareDcList = new ArrayList<VmwareDatacenterVO>();
         VmwareDatacenterZoneMapVO vmwareDcZoneMap;
         VmwareDatacenterVO vmwareDatacenter;
         long vmwareDcId;
@@ -1484,7 +1505,7 @@ public List<? extends VsphereStoragePolicy> importVsphereStoragePoliciesInternal
         String vCenterHost = vmwareDatacenter.getVcenterHost();
         String userName = vmwareDatacenter.getUser();
         String password = vmwareDatacenter.getPassword();
-        List<PbmProfile> storageProfiles;
+        List<PbmProfile> storageProfiles = null;
         try {
             s_logger.debug(String.format("Importing vSphere Storage Policies for the vmware DC %d in zone %d", vmwareDcId, zoneId));
             VmwareContext context = VmwareContextFactory.getContext(vCenterHost, userName, password);
@@ -1512,15 +1533,16 @@ public List<? extends VsphereStoragePolicy> importVsphereStoragePoliciesInternal
         List<VsphereStoragePolicyVO> allStoragePolicies = vsphereStoragePolicyDao.listAll();
         List<PbmProfile> finalStorageProfiles = storageProfiles;
         List<VsphereStoragePolicyVO> needToMarkRemoved = allStoragePolicies.stream()
-                .filter(existingPolicy -> finalStorageProfiles.stream()
-                    .noneMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId())))
+                .filter(existingPolicy -> !finalStorageProfiles.stream()
+                    .anyMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId())))
                 .collect(Collectors.toList());
 
         for (VsphereStoragePolicyVO storagePolicy : needToMarkRemoved) {
             vsphereStoragePolicyDao.remove(storagePolicy.getId());
         }
 
-        return vsphereStoragePolicyDao.listAll();
+        List<VsphereStoragePolicyVO> storagePolicies = vsphereStoragePolicyDao.listAll();
+        return storagePolicies;
     }
 
     @Override
@@ -1566,87 +1588,13 @@ public List<StoragePool> listVsphereStoragePolicyCompatibleStoragePools(ListVsph
     }
 
     @Override
-    public List<HostMO> listHostsInDatacenter(ListVmwareDcHostsCmd cmd) {
-        VcenterData vmwaredc = getVcenterData(cmd);
-
-        try {
-            VmwareContext context = getVmwareContext(vmwaredc);
-            DatacenterMO dcMo = getDatacenterMO(context, vmwaredc);
-            return dcMo.getAllHostsOnDatacenter();
-        } catch (RuntimeFaultFaultMsg | URISyntaxException | VmwareClientException | InvalidLocaleFaultMsg |
-                 InvalidLoginFaultMsg | InvalidPropertyFaultMsg e) {
-            String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
-                    vmwaredc.vcenter, vmwaredc.datacenterName, e.getMessage());
-            s_logger.error(errorMsg, e);
-            throw new CloudRuntimeException(errorMsg);
-        }
-
-    }
-
-    @Override
-    public Pair<String, List<UnmanagedInstanceTO>> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) {
-        Integer maxObjects = cmd.getBatchSize();
-        String token = cmd.getToken();
-        String host = cmd.getHost();
-
-        VcenterData vmwaredc = getVcenterData(cmd);
-
-        try {
-            VmwareContext context = getVmwareContext(vmwaredc);
-
-            DatacenterMO dcMo = getDatacenterMO(context, vmwaredc);
-
-            if (com.cloud.utils.StringUtils.isNotBlank(host)) {
-                ManagedObjectReference hostMor = dcMo.findHost(host);
-                if (hostMor == null) {
-                    throw new VmwareClientException(String.format("No host '%s' found on DC: %s.", host, dcMo.getName()));
-                }
-                HostMO hostMo = new HostMO(context, hostMor);
-                return hostMo.getVms(maxObjects, token);
-            } else {
-                return dcMo.getVms(maxObjects, token);
-            }
-        } catch (InvalidParameterValueException | VmwareClientException | InvalidLocaleFaultMsg | InvalidLoginFaultMsg |
-                 RuntimeFaultFaultMsg | URISyntaxException | InvalidPropertyFaultMsg | InvocationTargetException |
-                 NoSuchMethodException | IllegalAccessException e) {
-            String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
-                    vmwaredc.vcenter, vmwaredc.datacenterName, e.getMessage());
-            s_logger.error(errorMsg, e);
-            throw new CloudRuntimeException(errorMsg);
-        }
-    }
-
-    @NotNull
-    private static DatacenterMO getDatacenterMO(VmwareContext context, VcenterData vmwaredc) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
-        DatacenterMO dcMo = new DatacenterMO(context, vmwaredc.datacenterName);
-        ManagedObjectReference dcMor = dcMo.getMor();
-        if (dcMor == null) {
-            String msg = String.format("Unable to find VMware datacenter %s in vCenter %s",
-                    vmwaredc.datacenterName, vmwaredc.vcenter);
-            s_logger.error(msg);
-            throw new InvalidParameterValueException(msg);
-        }
-        return dcMo;
-    }
-
-    @NotNull
-    private static VmwareContext getVmwareContext(VcenterData vmwaredc) throws RuntimeFaultFaultMsg, URISyntaxException, VmwareClientException, InvalidLocaleFaultMsg, InvalidLoginFaultMsg {
-        s_logger.debug(String.format("Connecting to the VMware datacenter %s at vCenter %s to retrieve VMs",
-                vmwaredc.datacenterName, vmwaredc.vcenter));
-        String serviceUrl = String.format("https://%s/sdk/vimService", vmwaredc.vcenter);
-        VmwareClient vimClient = new VmwareClient(vmwaredc.vcenter);
-        vimClient.connect(serviceUrl, vmwaredc.username, vmwaredc.password);
-        VmwareContext context = new VmwareContext(vimClient, vmwaredc.vcenter);
-        return context;
-    }
-
-    @NotNull
-    private VcenterData getVcenterData(ListVmwareDcItems cmd) {
+    public List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) {
         String vcenter = cmd.getVcenter();
         String datacenterName = cmd.getDatacenterName();
         String username = cmd.getUsername();
         String password = cmd.getPassword();
         Long existingVcenterId = cmd.getExistingVcenterId();
+        String keyword = cmd.getKeyword();
 
         if ((existingVcenterId == null && StringUtils.isBlank(vcenter)) ||
                 (existingVcenterId != null && StringUtils.isNotBlank(vcenter))) {
@@ -1667,27 +1615,37 @@ private VcenterData getVcenterData(ListVmwareDcItems cmd) {
             username = vmwareDc.getUser();
             password = vmwareDc.getPassword();
         }
-        VcenterData vmwaredc = new VcenterData(vcenter, datacenterName, username, password);
-        return vmwaredc;
-    }
 
-    private static class VcenterData {
-        public final String vcenter;
-        public final String datacenterName;
-        public final String username;
-        public final String password;
-
-        public VcenterData(String vcenter, String datacenterName, String username, String password) {
-            this.vcenter = vcenter;
-            this.datacenterName = datacenterName;
-            this.username = username;
-            this.password = password;
+        try {
+            s_logger.debug(String.format("Connecting to the VMware datacenter %s at vCenter %s to retrieve VMs",
+                    datacenterName, vcenter));
+            String serviceUrl = String.format("https://%s/sdk/vimService", vcenter);
+            VmwareClient vimClient = new VmwareClient(vcenter);
+            vimClient.connect(serviceUrl, username, password);
+            VmwareContext context = new VmwareContext(vimClient, vcenter);
+
+            DatacenterMO dcMo = new DatacenterMO(context, datacenterName);
+            ManagedObjectReference dcMor = dcMo.getMor();
+            if (dcMor == null) {
+                String msg = String.format("Unable to find VMware datacenter %s in vCenter %s",
+                        datacenterName, vcenter);
+                s_logger.error(msg);
+                throw new InvalidParameterValueException(msg);
+            }
+            List<UnmanagedInstanceTO> instances = dcMo.getAllVmsOnDatacenter();
+            return StringUtils.isBlank(keyword) ? instances :
+                    instances.stream().filter(x -> x.getName().toLowerCase().contains(keyword.toLowerCase())).collect(Collectors.toList());
+        } catch (Exception e) {
+            String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
+                    vcenter, datacenterName, e.getMessage());
+            s_logger.error(errorMsg, e);
+            throw new CloudRuntimeException(errorMsg);
         }
     }
 
     @Override
     public boolean hasNexusVSM(Long clusterId) {
-        ClusterVSMMapVO vsmMapVo;
+        ClusterVSMMapVO vsmMapVo = null;
 
         vsmMapVo = _vsmMapDao.findByClusterId(clusterId);
         if (vsmMapVo == null) {
@@ -1737,7 +1695,7 @@ private void startTemplateCleanJobSchedule() {
     }
 
     /**
-     * This task is to clean-up templates from primary storage that are otherwise not cleaned by the {@see com.cloud.storage.StorageManagerImpl.StorageGarbageCollector}.
+     * This task is to cleanup templates from primary storage that are otherwise not cleaned by the {@link com.cloud.storage.StorageManagerImpl.StorageGarbageCollector}.
      * it is called at regular intervals when storage.template.cleanup.enabled == true
      * It collect all templates that
      * - are deleted from cloudstack
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
index 5da2c7b70033..9f4985a1363b 100644
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
@@ -37,8 +37,8 @@
 import com.cloud.user.Account;
 import com.cloud.utils.exception.CloudRuntimeException;
 
-@APICommand(name = "addVmwareDc", description = "Adds a Vmware datacenter to specified zone",
-        responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false)
+@APICommand(name = "addVmwareDc", description = "Adds a VMware datacenter to specified zone", responseObject = VmwareDatacenterResponse.class,
+        requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
 public class AddVmwareDcCmd extends BaseCmd {
 
     @Inject
@@ -47,7 +47,7 @@ public class AddVmwareDcCmd extends BaseCmd {
     public static final Logger s_logger = Logger.getLogger(AddVmwareDcCmd.class.getName());
 
 
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of Vmware datacenter to be added to specified zone.")
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of VMware datacenter to be added to specified zone.")
     private String name;
 
     @Parameter(name = ApiConstants.VCENTER,
@@ -56,10 +56,10 @@ public class AddVmwareDcCmd extends BaseCmd {
                description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
     private String vCenter;
 
-    @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
+    @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = false, description = "The Username required to connect to resource.")
     private String username;
 
-    @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
+    @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = false, description = "The password for specified username.")
     private String password;
 
     @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "The Zone ID.")
@@ -101,7 +101,7 @@ public void execute() {
                 response.setResponseName(getCommandName());
                 response.setObjectName("vmwaredc");
             } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Vmware Datacenter to zone.");
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add VMware Datacenter to zone.");
             }
             this.setResponseObject(response);
         } catch (DiscoveryException ex) {
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java
index 40b479f809cc..c7ba63c02a77 100644
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java
@@ -37,6 +37,7 @@
 import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import javax.inject.Inject;
 import java.util.ArrayList;
@@ -48,6 +49,9 @@
         authorized = {RoleType.Admin})
 public class ImportVsphereStoragePoliciesCmd extends BaseCmd {
 
+    public static final Logger LOGGER = Logger.getLogger(ImportVsphereStoragePoliciesCmd.class.getName());
+
+
     @Inject
     public VmwareDatacenterService _vmwareDatacenterService;
 
@@ -72,13 +76,6 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
 
         List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.importVsphereStoragePolicies(this);
         final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
-        final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = getVsphereStoragePoliciesResponses(storagePolicies, dataCenter);
-        responseList.setResponses(storagePoliciesResponseList);
-        responseList.setResponseName(getCommandName());
-        setResponseObject(responseList);
-    }
-
-    private static List<VsphereStoragePoliciesResponse> getVsphereStoragePoliciesResponses(List<? extends VsphereStoragePolicy> storagePolicies, DataCenter dataCenter) {
         final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
         for (VsphereStoragePolicy storagePolicy : storagePolicies) {
             final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
@@ -91,7 +88,9 @@ private static List<VsphereStoragePoliciesResponse> getVsphereStoragePoliciesRes
 
             storagePoliciesResponseList.add(storagePoliciesResponse);
         }
-        return storagePoliciesResponseList;
+        responseList.setResponses(storagePoliciesResponseList);
+        responseList.setResponseName(getCommandName());
+        setResponseObject(responseList);
     }
 
     @Override
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java
deleted file mode 100644
index 6f193c9c1b27..000000000000
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.zone;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.vmware.VmwareDatacenterService;
-import com.cloud.hypervisor.vmware.mo.HostMO;
-import com.cloud.user.Account;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-import com.vmware.vim25.InvalidPropertyFaultMsg;
-import com.vmware.vim25.RuntimeFaultFaultMsg;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-
-import javax.inject.Inject;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-
-@APICommand(name = "listVmwareDcHosts", responseObject = VmwareRequestResponse.class,
-        description = "Lists the VMs in a Vmware Datacenter",
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ListVmwareDcHostsCmd extends BaseCmd implements ListVmwareDcItems {
-
-    @Inject
-    public VmwareDatacenterService _vmwareDatacenterService;
-
-    @Parameter(name = ApiConstants.EXISTING_VCENTER_ID,
-            type = CommandType.UUID,
-            entityType = VmwareDatacenterResponse.class,
-            description = "UUID of a linked existing vCenter")
-    private Long existingVcenterId;
-
-    @Parameter(name = ApiConstants.VCENTER,
-            type = CommandType.STRING,
-            description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
-    private String vcenter;
-
-    @Parameter(name = ApiConstants.DATACENTER_NAME, type = CommandType.STRING, description = "Name of Vmware datacenter.")
-    private String datacenterName;
-
-    @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
-    private String username;
-
-    @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
-    private String password;
-
-    public String getVcenter() {
-        return vcenter;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public String getDatacenterName() {
-        return datacenterName;
-    }
-
-    public Long getExistingVcenterId() {
-        return existingVcenterId;
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
-        checkParameters();
-        try {
-            List<HostMO> hosts = _vmwareDatacenterService.listHostsInDatacenter(this);
-            List<BaseResponse> baseResponseList = new ArrayList<>();
-            if (CollectionUtils.isNotEmpty(hosts)) {
-                for (HostMO vmwareHost : hosts) {
-                    HostResponse resp = createHostResponse(vmwareHost);
-                    baseResponseList.add(resp);
-                }
-            }
-            VmwareRequestResponse<BaseResponse> response = new VmwareRequestResponse<>();
-            response.setResponses(baseResponseList, baseResponseList.size());
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } catch (CloudRuntimeException | InvalidPropertyFaultMsg | RuntimeFaultFaultMsg | InvocationTargetException |
-                 NoSuchMethodException | IllegalAccessException e) {
-            String errorMsg = String.format("Error retrieving VMs from Vmware VC: %s", e.getMessage());
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
-        }
-    }
-
-    private HostResponse createHostResponse(HostMO hostInstance) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
-        HostResponse response = new HostResponse();
-        response.setHypervisor(Hypervisor.HypervisorType.VMware.toString());
-        response.setName(hostInstance.getHostName());
-        response.setObjectName("host");
-        return response;
-    }
-
-    private void checkParameters() {
-        if ((existingVcenterId == null && vcenter == null) || (existingVcenterId != null && vcenter != null)) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
-                    "Please provide an existing vCenter ID or a vCenter IP/Name, parameters are mutually exclusive");
-        }
-        if (existingVcenterId == null && StringUtils.isAnyBlank(vcenter, datacenterName, username, password)) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
-                    "Please set all the information for a vCenter IP/Name, datacenter, username and password");
-        }
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-}
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcItems.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcItems.java
deleted file mode 100644
index 580fb3bad9bd..000000000000
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcItems.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.zone;
-
-public interface ListVmwareDcItems {
-    String getVcenter();
-
-    String getDatacenterName();
-
-    String getUsername();
-
-    String getPassword();
-
-    Long getExistingVcenterId();
-}
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java
index 544e756fe807..4dd1b4beb091 100644
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java
@@ -23,15 +23,15 @@
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.hypervisor.vmware.VmwareDatacenterService;
 import com.cloud.user.Account;
-import com.cloud.utils.Pair;
 import com.cloud.utils.exception.CloudRuntimeException;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseListCmd;
 import org.apache.cloudstack.api.BaseResponse;
 import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.api.response.UnmanagedInstanceResponse;
 import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
 import org.apache.cloudstack.vm.UnmanagedInstanceTO;
@@ -42,10 +42,10 @@
 import java.util.ArrayList;
 import java.util.List;
 
-@APICommand(name = "listVmwareDcVms", responseObject = VmwareRequestResponse.class,
-        description = "Lists the VMs in a Vmware Datacenter",
+@APICommand(name = "listVmwareDcVms", responseObject = UnmanagedInstanceResponse.class,
+        description = "Lists the VMs in a VMware Datacenter",
         requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ListVmwareDcVmsCmd extends BaseCmd  implements ListVmwareDcItems {
+public class ListVmwareDcVmsCmd extends BaseListCmd {
 
     @Inject
     public VmwareDatacenterService _vmwareDatacenterService;
@@ -61,7 +61,7 @@ public class ListVmwareDcVmsCmd extends BaseCmd  implements ListVmwareDcItems {
             description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
     private String vcenter;
 
-    @Parameter(name = ApiConstants.DATACENTER_NAME, type = CommandType.STRING, description = "Name of Vmware datacenter.")
+    @Parameter(name = ApiConstants.DATACENTER_NAME, type = CommandType.STRING, description = "Name of VMware datacenter.")
     private String datacenterName;
 
     @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
@@ -70,18 +70,6 @@ public class ListVmwareDcVmsCmd extends BaseCmd  implements ListVmwareDcItems {
     @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
     private String password;
 
-    @Parameter(name = ApiConstants.HOST, type = CommandType.STRING, description = "get only the VMs from the specified host.")
-    private String host;
-
-    @Parameter(name = ApiConstants.BATCH_SIZE, type = CommandType.INTEGER, description = "The maximum number of results to return.")
-    private Integer batchSize;
-
-    @Parameter(name = ApiConstants.TOKEN, type = CommandType.STRING,
-            description = "For listVmwareDcVms, if the maximum number of results (the `batchsize`) is exceeded, " +
-                    " a token is returned. This token can be used in subsequent calls to retrieve more results." +
-                    " As long as a token is returned, more results can be retrieved.")
-    private String token;
-
     public String getVcenter() {
         return vcenter;
     }
@@ -94,18 +82,6 @@ public String getPassword() {
         return password;
     }
 
-    public Integer getBatchSize() {
-        return batchSize;
-    }
-
-    public String getHost() {
-        return host;
-    }
-
-    public String getToken() {
-        return token;
-    }
-
     public String getDatacenterName() {
         return datacenterName;
     }
@@ -118,8 +94,7 @@ public Long getExistingVcenterId() {
     public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
         checkParameters();
         try {
-            Pair<String, List<UnmanagedInstanceTO>> results = _vmwareDatacenterService.listVMsInDatacenter(this);
-            List<UnmanagedInstanceTO> vms = results.second();
+            List<UnmanagedInstanceTO> vms = _vmwareDatacenterService.listVMsInDatacenter(this);
             List<BaseResponse> baseResponseList = new ArrayList<>();
             if (CollectionUtils.isNotEmpty(vms)) {
                 for (UnmanagedInstanceTO vmwareVm : vms) {
@@ -127,13 +102,16 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
                     baseResponseList.add(resp);
                 }
             }
-            VmwareRequestResponse<BaseResponse> response = new VmwareRequestResponse<>();
-            response.setResponses(baseResponseList, baseResponseList.size());
+            List<BaseResponse> pagingList = com.cloud.utils.StringUtils.applyPagination(baseResponseList, this.getStartIndex(), this.getPageSizeVal());
+            if (CollectionUtils.isEmpty(pagingList)) {
+                pagingList = baseResponseList;
+            }
+            ListResponse<BaseResponse> response = new ListResponse<>();
+            response.setResponses(pagingList, baseResponseList.size());
             response.setResponseName(getCommandName());
-            response.setToken(results.first());
             setResponseObject(response);
         } catch (CloudRuntimeException e) {
-            String errorMsg = String.format("Error retrieving VMs from Vmware VC: %s", e.getMessage());
+            String errorMsg = String.format("Error retrieving VMs from VMware VC: %s", e.getMessage());
             throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
         }
     }
@@ -156,6 +134,6 @@ public long getEntityOwnerId() {
 
     @Override
     public String getCommandName() {
-        return "listVmwareDcVmsResponse".toLowerCase();
+        return "listvmwaredcvmsresponse";
     }
 }
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java
index 9f7c4cf2944e..61b5210bb3a5 100644
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java
@@ -43,7 +43,7 @@
 import com.cloud.hypervisor.vmware.VmwareDatacenterService;
 import com.cloud.user.Account;
 
-@APICommand(name = "listVmwareDcs", responseObject = VmwareDatacenterResponse.class, description = "Retrieves Vmware DC(s) associated with a zone.",
+@APICommand(name = "listVmwareDcs", responseObject = VmwareDatacenterResponse.class, description = "Retrieves VMware DC(s) associated with a zone.",
         requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
 public class ListVmwareDcsCmd extends BaseListCmd {
 
@@ -52,6 +52,7 @@ public class ListVmwareDcsCmd extends BaseListCmd {
 
     public static final Logger s_logger = Logger.getLogger(ListVmwareDcsCmd.class.getName());
 
+
     /////////////////////////////////////////////////////
     //////////////// API parameters /////////////////////
     /////////////////////////////////////////////////////
@@ -74,27 +75,20 @@ public Long getZoneId() {
     @Override
     public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
         ResourceAllocationException {
-        List<? extends VmwareDatacenter> vmwareDcList;
+        List<? extends VmwareDatacenter> vmwareDcList = null;
 
         try {
             vmwareDcList = _vmwareDatacenterService.listVmwareDatacenters(this);
         } catch (InvalidParameterValueException ie) {
             throw new InvalidParameterValueException("Invalid zone id " + getZoneId());
         } catch (Exception e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find associated Vmware DCs associated with zone " + getZoneId());
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find associated VMware DCs associated with zone " + getZoneId());
         }
 
-        ListResponse<VmwareDatacenterResponse> response = new ListResponse<>();
-        List<VmwareDatacenterResponse> vmwareDcResponses = getVmwareDatacenterResponses(vmwareDcList);
-        response.setResponses(vmwareDcResponses);
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-    }
+        ListResponse<VmwareDatacenterResponse> response = new ListResponse<VmwareDatacenterResponse>();
+        List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<VmwareDatacenterResponse>();
 
-    private List<VmwareDatacenterResponse> getVmwareDatacenterResponses(List<? extends VmwareDatacenter> vmwareDcList) {
-        List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<>();
-
-        if (vmwareDcList != null && !vmwareDcList.isEmpty()) {
+        if (vmwareDcList != null && vmwareDcList.size() > 0) {
             for (VmwareDatacenter vmwareDc : vmwareDcList) {
                 VmwareDatacenterResponse vmwareDcResponse = new VmwareDatacenterResponse();
 
@@ -102,12 +96,14 @@ private List<VmwareDatacenterResponse> getVmwareDatacenterResponses(List<? exten
                 vmwareDcResponse.setVcenter(vmwareDc.getVcenterHost());
                 vmwareDcResponse.setName(vmwareDc.getVmwareDatacenterName());
                 vmwareDcResponse.setZoneId(getZoneId());
-                vmwareDcResponse.setObjectName(ApiConstants.VMWARE_DC);
+                vmwareDcResponse.setObjectName("VMwareDC");
 
                 vmwareDcResponses.add(vmwareDcResponse);
             }
         }
-        return vmwareDcResponses;
+        response.setResponses(vmwareDcResponses);
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
     }
 
     @Override
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java
index 35631ba1315a..ac909a0dc647 100644
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java
@@ -36,6 +36,7 @@
 import org.apache.cloudstack.api.response.VsphereStoragePoliciesResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import javax.inject.Inject;
 import java.util.ArrayList;
@@ -47,6 +48,9 @@
         authorized = {RoleType.Admin})
 public class ListVsphereStoragePoliciesCmd extends BaseCmd {
 
+    public static final Logger LOGGER = Logger.getLogger(ListVsphereStoragePoliciesCmd.class.getName());
+
+
     @Inject
     public VmwareDatacenterService _vmwareDatacenterService;
 
@@ -71,13 +75,6 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
 
         List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.listVsphereStoragePolicies(this);
         final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
-        final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = getVsphereStoragePoliciesResponses(storagePolicies, dataCenter);
-        responseList.setResponses(storagePoliciesResponseList);
-        responseList.setResponseName(getCommandName());
-        setResponseObject(responseList);
-    }
-
-    private static List<VsphereStoragePoliciesResponse> getVsphereStoragePoliciesResponses(List<? extends VsphereStoragePolicy> storagePolicies, DataCenter dataCenter) {
         final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
         for (VsphereStoragePolicy storagePolicy : storagePolicies) {
             final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
@@ -86,11 +83,13 @@ private static List<VsphereStoragePoliciesResponse> getVsphereStoragePoliciesRes
             storagePoliciesResponse.setName(storagePolicy.getName());
             storagePoliciesResponse.setPolicyId(storagePolicy.getPolicyId());
             storagePoliciesResponse.setDescription(storagePolicy.getDescription());
-            storagePoliciesResponse.setObjectName(ApiConstants.STORAGE_POLICY);
+            storagePoliciesResponse.setObjectName("StoragePolicy");
 
             storagePoliciesResponseList.add(storagePoliciesResponse);
         }
-        return storagePoliciesResponseList;
+        responseList.setResponses(storagePoliciesResponseList);
+        responseList.setResponseName(getCommandName());
+        setResponseObject(responseList);
     }
 
     @Override
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java
index ab697fbad67f..d66972ded2e7 100644
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java
@@ -68,7 +68,7 @@ public void execute() throws ServerApiException, ConcurrentOperationException {
         List<StoragePoolResponse> poolResponses = new ArrayList<>();
         for (StoragePool pool : pools) {
             StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
-            poolResponse.setObjectName(ApiConstants.STORAGE_POOL);
+            poolResponse.setObjectName("storagepool");
             poolResponses.add(poolResponse);
         }
         response.setResponses(poolResponses);
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
index d15369d2983a..735d00d6ca99 100644
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
@@ -35,7 +35,7 @@
 import com.cloud.user.Account;
 import com.cloud.utils.exception.CloudRuntimeException;
 
-@APICommand(name = "removeVmwareDc", responseObject = SuccessResponse.class, description = "Remove a Vmware datacenter from a zone.",
+@APICommand(name = "removeVmwareDc", responseObject = SuccessResponse.class, description = "Remove a VMware datacenter from a zone.",
         requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
 public class RemoveVmwareDcCmd extends BaseCmd {
 
@@ -49,7 +49,7 @@ public class RemoveVmwareDcCmd extends BaseCmd {
                type = CommandType.UUID,
                entityType = ZoneResponse.class,
                required = true,
-               description = "The id of Zone from which Vmware datacenter has to be removed.")
+               description = "The id of Zone from which VMware datacenter has to be removed.")
     private Long zoneId;
 
     public Long getZoneId() {
@@ -65,10 +65,10 @@ public void execute() {
                 response.setResponseName(getCommandName());
                 setResponseObject(response);
             } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove Vmware datacenter from zone");
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove VMware datacenter from zone");
             }
         } catch (ResourceInUseException ex) {
-            s_logger.warn("The zone has one or more resources (like cluster), hence not able to remove Vmware datacenter from zone."
+            s_logger.warn("The zone has one or more resources (like cluster), hence not able to remove VMware datacenter from zone."
                 + " Please remove all resource from zone, and retry. Exception: ", ex);
             ServerApiException e = new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
             for (String proxyObj : ex.getIdProxyList()) {
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java
index 5e02d5a96c20..2b6cf5984c51 100644
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java
@@ -28,15 +28,18 @@
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.log4j.Logger;
 
 import com.cloud.dc.VmwareDatacenter;
 import com.cloud.hypervisor.vmware.VmwareDatacenterService;
 import com.cloud.user.Account;
 
-@APICommand(name = "updateVmwareDc", description = "Updates a Vmware datacenter details for a zone",
+@APICommand(name = "updateVmwareDc", description = "Updates a VMware datacenter details for a zone",
         responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false,
         since = "4.12.0", authorized = {RoleType.Admin})
 public class UpdateVmwareDcCmd extends BaseCmd {
+    public static final Logger LOG = Logger.getLogger(UpdateVmwareDcCmd.class);
+
 
     @Inject
     public VmwareDatacenterService vmwareDatacenterService;
@@ -50,7 +53,7 @@ public class UpdateVmwareDcCmd extends BaseCmd {
     private Long zoneId;
 
     @Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
-            description = "Vmware datacenter name.")
+            description = "VMware datacenter name.")
     private String name;
 
     @Parameter(name = ApiConstants.VCENTER, type = CommandType.STRING,
@@ -105,13 +108,13 @@ public Boolean isRecursive() {
     public void execute() {
         final VmwareDatacenter vmwareDatacenter = vmwareDatacenterService.updateVmwareDatacenter(this);
         if (vmwareDatacenter == null) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update Vmware datacenter");
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update VMware datacenter");
         }
         final VmwareDatacenterResponse response = new VmwareDatacenterResponse();
         response.setId(vmwareDatacenter.getUuid());
         response.setName(vmwareDatacenter.getVmwareDatacenterName());
         response.setResponseName(getCommandName());
-        response.setObjectName(ApiConstants.VMWARE_DC);
+        response.setObjectName("vmwaredc");
         setResponseObject(response);
     }
 
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestResponse.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestResponse.java
deleted file mode 100644
index 81c58ef27baf..000000000000
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestResponse.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.api.command.admin.zone;
-
-import com.cloud.serializer.Param;
-import com.google.gson.annotations.SerializedName;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ResponseObject;
-import org.apache.cloudstack.api.response.ListResponse;
-
-public class VmwareRequestResponse<T extends ResponseObject> extends ListResponse<T> {
-    @SerializedName(ApiConstants.TOKEN)
-    @Param(description = "The Vmware API token to use for retrieving further responses with")
-    private String token;
-
-    public String getToken() {
-        return token;
-    }
-
-    public void setToken(String token) {
-        this.token = token;
-    }
-}
diff --git a/test/integration/smoke/test_dynamicroles.py b/test/integration/smoke/test_dynamicroles.py
index 39f995a14a3b..b91ba9c2eba8 100644
--- a/test/integration/smoke/test_dynamicroles.py
+++ b/test/integration/smoke/test_dynamicroles.py
@@ -73,7 +73,6 @@ def __init__(self):
                 "listApis": "allow",
                 "listAccounts": "allow",
                 "listClusters": "deny",
-                "*VmwareDc*": "allow",
                 "*VM*": "allow",
                 "*Host*": "deny"
             }
diff --git a/ui/src/views/tools/ManageInstances.vue b/ui/src/views/tools/ManageInstances.vue
index 27ad4cc96960..2ff9052d8b98 100644
--- a/ui/src/views/tools/ManageInstances.vue
+++ b/ui/src/views/tools/ManageInstances.vue
@@ -1184,7 +1184,6 @@ export default {
         } else {
           params.existingvcenterid = this.selectedVmwareVcenter.existingvcenterid
         }
-        params.host = this.selectedVmwareVcenter.host
       }
 
       api(apiName, params).then(json => {
diff --git a/ui/src/views/tools/SelectVmwareVcenter.vue b/ui/src/views/tools/SelectVmwareVcenter.vue
index e93d893e9fca..806186557190 100644
--- a/ui/src/views/tools/SelectVmwareVcenter.vue
+++ b/ui/src/views/tools/SelectVmwareVcenter.vue
@@ -129,33 +129,11 @@
         &nbsp;
         <tooltip-label :title="$t('label.press.enter')" :tooltip="$t('label.press.enter.tooltip')"/>
       </div>
-      <div
-        v-if="selectedExistingVcenterId || (vcenterSelectedOption === 'new')">
-        <a-form-item :label="$t('label.esx.host')" ref="host" name="host" v-if="hosts.length > 0">
-          <a-select
-            v-model:value="form.host"
-            :loading="loading"
-            optionFilterProp="label"
-            :filterOption="(input, option) => {
-              return  option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
-            }"
-            :placeholder="$t('label.esx.host')"
-            @change="onSelectExistingVmwareHost">
-            <a-select-option key="" label="">{{ }}</a-select-option>
-            <a-select-option v-for="opt in hosts" :key="opt.name">
-                {{ 'ESXi: ' + opt.name }}
-            </a-select-option>
-          </a-select>
-        </a-form-item>
-        <div v-else>
-          {{ $t('message.list.zone.vmware.hosts.empty') }}
-        </div>
-      </div>
       <div class="card-footer">
         <a-button
           v-if="vcenterSelectedOption == 'existing' || vcenterSelectedOption == 'new'"
           :disabled="(vcenterSelectedOption === 'new' && (vcenter === '' || datacentername === '' || username === '' || password === '')) ||
-            (vcenterSelectedOption === 'existing' && selectedExistingVcenterId === '') && host === ''"
+            (vcenterSelectedOption === 'existing' && selectedExistingVcenterId === '')"
           :loading="loading"
           type="primary"
           @click="listVmwareDatacenterVms">{{ $t('label.list.vmware.vcenter.vms') }}</a-button>
@@ -186,8 +164,6 @@ export default {
       zones: {},
       vcenterSelectedOption: '',
       existingvcenter: [],
-      hosts: [],
-      selectedHost: '',
       selectedExistingVcenterId: '',
       selectedPoweredOnVm: false,
       vmwareDcVms: [],
@@ -251,7 +227,6 @@ export default {
       } else {
         params.existingvcenterid = this.selectedExistingVcenterId
       }
-      params.host = this.selectedHost
       api('listVmwareDcVms', params).then(json => {
         const obj = {
           params: params,
@@ -281,8 +256,8 @@ export default {
     listZoneVmwareDcs () {
       this.loading = true
       api('listVmwareDcs', { zoneid: this.sourcezoneid }).then(response => {
-        if (response.listvmwaredcsresponse.vmwaredc && response.listvmwaredcsresponse.vmwaredc.length > 0) {
-          this.existingvcenter = response.listvmwaredcsresponse.vmwaredc
+        if (response.listvmwaredcsresponse.VMwareDC && response.listvmwaredcsresponse.VMwareDC.length > 0) {
+          this.existingvcenter = response.listvmwaredcsresponse.VMwareDC
         }
       }).catch(error => {
         this.$notifyError(error)
@@ -290,43 +265,8 @@ export default {
         this.loading = false
       })
     },
-    loadZoneVmwareDcHosts (doNotify) {
-      this.loading = true
-      const params = {}
-      if (this.vcenterSelectedOption === 'new') {
-        params.datacentername = this.datacenter
-        params.vcenter = this.vcenter
-        params.username = this.username
-        params.password = this.password
-      } else {
-        params.existingvcenterid = this.selectedExistingVcenterId
-      }
-      api('listVmwareDcHosts', params).then(response => {
-        if (response.listvmwaredchostsresponse.host && response.listvmwaredchostsresponse.host.length > 0) {
-          this.hosts = response.listvmwaredchostsresponse.host
-        }
-      }).catch(error => {
-        if (doNotify) {
-          this.$notifyError(error)
-        }
-        this.hosts = []
-        return false
-      }).finally(() => {
-        this.loading = false
-        return true
-      })
-    },
     onSelectExistingVmwareDatacenter (value) {
       this.selectedExistingVcenterId = value
-      this.loadZoneVmwareDcHosts(true)
-    },
-    onSelectExternalVmwareDatacenter (value) {
-      if (this.vcenterSelectedOption === 'new' && !(this.vcenter === '' || this.datacentername === '' || this.username === '' || this.password === '')) {
-        this.loadZoneVmwareDcHosts(false)
-      }
-    },
-    onSelectExistingVmwareHost (value) {
-      this.selectedHost = value
     },
     onVcenterTypeChange () {
       this.$emit('onVcenterTypeChanged', this.vcenterSelectedOption)
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java
index 27ca6396a470..88f6c871fbde 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java
@@ -16,25 +16,13 @@
 // under the License.
 package com.cloud.hypervisor.vmware.mo;
 
-import com.cloud.hypervisor.vmware.util.VmwareHelper;
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-import com.cloud.utils.Pair;
-import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
-import org.apache.cloudstack.vm.UnmanagedInstanceTO;
-
 import org.apache.log4j.Logger;
 
 import com.vmware.vim25.CustomFieldDef;
 import com.vmware.vim25.CustomFieldStringValue;
 import com.vmware.vim25.ManagedObjectReference;
-import com.vmware.vim25.InvalidPropertyFaultMsg;
-import com.vmware.vim25.RuntimeFaultFaultMsg;
-import com.vmware.vim25.ObjectContent;
-import com.vmware.vim25.RetrieveResult;
 
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
+import com.cloud.hypervisor.vmware.util.VmwareContext;
 
 public class BaseMO {
     private static final Logger s_logger = Logger.getLogger(BaseMO.class);
@@ -62,18 +50,6 @@ public BaseMO(VmwareContext context, String morType, String morValue) {
         _mor.setValue(morValue);
     }
 
-    protected static Pair<String, List<ObjectContent>> createReturnObjectPair(RetrieveResult result) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("vmware result : " + ReflectionToStringBuilderUtils.reflectCollection(result));
-        }
-        if (result == null) {
-            return new Pair<>(null, new ArrayList<>());
-        }
-        String tokenForRetrievingNewResults = result.getToken();
-        List<ObjectContent> listOfObjects = result.getObjects();
-        return new Pair<>(tokenForRetrievingNewResults, listOfObjects);
-    }
-
     public VmwareContext getContext() {
         return _context;
     }
@@ -161,11 +137,11 @@ public String getCustomFieldValue(String fieldName) throws Exception {
         return null;
     }
 
-    public int getCustomFieldKey(String fieldName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+    public int getCustomFieldKey(String fieldName) throws Exception {
         return getCustomFieldKey(getMor().getType(), fieldName);
     }
 
-    public int getCustomFieldKey(String morType, String fieldName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+    public int getCustomFieldKey(String morType, String fieldName) throws Exception {
         assert (morType != null);
 
         ManagedObjectReference cfmMor = _context.getServiceContent().getCustomFieldsManager();
@@ -177,30 +153,4 @@ public int getCustomFieldKey(String morType, String fieldName) throws InvalidPro
 
         return cfmMo.getCustomFieldKey(morType, fieldName);
     }
-
-    protected Pair<String, List<ObjectContent>> retrieveNextSetOfProperties(String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
-        RetrieveResult result = _context.getService().continueRetrievePropertiesEx(_context.getPropertyCollector(), tokenForPriorQuery);
-        return BaseMO.createReturnObjectPair(result);
-    }
-
-    protected void objectContentToUnmanagedInstanceTO(Pair<String, List<ObjectContent>> objectContents, List<UnmanagedInstanceTO> vms) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
-        List<ObjectContent> ocs = objectContents.second();
-        if (ocs != null) {
-            for (ObjectContent oc : ocs) {
-                ManagedObjectReference vmMor = oc.getObj();
-                if (vmMor != null) {
-                    VirtualMachineMO vmMo = new VirtualMachineMO(_context, vmMor);
-                    try {
-                        if (!vmMo.isTemplate()) {
-                            HostMO hostMO = vmMo.getRunningHost();
-                            UnmanagedInstanceTO unmanagedInstance = VmwareHelper.getUnmanagedInstance(hostMO, vmMo);
-                            vms.add(unmanagedInstance);
-                        }
-                    } catch (Exception e) {
-                        s_logger.debug(String.format("Unexpected error checking unmanaged instance %s, excluding it: %s", vmMo.getVmName(), e.getMessage()), e);
-                    }
-                }
-            }
-        }
-    }
 }
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java
index 61958d1b9529..78ce9a83c687 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java
@@ -16,14 +16,11 @@
 // under the License.
 package com.cloud.hypervisor.vmware.mo;
 
-import java.lang.reflect.InvocationTargetException;
 import java.util.List;
 
 import com.vmware.vim25.CustomFieldDef;
 import com.vmware.vim25.ManagedObjectReference;
 import com.vmware.vim25.PrivilegePolicyDef;
-import com.vmware.vim25.InvalidPropertyFaultMsg;
-import com.vmware.vim25.RuntimeFaultFaultMsg;
 
 import com.cloud.hypervisor.vmware.util.VmwareContext;
 
@@ -53,12 +50,12 @@ public void setField(ManagedObjectReference morEntity, int key, String value) th
         _context.getService().setField(getMor(), morEntity, key, value);
     }
 
-    public List<CustomFieldDef> getFields() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+    public List<CustomFieldDef> getFields() throws Exception {
         return _context.getVimClient().getDynamicProperty(getMor(), "field");
     }
 
     @Override
-    public int getCustomFieldKey(String morType, String fieldName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+    public int getCustomFieldKey(String morType, String fieldName) throws Exception {
         List<CustomFieldDef> fields = getFields();
         if (fields != null) {
             for (CustomFieldDef field : fields) {
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
index 211972f2efc5..d8c7e8a61ea6 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
@@ -17,12 +17,11 @@
 
 package com.cloud.hypervisor.vmware.mo;
 
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-import com.cloud.utils.StringUtils;
+import com.cloud.hypervisor.vmware.util.VmwareHelper;
 import org.apache.cloudstack.vm.UnmanagedInstanceTO;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.log4j.Logger;
@@ -40,10 +39,6 @@
 import com.vmware.vim25.SelectionSpec;
 import com.vmware.vim25.TraversalSpec;
 import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
-import com.vmware.vim25.RetrieveOptions;
-import com.vmware.vim25.RetrieveResult;
-import com.vmware.vim25.InvalidPropertyFaultMsg;
-import com.vmware.vim25.RuntimeFaultFaultMsg;
 
 import com.cloud.hypervisor.vmware.util.VmwareContext;
 import com.cloud.utils.Pair;
@@ -59,7 +54,7 @@ public DatacenterMO(VmwareContext context, String morType, String morValue) {
         super(context, morType, morValue);
     }
 
-    public DatacenterMO(VmwareContext context, String dcName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
+    public DatacenterMO(VmwareContext context, String dcName) throws Exception {
         super(context, null);
 
         _mor = _context.getVimClient().getDecendentMoRef(_context.getRootFolder(), "Datacenter", dcName);
@@ -69,8 +64,25 @@ public DatacenterMO(VmwareContext context, String dcName) throws InvalidProperty
     }
 
     @Override
-    public String getName() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
-        return _context.getVimClient().getDynamicProperty(_mor, "name");
+    public String getName() throws Exception {
+        return (String)_context.getVimClient().getDynamicProperty(_mor, "name");
+    }
+
+    public void registerTemplate(ManagedObjectReference morHost, String datastoreName, String templateName, String templateFileName) throws Exception {
+
+        ManagedObjectReference morFolder = (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "vmFolder");
+        assert (morFolder != null);
+
+        ManagedObjectReference morTask =
+            _context.getService()
+                .registerVMTask(morFolder, String.format("[%s] %s/%s", datastoreName, templateName, templateFileName), templateName, true, null, morHost);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (!result) {
+            throw new Exception("Unable to register template due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        } else {
+            _context.waitForTaskProgressDone(morTask);
+        }
     }
 
     public VirtualMachineMO findVm(String vmName) throws Exception {
@@ -79,7 +91,7 @@ public VirtualMachineMO findVm(String vmName) throws Exception {
             s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
         }
         String instanceNameCustomField = "value[" + key + "]";
-        List<ObjectContent> ocs = getVmProperties(new String[] {"name", instanceNameCustomField});
+        List<ObjectContent> ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", instanceNameCustomField});
         return HypervisorHostHelper.findVmFromObjectContent(_context, ocs.toArray(new ObjectContent[0]), vmName, instanceNameCustomField);
     }
 
@@ -88,10 +100,10 @@ public List<VirtualMachineMO> findVmByNameAndLabel(String vmLabel) throws Except
         int key = cfmMo.getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_UUID);
         assert (key != 0);
 
-        List<VirtualMachineMO> list = new ArrayList<>();
+        List<VirtualMachineMO> list = new ArrayList<VirtualMachineMO>();
 
-        List<ObjectContent> ocs = getVmProperties(new String[] {"name", String.format("value[%d]", key)});
-        if (CollectionUtils.isNotEmpty(ocs)) {
+        List<ObjectContent> ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", String.format("value[%d]", key)});
+        if (ocs != null && ocs.size() > 0) {
             for (ObjectContent oc : ocs) {
                 List<DynamicProperty> props = oc.getPropSet();
                 if (props != null) {
@@ -123,8 +135,8 @@ public VirtualMachineMO checkIfVmAlreadyExistsInVcenter(String vmNameOnVcenter,
             s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
         }
 
-        List<ObjectContent> ocs = getVmProperties(new String[] {"name", String.format("value[%d]", key)});
-        if (CollectionUtils.isNotEmpty(ocs)) {
+        List<ObjectContent> ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", String.format("value[%d]", key)});
+        if (ocs != null && ocs.size() > 0) {
             for (ObjectContent oc : ocs) {
                 List<DynamicProperty> props = oc.getPropSet();
                 if (props != null) {
@@ -149,20 +161,31 @@ public VirtualMachineMO checkIfVmAlreadyExistsInVcenter(String vmNameOnVcenter,
         return null;
     }
 
-    public Pair<String, List<UnmanagedInstanceTO>> getVms(Integer maxObjects, String token) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+    public List<UnmanagedInstanceTO> getAllVmsOnDatacenter() throws Exception {
         List<UnmanagedInstanceTO> vms = new ArrayList<>();
-        Pair<String, List<ObjectContent>> objectContents = getVmProperties(new String[] {"name"}, maxObjects, token);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug(String.format("returning token %s for future retrievals, currently %d objects retrieved.", objectContents.first(), objectContents.second().size()));
+        List<ObjectContent> ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"});
+        if (ocs != null) {
+            for (ObjectContent oc : ocs) {
+                ManagedObjectReference vmMor = oc.getObj();
+                if (vmMor != null) {
+                    VirtualMachineMO vmMo = new VirtualMachineMO(_context, vmMor);
+                    try {
+                        if (!vmMo.isTemplate()) {
+                            HostMO hostMO = vmMo.getRunningHost();
+                            UnmanagedInstanceTO unmanagedInstance = VmwareHelper.getUnmanagedInstance(hostMO, vmMo);
+                            vms.add(unmanagedInstance);
+                        }
+                    } catch (Exception e) {
+                        s_logger.debug(String.format("Unexpected error checking unmanaged instance %s, excluding it: %s", vmMo.getVmName(), e.getMessage()), e);
+                    }
+                }
+            }
         }
-        Pair<String, List<UnmanagedInstanceTO>> retval = new Pair<>(objectContents.first(), vms);
-
-        objectContentToUnmanagedInstanceTO(objectContents, vms);
 
-        return retval;
+        return vms;
     }
 
-    public List<HostMO> getAllHostsOnDatacenter() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
+    public List<HostMO> getAllHostsOnDatacenter() throws Exception {
         List<HostMO> hosts = new ArrayList<>();
 
         List<ObjectContent> ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"});
@@ -189,7 +212,21 @@ public ManagedObjectReference findDatastore(String name) throws Exception {
         return null;
     }
 
-    public ManagedObjectReference findHost(String name) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
+    public ManagedObjectReference listDatastore(String name) throws Exception {
+        assert (name != null);
+
+        List<ObjectContent> ocs = getDatastorePropertiesOnDatacenter(new String[] {"name"});
+        if (ocs != null) {
+            for (ObjectContent oc : ocs) {
+                if (oc.getPropSet().get(0).getVal().toString().equals(name)) {
+                    return oc.getObj();
+                }
+            }
+        }
+        return null;
+    }
+
+    public ManagedObjectReference findHost(String name) throws Exception {
         List<ObjectContent> ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"});
 
         if (ocs != null) {
@@ -203,10 +240,10 @@ public ManagedObjectReference findHost(String name) throws InvalidPropertyFaultM
     }
 
     public ManagedObjectReference getVmFolder() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "vmFolder");
+        return (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "vmFolder");
     }
 
-    public List<ObjectContent> getHostPropertiesOnDatacenterHostFolder(String[] propertyPaths) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
+    public List<ObjectContent> getHostPropertiesOnDatacenterHostFolder(String[] propertyPaths) throws Exception {
         PropertySpec pSpec = new PropertySpec();
         pSpec.setType("HostSystem");
         pSpec.getPathSet().addAll(Arrays.asList(propertyPaths));
@@ -240,7 +277,7 @@ public List<ObjectContent> getHostPropertiesOnDatacenterHostFolder(String[] prop
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
@@ -266,41 +303,14 @@ public List<ObjectContent> getDatastorePropertiesOnDatacenter(String[] propertyP
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
 
     }
 
-    public List<ObjectContent> getVmProperties(String[] propertyPaths) throws  InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
-        return getVmProperties(propertyPaths, null, null).second();
-    }
-
-    /**
-     *
-     * @param propertyPaths Vmware side property names to query, for instance {"name"}
-     * @param maxObjects the number of objects to retrieve
-     * @param tokenForPriorQuery restart the query or continue a previous query
-     * @return The propertyPaths requested for the objects of type "VirtualMachine" in a list are found/returned by the DC
-     * @throws InvalidPropertyFaultMsg property does not exist as thrown by Vmware.
-     * @throws RuntimeFaultFaultMsg generic vmware runtime exception
-     */
-    public Pair<String, List<ObjectContent>> getVmProperties(String[] propertyPaths, Integer maxObjects, String tokenForPriorQuery) throws  InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
-        if(StringUtils.isNotBlank(tokenForPriorQuery)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(String.format("running repeat query with token \'%s\'", tokenForPriorQuery));
-            }
-            return retrieveNextSetOfProperties(tokenForPriorQuery);
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(String.format("running query for %d propertypaths and max %d objects", propertyPaths.length, maxObjects));
-            }
-            return retrieveNextSetOfProperties(propertyPaths, maxObjects);
-        }
-    }
-
-    private Pair<String, List<ObjectContent>> retrieveNextSetOfProperties(String[] propertyPaths, Integer maxObjects) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
+    public List<ObjectContent> getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths) throws Exception {
         PropertySpec pSpec = new PropertySpec();
         pSpec.setType("VirtualMachine");
         pSpec.getPathSet().addAll(Arrays.asList(propertyPaths));
@@ -328,16 +338,10 @@ private Pair<String, List<ObjectContent>> retrieveNextSetOfProperties(String[] p
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
-        RetrieveOptions ro = new RetrieveOptions();
-        if (maxObjects != null && maxObjects > 0) {
-            ro.setMaxObjects(maxObjects);
-        }
-
-        RetrieveResult result = _context.getService().retrievePropertiesEx(_context.getPropertyCollector(), pfSpecArr, ro);
-        return createReturnObjectPair(result);
+        return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
     }
 
     public static Pair<DatacenterMO, String> getOwnerDatacenter(VmwareContext context, ManagedObjectReference morEntity) throws Exception {
@@ -362,18 +366,18 @@ public static Pair<DatacenterMO, String> getOwnerDatacenter(VmwareContext contex
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         List<ObjectContent> ocs = context.getService().retrieveProperties(context.getPropertyCollector(), pfSpecArr);
 
-        assert (CollectionUtils.isNotEmpty(ocs));
+        assert (ocs != null && ocs.size() > 0);
         assert (ocs.get(0).getObj() != null);
         assert (ocs.get(0).getPropSet().get(0) != null);
         assert (ocs.get(0).getPropSet().get(0).getVal() != null);
 
         String dcName = ocs.get(0).getPropSet().get(0).getVal().toString();
-        return new Pair<>(new DatacenterMO(context, ocs.get(0).getObj()), dcName);
+        return new Pair<DatacenterMO, String>(new DatacenterMO(context, ocs.get(0).getObj()), dcName);
     }
 
     public ManagedObjectReference getDvPortGroupMor(String dvPortGroupName) throws Exception {
@@ -394,7 +398,7 @@ public ManagedObjectReference getDvPortGroupMor(String dvPortGroupName) throws E
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
@@ -415,7 +419,9 @@ public ManagedObjectReference getDvPortGroupMor(String dvPortGroupName) throws E
 
     public boolean hasDvPortGroup(String dvPortGroupName) throws Exception {
         ManagedObjectReference morNetwork = getDvPortGroupMor(dvPortGroupName);
-        return morNetwork != null;
+        if (morNetwork != null)
+            return true;
+        return false;
     }
 
     public DVPortgroupConfigInfo getDvPortGroupSpec(String dvPortGroupName) throws Exception {
@@ -439,7 +445,7 @@ public DVPortgroupConfigInfo getDvPortGroupSpec(String dvPortGroupName) throws E
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
@@ -456,7 +462,7 @@ public DVPortgroupConfigInfo getDvPortGroupSpec(String dvPortGroupName) throws E
                             nameProperty = prop.getVal().toString();
                         }
                     }
-                    if (nameProperty != null && nameProperty.equalsIgnoreCase(dvPortGroupName)) {
+                    if (nameProperty.equalsIgnoreCase(dvPortGroupName)) {
                         return configSpec;
                     }
                 }
@@ -486,7 +492,7 @@ public ManagedObjectReference getDvSwitchMor(ManagedObjectReference dvPortGroupM
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
@@ -514,7 +520,7 @@ public ManagedObjectReference getDvSwitchMor(ManagedObjectReference dvPortGroupM
 
     public String getDvSwitchUuid(ManagedObjectReference dvSwitchMor) throws Exception {
         assert (dvSwitchMor != null);
-        return _context.getVimClient().getDynamicProperty(dvSwitchMor, "uuid");
+        return (String)_context.getVimClient().getDynamicProperty(dvSwitchMor, "uuid");
     }
 
     public VirtualEthernetCardDistributedVirtualPortBackingInfo getDvPortBackingInfo(Pair<ManagedObjectReference, String> networkInfo) throws Exception {
@@ -532,8 +538,8 @@ public VirtualEthernetCardDistributedVirtualPortBackingInfo getDvPortBackingInfo
     }
 
     public ManagedObjectReference getDvSwitchMor(String dvSwitchName) throws Exception {
-        ManagedObjectReference dvSwitchMor;
-        ManagedObjectReference networkFolderMor;
+        ManagedObjectReference dvSwitchMor = null;
+        ManagedObjectReference networkFolderMor = null;
         networkFolderMor = _context.getVimClient().getMoRefProp(_mor, "networkFolder");
         dvSwitchMor = _context.getVimClient().getDecendentMoRef(networkFolderMor, "VmwareDistributedVirtualSwitch", dvSwitchName);
         return dvSwitchMor;
@@ -545,6 +551,7 @@ public boolean ensureCustomFieldDef(String fieldName) throws Exception {
     }
 
     public DatacenterConfigInfo getDatacenterConfigInfo() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "configuration");
+        DatacenterConfigInfo configInfo = (DatacenterConfigInfo)_context.getVimClient().getDynamicProperty(_mor, "configuration");
+        return configInfo;
     }
 }
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
index edffd8b09068..3b96e7e19990 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
@@ -16,7 +16,6 @@
 // under the License.
 package com.cloud.hypervisor.vmware.mo;
 
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -25,20 +24,11 @@
 import java.util.Map;
 import java.util.regex.Pattern;
 
-import org.apache.cloudstack.vm.UnmanagedInstanceTO;
-
-import com.cloud.hypervisor.vmware.util.VmwareClientException;
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-import com.cloud.hypervisor.vmware.util.VmwareHelper;
-import com.cloud.utils.LogUtils;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 
 import com.google.gson.Gson;
-
 import com.vmware.vim25.AboutInfo;
 import com.vmware.vim25.AlreadyExistsFaultMsg;
 import com.vmware.vim25.ClusterDasConfigInfo;
@@ -68,7 +58,6 @@
 import com.vmware.vim25.HostSystemConnectionState;
 import com.vmware.vim25.HostVirtualNic;
 import com.vmware.vim25.HostVirtualSwitch;
-import com.vmware.vim25.InvalidPropertyFaultMsg;
 import com.vmware.vim25.ManagedObjectReference;
 import com.vmware.vim25.NasDatastoreInfo;
 import com.vmware.vim25.ObjectContent;
@@ -76,12 +65,13 @@
 import com.vmware.vim25.OptionValue;
 import com.vmware.vim25.PropertyFilterSpec;
 import com.vmware.vim25.PropertySpec;
-import com.vmware.vim25.RetrieveOptions;
-import com.vmware.vim25.RetrieveResult;
-import com.vmware.vim25.RuntimeFaultFaultMsg;
 import com.vmware.vim25.TraversalSpec;
 import com.vmware.vim25.VirtualMachineConfigSpec;
 import com.vmware.vim25.VirtualNicManagerNetConfig;
+import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.hypervisor.vmware.util.VmwareHelper;
+import com.cloud.utils.LogUtils;
+import com.cloud.utils.Pair;
 
 public class HostMO extends BaseMO implements VmwareHypervisorHost {
     private static final Logger s_logger = Logger.getLogger(HostMO.class);
@@ -545,22 +535,18 @@ public List<ManagedObjectReference> getVmMorsOnNetwork(String portGroupName) thr
         return null;
     }
 
-    public String getHostName() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+    public String getHostName() throws Exception {
         return (String)_context.getVimClient().getDynamicProperty(_mor, "name");
     }
 
     @Override
-    public synchronized List<VirtualMachineMO> listVmsOnHyperHostWithHypervisorName(String vmName) throws VmwareClientException {
+    public synchronized List<VirtualMachineMO> listVmsOnHyperHostWithHypervisorName(String vmName) throws Exception {
         List<VirtualMachineMO> vms = new ArrayList<>();
-        try {
-            if (StringUtils.isNotEmpty(vmName)) {
-                vms.add(findVmOnHyperHostWithHypervisorName(vmName));
-            } else {
-                    loadVmCache();
-                vms.addAll(_vmCache.values());
-            }
-        } catch (InvalidPropertyFaultMsg | RuntimeFaultFaultMsg | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
-            throw new VmwareClientException("problem loading vm cache.", e);
+        if (StringUtils.isNotEmpty(vmName)) {
+            vms.add(findVmOnHyperHostWithHypervisorName(vmName));
+        } else {
+            loadVmCache();
+            vms.addAll(_vmCache.values());
         }
         return vms;
     }
@@ -596,7 +582,7 @@ private boolean isUserVMInternalCSName(String vmInternalCSName) {
         }
     }
 
-    private void loadVmCache() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+    private void loadVmCache() throws Exception {
         if (s_logger.isDebugEnabled())
             s_logger.debug("load VM cache on host");
 
@@ -718,16 +704,11 @@ public HashMap<String, Integer> getVmVncPortsOnHost() throws Exception {
     }
 
     @Override
-    public ObjectContent[] getVmPropertiesOnHyperHost(String[] propertyPaths) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
-        List<ObjectContent> properties = getVmProperties(propertyPaths, null, null).second();
-        return properties.toArray(new ObjectContent[properties.size()]);
-    }
-
-    public Pair<String, List<ObjectContent>> getVmProperties(String[] propertyPaths, Integer maxObjects) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
-        if (s_logger.isTraceEnabled()) {
+    public ObjectContent[] getVmPropertiesOnHyperHost(String[] propertyPaths) throws Exception {
+        if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - retrieveProperties() for VM properties. target MOR: " + _mor.getValue() + ", properties: " +
                     new Gson().toJson(propertyPaths));
-        }
+
         PropertySpec pSpec = new PropertySpec();
         pSpec.setType("VirtualMachine");
         pSpec.getPathSet().addAll(Arrays.asList(propertyPaths));
@@ -745,19 +726,14 @@ public Pair<String, List<ObjectContent>> getVmProperties(String[] propertyPaths,
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
-        RetrieveOptions ro = new RetrieveOptions();
-        if (maxObjects != null && maxObjects > 0) {
-            ro.setMaxObjects(maxObjects);
-        }
-
-        RetrieveResult result = _context.getService().retrievePropertiesEx(_context.getPropertyCollector(), pfSpecArr, ro);
+        List<ObjectContent> properties = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
 
         if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - retrieveProperties() done");
-        return createReturnObjectPair(result);
+        return properties.toArray(new ObjectContent[properties.size()]);
     }
 
     @Override
@@ -783,7 +759,7 @@ public ObjectContent[] getDatastorePropertiesOnHyperHost(String[] propertyPaths)
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         List<ObjectContent> properties = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
@@ -1342,7 +1318,7 @@ public boolean isUefiLegacySupported() throws Exception {
         return false;
     }
 
-    private synchronized VirtualMachineMO findVmOnHyperHostWithHypervisorName(String vmName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+    private synchronized VirtualMachineMO findVmOnHyperHostWithHypervisorName(String vmName) throws Exception {
         if (s_logger.isDebugEnabled())
             s_logger.debug("find VM hypervisor name: " + vmName + " on host");
 
@@ -1374,29 +1350,4 @@ private VirtualMachineMO getVmWithHypervisorName(Collection<VirtualMachineMO> vm
         return null;
     }
 
-    public Pair<String, List<UnmanagedInstanceTO>> getVms(Integer maxObjects, String token) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
-        List<UnmanagedInstanceTO> vms = new ArrayList<>();
-        Pair<String, List<ObjectContent>> objectContents = getVmProperties(new String[] {"name"}, maxObjects, token);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug(String.format("returning token %s for future retrievals, currently %d objects retrieved.", objectContents.first(), objectContents.second().size()));
-        }
-        Pair<String, List<UnmanagedInstanceTO>> retval = new Pair<>(objectContents.first(), vms);
-
-        objectContentToUnmanagedInstanceTO(objectContents, vms);
-
-        return retval;
-    }
-    public Pair<String, List<ObjectContent>> getVmProperties(String[] propertyPaths, Integer maxObjects, String tokenForPriorQuery) throws  InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
-        if(com.cloud.utils.StringUtils.isNotBlank(tokenForPriorQuery)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(String.format("running repeat query with token \'%s\'", tokenForPriorQuery));
-            }
-            return retrieveNextSetOfProperties(tokenForPriorQuery);
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(String.format("running query for %d propertypaths and max %d objects", propertyPaths.length, maxObjects));
-            }
-            return getVmProperties(propertyPaths, maxObjects);
-        }
-    }
 }
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
index 1e824f34fbb6..dcdeb04734e8 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
@@ -26,8 +26,7 @@
 import java.io.FileOutputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.nio.charset.StandardCharsets;
+import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -42,6 +41,11 @@
 
 import com.cloud.storage.Storage;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.vmware.vim25.InvalidStateFaultMsg;
+import com.vmware.vim25.RuntimeFaultFaultMsg;
+import com.vmware.vim25.TaskInfo;
+import com.vmware.vim25.TaskInfoState;
+import com.vmware.vim25.VirtualMachineTicket;
 import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -51,13 +55,12 @@
 import com.cloud.hypervisor.vmware.util.VmwareContext;
 import com.cloud.hypervisor.vmware.util.VmwareHelper;
 import com.cloud.utils.ActionDelegate;
+import com.cloud.utils.LogUtils;
 import com.cloud.utils.Pair;
 import com.cloud.utils.Ternary;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.script.Script;
-
 import com.google.gson.Gson;
-
 import com.vmware.vim25.ArrayOfManagedObjectReference;
 import com.vmware.vim25.ChoiceOption;
 import com.vmware.vim25.CustomFieldStringValue;
@@ -69,8 +72,6 @@
 import com.vmware.vim25.HttpNfcLeaseDeviceUrl;
 import com.vmware.vim25.HttpNfcLeaseInfo;
 import com.vmware.vim25.HttpNfcLeaseState;
-import com.vmware.vim25.InvalidPropertyFaultMsg;
-import com.vmware.vim25.InvalidStateFaultMsg;
 import com.vmware.vim25.ManagedObjectReference;
 import com.vmware.vim25.ObjectContent;
 import com.vmware.vim25.ObjectSpec;
@@ -81,14 +82,12 @@
 import com.vmware.vim25.ParaVirtualSCSIController;
 import com.vmware.vim25.PropertyFilterSpec;
 import com.vmware.vim25.PropertySpec;
-import com.vmware.vim25.RuntimeFaultFaultMsg;
-import com.vmware.vim25.TaskInfo;
-import com.vmware.vim25.TaskInfoState;
 import com.vmware.vim25.TraversalSpec;
 import com.vmware.vim25.VirtualBusLogicController;
 import com.vmware.vim25.VirtualCdrom;
 import com.vmware.vim25.VirtualCdromIsoBackingInfo;
 import com.vmware.vim25.VirtualCdromRemotePassthroughBackingInfo;
+import com.vmware.vim25.VirtualController;
 import com.vmware.vim25.VirtualDevice;
 import com.vmware.vim25.VirtualDeviceBackingInfo;
 import com.vmware.vim25.VirtualDeviceConfigSpec;
@@ -127,7 +126,6 @@
 import com.vmware.vim25.VirtualMachineRuntimeInfo;
 import com.vmware.vim25.VirtualMachineSnapshotInfo;
 import com.vmware.vim25.VirtualMachineSnapshotTree;
-import com.vmware.vim25.VirtualMachineTicket;
 import com.vmware.vim25.VirtualSCSIController;
 import com.vmware.vim25.VirtualSCSISharing;
 
@@ -162,17 +160,54 @@ public Pair<DatacenterMO, String> getOwnerDatacenter() throws Exception {
         return DatacenterMO.getOwnerDatacenter(getContext(), getMor());
     }
 
+    public Pair<DatastoreMO, String> getOwnerDatastore(String dsFullPath) throws Exception {
+        String dsName = DatastoreFile.getDatastoreNameFromPath(dsFullPath);
+
+        PropertySpec pSpec = new PropertySpec();
+        pSpec.setType("Datastore");
+        pSpec.getPathSet().add("name");
+
+        TraversalSpec vmDatastoreTraversal = new TraversalSpec();
+        vmDatastoreTraversal.setType("VirtualMachine");
+        vmDatastoreTraversal.setPath("datastore");
+        vmDatastoreTraversal.setName("vmDatastoreTraversal");
+
+        ObjectSpec oSpec = new ObjectSpec();
+        oSpec.setObj(_mor);
+        oSpec.setSkip(Boolean.TRUE);
+        oSpec.getSelectSet().add(vmDatastoreTraversal);
+
+        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
+        pfSpec.getPropSet().add(pSpec);
+        pfSpec.getObjectSet().add(oSpec);
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
+        pfSpecArr.add(pfSpec);
+
+        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
+
+        if (ocs != null) {
+            for (ObjectContent oc : ocs) {
+                DynamicProperty prop = oc.getPropSet().get(0);
+                if (prop.getVal().toString().equals(dsName)) {
+                    return new Pair<DatastoreMO, String>(new DatastoreMO(_context, oc.getObj()), dsName);
+                }
+            }
+        }
+
+        return null;
+    }
+
     public HostMO getRunningHost() throws Exception {
         VirtualMachineRuntimeInfo runtimeInfo = getRuntimeInfo();
         return new HostMO(_context, runtimeInfo.getHost());
     }
 
-    public String getVmName() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
-        return getContext().getVimClient().getDynamicProperty(_mor, "name");
+    public String getVmName() throws Exception {
+        return (String)getContext().getVimClient().getDynamicProperty(_mor, "name");
     }
 
     public GuestInfo getVmGuestInfo() throws Exception {
-        return getContext().getVimClient().getDynamicProperty(_mor, "guest");
+        return (GuestInfo)getContext().getVimClient().getDynamicProperty(_mor, "guest");
     }
 
     public void answerVM(String questionId, String choice) throws Exception {
@@ -181,7 +216,11 @@ public void answerVM(String questionId, String choice) throws Exception {
 
     public boolean isVMwareToolsRunning() throws Exception {
         GuestInfo guestInfo = getVmGuestInfo();
-        return guestInfo != null && "guestToolsRunning".equalsIgnoreCase(guestInfo.getToolsRunningStatus());
+        if (guestInfo != null) {
+            if ("guestToolsRunning".equalsIgnoreCase(guestInfo.getToolsRunningStatus()))
+                return true;
+        }
+        return false;
     }
 
     public boolean powerOn() throws Exception {
@@ -350,7 +389,7 @@ public VirtualMachinePowerState getResetSafePowerState() throws Exception {
         // In the future, VMsync should not kick off CloudStack action (this is not a HA case) based on VM
         // state report, until then we can remove this hacking fix
         for (int i = 0; i < 3; i++) {
-            powerState = getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState");
+            powerState = (VirtualMachinePowerState)getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState");
             if (powerState == VirtualMachinePowerState.POWERED_OFF) {
                 try {
                     Thread.sleep(1000);
@@ -366,7 +405,7 @@ public VirtualMachinePowerState getResetSafePowerState() throws Exception {
     }
 
     public VirtualMachinePowerState getPowerState() throws Exception {
-        return getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState");
+        return (VirtualMachinePowerState)getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState");
     }
 
     public boolean reset() throws Exception {
@@ -429,6 +468,39 @@ public boolean changeDatastore(VirtualMachineRelocateSpec relocateSpec) throws E
         return false;
     }
 
+    public boolean changeHost(VirtualMachineRelocateSpec relocateSpec) throws Exception {
+        ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, VirtualMachineMovePriority.DEFAULT_PRIORITY);
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware RelocateVM_Task to change host failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+        return false;
+    }
+
+    public boolean changeDatastore(ManagedObjectReference morDataStore, VmwareHypervisorHost targetHost) throws Exception {
+        VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
+        relocateSpec.setDatastore(morDataStore);
+        if (targetHost != null) {
+            relocateSpec.setHost(targetHost.getMor());
+            relocateSpec.setPool(targetHost.getHyperHostOwnerResourcePool());
+        }
+
+        ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, null);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware change datastore relocateVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return false;
+    }
+
     public boolean relocate(ManagedObjectReference morTargetHost) throws Exception {
         VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
         relocateSpec.setHost(morTargetHost);
@@ -447,7 +519,7 @@ public boolean relocate(ManagedObjectReference morTargetHost) throws Exception {
     }
 
     public VirtualMachineSnapshotInfo getSnapshotInfo() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "snapshot");
+        return (VirtualMachineSnapshotInfo)_context.getVimClient().getDynamicProperty(_mor, "snapshot");
     }
 
     public boolean createSnapshot(String snapshotName, String snapshotDescription, boolean dumpMemory, boolean quiesce) throws Exception {
@@ -517,6 +589,39 @@ public boolean removeSnapshot(String snapshotName, boolean removeChildren) throw
         return false;
     }
 
+    public boolean revertToSnapshot(String snapshotName) throws Exception {
+        ManagedObjectReference morSnapshot = getSnapshotMor(snapshotName);
+        if (morSnapshot == null) {
+            s_logger.warn("Unable to find snapshot: " + snapshotName);
+            return false;
+        }
+        ManagedObjectReference morTask = _context.getService().revertToSnapshotTask(morSnapshot, _mor, null);
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware revert to snapshot failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return false;
+    }
+
+    /**
+     * Deletes all of the snapshots of a VM.
+     */
+    public void consolidateAllSnapshots() throws Exception {
+        ManagedObjectReference task = _context.getService().removeAllSnapshotsTask(_mor, true);
+
+        boolean result = _context.getVimClient().waitForTask(task);
+
+        if (result) {
+            _context.waitForTaskProgressDone(task);
+        } else {
+            throw new Exception("Unable to register VM due to the following issue: " + TaskMO.getTaskFailureInfo(_context, task));
+        }
+    }
+
     public boolean removeAllSnapshots() throws Exception {
         VirtualMachineSnapshotInfo snapshotInfo = getSnapshotInfo();
 
@@ -596,7 +701,7 @@ public String getSnapshotDescriptorDatastorePath() throws Exception {
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
@@ -645,7 +750,9 @@ public boolean hasSnapshot() throws Exception {
                 return true;
             }
             List<VirtualMachineSnapshotTree> rootSnapshotList = info.getRootSnapshotList();
-            return CollectionUtils.isNotEmpty(rootSnapshotList);
+            if (rootSnapshotList != null && rootSnapshotList.size() > 0) {
+                return true;
+            }
         }
         return false;
     }
@@ -798,11 +905,11 @@ public boolean createLinkedClone(String cloneName, ManagedObjectReference morBas
         VirtualDisk[] independentDisks = getAllIndependentDiskDevice();
         VirtualMachineRelocateSpec rSpec = new VirtualMachineRelocateSpec();
         if (independentDisks.length > 0) {
-            List<VirtualMachineRelocateSpecDiskLocator> diskLocator = new ArrayList<>(independentDisks.length);
-            for (VirtualDisk independentDisk : independentDisks) {
+            List<VirtualMachineRelocateSpecDiskLocator> diskLocator = new ArrayList<VirtualMachineRelocateSpecDiskLocator>(independentDisks.length);
+            for (int i = 0; i < independentDisks.length; i++) {
                 VirtualMachineRelocateSpecDiskLocator loc = new VirtualMachineRelocateSpecDiskLocator();
                 loc.setDatastore(morDs);
-                loc.setDiskId(independentDisk.getKey());
+                loc.setDiskId(independentDisks[i].getKey());
                 loc.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING.value());
                 diskLocator.add(loc);
             }
@@ -834,26 +941,26 @@ public boolean createLinkedClone(String cloneName, ManagedObjectReference morBas
     }
 
     public VirtualMachineRuntimeInfo getRuntimeInfo() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "runtime");
+        return (VirtualMachineRuntimeInfo)_context.getVimClient().getDynamicProperty(_mor, "runtime");
     }
 
     public VirtualMachineConfigInfo getConfigInfo() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "config");
+        return (VirtualMachineConfigInfo)_context.getVimClient().getDynamicProperty(_mor, "config");
     }
 
     public boolean isToolsInstallerMounted() throws Exception {
         return _context.getVimClient().getDynamicProperty(_mor, "runtime.toolsInstallerMounted");
     }
     public GuestInfo getGuestInfo() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "guest");
+        return (GuestInfo)_context.getVimClient().getDynamicProperty(_mor, "guest");
     }
 
     public VirtualMachineConfigSummary getConfigSummary() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "summary.config");
+        return (VirtualMachineConfigSummary)_context.getVimClient().getDynamicProperty(_mor, "summary.config");
     }
 
     public VirtualMachineFileInfo getFileInfo() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "config.files");
+        return (VirtualMachineFileInfo)_context.getVimClient().getDynamicProperty(_mor, "config.files");
     }
 
     public VirtualMachineFileLayoutEx getFileLayout() throws Exception {
@@ -869,7 +976,7 @@ public VirtualMachineFileLayoutEx getFileLayout() throws Exception {
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
@@ -914,7 +1021,7 @@ public String getPath() throws Exception {
 
     @Override
     public ManagedObjectReference getParentMor() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "parent");
+        return (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "parent");
     }
 
     public String[] getNetworks() throws Exception {
@@ -935,13 +1042,13 @@ public String[] getNetworks() throws Exception {
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
 
-        List<String> networks = new ArrayList<>();
-        if (CollectionUtils.isNotEmpty(ocs)) {
+        List<String> networks = new ArrayList<String>();
+        if (ocs != null && ocs.size() > 0) {
             for (ObjectContent oc : ocs) {
                 networks.add(oc.getPropSet().get(0).getVal().toString());
             }
@@ -950,7 +1057,7 @@ public String[] getNetworks() throws Exception {
     }
 
     public List<NetworkDetails> getNetworksWithDetails() throws Exception {
-        List<NetworkDetails> networks = new ArrayList<>();
+        List<NetworkDetails> networks = new ArrayList<NetworkDetails>();
 
         int gcTagKey = getCustomFieldKey("Network", CustomFieldConstants.CLOUD_GC);
 
@@ -978,12 +1085,12 @@ public List<NetworkDetails> getNetworksWithDetails() throws Exception {
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
 
-        if (CollectionUtils.isNotEmpty(ocs)) {
+        if (ocs != null && ocs.size() > 0) {
             for (ObjectContent oc : ocs) {
                 ArrayOfManagedObjectReference morVms = null;
                 String gcTagValue = null;
@@ -1031,12 +1138,12 @@ public List<DatastoreMO> getAllDatastores() throws Exception {
         PropertyFilterSpec pfSpec = new PropertyFilterSpec();
         pfSpec.getPropSet().add(pSpec);
         pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
         pfSpecArr.add(pfSpec);
 
         List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
 
-        List<DatastoreMO> datastores = new ArrayList<>();
+        List<DatastoreMO> datastores = new ArrayList<DatastoreMO>();
         if (CollectionUtils.isNotEmpty(ocs)) {
             for (ObjectContent oc : ocs) {
                 datastores.add(new DatastoreMO(_context, oc.getObj()));
@@ -1045,6 +1152,61 @@ public List<DatastoreMO> getAllDatastores() throws Exception {
         return datastores;
     }
 
+    /**
+     * Retrieve path info to access VM files via vSphere web interface
+     * @return [0] vm-name, [1] data-center-name, [2] datastore-name
+     * @throws Exception
+     */
+    public String[] getHttpAccessPathInfo() throws Exception {
+        String[] pathInfo = new String[3];
+
+        Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
+
+        VirtualMachineFileInfo fileInfo = getFileInfo();
+        String vmxFilePath = fileInfo.getVmPathName();
+        String vmxPathTokens[] = vmxFilePath.split("\\[|\\]|/");
+        assert (vmxPathTokens.length == 4);
+        pathInfo[1] = vmxPathTokens[1].trim();                            // vSphere vm name
+        pathInfo[2] = dcInfo.second();                                    // vSphere datacenter name
+        pathInfo[3] = vmxPathTokens[0].trim();                            // vSphere datastore name
+        return pathInfo;
+    }
+
+    public String getVmxHttpAccessUrl() throws Exception {
+        Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
+
+        VirtualMachineFileInfo fileInfo = getFileInfo();
+        String vmxFilePath = fileInfo.getVmPathName();
+        String vmxPathTokens[] = vmxFilePath.split("\\[|\\]|/");
+
+        StringBuffer sb = new StringBuffer("https://" + _context.getServerAddress() + "/folder/");
+        sb.append(URLEncoder.encode(vmxPathTokens[2].trim(), "UTF-8"));
+        sb.append("/");
+        sb.append(URLEncoder.encode(vmxPathTokens[3].trim(), "UTF-8"));
+        sb.append("?dcPath=");
+        sb.append(URLEncoder.encode(dcInfo.second(), "UTF-8"));
+        sb.append("&dsName=");
+        sb.append(URLEncoder.encode(vmxPathTokens[1].trim(), "UTF-8"));
+
+        return sb.toString();
+    }
+
+    public boolean setVncConfigInfo(boolean enableVnc, String vncPassword, int vncPort, String keyboard) throws Exception {
+        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+        OptionValue[] vncOptions = VmwareHelper.composeVncOptions(null, enableVnc, vncPassword, vncPort, keyboard);
+        vmConfigSpec.getExtraConfig().addAll(Arrays.asList(vncOptions));
+        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, vmConfigSpec);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware reconfigVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+        return false;
+    }
+
     public boolean configureVm(VirtualMachineConfigSpec vmConfigSpec) throws Exception {
         ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, vmConfigSpec);
 
@@ -1098,12 +1260,12 @@ public Pair<String, Integer> getVncPort(String hostNetworkName) throws Exception
                 if (option.getKey().equals("RemoteDisplay.vnc.port")) {
                     String value = (String)option.getValue();
                     if (value != null) {
-                        return new Pair<>(summary.getHostIp(), Integer.parseInt(value));
+                        return new Pair<String, Integer>(summary.getHostIp(), Integer.parseInt(value));
                     }
                 }
             }
         }
-        return new Pair<>(summary.getHostIp(), 0);
+        return new Pair<String, Integer>(summary.getHostIp(), 0);
     }
 
     // vmdkDatastorePath: [datastore name] vmdkFilePath
@@ -1114,11 +1276,11 @@ public void createDisk(String vmdkDatastorePath, long sizeInMb, ManagedObjectRef
     // vmdkDatastorePath: [datastore name] vmdkFilePath
     public void createDisk(String vmdkDatastorePath, VirtualDiskType diskType, VirtualDiskMode diskMode, String rdmDeviceName, long sizeInMb,
                            ManagedObjectReference morDs, int controllerKey, String vSphereStoragePolicyId) throws Exception {
-        assert (morDs != null);
         s_logger.trace(String.format("Creating disk in target MOR [%s] with values: vmdkDatastorePath [%s], sizeInMb [%s], diskType [%s], diskMode [%s], rdmDeviceName [%s]"
                     + ", datastore [%s], controllerKey [%s].", _mor.getValue(), vmdkDatastorePath, sizeInMb, diskType, diskMode, rdmDeviceName, morDs.getValue(), controllerKey));
 
         assert (vmdkDatastorePath != null);
+        assert (morDs != null);
 
         int ideControllerKey = getIDEDeviceControllerKey();
         if (controllerKey < 0) {
@@ -1130,9 +1292,17 @@ public void createDisk(String vmdkDatastorePath, VirtualDiskType diskType, Virtu
 
             VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo();
             backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
-            backingInfo.setThinProvisioned(diskType == VirtualDiskType.THIN);
+            if (diskType == VirtualDiskType.THIN) {
+                backingInfo.setThinProvisioned(true);
+            } else {
+                backingInfo.setThinProvisioned(false);
+            }
 
-            backingInfo.setEagerlyScrub(diskType == VirtualDiskType.EAGER_ZEROED_THICK);
+            if (diskType == VirtualDiskType.EAGER_ZEROED_THICK) {
+                backingInfo.setEagerlyScrub(true);
+            } else {
+                backingInfo.setEagerlyScrub(false);
+            }
 
             backingInfo.setDatastore(morDs);
             backingInfo.setFileName(vmdkDatastorePath);
@@ -1209,7 +1379,7 @@ public void updateVmdkAdapter(String vmdkFileName, String diskController) throws
             if (!currentAdapterType.equalsIgnoreCase(newAdapterType)) {
                 s_logger.info("Updating adapter type to " + newAdapterType + " for VMDK file " + vmdkFileName);
                 Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
-                byte[] newVmdkContent = VmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType);
+                byte[] newVmdkContent = vmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType);
                 String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcInfo.first().getName(), vmdkFileName);
                 getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
                 s_logger.info("Updated VMDK file " + vmdkFileName);
@@ -1236,7 +1406,7 @@ public void updateAdapterTypeIfRequired(String vmdkFileName) throws Exception {
                 VmdkAdapterType newAdapterType = VmdkAdapterType.lsilogic;
                 s_logger.debug("Updating adapter type to " + newAdapterType + " from " + currentAdapterTypeStr + " for VMDK file " + vmdkFileName);
                 Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
-                byte[] newVmdkContent = VmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType.toString());
+                byte[] newVmdkContent = vmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType.toString());
                 String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcInfo.first().getName(), vmdkFileName);
 
                 getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
@@ -1257,8 +1427,8 @@ public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference m
         if(s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: "
                             + GSON.toJson(vmdkDatastorePathChain) + ", datastore: " + morDs.getValue());
-        int controllerKey;
-        int unitNumber;
+        int controllerKey = 0;
+        int unitNumber = 0;
 
         if (DiskControllerType.getType(diskController) == DiskControllerType.ide) {
             // IDE virtual disk cannot be added if VM is running
@@ -1319,6 +1489,21 @@ public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference m
             s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
     }
 
+    private int getControllerBusNumber(int controllerKey) throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualController && device.getKey() == controllerKey) {
+                    return ((VirtualController)device).getBusNumber();
+                }
+            }
+        }
+        throw new Exception("SCSI Controller with key " + controllerKey + " is Not Found");
+
+    }
+
     // vmdkDatastorePath: [datastore name] vmdkFilePath
     public List<Pair<String, ManagedObjectReference>> detachDisk(String vmdkDatastorePath, boolean deleteBackingFile) throws Exception {
 
@@ -1628,7 +1813,7 @@ public Pair<VmdkFileDescriptor, byte[]> getVmdkFileInfo(String vmdkDatastorePath
         VmdkFileDescriptor descriptor = new VmdkFileDescriptor();
         descriptor.parse(content);
 
-        Pair<VmdkFileDescriptor, byte[]> result = new Pair<>(descriptor, content);
+        Pair<VmdkFileDescriptor, byte[]> result = new Pair<VmdkFileDescriptor, byte[]>(descriptor, content);
         if (s_logger.isTraceEnabled()) {
             s_logger.trace("vCenter API trace - getVmdkFileInfo() done");
             s_logger.trace("VMDK file descriptor: " + GSON.toJson(result.first()));
@@ -1707,7 +1892,7 @@ public void exportVm(String exportDir, String exportName, boolean packToOva, boo
                                 if (s_logger.isInfoEnabled()) {
                                     s_logger.info("Download VMDK file for export url: " + deviceUrlStr + ", size: " + diskFileSize);
                                 }
-                                long lengthOfDiskFile = _context.downloadVmdkFile(diskUrlStr, diskLocalPath, totalBytesDownloaded, new ActionDelegate<>() {
+                                long lengthOfDiskFile = _context.downloadVmdkFile(diskUrlStr, diskLocalPath, totalBytesDownloaded, new ActionDelegate<Long>() {
                                     @Override
                                     public void action(Long param) {
                                         if (s_logger.isTraceEnabled()) {
@@ -1732,7 +1917,7 @@ public void action(Long param) {
                                 CompletableFuture<Long> future = CompletableFuture.supplyAsync(() -> {
                                     long lengthOfDiskFile = 0;
                                     try {
-                                        lengthOfDiskFile = _context.downloadVmdkFile(diskUrl, diskLocalPath, totalBytesDownloaded, new ActionDelegate<>() {
+                                        lengthOfDiskFile = _context.downloadVmdkFile(diskUrl, diskLocalPath, totalBytesDownloaded, new ActionDelegate<Long>() {
                                             @Override
                                             public void action(Long param) {
                                                 if (s_logger.isTraceEnabled()) {
@@ -1783,7 +1968,7 @@ public void action(Long param) {
                         String ovfPath = exportDir + File.separator + exportName + ".ovf";
                         fileNames.add(ovfPath);
 
-                        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(ovfPath), StandardCharsets.UTF_8);
+                        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(ovfPath),"UTF-8");
                         out.write(ovfCreateDescriptorResult.getOvfDescriptor());
                         out.close();
 
@@ -1805,7 +1990,7 @@ public void action(Long param) {
                                 }
                             }
 
-                            s_logger.info("Package OVA with command: " + command);
+                            s_logger.info("Package OVA with command: " + command.toString());
                             command.execute();
 
                             // to be safe, physically test existence of the target OVA file
@@ -1854,8 +2039,8 @@ public void setSnapshotDirectory(String snapshotDir) throws Exception {
 
         boolean replaced = false;
         try {
-            in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(vmxContent), StandardCharsets.UTF_8));
-            out = new BufferedWriter(new OutputStreamWriter(bos, StandardCharsets.UTF_8));
+            in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(vmxContent),"UTF-8"));
+            out = new BufferedWriter(new OutputStreamWriter(bos,"UTF-8"));
             String line;
             while ((line = in.readLine()) != null) {
                 if (line.startsWith("workingDir")) {
@@ -1888,6 +2073,70 @@ public void setSnapshotDirectory(String snapshotDir) throws Exception {
         // redoRegistration();
     }
 
+    // destName does not contain extension name
+    public void backupCurrentSnapshot(String deviceName, ManagedObjectReference morDestDs, String destDsDirectory, String destName, boolean includeBase) throws Exception {
+
+        SnapshotDescriptor descriptor = getSnapshotDescriptor();
+        SnapshotInfo[] snapshotInfo = descriptor.getCurrentDiskChain();
+        if (snapshotInfo.length == 0) {
+            String msg = "No snapshot found in this VM";
+            throw new Exception(msg);
+        }
+
+        HostMO hostMo = getRunningHost();
+        DatacenterMO dcMo = getOwnerDatacenter().first();
+        List<Pair<ManagedObjectReference, String>> mounts = hostMo.getDatastoreMountsOnHost();
+        VirtualMachineFileInfo vmFileInfo = getFileInfo();
+
+        List<Ternary<String, String, String>> backupInfo = new ArrayList<Ternary<String, String, String>>();
+
+        for (int i = 0; i < snapshotInfo.length; i++) {
+            if (!includeBase && i == snapshotInfo.length - 1) {
+                break;
+            }
+
+            SnapshotDescriptor.DiskInfo[] disks = snapshotInfo[i].getDisks();
+            if (disks != null) {
+                String destBaseFileName;
+                String destFileName;
+                String destParentFileName;
+                for (SnapshotDescriptor.DiskInfo disk : disks) {
+                    if (deviceName == null || deviceName.equals(disk.getDeviceName())) {
+                        String srcVmdkFullDsPath = getSnapshotDiskFileDatastorePath(vmFileInfo, mounts, disk.getDiskFileName());
+                        Pair<DatastoreMO, String> srcDsInfo = getOwnerDatastore(srcVmdkFullDsPath);
+
+                        Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(srcVmdkFullDsPath);
+                        String srcVmdkBaseFilePath = DatastoreFile.getCompanionDatastorePath(srcVmdkFullDsPath, vmdkInfo.first().getBaseFileName());
+
+                        destFileName = destName + (snapshotInfo.length - i - 1) + ".vmdk";
+                        if (vmdkInfo.first().getParentFileName() != null) {
+                            destBaseFileName = destName + (snapshotInfo.length - i - 1) + "-delta.vmdk";
+                            destParentFileName = destName + (snapshotInfo.length - i - 2) + ".vmdk";
+                        } else {
+                            destBaseFileName = destName + (snapshotInfo.length - i - 1) + "-flat.vmdk";
+                            destParentFileName = null;
+                        }
+
+                        s_logger.info("Copy VMDK base file " + srcVmdkBaseFilePath + " to " + destDsDirectory + "/" + destBaseFileName);
+                        srcDsInfo.first().copyDatastoreFile(srcVmdkBaseFilePath, dcMo.getMor(), morDestDs, destDsDirectory + "/" + destBaseFileName, dcMo.getMor(), true);
+
+                        byte[] newVmdkContent = VmdkFileDescriptor.changeVmdkContentBaseInfo(vmdkInfo.second(), destBaseFileName, destParentFileName);
+                        String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcMo.getName(), destDsDirectory + "/" + destFileName);
+
+                        s_logger.info("Upload VMDK content file to " + destDsDirectory + "/" + destFileName);
+                        getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
+
+                        backupInfo.add(new Ternary<String, String, String>(destFileName, destBaseFileName, destParentFileName));
+                    }
+                }
+            }
+        }
+
+        byte[] vdiskInfo = VmwareHelper.composeDiskInfo(backupInfo, snapshotInfo.length, includeBase);
+        String vdiskUploadUrl = getContext().composeDatastoreBrowseUrl(dcMo.getName(), destDsDirectory + "/" + destName + ".vdisk");
+        getContext().uploadResourceContent(vdiskUploadUrl, vdiskInfo);
+    }
+
     public String[] getCurrentSnapshotDiskChainDatastorePaths(String diskDevice) throws Exception {
         HostMO hostMo = getRunningHost();
         List<Pair<ManagedObjectReference, String>> mounts = hostMo.getDatastoreMountsOnHost();
@@ -1896,9 +2145,9 @@ public String[] getCurrentSnapshotDiskChainDatastorePaths(String diskDevice) thr
         SnapshotDescriptor descriptor = getSnapshotDescriptor();
         SnapshotInfo[] snapshotInfo = descriptor.getCurrentDiskChain();
 
-        List<String> diskDsFullPaths = new ArrayList<>();
-        for (SnapshotInfo info : snapshotInfo) {
-            SnapshotDescriptor.DiskInfo[] disks = info.getDisks();
+        List<String> diskDsFullPaths = new ArrayList<String>();
+        for (int i = 0; i < snapshotInfo.length; i++) {
+            SnapshotDescriptor.DiskInfo[] disks = snapshotInfo[i].getDisks();
             if (disks != null) {
                 for (SnapshotDescriptor.DiskInfo disk : disks) {
                     String deviceNameInDisk = disk.getDeviceName();
@@ -1918,7 +2167,7 @@ public Pair<VirtualMachineMO, String[]> cloneFromCurrentSnapshot(String clonedVm
         assert (morDs != null);
         String[] disks = getCurrentSnapshotDiskChainDatastorePaths(diskDevice);
         VirtualMachineMO clonedVm = cloneFromDiskChain(clonedVmName, cpuSpeedMHz, memoryMb, disks, morDs, virtualHardwareVersion);
-        return new Pair<>(clonedVm, disks);
+        return new Pair<VirtualMachineMO, String[]>(clonedVm, disks);
     }
 
     public VirtualMachineMO cloneFromDiskChain(String clonedVmName, int cpuSpeedMHz, int memoryMb, String[] disks, ManagedObjectReference morDs, String cloneHardwareVersion) throws Exception {
@@ -1969,6 +2218,19 @@ public GuestOsDescriptor getGuestOsDescriptor(String guestOsId) throws Exception
         return guestOsDescriptor;
     }
 
+    public void plugDevice(VirtualDevice device) throws Exception {
+        s_logger.debug(LogUtils.logGsonWithoutException("Pluging device [%s] to VM [%s].", device, getVmName()));
+        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+        deviceConfigSpec.setDevice(device);
+        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+        vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+        if (!configureVm(vmConfigSpec)) {
+            throw new Exception("Failed to add devices");
+        }
+    }
+
     public void tearDownDevice(VirtualDevice device) throws Exception {
         VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
         VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
@@ -2001,8 +2263,40 @@ public void tearDownDevices(Class<?>[] deviceClasses) throws Exception {
         }
     }
 
+    public void copyAllVmDiskFiles(DatastoreMO destDsMo, String destDsDir, boolean followDiskChain) throws Exception {
+        VirtualDevice[] disks = getAllDiskDevice();
+        DatacenterMO dcMo = getOwnerDatacenter().first();
+        if (disks != null) {
+            for (VirtualDevice disk : disks) {
+                List<Pair<String, ManagedObjectReference>> vmdkFiles = getDiskDatastorePathChain((VirtualDisk)disk, followDiskChain);
+                for (Pair<String, ManagedObjectReference> fileItem : vmdkFiles) {
+                    DatastoreMO srcDsMo = new DatastoreMO(_context, fileItem.second());
+
+                    DatastoreFile srcFile = new DatastoreFile(fileItem.first());
+                    DatastoreFile destFile = new DatastoreFile(destDsMo.getName(), destDsDir, srcFile.getFileName());
+
+                    Pair<VmdkFileDescriptor, byte[]> vmdkDescriptor = null;
+
+                    vmdkDescriptor = getVmdkFileInfo(fileItem.first());
+
+                    s_logger.info("Copy VM disk file " + srcFile.getPath() + " to " + destFile.getPath());
+                    srcDsMo.copyDatastoreFile(fileItem.first(), dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
+
+                    if (vmdkDescriptor != null) {
+                        String vmdkBaseFileName = vmdkDescriptor.first().getBaseFileName();
+                        String baseFilePath = srcFile.getCompanionPath(vmdkBaseFileName);
+                        destFile = new DatastoreFile(destDsMo.getName(), destDsDir, vmdkBaseFileName);
+
+                        s_logger.info("Copy VM disk file " + baseFilePath + " to " + destFile.getPath());
+                        srcDsMo.copyDatastoreFile(baseFilePath, dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
+                    }
+                }
+            }
+        }
+    }
+
     public List<String> getVmdkFileBaseNames() throws Exception {
-        List<String> vmdkFileBaseNames = new ArrayList<>();
+        List<String> vmdkFileBaseNames = new ArrayList<String>();
         VirtualDevice[] devices = getAllDiskDevice();
         for(VirtualDevice device : devices) {
             if(device instanceof VirtualDisk) {
@@ -2037,7 +2331,7 @@ public void moveAllVmDiskFiles(DatastoreMO destDsMo, String destDsDir, boolean f
                     DatastoreFile srcFile = new DatastoreFile(fileItem.first());
                     DatastoreFile destFile = new DatastoreFile(destDsMo.getName(), destDsDir, srcFile.getFileName());
 
-                    Pair<VmdkFileDescriptor, byte[]> vmdkDescriptor;
+                    Pair<VmdkFileDescriptor, byte[]> vmdkDescriptor = null;
                     vmdkDescriptor = getVmdkFileInfo(fileItem.first());
 
                     s_logger.info("Move VM disk file " + srcFile.getPath() + " to " + destFile.getPath());
@@ -2056,6 +2350,37 @@ public void moveAllVmDiskFiles(DatastoreMO destDsMo, String destDsDir, boolean f
         }
     }
 
+    public int getPvScsiDeviceControllerKeyNoException() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof ParaVirtualSCSIController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public int getPvScsiDeviceControllerKey() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof ParaVirtualSCSIController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        assert (false);
+        throw new Exception("VMware Paravirtual SCSI Controller Not Found");
+    }
+
     protected VirtualSCSIController getScsiController(DiskControllerType type) {
         switch (type) {
             case pvscsi:
@@ -2139,23 +2464,23 @@ public boolean isPvScsiSupported() throws Exception {
 
     // Would be useful if there exists multiple sub types of SCSI controllers per VM are supported in CloudStack f
     public int getScsiDiskControllerKey(String diskController) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
 
         if (CollectionUtils.isNotEmpty(devices)) {
             DiskControllerType diskControllerType = DiskControllerType.getType(diskController);
             for (VirtualDevice device : devices) {
                 if ((diskControllerType == DiskControllerType.lsilogic || diskControllerType == DiskControllerType.scsi)
                         && device instanceof VirtualLsiLogicController && isValidScsiDiskController((VirtualLsiLogicController)device)) {
-                    return device.getKey();
+                    return ((VirtualLsiLogicController)device).getKey();
                 } else if ((diskControllerType == DiskControllerType.lsisas1068 || diskControllerType == DiskControllerType.scsi)
                         && device instanceof VirtualLsiLogicSASController && isValidScsiDiskController((VirtualLsiLogicSASController)device)) {
-                    return device.getKey();
+                    return ((VirtualLsiLogicSASController)device).getKey();
                 } else if ((diskControllerType == DiskControllerType.pvscsi || diskControllerType == DiskControllerType.scsi)
                         && device instanceof ParaVirtualSCSIController && isValidScsiDiskController((ParaVirtualSCSIController)device)) {
-                    return device.getKey();
+                    return ((ParaVirtualSCSIController)device).getKey();
                 } else if ((diskControllerType == DiskControllerType.buslogic || diskControllerType == DiskControllerType.scsi)
                         && device instanceof VirtualBusLogicController && isValidScsiDiskController((VirtualBusLogicController)device)) {
-                    return device.getKey();
+                    return ((VirtualBusLogicController)device).getKey();
                 }
             }
         }
@@ -2165,7 +2490,7 @@ && device instanceof VirtualBusLogicController && isValidScsiDiskController((Vir
     }
 
     public int getScsiDiskControllerKeyNoException(String diskController, int scsiUnitNumber) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
 
         if (CollectionUtils.isNotEmpty(devices) && scsiUnitNumber >= 0) {
             int requiredScsiController = scsiUnitNumber / VmwareHelper.MAX_ALLOWED_DEVICES_SCSI_CONTROLLER;
@@ -2175,7 +2500,7 @@ public int getScsiDiskControllerKeyNoException(String diskController, int scsiUn
                 if ((diskControllerType == DiskControllerType.lsilogic || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualLsiLogicController) {
                     if (scsiControllerDeviceCount == requiredScsiController) {
                         if (isValidScsiDiskController((VirtualLsiLogicController)device)) {
-                            return device.getKey();
+                            return ((VirtualLsiLogicController)device).getKey();
                         }
                         break;
                     }
@@ -2183,7 +2508,7 @@ public int getScsiDiskControllerKeyNoException(String diskController, int scsiUn
                 } else if ((diskControllerType == DiskControllerType.lsisas1068 || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualLsiLogicSASController) {
                     if (scsiControllerDeviceCount == requiredScsiController) {
                         if (isValidScsiDiskController((VirtualLsiLogicSASController)device)) {
-                            return device.getKey();
+                            return ((VirtualLsiLogicSASController)device).getKey();
                         }
                         break;
                     }
@@ -2191,7 +2516,7 @@ public int getScsiDiskControllerKeyNoException(String diskController, int scsiUn
                 } else if ((diskControllerType == DiskControllerType.pvscsi || diskControllerType == DiskControllerType.scsi) && device instanceof ParaVirtualSCSIController) {
                     if (scsiControllerDeviceCount == requiredScsiController) {
                         if (isValidScsiDiskController((ParaVirtualSCSIController)device)) {
-                            return device.getKey();
+                            return ((ParaVirtualSCSIController)device).getKey();
                         }
                         break;
                     }
@@ -2199,7 +2524,7 @@ public int getScsiDiskControllerKeyNoException(String diskController, int scsiUn
                 } else if ((diskControllerType == DiskControllerType.buslogic || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualBusLogicController) {
                     if (scsiControllerDeviceCount == requiredScsiController) {
                         if (isValidScsiDiskController((VirtualBusLogicController)device)) {
-                            return device.getKey();
+                            return ((VirtualBusLogicController)device).getKey();
                         }
                         break;
                     }
@@ -2212,13 +2537,15 @@ public int getScsiDiskControllerKeyNoException(String diskController, int scsiUn
 
     public int getNextScsiDiskDeviceNumber() throws Exception {
         int scsiControllerKey = getScsiDeviceControllerKey();
-        return getNextDeviceNumber(scsiControllerKey);
+        int deviceNumber = getNextDeviceNumber(scsiControllerKey);
+
+        return deviceNumber;
     }
 
     public int getScsiDeviceControllerKey() throws Exception {
         List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
 
-        if (CollectionUtils.isNotEmpty(devices)) {
+        if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device instanceof VirtualSCSIController && isValidScsiDiskController((VirtualSCSIController)device)) {
                     return device.getKey();
@@ -2233,7 +2560,7 @@ public int getScsiDeviceControllerKey() throws Exception {
     public int getScsiDeviceControllerKeyNoException() throws Exception {
         List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
 
-        if (CollectionUtils.isNotEmpty(devices)) {
+        if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device instanceof VirtualSCSIController && isValidScsiDiskController((VirtualSCSIController)device)) {
                     return device.getKey();
@@ -2271,10 +2598,10 @@ public void ensureLsiLogicDeviceControllers(int count, int availableBusNum) thro
     }
 
     private int getLsiLogicDeviceControllerKeyNoException() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
                 getDynamicProperty(_mor, "config.hardware.device");
 
-        if (CollectionUtils.isNotEmpty(devices)) {
+        if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device instanceof VirtualLsiLogicController) {
                     return device.getKey();
@@ -2306,6 +2633,32 @@ public void ensureScsiDeviceController() throws Exception {
         }
     }
 
+    public void ensureScsiDeviceControllers(int count, int availableBusNum) throws Exception {
+        int scsiControllerKey = getScsiDeviceControllerKeyNoException();
+        if (scsiControllerKey < 0) {
+            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+            int busNum = availableBusNum;
+            while (busNum < count) {
+            VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
+            scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+                scsiController.setBusNumber(busNum);
+                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
+            VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+            scsiControllerSpec.setDevice(scsiController);
+            scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            vmConfig.getDeviceChange().add(scsiControllerSpec);
+                busNum++;
+            }
+            if (configureVm(vmConfig)) {
+                throw new Exception("Unable to add Scsi controllers to the VM " + getName());
+            } else {
+                s_logger.info("Successfully added " + count + " SCSI controllers.");
+            }
+        }
+    }
+
     private boolean isValidScsiDiskController(VirtualSCSIController scsiDiskController) {
         if (scsiDiskController == null) {
             return false;
@@ -2316,7 +2669,11 @@ private boolean isValidScsiDiskController(VirtualSCSIController scsiDiskControll
             return false;
         }
 
-        return scsiDiskController.getBusNumber() < VmwareHelper.MAX_SCSI_CONTROLLER_COUNT;
+        if (scsiDiskController.getBusNumber() >= VmwareHelper.MAX_SCSI_CONTROLLER_COUNT) {
+            return false;
+        }
+
+        return true;
     }
 
     // return pair of VirtualDisk and disk device bus name(ide0:0, etc)
@@ -2334,7 +2691,7 @@ public Pair<VirtualDisk, String> getDiskDevice(String vmdkDatastorePath) throws
 
         s_logger.info(String.format("Looking for disk device info for volume [%s] with base name [%s].", vmdkDatastorePath, srcBaseName));
 
-        if (CollectionUtils.isNotEmpty(devices)) {
+        if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device instanceof VirtualDisk) {
                     s_logger.info(String.format("Testing if disk device with controller key [%s] and unit number [%s] has backing of type VirtualDiskFlatVer2BackingInfo.",
@@ -2418,12 +2775,12 @@ public Pair<VirtualDisk, String> getDiskDevice(String vmdkDatastorePath, boolean
             s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath + " with trimmed base name: " + trimmedSrcBaseName);
         }
 
-        if (CollectionUtils.isNotEmpty(devices)) {
+        if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device instanceof VirtualDisk) {
                     s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber());
 
-                    VirtualDeviceBackingInfo backingInfo = device.getBacking();
+                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
                     if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
                         VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
                         do {
@@ -2436,14 +2793,14 @@ public Pair<VirtualDisk, String> getDiskDevice(String vmdkDatastorePath, boolean
                                     String deviceNumbering = getDeviceBusName(devices, device);
                                     s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
 
-                                    return new Pair<>((VirtualDisk)device, deviceNumbering);
+                                    return new Pair<VirtualDisk, String>((VirtualDisk)device, deviceNumbering);
                                 }
                             } else {
                                 if (backingBaseName.contains(trimmedSrcBaseName)) {
                                     String deviceNumbering = getDeviceBusName(devices, device);
                                     s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
 
-                                    return new Pair<>((VirtualDisk)device, deviceNumbering);
+                                    return new Pair<VirtualDisk, String>((VirtualDisk)device, deviceNumbering);
                                 }
                             }
 
@@ -2459,12 +2816,12 @@ public Pair<VirtualDisk, String> getDiskDevice(String vmdkDatastorePath, boolean
 
     public String getDiskCurrentTopBackingFileInChain(String deviceBusName) throws Exception {
         List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-        if (CollectionUtils.isNotEmpty(devices)) {
+        if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device instanceof VirtualDisk) {
                     s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber());
 
-                    VirtualDeviceBackingInfo backingInfo = device.getBacking();
+                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
                     if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
                         VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
 
@@ -2479,15 +2836,31 @@ public String getDiskCurrentTopBackingFileInChain(String deviceBusName) throws E
         return null;
     }
 
+    public VirtualDisk getDiskDeviceByDeviceBusName(String deviceBusName) throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk) {
+                    String deviceNumbering = getDeviceBusName(devices, device);
+                    if (deviceNumbering.equals(deviceBusName))
+                        return (VirtualDisk)device;
+                }
+            }
+        }
+
+        return null;
+    }
+
     public VirtualMachineDiskInfoBuilder getDiskInfoBuilder() throws Exception {
         VirtualMachineDiskInfoBuilder builder = new VirtualMachineDiskInfoBuilder();
 
         List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
 
-        if (CollectionUtils.isNotEmpty(devices)) {
+        if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device instanceof VirtualDisk) {
-                    VirtualDeviceBackingInfo backingInfo = device.getBacking();
+                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
                     if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
                         VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
                         while (diskBackingInfo != null) {
@@ -2504,16 +2877,16 @@ public VirtualMachineDiskInfoBuilder getDiskInfoBuilder() throws Exception {
     }
 
     public List<Pair<Integer, ManagedObjectReference>> getAllDiskDatastores() throws Exception {
-        List<Pair<Integer, ManagedObjectReference>> disks = new ArrayList<>();
+        List<Pair<Integer, ManagedObjectReference>> disks = new ArrayList<Pair<Integer, ManagedObjectReference>>();
 
         List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
         if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device instanceof VirtualDisk) {
-                    VirtualDeviceBackingInfo backingInfo = device.getBacking();
+                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
                     if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
                         VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
-                        disks.add(new Pair<Integer, ManagedObjectReference>(Integer.valueOf(device.getKey()), diskBackingInfo.getDatastore()));
+                        disks.add(new Pair<Integer, ManagedObjectReference>(new Integer(device.getKey()), diskBackingInfo.getDatastore()));
                     }
                 }
             }
@@ -2720,22 +3093,24 @@ public VirtualDisk getDiskDeviceByBusName(List<VirtualDevice> allDevices, String
     public VirtualDisk[] getAllIndependentDiskDevice() throws Exception {
         List<VirtualDisk> independentDisks = new ArrayList<VirtualDisk>();
         VirtualDisk[] allDisks = getAllDiskDevice();
-        for (VirtualDisk disk : allDisks) {
-            String diskMode = "";
-            if (disk.getBacking() instanceof VirtualDiskFlatVer1BackingInfo) {
-                diskMode = ((VirtualDiskFlatVer1BackingInfo) disk.getBacking()).getDiskMode();
-            } else if (disk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) {
-                diskMode = ((VirtualDiskFlatVer2BackingInfo) disk.getBacking()).getDiskMode();
-            } else if (disk.getBacking() instanceof VirtualDiskRawDiskMappingVer1BackingInfo) {
-                diskMode = ((VirtualDiskRawDiskMappingVer1BackingInfo) disk.getBacking()).getDiskMode();
-            } else if (disk.getBacking() instanceof VirtualDiskSparseVer1BackingInfo) {
-                diskMode = ((VirtualDiskSparseVer1BackingInfo) disk.getBacking()).getDiskMode();
-            } else if (disk.getBacking() instanceof VirtualDiskSparseVer2BackingInfo) {
-                diskMode = ((VirtualDiskSparseVer2BackingInfo) disk.getBacking()).getDiskMode();
-            }
+        if (allDisks.length > 0) {
+            for (VirtualDisk disk : allDisks) {
+                String diskMode = "";
+                if (disk.getBacking() instanceof VirtualDiskFlatVer1BackingInfo) {
+                    diskMode = ((VirtualDiskFlatVer1BackingInfo)disk.getBacking()).getDiskMode();
+                } else if (disk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) {
+                    diskMode = ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getDiskMode();
+                } else if (disk.getBacking() instanceof VirtualDiskRawDiskMappingVer1BackingInfo) {
+                    diskMode = ((VirtualDiskRawDiskMappingVer1BackingInfo)disk.getBacking()).getDiskMode();
+                } else if (disk.getBacking() instanceof VirtualDiskSparseVer1BackingInfo) {
+                    diskMode = ((VirtualDiskSparseVer1BackingInfo)disk.getBacking()).getDiskMode();
+                } else if (disk.getBacking() instanceof VirtualDiskSparseVer2BackingInfo) {
+                    diskMode = ((VirtualDiskSparseVer2BackingInfo)disk.getBacking()).getDiskMode();
+                }
 
-            if (diskMode.indexOf("independent") != -1) {
-                independentDisks.add(disk);
+                if (diskMode.indexOf("independent") != -1) {
+                    independentDisks.add(disk);
+                }
             }
         }
 
@@ -2748,7 +3123,7 @@ public int tryGetIDEDeviceControllerKey() throws Exception {
         if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device instanceof VirtualIDEController) {
-                    return device.getKey();
+                    return ((VirtualIDEController)device).getKey();
                 }
             }
         }
@@ -2762,7 +3137,7 @@ public int getIDEDeviceControllerKey() throws Exception {
         if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device instanceof VirtualIDEController) {
-                    return device.getKey();
+                    return ((VirtualIDEController)device).getKey();
                 }
             }
         }
@@ -2772,7 +3147,7 @@ public int getIDEDeviceControllerKey() throws Exception {
     }
 
     public int getIDEControllerKey(int ideUnitNumber) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
             getDynamicProperty(_mor, "config.hardware.device");
 
         int requiredIdeController = ideUnitNumber / VmwareHelper.MAX_IDE_CONTROLLER_COUNT;
@@ -2782,7 +3157,7 @@ public int getIDEControllerKey(int ideUnitNumber) throws Exception {
             for(VirtualDevice device : devices) {
                 if(device instanceof VirtualIDEController) {
                     if (ideControllerCount == requiredIdeController) {
-                        return device.getKey();
+                        return ((VirtualIDEController)device).getKey();
                     }
                     ideControllerCount++;
                 }
@@ -2795,7 +3170,7 @@ public int getIDEControllerKey(int ideUnitNumber) throws Exception {
 
     public int getNumberOfIDEDevices() throws Exception {
         int ideDeviceCount = 0;
-        List<VirtualDevice> devices = _context.getVimClient().
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
                 getDynamicProperty(_mor, "config.hardware.device");
 
         if (devices != null && devices.size() > 0) {
@@ -2810,7 +3185,7 @@ public int getNumberOfIDEDevices() throws Exception {
 
     public int getFreeUnitNumberOnIDEController(int controllerKey) throws Exception {
         int freeUnitNumber = 0;
-        List<VirtualDevice> devices = _context.getVimClient().
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
                 getDynamicProperty(_mor, "config.hardware.device");
 
         int deviceCount = 0;
@@ -2873,7 +3248,7 @@ public VirtualDevice getIsoDevice(int key) throws Exception {
     }
 
     public VirtualDevice getIsoDevice(String filename) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
                 getDynamicProperty(_mor, "config.hardware.device");
         if(devices != null && devices.size() > 0) {
             long isoDevices = devices.stream()
@@ -2973,19 +3348,19 @@ public Pair<Integer, VirtualDevice> getNicDeviceIndex(String networkNamePrefix)
         String attachedNetworkSummary;
         String dvPortGroupName;
         for (VirtualDevice nic : nics) {
-            attachedNetworkSummary = nic.getDeviceInfo().getSummary();
+            attachedNetworkSummary = ((VirtualEthernetCard)nic).getDeviceInfo().getSummary();
             if (attachedNetworkSummary.startsWith(networkNamePrefix)) {
-                return new Pair<Integer, VirtualDevice>(Integer.valueOf(index), nic);
+                return new Pair<Integer, VirtualDevice>(new Integer(index), nic);
             } else if (attachedNetworkSummary.endsWith("DistributedVirtualPortBackingInfo.summary") || attachedNetworkSummary.startsWith("DVSwitch")) {
                 dvPortGroupName = getDvPortGroupName((VirtualEthernetCard)nic);
                 if (dvPortGroupName != null && dvPortGroupName.startsWith(networkNamePrefix)) {
                     s_logger.debug("Found a dvPortGroup already associated with public NIC.");
-                    return new Pair<Integer, VirtualDevice>(Integer.valueOf(index), nic);
+                    return new Pair<Integer, VirtualDevice>(new Integer(index), nic);
                 }
             }
             index++;
         }
-        return new Pair<Integer, VirtualDevice>(Integer.valueOf(-1), null);
+        return new Pair<Integer, VirtualDevice>(new Integer(-1), null);
     }
 
     public String getDvPortGroupName(VirtualEthernetCard nic) throws Exception {
@@ -2995,7 +3370,7 @@ public String getDvPortGroupName(VirtualEthernetCard nic) throws Exception {
         ManagedObjectReference dvPortGroupMor = new ManagedObjectReference();
         dvPortGroupMor.setValue(dvPortGroupKey);
         dvPortGroupMor.setType("DistributedVirtualPortgroup");
-        return _context.getVimClient().getDynamicProperty(dvPortGroupMor, "name");
+        return (String)_context.getVimClient().getDynamicProperty(dvPortGroupMor, "name");
     }
 
     public VirtualDevice[] getMatchedDevices(Class<?>[] deviceClasses) throws Exception {
@@ -3147,14 +3522,14 @@ public void redoRegistration(ManagedObjectReference morHost) throws Exception {
     }
 
     public long getHotAddMemoryIncrementSizeInMb() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryIncrementSize");
+        return (Long)_context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryIncrementSize");
     }
 
     public long getHotAddMemoryLimitInMb() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryLimit");
+        return (Long)_context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryLimit");
     }
     public String getGuestId() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "config.guestId");
+        return (String)_context.getVimClient().getDynamicProperty(_mor, "config.guestId");
     }
 
     public int getCoresPerSocket() throws Exception {
@@ -3163,7 +3538,7 @@ public int getCoresPerSocket() throws Exception {
         if (apiVersion.compareTo("5.0") < 0) {
             return 1;
         }
-        Integer coresPerSocket = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.numCoresPerSocket");
+        Integer coresPerSocket = (Integer)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.numCoresPerSocket");
         return coresPerSocket != null ? coresPerSocket : 1;
     }
 
@@ -3270,7 +3645,7 @@ public void ensureLsiLogicSasDeviceControllers(int count, int availableBusNum) t
     }
 
     private int getLsiLogicSasDeviceControllerKeyNoException() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
                 getDynamicProperty(_mor, "config.hardware.device");
 
         if (devices != null && devices.size() > 0) {
@@ -3313,7 +3688,7 @@ public void ensureBusLogicDeviceControllers(int count, int availableBusNum) thro
     }
 
     private int getBusLogicDeviceControllerKeyNoException() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
                 getDynamicProperty(_mor, "config.hardware.device");
 
         if (devices != null && devices.size() > 0) {
@@ -3328,7 +3703,7 @@ private int getBusLogicDeviceControllerKeyNoException() throws Exception {
     }
 
     public Ternary<Integer, Integer, DiskControllerType> getScsiControllerInfo() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
                 getDynamicProperty(_mor, "config.hardware.device");
 
         int scsiControllerCount = 0;
@@ -3359,7 +3734,7 @@ public Ternary<Integer, Integer, DiskControllerType> getScsiControllerInfo() thr
     }
 
     public int getNumberOfVirtualDisks() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
 
         s_logger.info("Counting disk devices attached to VM " + getVmName());
         int count = 0;
@@ -3375,7 +3750,7 @@ public int getNumberOfVirtualDisks() throws Exception {
     }
 
     public String getExternalDiskUUID(String datastoreVolumePath) throws Exception{
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
         if (CollectionUtils.isEmpty(devices) || datastoreVolumePath == null) {
             return null;
         }
@@ -3447,7 +3822,7 @@ public void cancelPendingTasks() throws Exception {
 
         int vmTasks = 0, vmPendingTasks = 0;
         for (ManagedObjectReference task : tasks) {
-            TaskInfo info = _context.getVimClient().getDynamicProperty(task, "info");
+            TaskInfo info = (TaskInfo) (_context.getVimClient().getDynamicProperty(task, "info"));
             if (info.getEntityName().equals(vmName)) {
                 vmTasks++;
                 if (!(info.getState().equals(TaskInfoState.SUCCESS) || info.getState().equals(TaskInfoState.ERROR))) {
@@ -3484,7 +3859,7 @@ public void removeChangeTrackPathFromVmdkForDisks() throws Exception {
             if (content == null || content.length == 0) {
                 break;
             }
-            byte[] newVmdkContent = VmdkFileDescriptor.removeChangeTrackPath(content);
+            byte[] newVmdkContent = vmdkFileDescriptor.removeChangeTrackPath(content);
 
             Pair<DatacenterMO, String> dcPair = getOwnerDatacenter();
             String vmdkUrl = getContext().composeDatastoreBrowseUrl(dcPair.second(), diskBackingInfo.getFileName());
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java
index 6ef0840f89ab..ccc68283d062 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java
@@ -16,10 +16,8 @@
 // under the License.
 package com.cloud.hypervisor.vmware.util;
 
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.URI;
-import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -38,23 +36,19 @@
 import javax.xml.ws.handler.HandlerResolver;
 import javax.xml.ws.handler.PortInfo;
 
+
 import org.apache.cloudstack.utils.security.SSLUtils;
 import org.apache.cloudstack.utils.security.SecureSSLSocketFactory;
-
-import com.cloud.utils.StringUtils;
-
-import org.apache.log4j.Logger;
-
-import org.w3c.dom.Element;
-
 import com.vmware.pbm.PbmPortType;
 import com.vmware.pbm.PbmService;
 import com.vmware.pbm.PbmServiceInstanceContent;
 
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Element;
+
 import com.vmware.vim25.DynamicProperty;
 import com.vmware.vim25.InvalidCollectorVersionFaultMsg;
-import com.vmware.vim25.InvalidLocaleFaultMsg;
-import com.vmware.vim25.InvalidLoginFaultMsg;
 import com.vmware.vim25.InvalidPropertyFaultMsg;
 import com.vmware.vim25.LocalizedMethodFault;
 import com.vmware.vim25.ManagedObjectReference;
@@ -164,7 +158,7 @@ public VmwareClient(String name) {
      * @throws Exception
      *             the exception
      */
-    public void connect(String url, String userName, String password) throws RuntimeFaultFaultMsg, URISyntaxException, VmwareClientException, InvalidLocaleFaultMsg, InvalidLoginFaultMsg {
+    public void connect(String url, String userName, String password) throws Exception {
         svcInstRef.setType(SVC_INST_NAME);
         svcInstRef.setValue(SVC_INST_NAME);
 
@@ -194,7 +188,7 @@ public void connect(String url, String userName, String password) throws Runtime
             if (cookies == null) {
                 String msg = "Login successful, but failed to get server cookies from url :[" + url + "]";
                 s_logger.error(msg);
-                throw new  VmwareClientException(msg);
+                throw new Exception(msg);
             }
         }
 
@@ -210,7 +204,7 @@ public void connect(String url, String userName, String password) throws Runtime
         isConnected = true;
     }
 
-    private void pbmConnect(String url, String cookieValue) throws URISyntaxException {
+    private void pbmConnect(String url, String cookieValue) throws Exception {
         URI uri = new URI(url);
         String pbmurl = "https://" + uri.getHost() + "/pbm";
         String[] tokens = cookieValue.split("=");
@@ -354,8 +348,8 @@ public boolean validate() {
      *             in case of error.
      */
     @SuppressWarnings("unchecked")
-    public <T> T getDynamicProperty(ManagedObjectReference mor, String propertyName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
-        List<String> props = new ArrayList<>();
+    public <T> T getDynamicProperty(ManagedObjectReference mor, String propertyName) throws Exception {
+        List<String> props = new ArrayList<String>();
         props.add(propertyName);
         List<ObjectContent> objContent = retrieveMoRefProperties(mor, props);
 
@@ -385,7 +379,7 @@ public <T> T getDynamicProperty(ManagedObjectReference mor, String propertyName)
         return (T)propertyValue;
     }
 
-    private List<ObjectContent> retrieveMoRefProperties(ManagedObjectReference mObj, List<String> props) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
+    private List<ObjectContent> retrieveMoRefProperties(ManagedObjectReference mObj, List<String> props) throws Exception {
         PropertySpec pSpec = new PropertySpec();
         pSpec.setAll(false);
         pSpec.setType(mObj.getType());
@@ -710,7 +704,7 @@ private List<SelectionSpec> constructCompleteTraversalSpec() {
      *
      * @return First ManagedObjectReference of the type / name pair found
      */
-    public ManagedObjectReference getDecendentMoRef(ManagedObjectReference root, String type, String name) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
+    public ManagedObjectReference getDecendentMoRef(ManagedObjectReference root, String type, String name) throws Exception {
         if (name == null || name.length() == 0) {
             return null;
         }
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java
deleted file mode 100644
index 828eed4622de..000000000000
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.vmware.util;
-
-import com.cloud.exception.CloudException;
-
-public class VmwareClientException extends CloudException {
-    public VmwareClientException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    public VmwareClientException(String msg) {
-        super(msg);
-    }
-    // TODO embed vmware classes in this one for use downstream
-    public VmwareClientException(String msg, Exception embedded) {
-        super(msg, embedded);
-    }
-}


Reviews:
user: login: nvazquez
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T08:28:54Z
user: login: sureshanaparti
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T08:24:06Z
user: login: sureshanaparti
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T08:24:52Z
user: login: harikrishna-patnala
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-16T08:47:42Z
user: login: sureshanaparti
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T13:12:57Z
user: login: sureshanaparti
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T13:14:46Z
user: login: DaanHoogland
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T13:27:53Z
user: login: vladimirpetrov
body: LGTM based on manual testing, let's wait for the smoke test results though.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-17T15:14:58Z
user: login: nvazquez
body: Code LGTM

@DaanHoogland can you update the title and description to explain which PR is being reverted and why?
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T11:31:16Z

Review comments:
diff_hunk: @@ -82,6 +82,49 @@ public VirtualMachineMO findVm(String vmName) throws Exception {
         List<ObjectContent> ocs = getVmProperties(new String[] {"name", instanceNameCustomField});
         return HypervisorHostHelper.findVmFromObjectContent(_context, ocs.toArray(new ObjectContent[0]), vmName, instanceNameCustomField);
     }
+    public VirtualMachineMO findVm2(String vmName) throws Exception {
path: vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
user: login: nvazquez
body: Can we rename the `findVm` method to something similar to `findVmThroughPropertiesEx` and rename this `findVm2` method to `findVm`? This way we can redirect all the existing usages of the method to it. Then we could invoke `findVmThroughPropertiesEx` to the listUnmanagedInstances execution
created_at: 2025-04-03T08:28:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -38,23 +36,19 @@
 import javax.xml.ws.handler.HandlerResolver;
 import javax.xml.ws.handler.PortInfo;
 
+
path: vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java
user: login: sureshanaparti
body: ```suggestion
```
created_at: 2025-04-16T08:24:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -281,52 +256,17 @@ export default {
     listZoneVmwareDcs () {
       this.loading = true
       api('listVmwareDcs', { zoneid: this.sourcezoneid }).then(response => {
-        if (response.listvmwaredcsresponse.vmwaredc && response.listvmwaredcsresponse.vmwaredc.length > 0) {
-          this.existingvcenter = response.listvmwaredcsresponse.vmwaredc
+        if (response.listvmwaredcsresponse.VMwareDC && response.listvmwaredcsresponse.VMwareDC.length > 0) {
+          this.existingvcenter = response.listvmwaredcsresponse.VMwareDC
path: ui/src/views/tools/SelectVmwareVcenter.vue
user: login: sureshanaparti
body: @DaanHoogland seems this is the issue for vmware dc listing in zone
created_at: 2025-04-16T08:24:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -281,52 +256,17 @@ export default {
     listZoneVmwareDcs () {
       this.loading = true
       api('listVmwareDcs', { zoneid: this.sourcezoneid }).then(response => {
-        if (response.listvmwaredcsresponse.vmwaredc && response.listvmwaredcsresponse.vmwaredc.length > 0) {
-          this.existingvcenter = response.listvmwaredcsresponse.vmwaredc
+        if (response.listvmwaredcsresponse.VMwareDC && response.listvmwaredcsresponse.VMwareDC.length > 0) {
+          this.existingvcenter = response.listvmwaredcsresponse.VMwareDC
path: ui/src/views/tools/SelectVmwareVcenter.vue
user: login: harikrishna-patnala
body: That is in VmwareData.vue @sureshanaparti but this change is also needed import VMware feature.
created_at: 2025-04-16T08:47:42Z
author_association: MEMBER
diff_hunk: @@ -74,40 +75,35 @@ public Long getZoneId() {
     @Override
     public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
         ResourceAllocationException {
-        List<? extends VmwareDatacenter> vmwareDcList;
+        List<? extends VmwareDatacenter> vmwareDcList = null;
 
         try {
             vmwareDcList = _vmwareDatacenterService.listVmwareDatacenters(this);
         } catch (InvalidParameterValueException ie) {
             throw new InvalidParameterValueException("Invalid zone id " + getZoneId());
         } catch (Exception e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find associated Vmware DCs associated with zone " + getZoneId());
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find associated VMware DCs associated with zone " + getZoneId());
         }
 
-        ListResponse<VmwareDatacenterResponse> response = new ListResponse<>();
-        List<VmwareDatacenterResponse> vmwareDcResponses = getVmwareDatacenterResponses(vmwareDcList);
-        response.setResponses(vmwareDcResponses);
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-    }
+        ListResponse<VmwareDatacenterResponse> response = new ListResponse<VmwareDatacenterResponse>();
+        List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<VmwareDatacenterResponse>();
 
-    private List<VmwareDatacenterResponse> getVmwareDatacenterResponses(List<? extends VmwareDatacenter> vmwareDcList) {
-        List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<>();
-
-        if (vmwareDcList != null && !vmwareDcList.isEmpty()) {
+        if (vmwareDcList != null && vmwareDcList.size() > 0) {
             for (VmwareDatacenter vmwareDc : vmwareDcList) {
                 VmwareDatacenterResponse vmwareDcResponse = new VmwareDatacenterResponse();
 
                 vmwareDcResponse.setId(vmwareDc.getUuid());
                 vmwareDcResponse.setVcenter(vmwareDc.getVcenterHost());
                 vmwareDcResponse.setName(vmwareDc.getVmwareDatacenterName());
                 vmwareDcResponse.setZoneId(getZoneId());
-                vmwareDcResponse.setObjectName(ApiConstants.VMWARE_DC);
+                vmwareDcResponse.setObjectName("VMwareDC");
path: plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java
user: login: sureshanaparti
body: is this change needed? most of the object names used are in lower case. 
created_at: 2025-04-16T13:12:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -281,52 +256,17 @@ export default {
     listZoneVmwareDcs () {
       this.loading = true
       api('listVmwareDcs', { zoneid: this.sourcezoneid }).then(response => {
-        if (response.listvmwaredcsresponse.vmwaredc && response.listvmwaredcsresponse.vmwaredc.length > 0) {
-          this.existingvcenter = response.listvmwaredcsresponse.vmwaredc
+        if (response.listvmwaredcsresponse.VMwareDC && response.listvmwaredcsresponse.VMwareDC.length > 0) {
+          this.existingvcenter = response.listvmwaredcsresponse.VMwareDC
path: ui/src/views/tools/SelectVmwareVcenter.vue
user: login: sureshanaparti
body: correct, @DaanHoogland check if the object name change is requried or not.
created_at: 2025-04-16T13:14:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -74,40 +75,35 @@ public Long getZoneId() {
     @Override
     public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
         ResourceAllocationException {
-        List<? extends VmwareDatacenter> vmwareDcList;
+        List<? extends VmwareDatacenter> vmwareDcList = null;
 
         try {
             vmwareDcList = _vmwareDatacenterService.listVmwareDatacenters(this);
         } catch (InvalidParameterValueException ie) {
             throw new InvalidParameterValueException("Invalid zone id " + getZoneId());
         } catch (Exception e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find associated Vmware DCs associated with zone " + getZoneId());
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find associated VMware DCs associated with zone " + getZoneId());
         }
 
-        ListResponse<VmwareDatacenterResponse> response = new ListResponse<>();
-        List<VmwareDatacenterResponse> vmwareDcResponses = getVmwareDatacenterResponses(vmwareDcList);
-        response.setResponses(vmwareDcResponses);
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-    }
+        ListResponse<VmwareDatacenterResponse> response = new ListResponse<VmwareDatacenterResponse>();
+        List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<VmwareDatacenterResponse>();
 
-    private List<VmwareDatacenterResponse> getVmwareDatacenterResponses(List<? extends VmwareDatacenter> vmwareDcList) {
-        List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<>();
-
-        if (vmwareDcList != null && !vmwareDcList.isEmpty()) {
+        if (vmwareDcList != null && vmwareDcList.size() > 0) {
             for (VmwareDatacenter vmwareDc : vmwareDcList) {
                 VmwareDatacenterResponse vmwareDcResponse = new VmwareDatacenterResponse();
 
                 vmwareDcResponse.setId(vmwareDc.getUuid());
                 vmwareDcResponse.setVcenter(vmwareDc.getVcenterHost());
                 vmwareDcResponse.setName(vmwareDc.getVmwareDatacenterName());
                 vmwareDcResponse.setZoneId(getZoneId());
-                vmwareDcResponse.setObjectName(ApiConstants.VMWARE_DC);
+                vmwareDcResponse.setObjectName("VMwareDC");
path: plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java
user: login: DaanHoogland
body: I agree @sureshanaparti , but this is a revert I can remove this part but than we need to add the code for https://github.com/apache/cloudstack/pull/10731/files
created_at: 2025-04-16T13:27:52Z
author_association: CONTRIBUTOR

PR comments:
user: login: DaanHoogland
created_at: 2025-04-01T15:37:47Z
body: @blueorangutan package
author_association: CONTRIBUTOR
user: login: DaanHoogland
created_at: 2025-04-08T09:51:37Z
body: @blueorangutan package
author_association: CONTRIBUTOR
user: login: blueorangutan
created_at: 2025-04-08T09:52:03Z
body: @DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with  KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
author_association: NONE
user: login: codecov[bot]
created_at: 2025-04-08T09:59:43Z
body: ## [Codecov](https://app.codecov.io/gh/apache/cloudstack/pull/10647?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
Attention: Patch coverage is `1.95122%` with `603 lines` in your changes missing coverage. Please review.
> Project coverage is 15.16%. Comparing base [(`ee94ae5`)](https://app.codecov.io/gh/apache/cloudstack/commit/ee94ae575b7bb28d3350b049454b0026db85c7d1?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) to head [(`c7af57b`)](https://app.codecov.io/gh/apache/cloudstack/commit/c7af57b0b1964bb788e7158d0edfc732559a5cbf?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
> Report is 16 commits behind head on 4.19.

| [Files with missing lines](https://app.codecov.io/gh/apache/cloudstack/pull/10647?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Patch % | Lines |
|---|---|---|
| [...m/cloud/hypervisor/vmware/mo/VirtualMachineMO.java](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&filepath=vmware-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fcloud%2Fhypervisor%2Fvmware%2Fmo%2FVirtualMachineMO.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-dm13YXJlLWJhc2Uvc3JjL21haW4vamF2YS9jb20vY2xvdWQvaHlwZXJ2aXNvci92bXdhcmUvbW8vVmlydHVhbE1hY2hpbmVNTy5qYXZh) | 0.53% | [372 Missing and 3 partials :warning: ](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...d/hypervisor/vmware/manager/VmwareManagerImpl.java](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&filepath=plugins%2Fhypervisors%2Fvmware%2Fsrc%2Fmain%2Fjava%2Fcom%2Fcloud%2Fhypervisor%2Fvmware%2Fmanager%2FVmwareManagerImpl.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGx1Z2lucy9oeXBlcnZpc29ycy92bXdhcmUvc3JjL21haW4vamF2YS9jb20vY2xvdWQvaHlwZXJ2aXNvci92bXdhcmUvbWFuYWdlci9WbXdhcmVNYW5hZ2VySW1wbC5qYXZh) | 6.79% | [94 Missing and 2 partials :warning: ](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...a/com/cloud/hypervisor/vmware/mo/DatacenterMO.java](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&filepath=vmware-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fcloud%2Fhypervisor%2Fvmware%2Fmo%2FDatacenterMO.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-dm13YXJlLWJhc2Uvc3JjL21haW4vamF2YS9jb20vY2xvdWQvaHlwZXJ2aXNvci92bXdhcmUvbW8vRGF0YWNlbnRlck1PLmphdmE=) | 0.00% | [71 Missing :warning: ](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...in/java/com/cloud/hypervisor/vmware/mo/HostMO.java](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&filepath=vmware-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fcloud%2Fhypervisor%2Fvmware%2Fmo%2FHostMO.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-dm13YXJlLWJhc2Uvc3JjL21haW4vamF2YS9jb20vY2xvdWQvaHlwZXJ2aXNvci92bXdhcmUvbW8vSG9zdE1PLmphdmE=) | 0.00% | [14 Missing :warning: ](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...ack/api/command/admin/zone/ListVmwareDcVmsCmd.java](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&filepath=plugins%2Fhypervisors%2Fvmware%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fcloudstack%2Fapi%2Fcommand%2Fadmin%2Fzone%2FListVmwareDcVmsCmd.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGx1Z2lucy9oeXBlcnZpc29ycy92bXdhcmUvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2Nsb3Vkc3RhY2svYXBpL2NvbW1hbmQvYWRtaW4vem9uZS9MaXN0Vm13YXJlRGNWbXNDbWQuamF2YQ==) | 0.00% | [9 Missing :warning: ](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...stack/api/command/admin/zone/ListVmwareDcsCmd.java](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&filepath=plugins%2Fhypervisors%2Fvmware%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fcloudstack%2Fapi%2Fcommand%2Fadmin%2Fzone%2FListVmwareDcsCmd.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGx1Z2lucy9oeXBlcnZpc29ycy92bXdhcmUvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2Nsb3Vkc3RhY2svYXBpL2NvbW1hbmQvYWRtaW4vem9uZS9MaXN0Vm13YXJlRGNzQ21kLmphdmE=) | 0.00% | [9 Missing :warning: ](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...com/cloud/hypervisor/vmware/util/VmwareClient.java](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&filepath=vmware-base%2Fsrc%2Fmain%2Fjava%2Fcom%2Fcloud%2Fhypervisor%2Fvmware%2Futil%2FVmwareClient.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-dm13YXJlLWJhc2Uvc3JjL21haW4vamF2YS9jb20vY2xvdWQvaHlwZXJ2aXNvci92bXdhcmUvdXRpbC9WbXdhcmVDbGllbnQuamF2YQ==) | 0.00% | [7 Missing :warning: ](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...mand/admin/zone/ListVsphereStoragePoliciesCmd.java](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&filepath=plugins%2Fhypervisors%2Fvmware%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fcloudstack%2Fapi%2Fcommand%2Fadmin%2Fzone%2FListVsphereStoragePoliciesCmd.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGx1Z2lucy9oeXBlcnZpc29ycy92bXdhcmUvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2Nsb3Vkc3RhY2svYXBpL2NvbW1hbmQvYWRtaW4vem9uZS9MaXN0VnNwaGVyZVN0b3JhZ2VQb2xpY2llc0NtZC5qYXZh) | 0.00% | [5 Missing :warning: ](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...nd/admin/zone/ImportVsphereStoragePoliciesCmd.java](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&filepath=plugins%2Fhypervisors%2Fvmware%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fcloudstack%2Fapi%2Fcommand%2Fadmin%2Fzone%2FImportVsphereStoragePoliciesCmd.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGx1Z2lucy9oeXBlcnZpc29ycy92bXdhcmUvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2Nsb3Vkc3RhY2svYXBpL2NvbW1hbmQvYWRtaW4vem9uZS9JbXBvcnRWc3BoZXJlU3RvcmFnZVBvbGljaWVzQ21kLmphdmE=) | 0.00% | [4 Missing :warning: ](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...g/apache/cloudstack/api/response/HostResponse.java](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&filepath=api%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fcloudstack%2Fapi%2Fresponse%2FHostResponse.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-YXBpL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jbG91ZHN0YWNrL2FwaS9yZXNwb25zZS9Ib3N0UmVzcG9uc2UuamF2YQ==) | 0.00% | [3 Missing :warning: ](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| ... and [6 more](https://app.codecov.io/gh/apache/cloudstack/pull/10647?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##               4.19   #10647    +/-   ##
==========================================
  Coverage     15.16%   15.16%            
- Complexity    11328    11333     +5     
==========================================
  Files          5415     5412     -3     
  Lines        474824   474997   +173     
  Branches      57912    57957    +45     
==========================================
+ Hits          72014    72041    +27     
- Misses       394757   394899   +142     
- Partials       8053     8057     +4     
```

| [Flag](https://app.codecov.io/gh/apache/cloudstack/pull/10647/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
|---|---|---|
| [uitests](https://app.codecov.io/gh/apache/cloudstack/pull/10647/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `4.29% <ø> (+<0.01%)` | :arrow_up: |
| [unittests](https://app.codecov.io/gh/apache/cloudstack/pull/10647/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `15.89% <1.95%> (-0.01%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/apache/cloudstack/pull/10647?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: blueorangutan
created_at: 2025-04-08T10:17:59Z
body: Packaging result [SF]: ✖️ el8 ✖️ el9 ✖️ debian ✖️ suse15. SL-JID 12977
author_association: NONE
user: login: DaanHoogland
created_at: 2025-04-09T15:05:58Z
body: @blueorangutan package
author_association: CONTRIBUTOR
user: login: blueorangutan
created_at: 2025-04-09T15:08:03Z
body: @DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with  KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
author_association: NONE
user: login: blueorangutan
created_at: 2025-04-09T16:14:44Z
body: Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ debian ✔️ suse15. SL-JID 12997
author_association: NONE
user: login: DaanHoogland
created_at: 2025-04-14T12:02:27Z
body: @blueorangutan test
author_association: CONTRIBUTOR
user: login: blueorangutan
created_at: 2025-04-14T12:04:04Z
body: @DaanHoogland a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests
author_association: NONE
user: login: nvazquez
created_at: 2025-04-14T13:28:54Z
body: @blueorangutan package
author_association: CONTRIBUTOR
user: login: blueorangutan
created_at: 2025-04-14T13:30:04Z
body: @nvazquez a [SL] Jenkins job has been kicked to build packages. It will be bundled with  KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
author_association: NONE
user: login: blueorangutan
created_at: 2025-04-14T14:42:33Z
body: Packaging result [SF]: ✖️ el8 ✖️ el9 ✖️ debian ✖️ suse15. SL-JID 13048
author_association: NONE
user: login: nvazquez
created_at: 2025-04-14T23:37:38Z
body: @DaanHoogland it seems like there are some issues with the UI files, can you please check?
author_association: CONTRIBUTOR
user: login: blueorangutan
created_at: 2025-04-15T03:08:52Z
body: <b>[SF] Trillian test result (tid-12981)</b>
Environment: kvm-ol8 (x2), Advanced Networking with Mgmt server ol8
Total time taken: 51652 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr10647-t12981-kvm-ol8.zip
Smoke tests completed. 133 look OK, 0 have errors, 0 did not run
Only failed and skipped tests results shown below:


Test | Result | Time (s) | Test File
--- | --- | --- | ---

author_association: NONE
user: login: DaanHoogland
created_at: 2025-04-15T08:37:22Z
body: @blueorangutan package
author_association: CONTRIBUTOR
user: login: blueorangutan
created_at: 2025-04-15T08:38:04Z
body: @DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with  KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.
author_association: NONE
user: login: blueorangutan
created_at: 2025-04-15T11:13:33Z
body: Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ debian ✔️ suse15. SL-JID 13058
author_association: NONE
user: login: DaanHoogland
created_at: 2025-04-16T08:04:37Z
body: @blueorangutan test ol8 vmware-70u3
author_association: CONTRIBUTOR
user: login: blueorangutan
created_at: 2025-04-16T08:06:04Z
body: @DaanHoogland a [SL] Trillian-Jenkins test job (ol8 mgmt + vmware-70u3) has been kicked to run smoke tests
author_association: NONE
user: login: harikrishna-patnala
created_at: 2025-04-16T08:48:41Z
body: @blueorangutan ui
author_association: MEMBER
user: login: blueorangutan
created_at: 2025-04-16T08:50:04Z
body: @harikrishna-patnala a Jenkins job has been kicked to build UI QA env. I'll keep you posted as I make progress.
author_association: NONE
user: login: blueorangutan
created_at: 2025-04-16T09:07:24Z
body: UI build: :heavy_check_mark:
Live QA URL: https://qa.cloudstack.cloud/simulator/pr/10647 (QA-JID-600)
author_association: NONE
user: login: blueorangutan
created_at: 2025-04-17T06:23:55Z
body: <b>[SF] Trillian test result (tid-13015)</b>
Environment: vmware-70u3 (x2), Advanced Networking with Mgmt server ol8
Total time taken: 77755 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr10647-t13015-vmware-70u3.zip
Smoke tests completed. 128 look OK, 5 have errors, 0 did not run
Only failed and skipped tests results shown below:


Test | Result | Time (s) | Test File
--- | --- | --- | ---
test_01_events_resource | `Error` | 342.55 | test_events_resource.py
test_04_deploy_vm_for_other_user_and_test_vm_operations | `Error` | 121.76 | test_network_permissions.py
test_01_restore_vm | `Error` | 3626.59 | test_restore_vm.py
test_02_restore_vm_allocated_root | `Error` | 10.05 | test_restore_vm.py
test_01_deploy_vm_on_specific_host | `Error` | 3603.39 | test_vm_deployment_planner.py
test_02_deploy_vm_on_specific_cluster | `Error` | 2.42 | test_vm_deployment_planner.py
test_03_deploy_vm_on_specific_pod | `Error` | 1.42 | test_vm_deployment_planner.py
test_04_deploy_vm_on_host_override_pod_and_cluster | `Error` | 2.48 | test_vm_deployment_planner.py
test_05_deploy_vm_on_cluster_override_pod | `Error` | 2.43 | test_vm_deployment_planner.py
test_09_expunge_vm | `Failure` | 424.64 | test_vm_life_cycle.py

author_association: NONE
user: login: vladimirpetrov
created_at: 2025-04-17T15:03:35Z
body: @blueorangutan test ol8 vmware-70u3
author_association: CONTRIBUTOR
user: login: blueorangutan
created_at: 2025-04-17T15:04:04Z
body: @vladimirpetrov a [SL] Trillian-Jenkins test job (ol8 mgmt + vmware-70u3) has been kicked to run smoke tests
author_association: NONE
user: login: blueorangutan
created_at: 2025-04-17T16:06:33Z
body: <b>[SF] Trillian Build Failed (tid-13042)<b/>
author_association: NONE
user: login: blueorangutan
created_at: 2025-04-19T13:54:52Z
body: <b>[SF] Trillian test result (tid-13054)</b>
Environment: vmware-70u3 (x2), Advanced Networking with Mgmt server ol8
Total time taken: 96591 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr10647-t13054-vmware-70u3.zip
Smoke tests completed. 126 look OK, 7 have errors, 0 did not run
Only failed and skipped tests results shown below:


Test | Result | Time (s) | Test File
--- | --- | --- | ---
test_01_events_resource | `Error` | 333.25 | test_events_resource.py
test_list_vms_metrics_admin | `Error` | 3627.03 | test_metrics_api.py
test_list_vms_metrics_history | `Error` | 7.94 | test_metrics_api.py
test_list_volumes_metrics_history | `Error` | 3623.60 | test_metrics_api.py
test_04_deploy_vm_for_other_user_and_test_vm_operations | `Error` | 157.25 | test_network_permissions.py
test_01_restore_vm | `Error` | 3607.98 | test_restore_vm.py
test_02_restore_vm_allocated_root | `Error` | 3625.45 | test_restore_vm.py
test_02_list_cpvm_vm | `Failure` | 0.06 | test_ssvm.py
test_04_cpvm_internals | `Failure` | 0.06 | test_ssvm.py
test_01_deploy_vm_on_specific_host | `Error` | 3602.21 | test_vm_deployment_planner.py
test_02_deploy_vm_on_specific_cluster | `Error` | 4.46 | test_vm_deployment_planner.py
test_03_deploy_vm_on_specific_pod | `Error` | 4.50 | test_vm_deployment_planner.py
test_04_deploy_vm_on_host_override_pod_and_cluster | `Error` | 4.52 | test_vm_deployment_planner.py
test_05_deploy_vm_on_cluster_override_pod | `Error` | 2.40 | test_vm_deployment_planner.py
test_09_expunge_vm | `Failure` | 424.58 | test_vm_life_cycle.py

author_association: NONE
user: login: DaanHoogland
created_at: 2025-04-20T12:30:45Z
body: @nvazquez @NuxRo , lgty?
author_association: CONTRIBUTOR
user: login: yadvr
created_at: 2025-04-22T11:21:01Z
body: 
@blueorangutan test ol8 vmware-70u3


author_association: MEMBER
user: login: blueorangutan
created_at: 2025-04-22T11:22:04Z
body: @rohityadavcloud a [SL] Trillian-Jenkins test job (ol8 mgmt + vmware-70u3) has been kicked to run smoke tests
author_association: NONE
user: login: blueorangutan
created_at: 2025-04-23T03:45:17Z
body: <b>[SF] Trillian test result (tid-13084)</b>
Environment: vmware-70u3 (x2), Advanced Networking with Mgmt server ol8
Total time taken: 56596 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr10647-t13084-vmware-70u3.zip
Smoke tests completed. 130 look OK, 3 have errors, 0 did not run
Only failed and skipped tests results shown below:


Test | Result | Time (s) | Test File
--- | --- | --- | ---
test_01_events_resource | `Error` | 329.90 | test_events_resource.py
test_01_events_resource | `Error` | 329.91 | test_events_resource.py
test_04_deploy_vm_for_other_user_and_test_vm_operations | `Error` | 129.94 | test_network_permissions.py
test_01_create_redundant_VPC_2tiers_4VMs_4IPs_4PF_ACL | `Failure` | 1016.06 | test_vpc_redundant.py

author_association: NONE