diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/CleanupFullyClonedTemplatesTask.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/CleanupFullyClonedTemplatesTask.java new file mode 100644 index 00000000000..61c118f42e3 --- /dev/null +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/CleanupFullyClonedTemplatesTask.java @@ -0,0 +1,151 @@ +// 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.manager; + +import com.cloud.api.query.dao.TemplateJoinDao; +import com.cloud.api.query.vo.TemplateJoinVO; +import com.cloud.hypervisor.Hypervisor; +import com.cloud.hypervisor.HypervisorGuru; +import com.cloud.storage.VMTemplateStoragePoolVO; +import com.cloud.storage.dao.VMTemplatePoolDao; +import com.cloud.vm.UserVmCloneSettingVO; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.dao.UserVmCloneSettingDao; +import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.engine.orchestration.VolumeOrchestrator; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.log4j.Logger; + +import java.util.List; + +/** + * This Task marks templates that are only used as fully cloned templates and have been deleted from CloudStack for removal from primary stores. + */ +public class CleanupFullyClonedTemplatesTask extends ManagedContextRunnable { + + private static final Logger s_logger = Logger.getLogger(CleanupFullyClonedTemplatesTask.class); + + private PrimaryDataStoreDao primaryStorageDao; + private VMTemplatePoolDao templateDataStoreDao; + private TemplateJoinDao templateDao; + private VMInstanceDao vmInstanceDao; + private UserVmCloneSettingDao cloneSettingDao; + + private Thread mine; + + CleanupFullyClonedTemplatesTask(PrimaryDataStoreDao primaryStorageDao, + VMTemplatePoolDao templateDataStoreDao, + TemplateJoinDao templateDao, + VMInstanceDao vmInstanceDao, + UserVmCloneSettingDao cloneSettingDao) { + this.primaryStorageDao = primaryStorageDao; + this.templateDataStoreDao = templateDataStoreDao; + this.templateDao = templateDao; + this.vmInstanceDao = vmInstanceDao; + this.cloneSettingDao = cloneSettingDao; + if(s_logger.isDebugEnabled()) { + s_logger.debug("new task created: " + this); + } + } + + @Override + public void runInContext() { + mine = Thread.currentThread(); + s_logger.info("running job to mark fully cloned templates for gc in thread " + mine.getName()); + + if (HypervisorGuru.VmwareFullClone.value()) { // only run if full cloning is being used (might need to be more fine grained) + try { + queryAllPools(); + } catch (Throwable t) { + s_logger.error("error during job to mark fully cloned templates for gc in thread " + mine.getName()); + if(s_logger.isDebugEnabled()) { + s_logger.debug("running job to mark fully cloned templates for gc in thread " + mine.getName(),t); + } + } + } + } + + private void queryAllPools() { + List storagePools = primaryStorageDao.listAll(); + for (StoragePoolVO pool : storagePools) { + long zoneId = pool.getDataCenterId(); + queryPoolForTemplates(pool, zoneId); + } + } + + private void queryPoolForTemplates(StoragePoolVO pool, long zoneId) { + // we don't need those specific to other hypervisor types + if (pool.getHypervisor() == null || Hypervisor.HypervisorType.VMware.equals(pool.getHypervisor())) { + if(s_logger.isDebugEnabled()) { + s_logger.debug(mine.getName() + " is marking fully cloned templates in pool " + pool.getName()); + } + List templatePrimaryDataStoreVOS = templateDataStoreDao.listByPoolId(pool.getId()); + for (VMTemplateStoragePoolVO templateMapping : templatePrimaryDataStoreVOS) { + checkTemplateForRemoval(zoneId, templateMapping); + } + } else { + if(s_logger.isDebugEnabled()) { + s_logger.debug(mine.getName() + " is ignoring pool " + pool.getName() + " id == " + pool.getId()); + } + } + } + + private void checkTemplateForRemoval(long zoneId, VMTemplateStoragePoolVO templateMapping) { + if (!templateMapping.getMarkedForGC()) { + if(s_logger.isDebugEnabled()) { + s_logger.debug(mine.getName() + " is checking template with id " + templateMapping.getTemplateId() + " for deletion from pool with id " + templateMapping.getPoolId()); + } + + TemplateJoinVO templateJoinVO = templateDao.findByIdIncludingRemoved(templateMapping.getPoolId()); + // check if these are deleted (not removed is null) + if (templateJoinVO.getRemoved() != null) { // meaning it is removed! + // see if we can find vms using it with user_vm_clone_setting != full + markForGcAsNeeded(templateMapping, zoneId); + } + } + } + + private void markForGcAsNeeded(VMTemplateStoragePoolVO templateMapping, long zoneId) { + boolean used = false; + List vms = vmInstanceDao.listNonExpungedByZoneAndTemplate(zoneId, templateMapping.getTemplateId()); + for (VMInstanceVO vm : vms) { + try { + UserVmCloneSettingVO cloneSetting = cloneSettingDao.findByVmId(vm.getId()); + // VolumeOrchestrator or UserVmManagerImpl depending on version + if (VolumeOrchestrator.UserVmCloneType.linked.equals(VolumeOrchestrator.UserVmCloneType.valueOf(cloneSetting.getCloneType()))) { + used = true; + } + } catch (Exception e) { + s_logger.error("failed to retrieve vm clone setting for vm " + vm.toString()); + if(s_logger.isDebugEnabled()) { + s_logger.debug("failed to retrieve vm clone setting for vm " + vm.toString(), e); + } + } + } + if (!used) { + if(s_logger.isInfoEnabled()) { + s_logger.info(mine.getName() + " is marking template with id " + templateMapping.getTemplateId() + " for gc in pool with id " + templateMapping.getPoolId()); + } + // else + // mark it for removal from primary store + templateMapping.setMarkedForGC(true); + templateDataStoreDao.persist(templateMapping); + } + } +} diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java index 12c48fee026..e5c30da80ed 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java @@ -16,24 +16,25 @@ // under the License. package com.cloud.hypervisor.vmware.manager; -import java.io.File; -import java.util.List; -import java.util.Map; - -import com.vmware.vim25.ManagedObjectReference; - -import org.apache.cloudstack.framework.config.ConfigKey; - import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.vmware.mo.HostMO; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.utils.Pair; +import com.vmware.vim25.ManagedObjectReference; +import org.apache.cloudstack.framework.config.ConfigKey; + +import java.io.File; +import java.util.List; +import java.util.Map; public interface VmwareManager { public final String CONTEXT_STOCK_NAME = "vmwareMgr"; public static final ConfigKey s_vmwareNicHotplugWaitTimeout = new ConfigKey("Advanced", Long.class, "vmware.nic.hotplug.wait.timeout", "15000", - "Wait timeout (milli seconds) for hot plugged NIC of VM to be detected by guest OS.", false, ConfigKey.Scope.Global); + "Wait timeout (milli seconds) for hot plugged NIC of VM to be detected by guest OS.", false, ConfigKey.Scope.Global); + + public static final ConfigKey templateCleanupInterval = new ConfigKey("Advanced", Long.class, "vmware.full.clone.template.cleanup.period", "1440", + "period (in minutes) between the start of template cleanup jobs for vmware full cloned templates.", false, ConfigKey.Scope.Global); public static final ConfigKey s_vmwareCleanOldWorderVMs = new ConfigKey("Advanced", Boolean.class, "vmware.clean.old.worker.vms", "false", "If a worker vm is older then twice the 'job.expire.minutes' + 'job.cancel.threshold.minutes' , remove it.", true, ConfigKey.Scope.Global); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index b0f87af648d..ff85dfe4a7e 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -16,43 +16,6 @@ // under the License. package com.cloud.hypervisor.vmware.manager; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.rmi.RemoteException; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl; -import org.apache.log4j.Logger; - -import com.vmware.vim25.AboutInfo; -import com.vmware.vim25.ManagedObjectReference; - -import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd; -import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd; -import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.framework.config.ConfigKey; -import org.apache.cloudstack.framework.config.Configurable; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.cloudstack.utils.identity.ManagementServerNode; - import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; @@ -61,6 +24,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.api.query.dao.TemplateJoinDao; import com.cloud.cluster.ClusterManager; import com.cloud.cluster.ManagementServerHost; import com.cloud.cluster.dao.ManagementServerHostPeerDao; @@ -103,9 +67,9 @@ import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.network.CiscoNexusVSMDeviceVO; import com.cloud.network.NetworkModel; -import com.cloud.network.VmwareTrafficLabel; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.VmwareTrafficLabel; import com.cloud.network.dao.CiscoNexusVSMDeviceDao; import com.cloud.org.Cluster.ClusterType; import com.cloud.secstorage.CommandExecLogDao; @@ -113,6 +77,8 @@ import com.cloud.server.ConfigurationServer; import com.cloud.storage.ImageStoreDetailsUtil; import com.cloud.storage.JavaStorageLayer; import com.cloud.storage.StorageLayer; +import com.cloud.storage.StorageManager; +import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.utils.FileUtil; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -127,14 +93,48 @@ 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; +import com.vmware.vim25.AboutInfo; +import com.vmware.vim25.ManagedObjectReference; +import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd; +import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd; +import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.utils.identity.ManagementServerNode; +import org.apache.log4j.Logger; + +import javax.inject.Inject; +import javax.naming.ConfigurationException; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.rmi.RemoteException; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable { private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class); private static final long SECONDS_PER_MINUTE = 60; - private static final int STARTUP_DELAY = 60000; // 60 seconds - private static final long DEFAULT_HOST_SCAN_INTERVAL = 600000; // every 10 minutes - private long _hostScanInterval = DEFAULT_HOST_SCAN_INTERVAL; private int _timeout; private String _instance; @@ -175,6 +175,16 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw private ClusterManager _clusterMgr; @Inject private ImageStoreDetailsUtil imageStoreDetailsUtil; + @Inject + private PrimaryDataStoreDao primaryStorageDao; + @Inject + private VMTemplatePoolDao templateDataStoreDao; + @Inject + private TemplateJoinDao templateDao; + @Inject + private VMInstanceDao vmInstanceDao; + @Inject + private UserVmCloneSettingDao cloneSettingDao; private String _mountParent; private StorageLayer _storage; @@ -196,15 +206,15 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw private final String _dataDiskController = DiskControllerType.osdefault.toString(); - private final Map _storageMounts = new HashMap(); + private final Map _storageMounts = new HashMap<>(); private final Random _rand = new Random(System.currentTimeMillis()); + private static ScheduledExecutorService templateCleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-FullyClonedTemplateCheck"));; + private final VmwareStorageManager _storageMgr; private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op"); - private final ScheduledExecutorService _hostScanScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-Host-Scan")); - public VmwareManagerImpl() { _storageMgr = new VmwareStorageManagerImpl(this); } @@ -216,7 +226,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs}; + return new ConfigKey[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs, templateCleanupInterval}; } @Override @@ -313,10 +323,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw s_logger.info("Additional VNC port allocation range is settled at " + _additionalPortRangeStart + " to " + (_additionalPortRangeStart + _additionalPortRangeSize)); - value = _configDao.getValue("vmware.host.scan.interval"); - _hostScanInterval = NumbersUtil.parseLong(value, DEFAULT_HOST_SCAN_INTERVAL); - s_logger.info("VmwareManagerImpl config - vmware.host.scan.interval: " + _hostScanInterval); - ((VmwareStorageManagerImpl)_storageMgr).configure(params); _agentMgr.registerForHostEvents(this, true, true, true); @@ -327,21 +333,20 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw @Override public boolean start() { - _hostScanScheduler.scheduleAtFixedRate(getHostScanTask(), STARTUP_DELAY, _hostScanInterval, TimeUnit.MILLISECONDS); +// Do not run empty task _hostScanScheduler.scheduleAtFixedRate(getHostScanTask(), STARTUP_DELAY, _hostScanInterval, TimeUnit.MILLISECONDS); +// but implement it first! + startTemplateCleanJobSchedule(); startupCleanup(_mountParent); + + s_logger.info("start done"); return true; } @Override public boolean stop() { - _hostScanScheduler.shutdownNow(); - try { - _hostScanScheduler.awaitTermination(3000, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - s_logger.debug("[ignored] interupted while stopping<:/."); - } - + s_logger.info("shutting down scheduled tasks"); + templateCleanupScheduler.shutdown(); shutdownCleanup(); return true; } @@ -670,19 +675,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw return keyFile; } - private Runnable getHostScanTask() { - return new Runnable() { - @Override - public void run() { - // TODO scan vSphere for newly added hosts. - // we are going to both support adding host from CloudStack UI and - // adding host via vSphere server - // - // will implement host scanning later - } - }; - } - @Override public String getMountPoint(String storageUrl, Integer nfsVersion) { String mountPoint = null; @@ -1288,4 +1280,52 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw } } + private void startTemplateCleanJobSchedule() { + if(s_logger.isDebugEnabled()) { + s_logger.debug("checking to see if we should schedule a job to search for fully cloned templates to clean-up"); + } + if(StorageManager.StorageCleanupEnabled.value() && StorageManager.TemplateCleanupEnabled.value()) { + try { + if (s_logger.isInfoEnabled()) { + s_logger.info("scheduling job to search for fully cloned templates to clean-up once per " + templateCleanupInterval.value() + " minutes."); + } +// futureTemplateCleanup = + Runnable task = getCleanupFullyClonedTemplatesTask(); + templateCleanupScheduler.scheduleAtFixedRate(task, + templateCleanupInterval.value(), + templateCleanupInterval.value(), + TimeUnit.MINUTES); + if (s_logger.isTraceEnabled()) { + s_logger.trace("scheduled job to search for fully cloned templates to clean-up."); + } + } catch (RejectedExecutionException ree) { + s_logger.error("job to search for fully cloned templates cannot be scheduled"); + s_logger.debug("job to search for fully cloned templates cannot be scheduled;", ree); + } catch (NullPointerException npe) { + s_logger.error("job to search for fully cloned templates is invalid"); + s_logger.debug("job to search for fully cloned templates is invalid;", npe); + } catch (IllegalArgumentException iae) { + s_logger.error("job to search for fully cloned templates is scheduled at invalid intervals"); + s_logger.debug("job to search for fully cloned templates is scheduled at invalid intervals;", iae); + } catch (Exception e) { + s_logger.error("job to search for fully cloned templates failed for unknown reasons"); + s_logger.debug("job to search for fully cloned templates failed for unknown reasons;", e); + } + } + } + + /** + * 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 + * - when vmware.create.full.clone == true and the entries for VMs having volumes on the primary storage in db table “user_vm_clone_setting” reads 'full' + */ + private Runnable getCleanupFullyClonedTemplatesTask() { + return new CleanupFullyClonedTemplatesTask(primaryStorageDao, + templateDataStoreDao, + templateDao, + vmInstanceDao, + cloneSettingDao); + } } diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java index fec2aba40f6..dea851dfc1b 100644 --- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java +++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java @@ -17,48 +17,8 @@ package com.cloud.hypervisor.vmware; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import javax.inject.Inject; - -import com.cloud.user.User; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.ComponentScan.Filter; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.FilterType; -import org.springframework.core.type.classreading.MetadataReader; -import org.springframework.core.type.classreading.MetadataReaderFactory; -import org.springframework.core.type.filter.TypeFilter; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.support.AnnotationConfigContextLoader; -import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd; -import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd; -import org.apache.cloudstack.context.CallContext; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; -import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; -import org.apache.cloudstack.test.utils.SpringUtils; - import com.cloud.agent.AgentManager; +import com.cloud.api.query.dao.TemplateJoinDao; import com.cloud.cluster.ClusterManager; import com.cloud.cluster.dao.ManagementServerHostPeerDao; import com.cloud.dc.ClusterDetailsDao; @@ -89,15 +49,57 @@ import com.cloud.org.Managed.ManagedState; import com.cloud.secstorage.CommandExecLogDao; import com.cloud.server.ConfigurationServer; import com.cloud.storage.ImageStoreDetailsUtil; +import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountService; import com.cloud.user.AccountVO; +import com.cloud.user.User; import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.dao.UserVmCloneSettingDao; import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd; +import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.test.utils.SpringUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.core.type.filter.TypeFilter; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import javax.inject.Inject; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.mockito.Mockito.when; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = AnnotationConfigContextLoader.class) @@ -447,6 +449,27 @@ public class VmwareDatacenterApiUnitTest { return Mockito.mock(ImageStoreDetailsDao.class); } + @Bean + public VMTemplatePoolDao templateDataStoreDao() { + return Mockito.mock(VMTemplatePoolDao.class); + } + @Bean + public TemplateJoinDao templateDao() { + return Mockito.mock(TemplateJoinDao.class); + } + @Bean + public VMInstanceDao vmInstanceDao() { + return Mockito.mock(VMInstanceDao.class); + } + @Bean + public UserVmCloneSettingDao cloneSettingDao() { + return Mockito.mock(UserVmCloneSettingDao.class); + } + @Bean + public PrimaryDataStoreDao primaryStorageDao() { + return Mockito.mock(PrimaryDataStoreDao.class); + } + public static class Library implements TypeFilter { @Override