Liron Aravot has uploaded a new change for review.

Change subject: core: Extracting OvfDataUpdater logic to commands
......................................................................

core: Extracting OvfDataUpdater logic to commands

This patch moves the ovf update logic resides within the
OvfDataUpdater to BLL commands, so that it can be executed easily by
other flows as well.

The logic was mainly moved to ProcessOvfUpdateForStoragePoolCommand,
tests were added accordingly.

Change-Id: I6780aedf2d215d08c4bed0ff4f7520c45f753f66
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1138124
Signed-off-by: Liron Aravot <[email protected]>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ExportVmCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ExportVmTemplateCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OvfDataUpdater.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OvfUpdateProcessHelper.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessDownVmCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessOvfUpdateForStoragePoolCommand.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/OvfDataUpdaterTest.java
A 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/ProcessOvfUpdateForStoragePoolCommandTest.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
10 files changed, 1,390 insertions(+), 1,398 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/15/35815/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ExportVmCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ExportVmCommand.java
index d69ff8e..7973010 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ExportVmCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ExportVmCommand.java
@@ -512,13 +512,14 @@
     }
 
     protected boolean updateVmInSpm() {
+        OvfUpdateProcessHelper ovfHelper = new OvfUpdateProcessHelper();
         Map<Guid, KeyValuePairCompat<String, List<Guid>>> metaDictionary =
                 new HashMap<Guid, KeyValuePairCompat<String, List<Guid>>>();
-        OvfDataUpdater.getInstance().loadVmData(getVm());
-        OvfDataUpdater.getInstance().buildMetadataDictionaryForVm(getVm(),
+        ovfHelper.loadVmData(getVm());
+        ovfHelper.buildMetadataDictionaryForVm(getVm(),
                 metaDictionary,
-                OvfDataUpdater.getInstance().getVmImagesFromDb(getVm()));
-        return 
OvfDataUpdater.getInstance().executeUpdateVmInSpmCommand(getVm().getStoragePoolId(),
+                ovfHelper.getVmImagesFromDb(getVm()));
+        return 
ovfHelper.executeUpdateVmInSpmCommand(getVm().getStoragePoolId(),
                 metaDictionary, getParameters().getStorageDomainId());
     }
 
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ExportVmTemplateCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ExportVmTemplateCommand.java
index 662c1df..25770bb 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ExportVmTemplateCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ExportVmTemplateCommand.java
@@ -181,11 +181,12 @@
         if (getParameters().getTaskGroupSuccess()) {
             Map<Guid, KeyValuePairCompat<String, List<Guid>>> metaDictionary =
                     new HashMap<Guid, KeyValuePairCompat<String, 
List<Guid>>>();
-            OvfDataUpdater.getInstance().loadTemplateData(getVmTemplate());
+            OvfUpdateProcessHelper ovfUpdateProcessHelper = new 
OvfUpdateProcessHelper();
+            ovfUpdateProcessHelper.loadTemplateData(getVmTemplate());
             VmTemplateHandler.updateDisksFromDb(getVmTemplate());
             // update the target (export) domain
-            
OvfDataUpdater.getInstance().buildMetadataDictionaryForTemplate(getVmTemplate(),
 metaDictionary);
-            
OvfDataUpdater.getInstance().executeUpdateVmInSpmCommand(getVmTemplate().getStoragePoolId(),
+            
ovfUpdateProcessHelper.buildMetadataDictionaryForTemplate(getVmTemplate(), 
metaDictionary);
+            
ovfUpdateProcessHelper.executeUpdateVmInSpmCommand(getVmTemplate().getStoragePoolId(),
                     metaDictionary,
                     getParameters().getStorageDomainId());
         }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OvfDataUpdater.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OvfDataUpdater.java
index 4cb75ce..4e31c59 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OvfDataUpdater.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OvfDataUpdater.java
@@ -1,71 +1,23 @@
 package org.ovirt.engine.core.bll;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.commons.lang.StringUtils;
-import org.ovirt.engine.core.bll.utils.ClusterUtils;
-import org.ovirt.engine.core.common.AuditLogType;
 import org.ovirt.engine.core.common.FeatureSupported;
 import org.ovirt.engine.core.common.action.StorageDomainParametersBase;
+import org.ovirt.engine.core.common.action.StoragePoolParametersBase;
 import org.ovirt.engine.core.common.action.VdcActionType;
-import org.ovirt.engine.core.common.businessentities.Disk;
-import org.ovirt.engine.core.common.businessentities.DiskImage;
-import org.ovirt.engine.core.common.businessentities.ImageStatus;
-import org.ovirt.engine.core.common.businessentities.Snapshot;
-import org.ovirt.engine.core.common.businessentities.Snapshot.SnapshotStatus;
-import org.ovirt.engine.core.common.businessentities.StorageDomain;
-import org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfo;
-import 
org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfoStatus;
-import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
+import org.ovirt.engine.core.common.action.VdcReturnValueBase;
 import org.ovirt.engine.core.common.businessentities.StoragePool;
 import org.ovirt.engine.core.common.businessentities.StoragePoolStatus;
-import org.ovirt.engine.core.common.businessentities.VM;
-import org.ovirt.engine.core.common.businessentities.VMStatus;
-import org.ovirt.engine.core.common.businessentities.VmBase;
-import org.ovirt.engine.core.common.businessentities.VmDevice;
-import org.ovirt.engine.core.common.businessentities.VmDeviceGeneralType;
-import org.ovirt.engine.core.common.businessentities.VmTemplate;
-import org.ovirt.engine.core.common.businessentities.VmTemplateStatus;
 import org.ovirt.engine.core.common.config.Config;
 import org.ovirt.engine.core.common.config.ConfigValues;
-import org.ovirt.engine.core.common.constants.StorageConstants;
-import org.ovirt.engine.core.common.errors.VdcBllMessages;
-import org.ovirt.engine.core.common.locks.LockingGroup;
-import org.ovirt.engine.core.common.utils.Pair;
-import org.ovirt.engine.core.common.vdscommands.RemoveVMVDSCommandParameters;
-import org.ovirt.engine.core.common.vdscommands.UpdateVMVDSCommandParameters;
-import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
 import org.ovirt.engine.core.compat.Guid;
-import org.ovirt.engine.core.compat.KeyValuePairCompat;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
-import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector;
-import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase;
-import org.ovirt.engine.core.dao.SnapshotDao;
-import org.ovirt.engine.core.dao.StorageDomainDAO;
-import org.ovirt.engine.core.dao.StorageDomainOvfInfoDao;
 import org.ovirt.engine.core.dao.StoragePoolDAO;
-import org.ovirt.engine.core.dao.StoragePoolIsoMapDAO;
-import org.ovirt.engine.core.dao.VmAndTemplatesGenerationsDAO;
-import org.ovirt.engine.core.dao.VmDAO;
-import org.ovirt.engine.core.dao.VmStaticDAO;
-import org.ovirt.engine.core.dao.VmTemplateDAO;
-import org.ovirt.engine.core.dao.network.VmNetworkInterfaceDao;
-import org.ovirt.engine.core.utils.linq.Function;
-import org.ovirt.engine.core.utils.linq.LinqUtils;
-import org.ovirt.engine.core.utils.lock.EngineLock;
-import org.ovirt.engine.core.utils.lock.LockManager;
-import org.ovirt.engine.core.utils.lock.LockManagerFactory;
 import org.ovirt.engine.core.utils.log.Log;
 import org.ovirt.engine.core.utils.log.LogFactory;
-import org.ovirt.engine.core.utils.ovf.OvfManager;
 import org.ovirt.engine.core.utils.timer.OnTimerMethodAnnotation;
 import org.ovirt.engine.core.utils.timer.SchedulerUtil;
 import org.ovirt.engine.core.utils.timer.SchedulerUtilQuartzImpl;
@@ -73,18 +25,8 @@
 public class OvfDataUpdater {
     private static final Log log = LogFactory.getLog(OvfDataUpdater.class);
     private static final OvfDataUpdater INSTANCE = new OvfDataUpdater();
-    private int itemsCountPerUpdate;
-
-    private List<Guid> proccessedIdsInfo;
-    private List<Long> proccessedOvfGenerationsInfo;
-    private List<String> proccessedOvfConfigurationsInfo;
-    private HashSet<Guid> proccessedDomains;
-    private List<Guid> removedOvfIdsInfo;
-
-    private OvfManager ovfManager;
 
     private OvfDataUpdater() {
-        ovfManager = new OvfManager();
     }
 
     public static OvfDataUpdater getInstance() {
@@ -103,509 +45,43 @@
         log.info("Initialization of OvfDataUpdater completed successfully.");
     }
 
-    protected int reloadConfigValue() {
-        return Config.<Integer> getValue(ConfigValues.OvfItemsCountPerUpdate);
-    }
-
-    private LockManager getLockManager() {
-        return LockManagerFactory.getLockManager();
-    }
-
-    protected boolean acquireLock(EngineLock engineLock) {
-        return 
LockManagerFactory.getLockManager().acquireLock(engineLock).getFirst();
-    }
-
-    protected void releaseLock(EngineLock engineLock) {
-        LockManagerFactory.getLockManager().releaseLock(engineLock);
-    }
-
-    private void logInfoIfNeeded(StoragePool pool, String message, Object... 
args) {
-        // if supported, the info would be logged when executing for each 
domain
-        if (!ovfOnAnyDomainSupported(pool)) {
-            log.infoFormat(message, args);
-        }
-    }
-
-    protected void proceedPoolOvfUpdate(StoragePool pool) {
-        proccessedDomains = new HashSet<>();
-        if (ovfOnAnyDomainSupported(pool)) {
-            proccessDomainsForOvfUpdate(pool);
-        }
-
-        logInfoIfNeeded(pool, "Attempting to update VM OVFs in Data Center 
{0}",
-                pool.getName());
-        initProcessedInfoLists();
-
-        updateOvfForVmsOfStoragePool(pool);
-
-        logInfoIfNeeded(pool, "Successfully updated VM OVFs in Data Center 
{0}",
-                pool.getName());
-        logInfoIfNeeded(pool, "Attempting to update template OVFs in Data 
Center {0}",
-                pool.getName());
-
-        updateOvfForTemplatesOfStoragePool(pool);
-
-        logInfoIfNeeded(pool, "Successfully updated templates OVFs in Data 
Center {0}",
-                pool.getName());
-        logInfoIfNeeded(pool, "Attempting to remove unneeded template/vm OVFs 
in Data Center {0}",
-                pool.getName());
-
-        removeOvfForTemplatesAndVmsOfStoragePool(pool);
-
-        logInfoIfNeeded(pool, "Successfully removed unneeded template/vm OVFs 
in Data Center {0}",
-                pool.getName());
-    }
-
     protected void performOvfUpdateForDomain(Guid storagePoolId, Guid 
domainId) {
         
Backend.getInstance().runInternalAction(VdcActionType.ProcessOvfUpdateForStorageDomain,
 new StorageDomainParametersBase(storagePoolId, domainId));
     }
 
-    private EngineLock buildPoolEngineLock(StoragePool pool) {
-        Map<String, Pair<String, String>> exclusiveLocks =
-                Collections.singletonMap(pool.getId().toString(),
-                        
LockMessagesMatchUtil.makeLockingPair(LockingGroup.OVF_UPDATE,
-                                
VdcBllMessages.ACTION_TYPE_FAILED_OBJECT_LOCKED));
-        return new EngineLock(exclusiveLocks, null);
+    protected VdcReturnValueBase performOvfUpdateForStoragePool(Guid 
storagePoolId) {
+        return 
Backend.getInstance().runInternalAction(VdcActionType.ProcessOvfUpdateForStoragePool,
 new StoragePoolParametersBase(storagePoolId));
     }
 
     @OnTimerMethodAnnotation("ovfUpdate_timer")
     public void ovfUpdate_timer() {
-        itemsCountPerUpdate = reloadConfigValue();
-        log.info("Attempting to update VMs/Templates Ovf.");
         List<StoragePool> storagePools = 
getStoragePoolDao().getAllByStatus(StoragePoolStatus.Up);
+        updateOvfData(storagePools);
+    }
+
+
+    public void updateOvfData(List<StoragePool> storagePools) {
+        log.info("Attempting to update VMs/Templates Ovf.");
         for (StoragePool pool : storagePools) {
-            EngineLock poolLock = buildPoolEngineLock(pool);
-            if (!acquireLock(poolLock)) {
-                    log.errorFormat("Failed to update OVFs in Data Center {0} 
as there is a related operation in progress.", pool.getName());
-                continue;
+            VdcReturnValueBase returnValueBase = 
performOvfUpdateForStoragePool(pool.getId());
+            if (!returnValueBase.getSucceeded()) {
+                log.errorFormat("Exception while trying to update or remove 
VMs/Templates ovf in Data Center {0}.", pool.getName());
             }
 
-            boolean lockReleased = false;
+            if (ovfOnAnyDomainSupported(pool)) {
+                log.debugFormat("Attempting to update ovfs in domain in Data 
Center {0}",
+                        pool.getName());
 
-            try {
-                proceedPoolOvfUpdate(pool);
-                if (ovfOnAnyDomainSupported(pool)) {
-                    logInfoIfNeeded(pool, "Attempting to update ovfs in domain 
in Data Center {0}",
-                            pool.getName());
-
-                    releaseLock(poolLock);
-                    lockReleased = true;
-
-                    for (Guid id : proccessedDomains) {
+                Set<Guid> domainsToUpdate = (Set<Guid>) 
returnValueBase.getActionReturnValue();
+                if (domainsToUpdate != null) {
+                    for (Guid id : domainsToUpdate) {
                         performOvfUpdateForDomain(pool.getId(), id);
                     }
-                }
-            } catch (Exception ex) {
-                addAuditLogError(pool.getName());
-                log.errorFormat("Exception while trying to update or remove 
VMs/Templates ovf in Data Center {0}.", pool.getName(), ex);
-            } finally {
-                if (!lockReleased) {
-                    releaseLock(poolLock);
+                } else {
+                    log.error("Data Center {0} domains list for OVF update 
returned as NULL");
                 }
             }
         }
-        proccessedIdsInfo = null;
-        removedOvfIdsInfo = null;
-        proccessedOvfGenerationsInfo = null;
-        proccessedOvfConfigurationsInfo = null;
-        proccessedDomains = null;
-    }
-
-
-    protected void proccessDomainsForOvfUpdate(StoragePool pool) {
-        List<StorageDomain> domainsInPool = 
getStorageDomainDao().getAllForStoragePool(pool.getId());
-        for (StorageDomain domain : domainsInPool) {
-            if (!domain.getStorageDomainType().isDataDomain() || 
domain.getStatus() != StorageDomainStatus.Active) {
-               continue;
-            }
-
-            Integer ovfStoresCountForDomain = Config.<Integer> 
getValue(ConfigValues.StorageDomainOvfStoreCount);
-            List<StorageDomainOvfInfo> storageDomainOvfInfos = 
getStorageDomainOvfInfoDao().getAllForDomain(domain.getId());
-
-            if (storageDomainOvfInfos.size() < ovfStoresCountForDomain) {
-                proccessedDomains.add(domain.getId());
-                continue;
-            }
-
-            for (StorageDomainOvfInfo storageDomainOvfInfo : 
storageDomainOvfInfos) {
-                if (storageDomainOvfInfo.getStatus() == 
StorageDomainOvfInfoStatus.OUTDATED) {
-                    
proccessedDomains.add(storageDomainOvfInfo.getStorageDomainId());
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * Update ovfs for updated/newly vms since last run for the given storage 
pool
-     *
-     */
-    protected void updateOvfForVmsOfStoragePool(StoragePool pool) {
-        Guid poolId = pool.getId();
-        List<Guid> vmsIdsForUpdate = 
getVmAndTemplatesGenerationsDao().getVmsIdsForOvfUpdate(poolId);
-        int i = 0;
-        while (i < vmsIdsForUpdate.size()) {
-            int size = Math.min(itemsCountPerUpdate, vmsIdsForUpdate.size() - 
i);
-            List<Guid> idsToProcess = vmsIdsForUpdate.subList(i, i + size);
-            i += size;
-
-            Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
vmsAndTemplateMetadata =
-                    populateVmsMetadataForOvfUpdate(idsToProcess);
-            if (!vmsAndTemplateMetadata.isEmpty()) {
-                performOvfUpdate(pool, vmsAndTemplateMetadata);
-            }
-        }
-    }
-
-    /**
-     * Removes from the storage ovf files of vm/templates that were removed 
from the db since the last OvfDataUpdater
-     * run.
-     *
-     */
-    protected void removeOvfForTemplatesAndVmsOfStoragePool(StoragePool pool) {
-        Guid poolId = pool.getId();
-        removedOvfIdsInfo = 
getVmAndTemplatesGenerationsDao().getIdsForOvfDeletion(poolId);
-
-        if (!ovfOnAnyDomainSupported(pool)) {
-            for (Guid id : removedOvfIdsInfo) {
-                executeRemoveVmInSpm(poolId, id, Guid.Empty);
-            }
-        }
-
-        markDomainsWithOvfsForOvfUpdate(removedOvfIdsInfo);
-        
getVmAndTemplatesGenerationsDao().deleteOvfGenerations(removedOvfIdsInfo);
-    }
-
-    protected void markDomainsWithOvfsForOvfUpdate(Collection<Guid> ovfIds) {
-        List<Guid> relevantDomains = 
getStorageDomainOvfInfoDao().loadStorageDomainIdsForOvfIds(ovfIds);
-        proccessedDomains.addAll(relevantDomains);
-        getStorageDomainOvfInfoDao().updateOvfUpdatedInfo(proccessedDomains, 
StorageDomainOvfInfoStatus.OUTDATED, StorageDomainOvfInfoStatus.DISABLED);
-    }
-
-    /**
-     * Perform vdsm call which performs ovf update for the given metadata map
-     *
-     */
-    protected void performOvfUpdate(StoragePool pool,
-            Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
vmsAndTemplateMetadata) {
-        if (!ovfOnAnyDomainSupported(pool)) {
-            executeUpdateVmInSpmCommand(pool.getId(), vmsAndTemplateMetadata, 
Guid.Empty);
-        } else {
-            markDomainsWithOvfsForOvfUpdate(vmsAndTemplateMetadata.keySet());
-        }
-
-        int i = 0;
-        while (i < proccessedIdsInfo.size()) {
-            int sizeToUpdate = 
Math.min(StorageConstants.OVF_MAX_ITEMS_PER_SQL_STATEMENT, 
proccessedIdsInfo.size() - i);
-            List<Guid> guidsForUpdate = proccessedIdsInfo.subList(i, i + 
sizeToUpdate);
-            List<Long> ovfGenerationsForUpdate = 
proccessedOvfGenerationsInfo.subList(i, i + sizeToUpdate);
-            List<String> ovfConfigurationsInfo = 
proccessedOvfConfigurationsInfo.subList(i, i + sizeToUpdate);
-            
getVmAndTemplatesGenerationsDao().updateOvfGenerations(guidsForUpdate, 
ovfGenerationsForUpdate, ovfConfigurationsInfo);
-            i += sizeToUpdate;
-            initProcessedInfoLists();
-        }
-    }
-
-    /**
-     * Creates and returns a map containing valid templates metadata
-     */
-    protected Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
populateTemplatesMetadataForOvfUpdate(List<Guid> idsToProcess) {
-        Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
vmsAndTemplateMetadata =
-                new HashMap<Guid, KeyValuePairCompat<String, List<Guid>>>();
-        List<VmTemplate> templates = 
getVmTemplateDao().getVmTemplatesByIds(idsToProcess);
-
-        for (VmTemplate template : templates) {
-            if (VmTemplateStatus.Locked != template.getStatus()) {
-                updateTemplateDisksFromDb(template);
-                boolean verifyDisksNotLocked = 
verifyImagesStatus(template.getDiskList());
-                if (verifyDisksNotLocked) {
-                    loadTemplateData(template);
-                    Long currentDbGeneration = 
getVmStaticDao().getDbGeneration(template.getId());
-                    // currentDbGeneration can be null in case that the 
template was deleted during the run of OvfDataUpdater.
-                    if (currentDbGeneration != null && 
template.getDbGeneration() == currentDbGeneration) {
-                        
proccessedOvfConfigurationsInfo.add(buildMetadataDictionaryForTemplate(template,
 vmsAndTemplateMetadata));
-                        proccessedIdsInfo.add(template.getId());
-                        
proccessedOvfGenerationsInfo.add(template.getDbGeneration());
-                        proccessDisksDomains(template.getDiskList());
-                    }
-                }
-            }
-        }
-
-        return vmsAndTemplateMetadata;
-    }
-
-    protected void updateTemplateDisksFromDb(VmTemplate template) {
-        VmTemplateHandler.updateDisksFromDb(template);
-    }
-
-    protected void updateVmDisksFromDb(VM vm) {
-        VmHandler.updateDisksFromDb(vm);
-    }
-
-    /**
-     * Update ovfs for updated/added templates since last for the given 
storage pool
-     */
-    protected void updateOvfForTemplatesOfStoragePool(StoragePool pool) {
-        Guid poolId = pool.getId();
-        List<Guid> templateIdsForUpdate =
-                
getVmAndTemplatesGenerationsDao().getVmTemplatesIdsForOvfUpdate(poolId);
-        int i = 0;
-        while (i < templateIdsForUpdate.size()) {
-            int size = Math.min(templateIdsForUpdate.size() - i, 
itemsCountPerUpdate);
-            List<Guid> idsToProcess = templateIdsForUpdate.subList(i, i + 
size);
-            i += size;
-
-            Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
vmsAndTemplateMetadata =
-                    populateTemplatesMetadataForOvfUpdate(idsToProcess);
-            if (!vmsAndTemplateMetadata.isEmpty()) {
-                performOvfUpdate(pool, vmsAndTemplateMetadata);
-            }
-        }
-    }
-
-    /**
-     * Create and returns map contains valid vms metadata
-     */
-    protected Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
populateVmsMetadataForOvfUpdate(List<Guid> idsToProcess) {
-        Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
vmsAndTemplateMetadata =
-                new HashMap<Guid, KeyValuePairCompat<String, List<Guid>>>();
-        List<VM> vms = getVmDao().getVmsByIds(idsToProcess);
-        for (VM vm : vms) {
-            if (VMStatus.ImageLocked != vm.getStatus()) {
-                updateVmDisksFromDb(vm);
-                if (!verifyImagesStatus(vm.getDiskList())) {
-                    continue;
-                }
-                ArrayList<DiskImage> vmImages = getVmImagesFromDb(vm);
-                if (!verifyImagesStatus(vmImages)) {
-                    continue;
-                }
-                
vm.setSnapshots(getSnapshotDao().getAllWithConfiguration(vm.getId()));
-                if (!verifySnapshotsStatus(vm.getSnapshots())) {
-                    continue;
-                }
-
-                loadVmData(vm);
-                Long currentDbGeneration = 
getVmStaticDao().getDbGeneration(vm.getId());
-                if (currentDbGeneration == null) {
-                    log.warnFormat("currentDbGeneration of VM (name: {0}, id: 
{1}) is null, probably because the VM was deleted during the run of 
OvfDataUpdater.",
-                            vm.getName(),
-                            vm.getId());
-                    continue;
-                }
-                if (vm.getStaticData().getDbGeneration() == 
currentDbGeneration) {
-                    
proccessedOvfConfigurationsInfo.add(buildMetadataDictionaryForVm(vm, 
vmsAndTemplateMetadata, vmImages));
-                    proccessedIdsInfo.add(vm.getId());
-                    
proccessedOvfGenerationsInfo.add(vm.getStaticData().getDbGeneration());
-                    proccessDisksDomains(vm.getDiskList());
-                }
-            }
-        }
-        return vmsAndTemplateMetadata;
-    }
-
-    protected ArrayList<DiskImage> getVmImagesFromDb(VM vm) {
-        ArrayList<DiskImage> allVmImages = new ArrayList<>();
-        List<DiskImage> filteredDisks = 
ImagesHandler.filterImageDisks(vm.getDiskList(), false, true, true);
-
-        for (DiskImage diskImage : filteredDisks) {
-            allVmImages.addAll(getAllImageSnapshots(diskImage));
-        }
-        return allVmImages;
-    }
-
-    protected void proccessDisksDomains(List<DiskImage> disks) {
-        for (DiskImage disk : disks) {
-            proccessedDomains.addAll(disk.getStorageIds());
-        }
-    }
-
-    /**
-     * Returns true if all snapshots have a valid status to use in the OVF.
-     */
-    protected boolean verifySnapshotsStatus(List<Snapshot> snapshots) {
-        for (Snapshot snapshot : snapshots) {
-            if (snapshot.getStatus() != SnapshotStatus.OK) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Returns true if none of the given disks is in status 'LOCKED', 
otherwise false.
-     */
-    protected boolean verifyImagesStatus(List<DiskImage> diskImages) {
-        for (DiskImage diskImage : diskImages) {
-            if (diskImage.getImageStatus() == ImageStatus.LOCKED) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    protected String generateVmTemplateMetadata(VmTemplate template, 
List<DiskImage> allTemplateImages) {
-        return ovfManager.ExportTemplate(template, allTemplateImages, 
ClusterUtils.getCompatibilityVersion(template));
-    }
-
-    /**
-     * Adds the given template metadata to the given map
-     */
-    protected String buildMetadataDictionaryForTemplate(VmTemplate template,
-            Map<Guid, KeyValuePairCompat<String, List<Guid>>> metaDictionary) {
-        List<DiskImage> allTemplateImages = template.getDiskList();
-        String templateMeta = generateVmTemplateMetadata(template, 
allTemplateImages);
-        metaDictionary.put(template.getId(), new KeyValuePairCompat<String, 
List<Guid>>(
-                templateMeta, LinqUtils.transformToList(allTemplateImages, new 
Function<DiskImage, Guid>() {
-                    @Override
-                    public Guid eval(DiskImage diskImage) {
-                        return diskImage.getId();
-                    }
-                })));
-        return templateMeta;
-    }
-
-    /**
-     * Loads additional need template data for it's ovf
-     */
-    protected void loadTemplateData(VmTemplate template) {
-        setManagedVideoDevices(template);
-        if (template.getInterfaces() == null || 
template.getInterfaces().isEmpty()) {
-            template.setInterfaces(getVmNetworkInterfaceDao()
-                    .getAllForTemplate(template.getId()));
-        }
-    }
-
-    /**
-     * Loads additional need vm data for it's ovf
-     */
-    protected void loadVmData(VM vm) {
-        setManagedVideoDevices(vm.getStaticData());
-        if (vm.getInterfaces().isEmpty()) {
-            
vm.setInterfaces(getVmNetworkInterfaceDao().getAllForVm(vm.getId()));
-        }
-        if (StringUtils.isEmpty(vm.getVmtName())) {
-            if (!Guid.Empty.equals(vm.getVmtGuid())) {
-                VmTemplate t = getVmTemplateDao().get(vm.getVmtGuid());
-                vm.setVmtName(t.getName());
-            } else {
-                vm.setVmtName(VmTemplateHandler.BLANK_VM_TEMPLATE_NAME);
-            }
-        }
-    }
-
-    private void setManagedVideoDevices(VmBase vmBase) {
-        Map<Guid, VmDevice> managedDeviceMap = vmBase.getManagedDeviceMap();
-        if (managedDeviceMap == null) {
-            managedDeviceMap = new HashMap<Guid, VmDevice>();
-        }
-        List<VmDevice> devices =
-                DbFacade.getInstance()
-                        .getVmDeviceDao()
-                        .getVmDeviceByVmIdAndType(vmBase.getId(), 
VmDeviceGeneralType.VIDEO);
-        for (VmDevice device : devices) {
-            managedDeviceMap.put(device.getDeviceId(), device);
-        }
-    }
-
-    protected List<DiskImage> getAllImageSnapshots(DiskImage diskImage) {
-        return ImagesHandler.getAllImageSnapshots(diskImage.getImageId());
-    }
-
-    protected String generateVmMetadata(VM vm, ArrayList<DiskImage> 
AllVmImages) {
-        return ovfManager.ExportVm(vm, AllVmImages, 
ClusterUtils.getCompatibilityVersion(vm));
-    }
-
-    /**
-     * Adds the given vm metadata to the given map
-     */
-    protected String buildMetadataDictionaryForVm(VM vm,
-            Map<Guid, KeyValuePairCompat<String, List<Guid>>> metaDictionary,
-            ArrayList<DiskImage> allVmImages) {
-        String vmMeta = generateVmMetadata(vm, allVmImages);
-        metaDictionary.put(
-                vm.getId(),
-                new KeyValuePairCompat<String, List<Guid>>(vmMeta, 
LinqUtils.transformToList(vm.getDiskMap().values(),
-                        new Function<Disk, Guid>() {
-                            @Override
-                            public Guid eval(Disk a) {
-                                return a.getId();
-                            }
-                        })));
-        return vmMeta;
-    }
-
-    protected VmDAO getVmDao() {
-        return DbFacade.getInstance().getVmDao();
-    }
-
-    protected VmTemplateDAO getVmTemplateDao() {
-        return DbFacade.getInstance().getVmTemplateDao();
-    }
-
-    protected StoragePoolIsoMapDAO getSoragePoolIsoMapDao() {
-        return DbFacade.getInstance().getStoragePoolIsoMapDao();
-    }
-
-    protected StorageDomainDAO getStorageDomainDao() {
-        return DbFacade.getInstance().getStorageDomainDao();
-    }
-
-    protected VmNetworkInterfaceDao getVmNetworkInterfaceDao() {
-        return DbFacade.getInstance().getVmNetworkInterfaceDao();
-    }
-
-    protected VmAndTemplatesGenerationsDAO getVmAndTemplatesGenerationsDao() {
-        return DbFacade.getInstance().getVmAndTemplatesGenerationsDao();
-    }
-
-    protected StorageDomainOvfInfoDao getStorageDomainOvfInfoDao() {
-        return DbFacade.getInstance().getStorageDomainOvfInfoDao();
-    }
-
-    protected VmStaticDAO getVmStaticDao() {
-        return DbFacade.getInstance().getVmStaticDao();
-    }
-
-    protected SnapshotDao getSnapshotDao() {
-        return DbFacade.getInstance().getSnapshotDao();
-    }
-
-    /**
-     * Init the lists contain the processed info.
-     */
-    private void initProcessedInfoLists() {
-        proccessedIdsInfo = new LinkedList<Guid>();
-        proccessedOvfGenerationsInfo = new LinkedList<Long>();
-        proccessedOvfConfigurationsInfo = new LinkedList<>();
-        removedOvfIdsInfo = null;
-    }
-
-    /**
-     * Update the information contained in the given meta dictionary table in 
the given storage pool/storage domain.
-     */
-    protected boolean executeUpdateVmInSpmCommand(Guid storagePoolId,
-            Map<Guid, KeyValuePairCompat<String, List<Guid>>> metaDictionary,
-            Guid storageDomainId) {
-        UpdateVMVDSCommandParameters tempVar = new 
UpdateVMVDSCommandParameters(storagePoolId, metaDictionary);
-        tempVar.setStorageDomainId(storageDomainId);
-        return 
Backend.getInstance().getResourceManager().RunVdsCommand(VDSCommandType.UpdateVM,
 tempVar)
-                .getSucceeded();
-    }
-
-    /**
-     * Removes the ovf of the vm/template with the given id from the given 
storage pool/storage domain.
-     */
-    protected boolean executeRemoveVmInSpm(Guid storagePoolId, Guid id, Guid 
storageDomainId) {
-        return 
Backend.getInstance().getResourceManager().RunVdsCommand(VDSCommandType.RemoveVM,
-                new RemoveVMVDSCommandParameters(storagePoolId, id, 
storageDomainId)).getSucceeded();
-    }
-
-    protected void addAuditLogError(String storagePoolName) {
-        AuditLogableBase logable = new AuditLogableBase();
-        logable.addCustomValue("StoragePoolName", storagePoolName);
-        AuditLogDirector.log(logable, 
AuditLogType.UPDATE_OVF_FOR_STORAGE_POOL_FAILED);
     }
 
     protected boolean ovfOnAnyDomainSupported(StoragePool pool) {
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OvfUpdateProcessHelper.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OvfUpdateProcessHelper.java
new file mode 100644
index 0000000..63ddf2d
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OvfUpdateProcessHelper.java
@@ -0,0 +1,186 @@
+package org.ovirt.engine.core.bll;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.ovirt.engine.core.bll.utils.ClusterUtils;
+import org.ovirt.engine.core.common.businessentities.Disk;
+import org.ovirt.engine.core.common.businessentities.DiskImage;
+import org.ovirt.engine.core.common.businessentities.VM;
+import org.ovirt.engine.core.common.businessentities.VmBase;
+import org.ovirt.engine.core.common.businessentities.VmDevice;
+import org.ovirt.engine.core.common.businessentities.VmDeviceGeneralType;
+import org.ovirt.engine.core.common.businessentities.VmTemplate;
+import org.ovirt.engine.core.common.vdscommands.RemoveVMVDSCommandParameters;
+import org.ovirt.engine.core.common.vdscommands.UpdateVMVDSCommandParameters;
+import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.compat.KeyValuePairCompat;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.dao.SnapshotDao;
+import org.ovirt.engine.core.dao.StorageDomainDAO;
+import org.ovirt.engine.core.dao.VmDAO;
+import org.ovirt.engine.core.dao.VmStaticDAO;
+import org.ovirt.engine.core.dao.VmTemplateDAO;
+import org.ovirt.engine.core.dao.network.VmNetworkInterfaceDao;
+import org.ovirt.engine.core.utils.linq.Function;
+import org.ovirt.engine.core.utils.linq.LinqUtils;
+import org.ovirt.engine.core.utils.ovf.OvfManager;
+
+public class OvfUpdateProcessHelper {
+    private OvfManager ovfManager;
+
+    public OvfUpdateProcessHelper() {
+        ovfManager = new OvfManager();
+    }
+
+    /**
+     * Adds the given vm metadata to the given map
+     */
+    protected String buildMetadataDictionaryForVm(VM vm,
+                                                  Map<Guid, 
KeyValuePairCompat<String, List<Guid>>> metaDictionary,
+                                                  ArrayList<DiskImage> 
allVmImages) {
+        String vmMeta = generateVmMetadata(vm, allVmImages);
+        metaDictionary.put(
+                vm.getId(),
+                new KeyValuePairCompat<String, List<Guid>>(vmMeta, 
LinqUtils.transformToList(vm.getDiskMap().values(),
+                        new Function<Disk, Guid>() {
+                            @Override
+                            public Guid eval(Disk a) {
+                                return a.getId();
+                            }
+                        })));
+        return vmMeta;
+    }
+
+    protected String generateVmTemplateMetadata(VmTemplate template, 
List<DiskImage> allTemplateImages) {
+        return ovfManager.ExportTemplate(template, allTemplateImages, 
ClusterUtils.getCompatibilityVersion(template));
+    }
+
+    /**
+     * Adds the given template metadata to the given map
+     */
+    protected String buildMetadataDictionaryForTemplate(VmTemplate template,
+                                                        Map<Guid, 
KeyValuePairCompat<String, List<Guid>>> metaDictionary) {
+        List<DiskImage> allTemplateImages = template.getDiskList();
+        String templateMeta = generateVmTemplateMetadata(template, 
allTemplateImages);
+        metaDictionary.put(template.getId(), new KeyValuePairCompat<String, 
List<Guid>>(
+                templateMeta, LinqUtils.transformToList(allTemplateImages, new 
Function<DiskImage, Guid>() {
+            @Override
+            public Guid eval(DiskImage diskImage) {
+                return diskImage.getId();
+            }
+        })));
+        return templateMeta;
+    }
+
+    /**
+     * Loads additional need vm data for it's ovf
+     */
+    protected void loadVmData(VM vm) {
+        setManagedVideoDevices(vm.getStaticData());
+        if (vm.getInterfaces().isEmpty()) {
+            
vm.setInterfaces(getVmNetworkInterfaceDao().getAllForVm(vm.getId()));
+        }
+        if (StringUtils.isEmpty(vm.getVmtName())) {
+            if (!Guid.Empty.equals(vm.getVmtGuid())) {
+                VmTemplate t = getVmTemplateDao().get(vm.getVmtGuid());
+                vm.setVmtName(t.getName());
+            } else {
+                vm.setVmtName(VmTemplateHandler.BLANK_VM_TEMPLATE_NAME);
+            }
+        }
+    }
+
+    private void setManagedVideoDevices(VmBase vmBase) {
+        Map<Guid, VmDevice> managedDeviceMap = vmBase.getManagedDeviceMap();
+        if (managedDeviceMap == null) {
+            managedDeviceMap = new HashMap<Guid, VmDevice>();
+        }
+        List<VmDevice> devices =
+                DbFacade.getInstance()
+                        .getVmDeviceDao()
+                        .getVmDeviceByVmIdAndType(vmBase.getId(), 
VmDeviceGeneralType.VIDEO);
+        for (VmDevice device : devices) {
+            managedDeviceMap.put(device.getDeviceId(), device);
+        }
+    }
+
+    protected List<DiskImage> getAllImageSnapshots(DiskImage diskImage) {
+        return ImagesHandler.getAllImageSnapshots(diskImage.getImageId());
+    }
+
+
+    protected ArrayList<DiskImage> getVmImagesFromDb(VM vm) {
+        ArrayList<DiskImage> allVmImages = new ArrayList<>();
+        List<DiskImage> filteredDisks = 
ImagesHandler.filterImageDisks(vm.getDiskList(), false, true, true);
+
+        for (DiskImage diskImage : filteredDisks) {
+            allVmImages.addAll(getAllImageSnapshots(diskImage));
+        }
+        return allVmImages;
+    }
+
+    /**
+     * Loads additional need template data for it's ovf
+     */
+    protected void loadTemplateData(VmTemplate template) {
+        setManagedVideoDevices(template);
+        if (template.getInterfaces() == null || 
template.getInterfaces().isEmpty()) {
+            template.setInterfaces(getVmNetworkInterfaceDao()
+                    .getAllForTemplate(template.getId()));
+        }
+    }
+
+    protected String generateVmMetadata(VM vm, ArrayList<DiskImage> 
AllVmImages) {
+        return ovfManager.ExportVm(vm, AllVmImages, 
ClusterUtils.getCompatibilityVersion(vm));
+    }
+
+    protected VmDAO getVmDao() {
+        return DbFacade.getInstance().getVmDao();
+    }
+
+    protected StorageDomainDAO getStorageDomainDao() {
+        return DbFacade.getInstance().getStorageDomainDao();
+    }
+
+
+    protected VmTemplateDAO getVmTemplateDao() {
+        return DbFacade.getInstance().getVmTemplateDao();
+    }
+
+    protected VmNetworkInterfaceDao getVmNetworkInterfaceDao() {
+        return DbFacade.getInstance().getVmNetworkInterfaceDao();
+    }
+
+    protected VmStaticDAO getVmStaticDao() {
+        return DbFacade.getInstance().getVmStaticDao();
+    }
+
+    protected SnapshotDao getSnapshotDao() {
+        return DbFacade.getInstance().getSnapshotDao();
+    }
+
+    /**
+     * Update the information contained in the given meta dictionary table in 
the given storage pool/storage domain.
+     */
+    protected boolean executeUpdateVmInSpmCommand(Guid storagePoolId,
+                                                  Map<Guid, 
KeyValuePairCompat<String, List<Guid>>> metaDictionary,
+                                                  Guid storageDomainId) {
+        UpdateVMVDSCommandParameters tempVar = new 
UpdateVMVDSCommandParameters(storagePoolId, metaDictionary);
+        tempVar.setStorageDomainId(storageDomainId);
+        return 
Backend.getInstance().getResourceManager().RunVdsCommand(VDSCommandType.UpdateVM,
 tempVar)
+                .getSucceeded();
+    }
+
+    /**
+     * Removes the ovf of the vm/template with the given id from the given 
storage pool/storage domain.
+     */
+    protected boolean executeRemoveVmInSpm(Guid storagePoolId, Guid id, Guid 
storageDomainId) {
+        return 
Backend.getInstance().getResourceManager().RunVdsCommand(VDSCommandType.RemoveVM,
+                new RemoveVMVDSCommandParameters(storagePoolId, id, 
storageDomainId)).getSucceeded();
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessDownVmCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessDownVmCommand.java
index 1a7071b..de86b6d 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessDownVmCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessDownVmCommand.java
@@ -27,7 +27,6 @@
 import org.ovirt.engine.core.common.utils.VmDeviceType;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
-import org.ovirt.engine.core.dao.SnapshotDao;
 import org.ovirt.engine.core.dao.VmPoolDAO;
 import org.ovirt.engine.core.utils.log.Log;
 import org.ovirt.engine.core.utils.log.LogFactory;
@@ -106,10 +105,6 @@
 
     private VmPoolDAO getVmPoolDAO() {
         return DbFacade.getInstance().getVmPoolDao();
-    }
-
-    private SnapshotDao getSnapshotDAO() {
-        return DbFacade.getInstance().getSnapshotDao();
     }
 
     @Override
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessOvfUpdateForStoragePoolCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessOvfUpdateForStoragePoolCommand.java
new file mode 100644
index 0000000..4770c88
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/ProcessOvfUpdateForStoragePoolCommand.java
@@ -0,0 +1,363 @@
+package org.ovirt.engine.core.bll;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.ovirt.engine.core.bll.context.CommandContext;
+import org.ovirt.engine.core.bll.storage.StorageHandlingCommandBase;
+import org.ovirt.engine.core.common.AuditLogType;
+import org.ovirt.engine.core.common.FeatureSupported;
+import org.ovirt.engine.core.common.action.LockProperties;
+import org.ovirt.engine.core.common.action.StoragePoolParametersBase;
+import org.ovirt.engine.core.common.businessentities.DiskImage;
+import org.ovirt.engine.core.common.businessentities.ImageStatus;
+import org.ovirt.engine.core.common.businessentities.Snapshot;
+import org.ovirt.engine.core.common.businessentities.StorageDomain;
+import org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfo;
+import 
org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfoStatus;
+import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
+import org.ovirt.engine.core.common.businessentities.StoragePool;
+import org.ovirt.engine.core.common.businessentities.VM;
+import org.ovirt.engine.core.common.businessentities.VMStatus;
+import org.ovirt.engine.core.common.businessentities.VmTemplate;
+import org.ovirt.engine.core.common.businessentities.VmTemplateStatus;
+import org.ovirt.engine.core.common.config.Config;
+import org.ovirt.engine.core.common.config.ConfigValues;
+import org.ovirt.engine.core.common.constants.StorageConstants;
+import org.ovirt.engine.core.common.errors.VdcBllMessages;
+import org.ovirt.engine.core.common.locks.LockingGroup;
+import org.ovirt.engine.core.common.utils.Pair;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.compat.KeyValuePairCompat;
+
+@NonTransactiveCommandAttribute
+@InternalCommandAttribute
+public class ProcessOvfUpdateForStoragePoolCommand <T extends 
StoragePoolParametersBase> extends StorageHandlingCommandBase<T> {
+
+    private int itemsCountPerUpdate;
+    private List<Guid> proccessedIdsInfo;
+    private List<Long> proccessedOvfGenerationsInfo;
+    private List<String> proccessedOvfConfigurationsInfo;
+    private HashSet<Guid> proccessedDomains;
+    private List<Guid> removedOvfIdsInfo;
+    private OvfUpdateProcessHelper ovfUpdateProcessHelper;
+
+    public ProcessOvfUpdateForStoragePoolCommand(T parameters) {
+        this(parameters, null);
+    }
+
+    public ProcessOvfUpdateForStoragePoolCommand(T parameters, CommandContext 
commandContext) {
+        super(parameters, commandContext);
+        setStoragePoolId(parameters.getStoragePoolId());
+        ovfUpdateProcessHelper = new OvfUpdateProcessHelper();
+    }
+
+    protected OvfUpdateProcessHelper getOvfUpdateProcessHelper() {
+        return ovfUpdateProcessHelper;
+    }
+
+    protected int loadConfigValue() {
+        return Config.<Integer> getValue(ConfigValues.OvfItemsCountPerUpdate);
+    }
+
+    @Override
+    protected void executeCommand() {
+        itemsCountPerUpdate = loadConfigValue();
+        proccessedDomains = new HashSet<>();
+        StoragePool pool = getStoragePool();
+        if (ovfOnAnyDomainSupported(pool)) {
+            proccessDomainsForOvfUpdate(pool);
+        }
+
+        logInfoIfNeeded(pool, "Attempting to update VM OVFs in Data Center 
{0}",
+                pool.getName());
+        initProcessedInfoLists();
+
+        updateOvfForVmsOfStoragePool(pool);
+
+        logInfoIfNeeded(pool, "Successfully updated VM OVFs in Data Center 
{0}",
+                pool.getName());
+        logInfoIfNeeded(pool, "Attempting to update template OVFs in Data 
Center {0}",
+                pool.getName());
+
+        updateOvfForTemplatesOfStoragePool(pool);
+
+        logInfoIfNeeded(pool, "Successfully updated templates OVFs in Data 
Center {0}",
+                pool.getName());
+        logInfoIfNeeded(pool, "Attempting to remove unneeded template/vm OVFs 
in Data Center {0}",
+                pool.getName());
+
+        removeOvfForTemplatesAndVmsOfStoragePool(pool);
+
+        logInfoIfNeeded(pool, "Successfully removed unneeded template/vm OVFs 
in Data Center {0}",
+                pool.getName());
+
+        getReturnValue().setActionReturnValue(proccessedDomains);
+        setSucceeded(true);
+    }
+
+    @Override
+    protected Map<String, Pair<String, String>> getExclusiveLocks() {
+        return 
Collections.singletonMap(getParameters().getStoragePoolId().toString(),
+                LockMessagesMatchUtil.makeLockingPair(LockingGroup.OVF_UPDATE,
+                        VdcBllMessages.ACTION_TYPE_FAILED_OBJECT_LOCKED));
+    }
+
+    private void logInfoIfNeeded(StoragePool pool, String message, Object... 
args) {
+        // if supported, the info would be logged when executing for each 
domain
+        if (!ovfOnAnyDomainSupported(pool)) {
+            log.infoFormat(message, args);
+        }
+    }
+
+    protected void proccessDomainsForOvfUpdate(StoragePool pool) {
+        List<StorageDomain> domainsInPool = 
getStorageDomainDAO().getAllForStoragePool(pool.getId());
+        for (StorageDomain domain : domainsInPool) {
+            if (!domain.getStorageDomainType().isDataDomain() || 
domain.getStatus() != StorageDomainStatus.Active) {
+                continue;
+            }
+
+            Integer ovfStoresCountForDomain = Config.<Integer> 
getValue(ConfigValues.StorageDomainOvfStoreCount);
+            List<StorageDomainOvfInfo> storageDomainOvfInfos = 
getStorageDomainOvfInfoDAO().getAllForDomain(domain.getId());
+
+            if (storageDomainOvfInfos.size() < ovfStoresCountForDomain) {
+                proccessedDomains.add(domain.getId());
+                continue;
+            }
+
+            for (StorageDomainOvfInfo storageDomainOvfInfo : 
storageDomainOvfInfos) {
+                if (storageDomainOvfInfo.getStatus() == 
StorageDomainOvfInfoStatus.OUTDATED) {
+                    
proccessedDomains.add(storageDomainOvfInfo.getStorageDomainId());
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Update ovfs for updated/newly vms since last run for the given storage 
pool
+     *
+     */
+    protected void updateOvfForVmsOfStoragePool(StoragePool pool) {
+        Guid poolId = pool.getId();
+        List<Guid> vmsIdsForUpdate = 
getVmAndTemplatesGenerationsDAO().getVmsIdsForOvfUpdate(poolId);
+        int i = 0;
+        while (i < vmsIdsForUpdate.size()) {
+            int size = Math.min(itemsCountPerUpdate, vmsIdsForUpdate.size() - 
i);
+            List<Guid> idsToProcess = vmsIdsForUpdate.subList(i, i + size);
+            i += size;
+
+            Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
vmsAndTemplateMetadata =
+                    populateVmsMetadataForOvfUpdate(idsToProcess);
+            if (!vmsAndTemplateMetadata.isEmpty()) {
+                performOvfUpdate(pool, vmsAndTemplateMetadata);
+            }
+        }
+    }
+
+    /**
+     * Removes from the storage ovf files of vm/templates that were removed 
from the db since the last OvfDataUpdater
+     * run.
+     *
+     */
+    protected void removeOvfForTemplatesAndVmsOfStoragePool(StoragePool pool) {
+        Guid poolId = pool.getId();
+        removedOvfIdsInfo = 
getVmAndTemplatesGenerationsDAO().getIdsForOvfDeletion(poolId);
+
+        if (!ovfOnAnyDomainSupported(pool)) {
+            for (Guid id : removedOvfIdsInfo) {
+                getOvfUpdateProcessHelper().executeRemoveVmInSpm(poolId, id, 
Guid.Empty);
+            }
+        }
+
+        markDomainsWithOvfsForOvfUpdate(removedOvfIdsInfo);
+        
getVmAndTemplatesGenerationsDAO().deleteOvfGenerations(removedOvfIdsInfo);
+    }
+
+    protected void markDomainsWithOvfsForOvfUpdate(Collection<Guid> ovfIds) {
+        List<Guid> relevantDomains = 
getStorageDomainOvfInfoDAO().loadStorageDomainIdsForOvfIds(ovfIds);
+        proccessedDomains.addAll(relevantDomains);
+        getStorageDomainOvfInfoDAO().updateOvfUpdatedInfo(proccessedDomains, 
StorageDomainOvfInfoStatus.OUTDATED, StorageDomainOvfInfoStatus.DISABLED);
+    }
+
+    /**
+     * Perform vdsm call which performs ovf update for the given metadata map
+     *
+     */
+    protected void performOvfUpdate(StoragePool pool,
+                                    Map<Guid, KeyValuePairCompat<String, 
List<Guid>>> vmsAndTemplateMetadata) {
+        if (!ovfOnAnyDomainSupported(pool)) {
+            
getOvfUpdateProcessHelper().executeUpdateVmInSpmCommand(pool.getId(), 
vmsAndTemplateMetadata, Guid.Empty);
+        } else {
+            markDomainsWithOvfsForOvfUpdate(vmsAndTemplateMetadata.keySet());
+        }
+
+        int i = 0;
+        while (i < proccessedIdsInfo.size()) {
+            int sizeToUpdate = 
Math.min(StorageConstants.OVF_MAX_ITEMS_PER_SQL_STATEMENT, 
proccessedIdsInfo.size() - i);
+            List<Guid> guidsForUpdate = proccessedIdsInfo.subList(i, i + 
sizeToUpdate);
+            List<Long> ovfGenerationsForUpdate = 
proccessedOvfGenerationsInfo.subList(i, i + sizeToUpdate);
+            List<String> ovfConfigurationsInfo = 
proccessedOvfConfigurationsInfo.subList(i, i + sizeToUpdate);
+            
getVmAndTemplatesGenerationsDAO().updateOvfGenerations(guidsForUpdate, 
ovfGenerationsForUpdate, ovfConfigurationsInfo);
+            i += sizeToUpdate;
+            initProcessedInfoLists();
+        }
+    }
+
+    /**
+     * Creates and returns a map containing valid templates metadata
+     */
+    protected Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
populateTemplatesMetadataForOvfUpdate(List<Guid> idsToProcess) {
+        Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
vmsAndTemplateMetadata =
+                new HashMap<Guid, KeyValuePairCompat<String, List<Guid>>>();
+        List<VmTemplate> templates = 
getVmTemplateDAO().getVmTemplatesByIds(idsToProcess);
+
+        for (VmTemplate template : templates) {
+            if (VmTemplateStatus.Locked != template.getStatus()) {
+                updateTemplateDisksFromDb(template);
+                boolean verifyDisksNotLocked = 
verifyImagesStatus(template.getDiskList());
+                if (verifyDisksNotLocked) {
+                    getOvfUpdateProcessHelper().loadTemplateData(template);
+                    Long currentDbGeneration = 
getVmStaticDAO().getDbGeneration(template.getId());
+                    // currentDbGeneration can be null in case that the 
template was deleted during the run of OvfDataUpdater.
+                    if (currentDbGeneration != null && 
template.getDbGeneration() == currentDbGeneration) {
+                        
proccessedOvfConfigurationsInfo.add(getOvfUpdateProcessHelper().buildMetadataDictionaryForTemplate(template,
 vmsAndTemplateMetadata));
+                        proccessedIdsInfo.add(template.getId());
+                        
proccessedOvfGenerationsInfo.add(template.getDbGeneration());
+                        proccessDisksDomains(template.getDiskList());
+                    }
+                }
+            }
+        }
+
+        return vmsAndTemplateMetadata;
+    }
+
+    protected void updateTemplateDisksFromDb(VmTemplate template) {
+        VmTemplateHandler.updateDisksFromDb(template);
+    }
+
+    protected void updateVmDisksFromDb(VM vm) {
+        VmHandler.updateDisksFromDb(vm);
+    }
+
+    public AuditLogType getAuditLogTypeValue() {
+        return getSucceeded() ? super.getAuditLogTypeValue() : 
AuditLogType.UPDATE_OVF_FOR_STORAGE_POOL_FAILED;
+    }
+
+    /**
+     * Update ovfs for updated/added templates since last for the given 
storage pool
+     */
+    protected void updateOvfForTemplatesOfStoragePool(StoragePool pool) {
+        Guid poolId = pool.getId();
+        List<Guid> templateIdsForUpdate =
+                
getVmAndTemplatesGenerationsDAO().getVmTemplatesIdsForOvfUpdate(poolId);
+        int i = 0;
+        while (i < templateIdsForUpdate.size()) {
+            int size = Math.min(templateIdsForUpdate.size() - i, 
itemsCountPerUpdate);
+            List<Guid> idsToProcess = templateIdsForUpdate.subList(i, i + 
size);
+            i += size;
+
+            Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
vmsAndTemplateMetadata =
+                    populateTemplatesMetadataForOvfUpdate(idsToProcess);
+            if (!vmsAndTemplateMetadata.isEmpty()) {
+                performOvfUpdate(pool, vmsAndTemplateMetadata);
+            }
+        }
+    }
+
+
+    /**
+     * Returns true if none of the given disks is in status 'LOCKED', 
otherwise false.
+     */
+    protected boolean verifyImagesStatus(List<DiskImage> diskImages) {
+        for (DiskImage diskImage : diskImages) {
+            if (diskImage.getImageStatus() == ImageStatus.LOCKED) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if all snapshots have a valid status to use in the OVF.
+     */
+    protected boolean verifySnapshotsStatus(List<Snapshot> snapshots) {
+        for (Snapshot snapshot : snapshots) {
+            if (snapshot.getStatus() != Snapshot.SnapshotStatus.OK) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Create and returns map contains valid vms metadata
+     */
+    protected Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
populateVmsMetadataForOvfUpdate(List<Guid> idsToProcess) {
+        Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
vmsAndTemplateMetadata =
+                new HashMap<Guid, KeyValuePairCompat<String, List<Guid>>>();
+        List<VM> vms = getVmDAO().getVmsByIds(idsToProcess);
+        for (VM vm : vms) {
+            if (VMStatus.ImageLocked != vm.getStatus()) {
+                updateVmDisksFromDb(vm);
+                if (!verifyImagesStatus(vm.getDiskList())) {
+                    continue;
+                }
+                ArrayList<DiskImage> vmImages = 
getOvfUpdateProcessHelper().getVmImagesFromDb(vm);
+                if (!verifyImagesStatus(vmImages)) {
+                    continue;
+                }
+                
vm.setSnapshots(getSnapshotDAO().getAllWithConfiguration(vm.getId()));
+                if (!verifySnapshotsStatus(vm.getSnapshots())) {
+                    continue;
+                }
+
+                getOvfUpdateProcessHelper().loadVmData(vm);
+                Long currentDbGeneration = 
getVmStaticDAO().getDbGeneration(vm.getId());
+                if (currentDbGeneration == null) {
+                    log.warnFormat("currentDbGeneration of VM (name: {0}, id: 
{1}) is null, probably because the VM was deleted during the run of 
OvfDataUpdater.",
+                            vm.getName(),
+                            vm.getId());
+                    continue;
+                }
+                if (vm.getStaticData().getDbGeneration() == 
currentDbGeneration) {
+                    
proccessedOvfConfigurationsInfo.add(getOvfUpdateProcessHelper().buildMetadataDictionaryForVm(vm,
 vmsAndTemplateMetadata, vmImages));
+                    proccessedIdsInfo.add(vm.getId());
+                    
proccessedOvfGenerationsInfo.add(vm.getStaticData().getDbGeneration());
+                    proccessDisksDomains(vm.getDiskList());
+                }
+            }
+        }
+        return vmsAndTemplateMetadata;
+    }
+
+    protected void proccessDisksDomains(List<DiskImage> disks) {
+        for (DiskImage disk : disks) {
+            proccessedDomains.addAll(disk.getStorageIds());
+        }
+    }
+
+    /**
+     * Init the lists contain the processed info.
+     */
+    private void initProcessedInfoLists() {
+        proccessedIdsInfo = new LinkedList<>();
+        proccessedOvfGenerationsInfo = new LinkedList<>();
+        proccessedOvfConfigurationsInfo = new LinkedList<>();
+    }
+
+    protected boolean ovfOnAnyDomainSupported(StoragePool pool) {
+        return 
FeatureSupported.ovfStoreOnAnyDomain(pool.getcompatibility_version());
+    }
+
+    protected LockProperties applyLockProperties(LockProperties 
lockProperties) {
+        return 
lockProperties.withScope(LockProperties.Scope.Execution).withWait(true);
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/OvfDataUpdaterTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/OvfDataUpdaterTest.java
index 8597a74..026311f 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/OvfDataUpdaterTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/OvfDataUpdaterTest.java
@@ -1,900 +1,107 @@
 package org.ovirt.engine.core.bll;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyList;
-import static org.mockito.Matchers.anyMap;
-import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doCallRealMethod;
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
-import org.apache.commons.collections.CollectionUtils;
 import org.junit.Before;
-import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.mockito.exceptions.base.MockitoException;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
-import org.ovirt.engine.core.common.businessentities.DiskImage;
-import org.ovirt.engine.core.common.businessentities.ImageStatus;
-import org.ovirt.engine.core.common.businessentities.Snapshot;
-import org.ovirt.engine.core.common.businessentities.StorageDomain;
-import org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfo;
-import 
org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfoStatus;
-import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
+import org.ovirt.engine.core.common.action.VdcReturnValueBase;
 import org.ovirt.engine.core.common.businessentities.StoragePool;
-import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMap;
 import org.ovirt.engine.core.common.businessentities.StoragePoolStatus;
-import org.ovirt.engine.core.common.businessentities.VM;
-import org.ovirt.engine.core.common.businessentities.VMStatus;
-import org.ovirt.engine.core.common.businessentities.VmStatic;
-import org.ovirt.engine.core.common.businessentities.VmTemplate;
-import org.ovirt.engine.core.common.businessentities.VmTemplateStatus;
-import org.ovirt.engine.core.common.config.ConfigValues;
-import org.ovirt.engine.core.common.constants.StorageConstants;
-import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.compat.Guid;
-import org.ovirt.engine.core.compat.KeyValuePairCompat;
-import org.ovirt.engine.core.dao.SnapshotDao;
-import org.ovirt.engine.core.dao.StorageDomainDAO;
-import org.ovirt.engine.core.dao.StorageDomainOvfInfoDao;
 import org.ovirt.engine.core.dao.StoragePoolDAO;
-import org.ovirt.engine.core.dao.VmAndTemplatesGenerationsDAO;
-import org.ovirt.engine.core.dao.VmDAO;
-import org.ovirt.engine.core.dao.VmStaticDAO;
-import org.ovirt.engine.core.dao.VmTemplateDAO;
-import org.ovirt.engine.core.utils.MockConfigRule;
-import org.ovirt.engine.core.utils.lock.EngineLock;
 
-/** A test class for the {@link OvfDataUpdater} class */
 @RunWith(MockitoJUnitRunner.class)
 public class OvfDataUpdaterTest {
-    private final int ITEMS_COUNT_PER_UPDATE = 100;
-    OvfDataUpdater updater;
+    private OvfDataUpdater ovfDataUpdater;
+    private Map<Guid, Map<Guid, Boolean>> map;
+    private StoragePool pool1;
+    private StoragePool pool2;
 
     @Mock
     private StoragePoolDAO storagePoolDAO;
 
-    @Mock
-    private VmAndTemplatesGenerationsDAO vmAndTemplatesGenerationsDAO;
-
-    @Mock
-    private VmDAO vmDAO;
-
-    @Mock
-    private VmStaticDAO vmStaticDAO;
-
-    @Mock
-    private SnapshotDao snapshotDAO;
-
-    @Mock
-    private VmTemplateDAO vmTemplateDAO;
-
-    @Mock
-    private StorageDomainDAO storageDomainDAO;
-
-    @Mock
-    private StorageDomainOvfInfoDao storageDomainOvfInfoDao;
-
-    private StoragePool pool1;
-    private StoragePool pool2;
-    private Map<Guid, VM> vms;
-    private Map<Guid, VmTemplate> templates;
-    // those members are used to save the executed data during a run of the 
ovf data updater and are used for comprasion with the expected data needed to 
be executed
-    // in the end of each test.
-    private Guid executedUpdateStoragePoolId;
-    private Map<Guid, Map<Guid, KeyValuePairCompat<String, List<Guid>>>> 
executedUpdatedMetadataForStoragePool;
-    private Map<Guid, Map<Guid, Long>> executedUpdatedOvfGenerationIdsInDb;
-    private Guid executedUpdateStorageDomainId;
-    private Map<Guid, List<Guid>> executedRemovedIds;
-    private Map<Guid, List<Guid>> executedOvfUpdatedDomainForPool;
-    private Map<Guid, Map<Guid, Pair<List<StorageDomainOvfInfo>, 
StorageDomain>>> poolDomainsOvfInfo;
-    private Guid executedRemoveStoragePoolId;
-    private Guid executedRemoveStorageDomainId;
-
-    @ClassRule
-    public static MockConfigRule mcr = new MockConfigRule(
-            mockConfig(ConfigValues.StorageDomainOvfStoreCount, 1)
-    );
-
-
     @Before
     public void setUp() {
-        updater = Mockito.spy(OvfDataUpdater.getInstance());
-        doReturn(ITEMS_COUNT_PER_UPDATE).when(updater).reloadConfigValue();
-        doReturn(new 
ArrayList<DiskImage>()).when(updater).getAllImageSnapshots(any(DiskImage.class));
-        
doReturn(false).when(updater).ovfOnAnyDomainSupported(any(StoragePool.class));
-        doCallRealMethod().when(updater).ovfUpdate_timer();
-        // init members
-        initMembers();
-
-        //init daos
-        doReturn(storagePoolDAO).when(updater).getStoragePoolDao();
-        
doReturn(vmAndTemplatesGenerationsDAO).when(updater).getVmAndTemplatesGenerationsDao();
-        doReturn(vmDAO).when(updater).getVmDao();
-        doReturn(vmStaticDAO).when(updater).getVmStaticDao();
-        doReturn(snapshotDAO).when(updater).getSnapshotDao();
-        doReturn(vmTemplateDAO).when(updater).getVmTemplateDao();
-        
doReturn(storageDomainOvfInfoDao).when(updater).getStorageDomainOvfInfoDao();
-        doReturn(storageDomainDAO).when(updater).getStorageDomainDao();
-
-
-        // mock ovf data updater methods
-        doNothing().when(updater).loadTemplateData(any(VmTemplate.class));
-        doNothing().when(updater).loadVmData(any(VM.class));
-        doNothing().when(updater).updateVmDisksFromDb(any(VM.class));
-        doNothing().when(updater).addAuditLogError(anyString());
-        
doNothing().when(updater).updateTemplateDisksFromDb(any(VmTemplate.class));
-        doReturn(true).when(updater).acquireLock(any(EngineLock.class));
-        doNothing().when(updater).releaseLock(any(EngineLock.class));
-
-        // dao related mocks.
-        doReturn(1L).when(vmStaticDAO).getDbGeneration(any(Guid.class));
-        List<Snapshot> snapshots = new ArrayList<Snapshot>();
-        
doReturn(snapshots).when(snapshotDAO).getAllWithConfiguration(any(Guid.class));
+        ovfDataUpdater = Mockito.spy(OvfDataUpdater.getInstance());
+        map = new HashMap<>();
+        doReturn(storagePoolDAO).when(ovfDataUpdater).getStoragePoolDao();
         mockAnswers();
-    }
 
-    private void initMembers() {
-        executedUpdatedMetadataForStoragePool = new HashMap<Guid, Map<Guid, 
KeyValuePairCompat<String, List<Guid>>>>();
-        executedRemovedIds = new HashMap<Guid, List<Guid>>();
-        executedUpdatedOvfGenerationIdsInDb = new HashMap<Guid, Map<Guid, 
Long>>();
-        vms = new HashMap<Guid, VM>();
-        templates = new HashMap<Guid, VmTemplate>();
         pool1 = new StoragePool();
         pool1.setId(Guid.newGuid());
-        pool1.setStatus(StoragePoolStatus.Maintenance);
 
         pool2 = new StoragePool();
         pool2.setId(Guid.newGuid());
-        pool2.setStatus(StoragePoolStatus.Maintenance);
-        poolDomainsOvfInfo = new HashMap<>();
-        performStoragePoolInitOps(pool1);
-        performStoragePoolInitOps(pool2);
+
+        doReturn(Arrays.asList(pool1, 
pool2)).when(storagePoolDAO).getAllByStatus(StoragePoolStatus.Up);
     }
 
-    private void performStoragePoolInitOps(StoragePool pool) {
-        executedUpdatedMetadataForStoragePool.put(pool.getId(),
-                new HashMap<Guid, KeyValuePairCompat<String, List<Guid>>>());
-        executedRemovedIds.put(pool.getId(), new LinkedList<Guid>());
-        executedOvfUpdatedDomainForPool = new HashMap<>();
-        executedUpdatedOvfGenerationIdsInDb.put(pool.getId(), new 
HashMap<Guid, Long>());
+    @Test
+    public void poolUpdateOvfStoreOnAnyDomainSupported() throws Exception {
+        
doReturn(true).when(ovfDataUpdater).ovfOnAnyDomainSupported(any(StoragePool.class));
+        ovfDataUpdater.ovfUpdate_timer();
+        verify(Boolean.TRUE);
+    }
 
-        Map<Guid, Pair<List<StorageDomainOvfInfo>, StorageDomain>> 
domainOvfInfos = new HashMap<>();
-
-        for (int i=0; i<2; i++) {
-            Guid domainId = Guid.newGuid();
-            StorageDomainOvfInfo ovfInfo = new StorageDomainOvfInfo(domainId, 
null, null, StorageDomainOvfInfoStatus.UPDATED, null);
-            StorageDomain domain = new StorageDomain();
-            domain.setId(domainId);
-            domain.setStoragePoolIsoMapData(new StoragePoolIsoMap(domainId, 
pool.getId(), StorageDomainStatus.Active));
-            domainOvfInfos.put(domainId, new Pair<>(Arrays.asList(ovfInfo), 
domain));
-        }
-        poolDomainsOvfInfo.put(pool.getId(), domainOvfInfos);
+    @Test
+    public void poolUpdateOvfStoreOnAnyDomainUnsupported() throws Exception {
+        
doReturn(false).when(ovfDataUpdater).ovfOnAnyDomainSupported(any(StoragePool.class));
+        ovfDataUpdater.ovfUpdate_timer();
+        verify(Boolean.FALSE);
     }
 
     private void mockAnswers() {
-        doAnswer(new Answer<String>() {
+        doAnswer(new Answer<VdcReturnValueBase>() {
             @Override
-            public String answer(InvocationOnMock invocation) throws Throwable 
{
-                VM vm = (VM) invocation.getArguments()[0];
-                return vm.getId().toString();
-            }
-
-        }).when(updater).generateVmMetadata(any(VM.class), 
any(ArrayList.class));
-
-        doAnswer(new Answer<String>() {
-            @Override
-            public String answer(InvocationOnMock invocation) throws Throwable 
{
-                VmTemplate template = (VmTemplate) 
invocation.getArguments()[0];
-                return template.getId().toString();
-            }
-
-        }).when(updater).generateVmTemplateMetadata(any(VmTemplate.class), 
anyList());
-
-        doAnswer(new Answer<List<VM>>() {
-            @Override
-            public List<VM> answer(InvocationOnMock invocation) throws 
Throwable {
-                List<Guid> neededIds = (List<Guid>) 
invocation.getArguments()[0];
-                List<VM> toReturn = new LinkedList<VM>();
-                for (Guid id : neededIds) {
-                    toReturn.add(vms.get(id));
+            public VdcReturnValueBase answer(InvocationOnMock invocation) 
throws Throwable {
+                VdcReturnValueBase returnValueBase = new VdcReturnValueBase();
+                Map<Guid, Boolean> domains = new HashMap<>();
+                Set<Guid> domainIds = new HashSet<>();
+                domainIds.add(Guid.newGuid());
+                domainIds.add(Guid.newGuid());
+                for (Guid domainId : domainIds) {
+                    domains.put(domainId, Boolean.FALSE);
                 }
-                return toReturn;
+                returnValueBase.setActionReturnValue(domainIds);
+                Guid storagePoolId = (Guid) invocation.getArguments()[0];
+                map.put(storagePoolId, domains);
+                return returnValueBase;
             }
 
-        }).when(vmDAO).getVmsByIds(anyList());
-
-        doAnswer(new Answer<List<VmTemplate>>() {
-            @Override
-            public List<VmTemplate> answer(InvocationOnMock invocation) throws 
Throwable {
-                List<Guid> neededIds = (List<Guid>) 
invocation.getArguments()[0];
-                List<VmTemplate> toReturn = new LinkedList<VmTemplate>();
-                for (Guid id : neededIds) {
-                    toReturn.add(templates.get(id));
-                }
-                return toReturn;
-            }
-
-        }).when(vmTemplateDAO).getVmTemplatesByIds(anyList());
-
-        doAnswer(new Answer<Boolean>() {
-            @Override
-            public Boolean answer(InvocationOnMock invocation) throws 
Throwable {
-                executedUpdateStoragePoolId = (Guid) 
invocation.getArguments()[0];
-                Map<Guid, KeyValuePairCompat<String, List<Guid>>> updateMap =
-                        (Map<Guid, KeyValuePairCompat<String, List<Guid>>>) 
invocation.getArguments()[1];
-                
executedUpdatedMetadataForStoragePool.get(executedUpdateStoragePoolId).putAll(updateMap);
-                executedUpdateStorageDomainId = (Guid) 
invocation.getArguments()[2];
-                assertTrue("too many ovfs were sent in one vdsm call", 
updateMap.size() <= ITEMS_COUNT_PER_UPDATE);
-                return true;
-            }
-
-        }).when(updater).executeUpdateVmInSpmCommand(any(Guid.class), 
anyMap(), any(Guid.class));
-
-        doAnswer(new Answer<Boolean>() {
-            @Override
-            public Boolean answer(InvocationOnMock invocation) throws 
Throwable {
-                executedUpdateStoragePoolId = ((StoragePool) 
invocation.getArguments()[0]).getId();
-                return (Boolean) invocation.callRealMethod();
-            }
-
-        }).when(updater).proceedPoolOvfUpdate(any(StoragePool.class));
-
-        doAnswer(new Answer<Boolean>() {
-            @Override
-            public Boolean answer(InvocationOnMock invocation) throws 
Throwable {
-                Guid poolId = (Guid) invocation.getArguments()[0];
-                Guid domainId = (Guid) invocation.getArguments()[1];
-                List<Guid> executedDomains = 
executedOvfUpdatedDomainForPool.get(poolId);
-                if (executedDomains == null) {
-                    executedDomains = new LinkedList<>();
-                    executedOvfUpdatedDomainForPool.put(poolId, 
executedDomains);
-                }
-                executedDomains.add(domainId);
-                return true;
-            }
-
-        }).when(updater).performOvfUpdateForDomain(any(Guid.class), 
any(Guid.class));
-
-        doAnswer(new Answer<Boolean>() {
-            @Override
-            public Boolean answer(InvocationOnMock invocation) throws 
Throwable {
-                executedRemoveStoragePoolId = (Guid) 
invocation.getArguments()[0];
-                executedRemovedIds.get(executedRemoveStoragePoolId).add((Guid) 
invocation.getArguments()[1]);
-                executedRemoveStorageDomainId = (Guid) 
invocation.getArguments()[2];
-                return true;
-            }
-
-        }).when(updater).executeRemoveVmInSpm(any(Guid.class), 
any(Guid.class), any(Guid.class));
+        
}).when(ovfDataUpdater).performOvfUpdateForStoragePool(any(Guid.class));
 
         doAnswer(new Answer<Object>() {
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable 
{
-                List<Guid> ids = (List<Guid>) invocation.getArguments()[0];
-                List<Long> values = (List<Long>) invocation.getArguments()[1];
-                assertFalse("update of ovf version in db shouldn't be called 
with an empty value list",
-                        values.isEmpty());
-                assertTrue("update of ovf version in db shouldn't be called 
with more items then MAX_ITEMS_PER_SQL_STATEMENT",
-                        values.size() <= 
StorageConstants.OVF_MAX_ITEMS_PER_SQL_STATEMENT);
-                assertEquals("the size of the list of ids for update is not 
the same as the size of the " +
-                        "list with the new ovf values", values.size(), 
ids.size());
-                Guid[] ids_array = ids.toArray(new Guid[ids.size()]);
-                Long[] values_array = values.toArray(new Long[values.size()]);
-                for (int i = 0; i < ids_array.length; i++) {
-                    
executedUpdatedOvfGenerationIdsInDb.get(executedUpdateStoragePoolId).put(ids_array[i],
-                            values_array[i]);
-                }
+                Guid storagePoolId = (Guid) invocation.getArguments()[0];
+                Guid storageDomainId = (Guid) invocation.getArguments()[1];
+                map.get(storagePoolId).put(storageDomainId, Boolean.TRUE);
                 return null;
             }
 
-        }).when(vmAndTemplatesGenerationsDAO).updateOvfGenerations(anyList(), 
anyList(), anyList());
-
-        doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(InvocationOnMock invocation) throws Throwable 
{
-                StoragePoolStatus desiredStatus = (StoragePoolStatus) 
invocation.getArguments()[0];
-                List<StoragePool> toReturn = new LinkedList<>();
-                for (StoragePool pool : buildStoragePoolsList()) {
-                    if (desiredStatus.equals(pool.getStatus())) {
-                        toReturn.add(pool);
-                    }
-                }
-
-                return toReturn;
-            }
-
-        }).when(storagePoolDAO).getAllByStatus(any(StoragePoolStatus.class));
-
-        doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(InvocationOnMock invocation) throws Throwable 
{
-                Guid poolId = (Guid) invocation.getArguments()[0];
-                List<StorageDomain> toReturn = new LinkedList<>();
-                Map<Guid, Pair<List<StorageDomainOvfInfo>, StorageDomain>> 
domainsMap = poolDomainsOvfInfo.get(poolId);
-                for (Pair<List<StorageDomainOvfInfo>, StorageDomain> pair : 
domainsMap.values()) {
-                    toReturn.add(pair.getSecond());
-                }
-
-                return toReturn;
-            }
-
-        }).when(storageDomainDAO).getAllForStoragePool(any(Guid.class));
-
-        doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(InvocationOnMock invocation) throws Throwable 
{
-                Guid domainId = (Guid) invocation.getArguments()[0];
-                for (Map.Entry<Guid, Map<Guid, 
Pair<List<StorageDomainOvfInfo>, StorageDomain>>> entry : 
poolDomainsOvfInfo.entrySet()) {
-                    Map<Guid, Pair<List<StorageDomainOvfInfo>, StorageDomain>> 
domainsInfo = entry.getValue();
-                    Pair<List<StorageDomainOvfInfo>, StorageDomain> pair = 
domainsInfo.get(domainId);
-                    if (pair != null) {
-                        return pair.getFirst();
-                    }
-
-                }
-                return null;
-            }
-
-        }).when(storageDomainOvfInfoDao).getAllForDomain(any(Guid.class));
+        }).when(ovfDataUpdater).performOvfUpdateForDomain(any(Guid.class), 
any(Guid.class));
     }
 
-    private List<StoragePool> buildStoragePoolsList() {
-        return Arrays.asList(pool1, pool2);
-    }
-
-    private VM createVm(Guid id, VMStatus status) {
-        VM vm = new VM();
-        vm.setStatus(status);
-        vm.setStaticData(createVmStatic());
-        vm.setId(id);
-        return vm;
-    }
-
-    public VmStatic createVmStatic() {
-        VmStatic vms = new VmStatic();
-        vms.setDbGeneration(1L);
-        return vms;
-    }
-
-    private VmTemplate createVmTemplate(Guid id, VmTemplateStatus 
templateStatus) {
-        VmTemplate template = new VmTemplate();
-        template.setStatus(templateStatus);
-        template.setDbGeneration(1L);
-        template.setId(id);
-        return template;
-    }
-
-    private List<Guid> generateGuidList(int size) {
-        List<Guid> toReturn = new LinkedList<Guid>();
-        for (int i = 0; i < size; i++) {
-            toReturn.add(Guid.newGuid());
-        }
-        return toReturn;
-    }
-
-    private Map<Guid, VM> generateVmsMapByGuids(List<Guid> ids,
-            int diskCount,
-            VMStatus vmStatus,
-            ImageStatus diskStatus,
-            Guid poolId) {
-        Map<Guid, VM> toReturn = new HashMap<Guid, VM>();
-        for (Guid id : ids) {
-            VM vm = createVm(id, vmStatus);
-            for (int i = 0; i < diskCount; i++) {
-                DiskImage image = createDiskImage(diskStatus, poolId);
-                vm.getDiskMap().put(image.getId(), image);
-                vm.getDiskList().add(image);
-            }
-            toReturn.put(vm.getId(), vm);
-        }
-        return toReturn;
-    }
-
-    private Map<Guid, VmTemplate> generateVmTemplatesMapByGuids(List<Guid> ids,
-            int diskCount,
-            VmTemplateStatus templateStatus,
-            ImageStatus diskStatus, Guid poolId) {
-        Map<Guid, VmTemplate> toReturn = new HashMap<Guid, VmTemplate>();
-        for (Guid id : ids) {
-            VmTemplate template = createVmTemplate(id, templateStatus);
-            for (int i = 0; i < diskCount; i++) {
-                DiskImage image = createDiskImage(diskStatus, poolId);
-                template.getDiskTemplateMap().put(image.getId(), image);
-                template.getDiskList().add(image);
-            }
-            toReturn.put(template.getId(), template);
-        }
-        return toReturn;
-    }
-
-    private DiskImage createDiskImage(ImageStatus status, Guid poolId) {
-        DiskImage disk = new DiskImage();
-        disk.setId(Guid.newGuid());
-        disk.setImageStatus(status);
-        ArrayList<Guid> storageIds = new ArrayList<>();
-        Map<Guid, Pair<List<StorageDomainOvfInfo>, StorageDomain>> domains = 
poolDomainsOvfInfo.get(poolId);
-        storageIds.add(domains.keySet().iterator().next());
-        disk.setStorageIds(storageIds);
-        return disk;
-    }
-
-    private void initTestForPool(StoragePool pool, List<Guid> vmGuids, 
List<Guid> templatesGuids, List<Guid> removedGuids) {
-        Guid poolId = pool.getId();
-        
doReturn(vmGuids).when(vmAndTemplatesGenerationsDAO).getVmsIdsForOvfUpdate(poolId);
-        
doReturn(templatesGuids).when(vmAndTemplatesGenerationsDAO).getVmTemplatesIdsForOvfUpdate(poolId);
-        
doReturn(removedGuids).when(vmAndTemplatesGenerationsDAO).getIdsForOvfDeletion(poolId);
-        pool.setStatus(StoragePoolStatus.Up);
-    }
-
-    private void verifyCorrectOvfDataUpdaterRun(StoragePool storagePool,
-            Collection<Guid> needToBeUpdated,
-            Collection<Guid> removedGuids) {
-        Guid storagePoolId = storagePool.getId();
-        Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
storagePoolMetadataUpdatedMap =
-                executedUpdatedMetadataForStoragePool.get(storagePoolId);
-        Map<Guid, Long> storagePoolUpdateOvfGenerationsInDb = 
executedUpdatedOvfGenerationIdsInDb.get(storagePoolId);
-        if (!updater.ovfOnAnyDomainSupported(storagePool)) {
-            assertTrue("not all needed vms/templates were updated in vdsm",
-                    
CollectionUtils.isEqualCollection(storagePoolMetadataUpdatedMap.keySet(),
-                            needToBeUpdated));
-            for (Map.Entry<Guid, KeyValuePairCompat<String, List<Guid>>> entry 
: storagePoolMetadataUpdatedMap
-                    .entrySet()) {
-                assertEquals("wrong ovf data stored in storage for 
vm/template",
-                        entry.getKey().toString(),
-                        entry.getValue().getKey());
+    private void verify(Boolean expected) {
+        for (Map<Guid, Boolean> map1 : map.values()) {
+            for (Boolean b : map1.values()) {
+                assertEquals(expected, b);
             }
         }
-        assertTrue("not all needed vms/templates were updated in db",
-                
CollectionUtils.isEqualCollection(storagePoolUpdateOvfGenerationsInDb.keySet(),
-                        needToBeUpdated));
-
-        for (Map.Entry<Guid, Long> storagePoolGenerationEntry : 
storagePoolUpdateOvfGenerationsInDb.entrySet()) {
-            boolean isCorrectVersion = false;
-            if (vms.get(storagePoolGenerationEntry.getKey()) != null) {
-                isCorrectVersion =
-                        storagePoolGenerationEntry.getValue()
-                                
.equals(vms.get(storagePoolGenerationEntry.getKey()).getDbGeneration());
-            } else if (templates.get(storagePoolGenerationEntry.getKey()) != 
null) {
-                isCorrectVersion =
-                        storagePoolGenerationEntry.getValue()
-                                
.equals(templates.get(storagePoolGenerationEntry.getKey()).getDbGeneration());
-            }
-            assertTrue("wrong new ovf version persisted for vm/template", 
isCorrectVersion);
-        }
-
-        if (!updater.ovfOnAnyDomainSupported(storagePool)) {
-            assertTrue("not all needed vms/templates were removed from vdsm",
-                    CollectionUtils.isEqualCollection(removedGuids, 
executedRemovedIds.get(storagePoolId)));
-        }
-    }
-
-    private void addVms(List<Guid> vmGuids, int diskCount, VMStatus vmStatus, 
ImageStatus vmImageStatus, Guid poolId) {
-        vms.putAll(generateVmsMapByGuids(vmGuids, diskCount, vmStatus, 
vmImageStatus, poolId));
-
-    }
-
-    private void verifyOvfUpdatedForSupportedPools(List<Guid> 
poolsRequiredUpdate,
-            Map<Guid, List<Guid>> domainsRequiredUpdateForPool) {
-        assertTrue("wrong number of pools was updated",
-                executedOvfUpdatedDomainForPool.keySet().size() == 
poolsRequiredUpdate.size());
-        for (Guid storagePoolId : poolsRequiredUpdate) {
-            List<Guid> updatedDomainsForPool = 
executedOvfUpdatedDomainForPool.get(storagePoolId);
-            Map<Guid, Pair<List<StorageDomainOvfInfo>, StorageDomain>> 
domainOfPool = poolDomainsOvfInfo.get(storagePoolId);
-            for (Guid updatedDomainForPool : updatedDomainsForPool) {
-                assertTrue("ovf update for domain has been executed with wrong 
pool",
-                        domainOfPool.containsKey(updatedDomainForPool));
-                if (domainsRequiredUpdateForPool.get(storagePoolId) != null) {
-                    assertTrue("ovf updated hasn't been executed on needed 
domain",
-                            
domainsRequiredUpdateForPool.get(storagePoolId).contains(updatedDomainForPool));
-                }
-            }
-        }
-    }
-
-    private void addTemplates(List<Guid> templatesGuids,
-            int diskCount,
-            VmTemplateStatus templateStatus,
-            ImageStatus templateImageStatus, Guid poolId) {
-        templates.putAll(generateVmTemplatesMapByGuids(templatesGuids,
-                diskCount,
-                templateStatus,
-                templateImageStatus,
-                poolId));
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountTwoPoolsOvfOnAnyDomainSupported()
 {
-        testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountTwoPools(true);
-        verifyOvfUpdatedForSupportedPools(Arrays.asList(pool1.getId(), 
pool2.getId()),
-                Collections.<Guid, List<Guid>> emptyMap());
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountTwoPoolsOvfOnAnyDomainUnsupported()
 {
-        testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountTwoPools(false);
-    }
-
-    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountTwoPools(boolean 
ovfOnAnyDomainSupported) {
-        int size = 3 * ITEMS_COUNT_PER_UPDATE + 10;
-
-        
doReturn(ovfOnAnyDomainSupported).when(updater).ovfOnAnyDomainSupported(any(StoragePool.class));
-        List<Guid> vmGuids = generateGuidList(size);
-        List<Guid> templatesGuids = generateGuidList(size);
-        List<Guid> removedGuids = generateGuidList(size);
-        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
-        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.OK, pool1.getId());
-        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool1.getId());
-
-        List<Guid> vmGuids2 = generateGuidList(size);
-        List<Guid> templatesGuids2 = generateGuidList(size);
-        List<Guid> removedGuids2 = generateGuidList(size);
-        addVms(vmGuids2, 2, VMStatus.Down, ImageStatus.OK, pool2.getId());
-        addTemplates(templatesGuids2, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool2.getId());
-        initTestForPool(pool2, vmGuids2, templatesGuids2, removedGuids2);
-
-        updater.ovfUpdate_timer();
-
-        verify(updater, times(numberOfTimesToBeCalled(size, true) * 
2)).performOvfUpdate(any(StoragePool.class),
-                anyMap());
-
-        if (!ovfOnAnyDomainSupported) {
-            verify(updater, times(size * 
2)).executeRemoveVmInSpm(any(Guid.class), any(Guid.class), any(Guid.class));
-        }
-
-        List<Guid> idsThatNeededToBeUpdated = new LinkedList<Guid>(vmGuids);
-        idsThatNeededToBeUpdated.addAll(templatesGuids);
-
-        List<Guid> idsThatNeededToBeUpdated2 = new LinkedList<Guid>(vmGuids2);
-        idsThatNeededToBeUpdated2.addAll(templatesGuids2);
-
-        verifyCorrectOvfDataUpdaterRun(pool1, idsThatNeededToBeUpdated, 
removedGuids);
-        verifyCorrectOvfDataUpdaterRun(pool2, idsThatNeededToBeUpdated2, 
removedGuids2);
-    }
-
-    @Test
-    public void testOvfDataUpdaterRunWithUpdateAndRemoveExceptionInOnePool() {
-        int size = 3 * ITEMS_COUNT_PER_UPDATE + 10;
-
-        List<Guid> vmGuids = generateGuidList(size);
-        List<Guid> templatesGuids = generateGuidList(size);
-        List<Guid> removedGuids = generateGuidList(size);
-        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
-        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.OK, pool1.getId());
-        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool1.getId());
-
-        List<Guid> vmGuids2 = generateGuidList(size);
-        List<Guid> templatesGuids2 = generateGuidList(size);
-        List<Guid> removedGuids2 = generateGuidList(size);
-        addVms(vmGuids2, 2, VMStatus.Down, ImageStatus.OK, pool2.getId());
-        addTemplates(templatesGuids2, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool2.getId());
-        initTestForPool(pool2, vmGuids2, templatesGuids2, removedGuids2);
-
-        doAnswer(new Answer<Boolean>() {
-            @Override
-            public Boolean answer(InvocationOnMock invocation) throws 
Throwable {
-                executedUpdateStoragePoolId = (Guid) 
invocation.getArguments()[0];
-                if (executedUpdateStoragePoolId.equals(pool1.getId())) {
-                    throw new 
MockitoException("testOvfDataUpdaterRunWithUpdateAndRemoveExceptionInOnePool: 
intendent exception");
-                }
-                Map<Guid, KeyValuePairCompat<String, List<Guid>>> updateMap =
-                        (Map<Guid, KeyValuePairCompat<String, List<Guid>>>) 
invocation.getArguments()[1];
-                
executedUpdatedMetadataForStoragePool.get(executedUpdateStoragePoolId).putAll(updateMap);
-                executedUpdateStorageDomainId = (Guid) 
invocation.getArguments()[2];
-                assertTrue("too many ovfs were sent in one vdsm call", 
updateMap.size() <= ITEMS_COUNT_PER_UPDATE);
-                return true;
-            }
-
-        }).when(updater).executeUpdateVmInSpmCommand(any(Guid.class), 
anyMap(), any(Guid.class));
-
-        updater.ovfUpdate_timer();
-
-        // + 1 as the exception is thrown during the first call to this method 
during first update execution for the
-        // first pool.
-        int numOfExpectedRuns = numberOfTimesToBeCalled(size, true) + 1;
-        verify(updater, 
times(numOfExpectedRuns)).performOvfUpdate(any(StoragePool.class),
-                anyMap());
-        verify(updater, times(size)).executeRemoveVmInSpm(any(Guid.class), 
any(Guid.class), any(Guid.class));
-
-        List<Guid> idsToBeUpdated = new LinkedList<Guid>(vmGuids2);
-        idsToBeUpdated.addAll(templatesGuids2);
-        verifyCorrectOvfDataUpdaterRun(pool1, Collections.<Guid> emptyList(), 
Collections.<Guid> emptyList());
-        verifyCorrectOvfDataUpdaterRun(pool2, idsToBeUpdated, removedGuids2);
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountOnePoolOvfOnAnyDomainSupported()
 {
-        testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountOnePool(true);
-        verifyOvfUpdatedForSupportedPools(Arrays.asList(pool1.getId()), 
Collections.<Guid, List<Guid>> emptyMap());
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountOnePoolOvfOnAnyDomainUnsupported()
 {
-        testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountOnePool(false);
-    }
-
-    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountOnePool(boolean 
ovfOnAnyDomainSupported) {
-        int size = 3 * ITEMS_COUNT_PER_UPDATE + 10;
-        
doReturn(ovfOnAnyDomainSupported).when(updater).ovfOnAnyDomainSupported(any(StoragePool.class));
-        List<Guid> vmGuids = generateGuidList(size);
-        List<Guid> templatesGuids = generateGuidList(size);
-        List<Guid> removedGuids = generateGuidList(size);
-        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.OK, pool1.getId());
-        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool1.getId());
-
-        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
-
-        updater.ovfUpdate_timer();
-
-        verify(updater, times(numberOfTimesToBeCalled(size, 
true))).performOvfUpdate(any(StoragePool.class), anyMap());
-        if (!ovfOnAnyDomainSupported) {
-            verify(updater, times(size)).executeRemoveVmInSpm(any(Guid.class), 
any(Guid.class), any(Guid.class));
-        }
-
-        List<Guid> idsThatNeededToBeUpdated = new LinkedList<Guid>(vmGuids);
-        idsThatNeededToBeUpdated.addAll(templatesGuids);
-
-        verifyCorrectOvfDataUpdaterRun(pool1, idsThatNeededToBeUpdated, 
removedGuids);
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveLowerThanCountOvfOnAnyDomainSupported() 
{
-        testOvfDataUpdaterRunWithUpdateAndRemoveLowerThanCount(true);
-        verifyOvfUpdatedForSupportedPools(Arrays.asList(pool1.getId()), 
Collections.<Guid, List<Guid>> emptyMap());
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveLowerThanCountOvfOnAnyDomainUnupported()
 {
-        testOvfDataUpdaterRunWithUpdateAndRemoveLowerThanCount(false);
-    }
-
-    public void testOvfDataUpdaterRunWithUpdateAndRemoveLowerThanCount(boolean 
ovfOnAnyDomainSupported) {
-        int size = ITEMS_COUNT_PER_UPDATE - 1;
-
-        
doReturn(ovfOnAnyDomainSupported).when(updater).ovfOnAnyDomainSupported(any(StoragePool.class));
-        List<Guid> vmGuids = generateGuidList(size);
-        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.OK, pool1.getId());
-        List<Guid> templatesGuids = generateGuidList(size);
-        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool1.getId());
-        List<Guid> removedGuids = generateGuidList(size);
-
-        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
-
-        updater.ovfUpdate_timer();
-        verify(updater, times(numberOfTimesToBeCalled(size, 
true))).performOvfUpdate(any(StoragePool.class), anyMap());
-        if (!ovfOnAnyDomainSupported) {
-            verify(updater, times(size)).executeRemoveVmInSpm(any(Guid.class), 
any(Guid.class), any(Guid.class));
-        }
-        List<Guid> needToBeUpdated = new LinkedList<Guid>(vmGuids);
-        needToBeUpdated.addAll(templatesGuids);
-        verifyCorrectOvfDataUpdaterRun(pool1, needToBeUpdated, removedGuids);
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterAllDisksAreLockedNonToRemoveOvfOnAnyDomainSupported() {
-        testOvfDataUpdaterAllDisksAreLockedNonToRemove(true);
-        verifyOvfUpdatedForSupportedPools(Collections.<Guid> emptyList(), 
Collections.<Guid, List<Guid>> emptyMap());
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterAllDisksAreLockedNonToRemoveOvfOnAnyDomainUnupported() {
-        testOvfDataUpdaterAllDisksAreLockedNonToRemove(false);
-    }
-
-    public void testOvfDataUpdaterAllDisksAreLockedNonToRemove(boolean 
ovfOnAnyDomainSupported) {
-        int size = ITEMS_COUNT_PER_UPDATE - 1;
-
-        
doReturn(ovfOnAnyDomainSupported).when(updater).ovfOnAnyDomainSupported(any(StoragePool.class));
-        List<Guid> vmGuids = generateGuidList(size);
-        List<Guid> removedGuids = Collections.emptyList();
-        List<Guid> templatesGuids = generateGuidList(size);
-
-        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, 
ImageStatus.LOCKED, pool1.getId());
-        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.LOCKED, pool1.getId());
-
-        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
-
-        updater.ovfUpdate_timer();
-        verify(updater, never()).performOvfUpdate(any(StoragePool.class), 
anyMap());
-        if (!ovfOnAnyDomainSupported) {
-            verify(updater, never()).executeRemoveVmInSpm(any(Guid.class), 
any(Guid.class), any(Guid.class));
-        }
-        verifyCorrectOvfDataUpdaterRun(pool1, Collections.<Guid> emptyList(), 
removedGuids);
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterPartOfDisksAreLockedOvfOnAnyDomainSupported() {
-        testOvfDataUpdaterAllDisksAreLockedNonToRemove(true);
-        verifyOvfUpdatedForSupportedPools(Collections.<Guid> emptyList(), 
Collections.<Guid, List<Guid>> emptyMap());
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterPartOfDisksAreLockedOvfOnAnyDomainUnupported() {
-        testOvfDataUpdaterAllDisksAreLockedNonToRemove(false);
-    }
-
-    public void testOvfDataUpdaterPartOfDisksAreLocked(boolean 
ovfOnAnyDomainSupported) {
-        int size = ITEMS_COUNT_PER_UPDATE - 1;
-        // unlocked vms/templates
-        List<Guid> vmGuids = generateGuidList(size);
-        List<Guid> templatesGuids = generateGuidList(size);
-        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.OK, pool1.getId());
-        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool1.getId());
-
-        // locked vms/templates
-        List<Guid> lockedVmGuids = generateGuidList(size);
-        List<Guid> lockedTemplatesGuids = generateGuidList(size);
-        addVms(lockedVmGuids, 2, VMStatus.Down, ImageStatus.LOCKED, 
pool1.getId());
-        addTemplates(lockedTemplatesGuids, 2, VmTemplateStatus.OK, 
ImageStatus.LOCKED, pool1.getId());
-        // ids for removal
-        List<Guid> removedGuids = generateGuidList(size);
-
-        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
-
-        updater.ovfUpdate_timer();
-        verify(updater, times(numberOfTimesToBeCalled(size, 
true))).performOvfUpdate(any(StoragePool.class), anyMap());
-        if (!ovfOnAnyDomainSupported) {
-            verify(updater, times(size)).executeRemoveVmInSpm(any(Guid.class), 
any(Guid.class), any(Guid.class));
-        }
-        // list of ids that should have been updated.
-        List<Guid> needToBeUpdated = new LinkedList<Guid>(vmGuids);
-        needToBeUpdated.addAll(templatesGuids);
-        verifyCorrectOvfDataUpdaterRun(pool1, needToBeUpdated, removedGuids);
-    }
-
-    private int numberOfTimesToBeCalled(int size, boolean 
isBothVmAndTemplates) {
-        int toReturn = 0;
-        if (size % ITEMS_COUNT_PER_UPDATE != 0) {
-            toReturn++;
-        }
-        toReturn += size / ITEMS_COUNT_PER_UPDATE;
-        if (isBothVmAndTemplates) {
-            toReturn = toReturn * 2;
-        }
-        return toReturn;
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterAllVmsAndTemplatesAreLockedOvfOnAnyDomainSupported() {
-        testOvfDataUpdaterAllVmsAndTemplatesAreLocked(true);
-        verifyOvfUpdatedForSupportedPools(Collections.<Guid> emptyList(), 
Collections.<Guid, List<Guid>> emptyMap());
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterAllVmsAndTemplatesAreLockedOvfOnAnyDomainUnupported() {
-        testOvfDataUpdaterAllVmsAndTemplatesAreLocked(false);
-    }
-
-    public void testOvfDataUpdaterAllVmsAndTemplatesAreLocked(boolean 
ovfOnAnyDomainSupported) {
-        int size = ITEMS_COUNT_PER_UPDATE - 1;
-        List<Guid> vmGuids = generateGuidList(size);
-        addVms(vmGuids, 2, VMStatus.ImageLocked, ImageStatus.OK, 
pool1.getId());
-        List<Guid> removedGuids = generateGuidList(size);
-        List<Guid> templatesGuids = generateGuidList(size);
-        addTemplates(templatesGuids, 2, VmTemplateStatus.Locked, 
ImageStatus.OK, pool1.getId());
-
-        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
-
-        updater.ovfUpdate_timer();
-        verify(updater, never()).performOvfUpdate(any(StoragePool.class), 
anyMap());
-        if (!ovfOnAnyDomainSupported) {
-            verify(updater, times(size)).executeRemoveVmInSpm(any(Guid.class), 
any(Guid.class), any(Guid.class));
-        }
-        verifyCorrectOvfDataUpdaterRun(pool1, Collections.<Guid> emptyList(), 
removedGuids);
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterPartOfVmsAndTemplatesAreLockedOvfOnAnyDomainSupported() {
-        testOvfDataUpdaterPartOfVmsAndTemplatesAreLocked(true);
-        verifyOvfUpdatedForSupportedPools(Collections.<Guid> emptyList(), 
Collections.<Guid, List<Guid>> emptyMap());
-    }
-
-    @Test
-    public void 
testOvfDataUpdaterPartOfVmsAndTemplatesAreLockedOvfOnAnyDomainUnupported() {
-        testOvfDataUpdaterPartOfVmsAndTemplatesAreLocked(false);
-    }
-
-    public void testOvfDataUpdaterPartOfVmsAndTemplatesAreLocked(boolean 
ovfOnAnyDomainSupported) {
-        int size = ITEMS_COUNT_PER_UPDATE;
-        List<Guid> vmGuids = generateGuidList(size);
-        List<Guid> removedGuids = generateGuidList(size);
-        List<Guid> templatesGuids = generateGuidList(size);
-
-        addVms(vmGuids, 2, VMStatus.ImageLocked, ImageStatus.OK, 
pool1.getId());
-        addTemplates(templatesGuids, 2, VmTemplateStatus.Locked, 
ImageStatus.OK, pool1.getId());
-
-        List<Guid> vmGuidsUnlocked = generateGuidList(size);
-        List<Guid> templatesGuidsUnlocked = generateGuidList(size);
-
-        addVms(vmGuidsUnlocked, 2, VMStatus.Down, ImageStatus.OK, 
pool1.getId());
-        addTemplates(templatesGuidsUnlocked, 2, VmTemplateStatus.OK, 
ImageStatus.OK, pool1.getId());
-
-        vmGuids.addAll(vmGuidsUnlocked);
-        templatesGuids.addAll(templatesGuidsUnlocked);
-        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
-
-        updater.ovfUpdate_timer();
-
-        List<Guid> neededToBeUpdated = new LinkedList<Guid>(vmGuidsUnlocked);
-        neededToBeUpdated.addAll(templatesGuidsUnlocked);
-        verify(updater, times(numberOfTimesToBeCalled(size, 
true))).performOvfUpdate(any(StoragePool.class), anyMap());
-        if (!ovfOnAnyDomainSupported) {
-            verify(updater, times(size)).executeRemoveVmInSpm(any(Guid.class), 
any(Guid.class), any(Guid.class));
-        }
-        verifyCorrectOvfDataUpdaterRun(pool1, neededToBeUpdated, removedGuids);
-    }
-
-    @Test
-    public void testUpdatedDbGenerationOvfOnAnyDomainSupported() {
-        testUpdatedDbGeneration(true);
-        verifyOvfUpdatedForSupportedPools(Collections.<Guid> emptyList(), 
Collections.<Guid, List<Guid>> emptyMap());
-    }
-
-    @Test
-    public void testUpdatedDbGenerationOvfOnAnyDomainUnupported() {
-        testUpdatedDbGeneration(false);
-    }
-
-    public void testUpdatedDbGeneration(boolean ovfOnAnyDomainSupported) {
-        int size = 3 * ITEMS_COUNT_PER_UPDATE + 10;
-        List<Guid> vmGuids = generateGuidList(size);
-        List<Guid> templatesGuids = generateGuidList(size);
-        List<Guid> removedGuids = Collections.emptyList();
-        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.OK, pool1.getId());
-        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool1.getId());
-
-        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
-
-        doReturn(2L).when(vmStaticDAO).getDbGeneration(any(Guid.class));
-
-        updater.ovfUpdate_timer();
-
-        verify(updater, never()).performOvfUpdate(any(StoragePool.class), 
anyMap());
-        if (!ovfOnAnyDomainSupported) {
-            verify(updater, never()).executeRemoveVmInSpm(any(Guid.class), 
any(Guid.class), any(Guid.class));
-        }
-
-        List<Guid> idsThatNeededToBeUpdated = new LinkedList<Guid>(vmGuids);
-        idsThatNeededToBeUpdated.addAll(templatesGuids);
-
-        verifyCorrectOvfDataUpdaterRun(pool1, Collections.<Guid> emptyList(), 
removedGuids);
-    }
-
-    @Test
-    public void testUpdateCalledForUnupdatedDomain() {
-        Guid poolId = pool1.getId();
-        StorageDomainOvfInfo ovfInfo = 
poolDomainsOvfInfo.get(poolId).entrySet().iterator().next().getValue().getFirst().get(0);
-        ovfInfo.setStatus(StorageDomainOvfInfoStatus.OUTDATED);
-        
doReturn(true).when(updater).ovfOnAnyDomainSupported(any(StoragePool.class));
-        initTestForPool(pool1,
-                Collections.<Guid> emptyList(),
-                Collections.<Guid> emptyList(),
-                Collections.<Guid> emptyList());
-        updater.ovfUpdate_timer();
-        verify(updater, never()).performOvfUpdate(any(StoragePool.class), 
anyMap());
-        Map<Guid, List<Guid>> domainsRequiredUpdateForPool =
-                Collections.singletonMap(poolId, 
Arrays.asList(ovfInfo.getStorageDomainId()));
-        verifyOvfUpdatedForSupportedPools(Arrays.asList(poolId), 
domainsRequiredUpdateForPool);
     }
 }
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/ProcessOvfUpdateForStoragePoolCommandTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/ProcessOvfUpdateForStoragePoolCommandTest.java
new file mode 100644
index 0000000..7f11a1e
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/ProcessOvfUpdateForStoragePoolCommandTest.java
@@ -0,0 +1,748 @@
+package org.ovirt.engine.core.bll;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyList;
+import static org.mockito.Matchers.anyMap;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
+import org.ovirt.engine.core.common.action.StoragePoolParametersBase;
+import org.ovirt.engine.core.common.businessentities.DiskImage;
+import org.ovirt.engine.core.common.businessentities.ImageStatus;
+import org.ovirt.engine.core.common.businessentities.Snapshot;
+import org.ovirt.engine.core.common.businessentities.StorageDomain;
+import org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfo;
+import 
org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfoStatus;
+import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
+import org.ovirt.engine.core.common.businessentities.StoragePool;
+import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMap;
+import org.ovirt.engine.core.common.businessentities.StoragePoolStatus;
+import org.ovirt.engine.core.common.businessentities.VM;
+import org.ovirt.engine.core.common.businessentities.VMStatus;
+import org.ovirt.engine.core.common.businessentities.VmStatic;
+import org.ovirt.engine.core.common.businessentities.VmTemplate;
+import org.ovirt.engine.core.common.businessentities.VmTemplateStatus;
+import org.ovirt.engine.core.common.config.ConfigValues;
+import org.ovirt.engine.core.common.constants.StorageConstants;
+import org.ovirt.engine.core.common.utils.Pair;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.compat.KeyValuePairCompat;
+import org.ovirt.engine.core.dao.SnapshotDao;
+import org.ovirt.engine.core.dao.StorageDomainDAO;
+import org.ovirt.engine.core.dao.StorageDomainOvfInfoDao;
+import org.ovirt.engine.core.dao.StoragePoolDAO;
+import org.ovirt.engine.core.dao.VmAndTemplatesGenerationsDAO;
+import org.ovirt.engine.core.dao.VmDAO;
+import org.ovirt.engine.core.dao.VmStaticDAO;
+import org.ovirt.engine.core.dao.VmTemplateDAO;
+import org.ovirt.engine.core.utils.MockConfigRule;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ProcessOvfUpdateForStoragePoolCommandTest {
+    private final static int ITEMS_COUNT_PER_UPDATE = 100;
+    private ProcessOvfUpdateForStoragePoolCommand<StoragePoolParametersBase> 
command;
+
+    @Mock
+    private StoragePoolDAO storagePoolDAO;
+
+    @Mock
+    private VmAndTemplatesGenerationsDAO vmAndTemplatesGenerationsDAO;
+
+    @Mock
+    private VmDAO vmDAO;
+
+    @Mock
+    private VmStaticDAO vmStaticDAO;
+
+    @Mock
+    private SnapshotDao snapshotDAO;
+
+    @Mock
+    private VmTemplateDAO vmTemplateDAO;
+
+    @Mock
+    private StorageDomainDAO storageDomainDAO;
+
+    @Mock
+    private StorageDomainOvfInfoDao storageDomainOvfInfoDao;
+
+    private OvfUpdateProcessHelper ovfUpdateProcessHelper;
+
+    private StoragePool pool1;
+    private Map<Guid, VM> vms;
+    private Map<Guid, VmTemplate> templates;
+    private Map<Guid, KeyValuePairCompat<String, List<Guid>>> 
executedUpdatedMetadataForStoragePool;
+    private Map<Guid, Long> executedUpdatedOvfGenerationIdsInDb;
+    private Set<Guid> executedRemovedIds;
+    private Set<Guid> executedOvfUpdatedDomains;
+    private Map<Guid, Pair<List<StorageDomainOvfInfo>, StorageDomain>> 
poolDomainsOvfInfo;
+
+    @ClassRule
+    public static MockConfigRule mcr = new MockConfigRule(
+            mockConfig(ConfigValues.StorageDomainOvfStoreCount, 1)
+    );
+
+
+    @Before
+    public void setUp() {
+        command = Mockito.spy(new ProcessOvfUpdateForStoragePoolCommand<>(new 
StoragePoolParametersBase()));
+        ovfUpdateProcessHelper = Mockito.spy(new OvfUpdateProcessHelper());
+        doReturn(ITEMS_COUNT_PER_UPDATE).when(command).loadConfigValue();
+        doReturn(new 
ArrayList<DiskImage>()).when(ovfUpdateProcessHelper).getAllImageSnapshots(any(DiskImage.class));
+        
doReturn(false).when(command).ovfOnAnyDomainSupported(any(StoragePool.class));
+        doCallRealMethod().when(command).executeCommand();
+        // init members
+        initMembers();
+
+        //init daos
+        doReturn(storagePoolDAO).when(command).getStoragePoolDAO();
+        
doReturn(vmAndTemplatesGenerationsDAO).when(command).getVmAndTemplatesGenerationsDAO();
+        doReturn(vmDAO).when(command).getVmDAO();
+        doReturn(vmStaticDAO).when(command).getVmStaticDAO();
+        doReturn(snapshotDAO).when(command).getSnapshotDAO();
+        doReturn(vmTemplateDAO).when(command).getVmTemplateDAO();
+        
doReturn(storageDomainOvfInfoDao).when(command).getStorageDomainOvfInfoDAO();
+        doReturn(storageDomainDAO).when(command).getStorageDomainDAO();
+
+        
doReturn(ovfUpdateProcessHelper).when(command).getOvfUpdateProcessHelper();
+
+
+        // mock ovf data updater methods
+        
doNothing().when(ovfUpdateProcessHelper).loadTemplateData(any(VmTemplate.class));
+        doNothing().when(ovfUpdateProcessHelper).loadVmData(any(VM.class));
+        doNothing().when(command).updateVmDisksFromDb(any(VM.class));
+        
doNothing().when(command).updateTemplateDisksFromDb(any(VmTemplate.class));
+
+        // dao related mocks.
+        doReturn(1L).when(vmStaticDAO).getDbGeneration(any(Guid.class));
+        doReturn(pool1).when(command).getStoragePool();
+        List<Snapshot> snapshots = new ArrayList<>();
+        
doReturn(snapshots).when(snapshotDAO).getAllWithConfiguration(any(Guid.class));
+        mockAnswers();
+    }
+
+    private void initMembers() {
+        executedUpdatedMetadataForStoragePool = new HashMap<>();
+        executedRemovedIds = new HashSet<>();
+        executedUpdatedOvfGenerationIdsInDb = new HashMap<>();
+        poolDomainsOvfInfo = new HashMap<>();
+        vms = new HashMap<Guid, VM>();
+        templates = new HashMap<Guid, VmTemplate>();
+        pool1 = new StoragePool();
+        pool1.setId(Guid.newGuid());
+        pool1.setStatus(StoragePoolStatus.Maintenance);
+
+        performStoragePoolInitOps(pool1);
+    }
+
+    private void performStoragePoolInitOps(StoragePool pool) {
+        executedUpdatedMetadataForStoragePool = new HashMap<>();
+        executedRemovedIds = new HashSet<>();
+        executedUpdatedOvfGenerationIdsInDb = new HashMap<>();
+
+        for (int i = 0; i < 2; i++) {
+            Guid domainId = Guid.newGuid();
+            StorageDomainOvfInfo ovfInfo = new StorageDomainOvfInfo(domainId, 
null, null, StorageDomainOvfInfoStatus.UPDATED, null);
+            StorageDomain domain = new StorageDomain();
+            domain.setId(domainId);
+            domain.setStoragePoolIsoMapData(new StoragePoolIsoMap(domainId, 
pool.getId(), StorageDomainStatus.Active));
+            poolDomainsOvfInfo.put(domainId, new 
Pair<>(Arrays.asList(ovfInfo), domain));
+        }
+    }
+
+    private void mockAnswers() {
+        doAnswer(new Answer<String>() {
+            @Override
+            public String answer(InvocationOnMock invocation) throws Throwable 
{
+                VM vm = (VM) invocation.getArguments()[0];
+                return vm.getId().toString();
+            }
+
+        }).when(ovfUpdateProcessHelper).generateVmMetadata(any(VM.class), 
any(ArrayList.class));
+
+        doAnswer(new Answer<String>() {
+            @Override
+            public String answer(InvocationOnMock invocation) throws Throwable 
{
+                VmTemplate template = (VmTemplate) 
invocation.getArguments()[0];
+                return template.getId().toString();
+            }
+
+        
}).when(ovfUpdateProcessHelper).generateVmTemplateMetadata(any(VmTemplate.class),
 anyList());
+
+        doAnswer(new Answer<List<VM>>() {
+            @Override
+            public List<VM> answer(InvocationOnMock invocation) throws 
Throwable {
+                List<Guid> neededIds = (List<Guid>) 
invocation.getArguments()[0];
+                List<VM> toReturn = new LinkedList<VM>();
+                for (Guid id : neededIds) {
+                    toReturn.add(vms.get(id));
+                }
+                return toReturn;
+            }
+
+        }).when(vmDAO).getVmsByIds(anyList());
+
+        doAnswer(new Answer<List<VmTemplate>>() {
+            @Override
+            public List<VmTemplate> answer(InvocationOnMock invocation) throws 
Throwable {
+                List<Guid> neededIds = (List<Guid>) 
invocation.getArguments()[0];
+                List<VmTemplate> toReturn = new LinkedList<VmTemplate>();
+                for (Guid id : neededIds) {
+                    toReturn.add(templates.get(id));
+                }
+                return toReturn;
+            }
+
+        }).when(vmTemplateDAO).getVmTemplatesByIds(anyList());
+
+        doAnswer(new Answer<Boolean>() {
+            @Override
+            public Boolean answer(InvocationOnMock invocation) throws 
Throwable {
+                Map<Guid, KeyValuePairCompat<String, List<Guid>>> updateMap =
+                        (Map<Guid, KeyValuePairCompat<String, List<Guid>>>) 
invocation.getArguments()[1];
+                executedUpdatedMetadataForStoragePool.putAll(updateMap);
+                assertTrue("too many ovfs were sent in one vdsm call", 
updateMap.size() <= ITEMS_COUNT_PER_UPDATE);
+                return true;
+            }
+
+        
}).when(ovfUpdateProcessHelper).executeUpdateVmInSpmCommand(any(Guid.class), 
anyMap(), any(Guid.class));
+
+        doAnswer(new Answer<Boolean>() {
+            @Override
+            public Boolean answer(InvocationOnMock invocation) throws 
Throwable {
+                executedRemovedIds.add((Guid) invocation.getArguments()[1]);
+                return true;
+            }
+
+        }).when(ovfUpdateProcessHelper).executeRemoveVmInSpm(any(Guid.class), 
any(Guid.class), any(Guid.class));
+
+        doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable 
{
+                List<Guid> ids = (List<Guid>) invocation.getArguments()[0];
+                List<Long> values = (List<Long>) invocation.getArguments()[1];
+                assertFalse("update of ovf version in db shouldn't be called 
with an empty value list",
+                        values.isEmpty());
+                assertTrue("update of ovf version in db shouldn't be called 
with more items then MAX_ITEMS_PER_SQL_STATEMENT",
+                        values.size() <= 
StorageConstants.OVF_MAX_ITEMS_PER_SQL_STATEMENT);
+                assertEquals("the size of the list of ids for update is not 
the same as the size of the " +
+                        "list with the new ovf values", values.size(), 
ids.size());
+                Guid[] ids_array = ids.toArray(new Guid[ids.size()]);
+                Long[] values_array = values.toArray(new Long[values.size()]);
+                for (int i = 0; i < ids_array.length; i++) {
+                    executedUpdatedOvfGenerationIdsInDb.put(ids_array[i],
+                            values_array[i]);
+                }
+                return null;
+            }
+
+        }).when(vmAndTemplatesGenerationsDAO).updateOvfGenerations(anyList(), 
anyList(), anyList());
+
+        doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable 
{
+                StoragePoolStatus desiredStatus = (StoragePoolStatus) 
invocation.getArguments()[0];
+                List<StoragePool> toReturn = new LinkedList<>();
+                for (StoragePool pool : buildStoragePoolsList()) {
+                    if (desiredStatus.equals(pool.getStatus())) {
+                        toReturn.add(pool);
+                    }
+                }
+
+                return toReturn;
+            }
+
+        }).when(storagePoolDAO).getAllByStatus(any(StoragePoolStatus.class));
+
+        doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable 
{
+                Guid poolId = (Guid) invocation.getArguments()[0];
+                List<StorageDomain> toReturn = new LinkedList<>();
+                for (Pair<List<StorageDomainOvfInfo>, StorageDomain> pair : 
poolDomainsOvfInfo.values()) {
+                    toReturn.add(pair.getSecond());
+                }
+
+                return toReturn;
+            }
+
+        }).when(storageDomainDAO).getAllForStoragePool(any(Guid.class));
+
+        doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable 
{
+                Guid domainId = (Guid) invocation.getArguments()[0];
+                Pair<List<StorageDomainOvfInfo>, StorageDomain> pair = 
poolDomainsOvfInfo.get(domainId);
+                if (pair != null) {
+                    return pair.getFirst();
+                }
+                return null;
+            }
+
+        }).when(storageDomainOvfInfoDao).getAllForDomain(any(Guid.class));
+    }
+
+    private List<StoragePool> buildStoragePoolsList() {
+        return Arrays.asList(pool1);
+    }
+
+    private VM createVm(Guid id, VMStatus status) {
+        VM vm = new VM();
+        vm.setStatus(status);
+        vm.setStaticData(createVmStatic());
+        vm.setId(id);
+        return vm;
+    }
+
+    public VmStatic createVmStatic() {
+        VmStatic vms = new VmStatic();
+        vms.setDbGeneration(1L);
+        return vms;
+    }
+
+    private VmTemplate createVmTemplate(Guid id, VmTemplateStatus 
templateStatus) {
+        VmTemplate template = new VmTemplate();
+        template.setStatus(templateStatus);
+        template.setDbGeneration(1L);
+        template.setId(id);
+        return template;
+    }
+
+    private List<Guid> generateGuidList(int size) {
+        List<Guid> toReturn = new LinkedList<Guid>();
+        for (int i = 0; i < size; i++) {
+            toReturn.add(Guid.newGuid());
+        }
+        return toReturn;
+    }
+
+    private Map<Guid, VM> generateVmsMapByGuids(List<Guid> ids,
+            int diskCount,
+            VMStatus vmStatus,
+            ImageStatus diskStatus,
+            Guid poolId) {
+        Map<Guid, VM> toReturn = new HashMap<Guid, VM>();
+        for (Guid id : ids) {
+            VM vm = createVm(id, vmStatus);
+            for (int i = 0; i < diskCount; i++) {
+                DiskImage image = createDiskImage(diskStatus, poolId);
+                vm.getDiskMap().put(image.getId(), image);
+                vm.getDiskList().add(image);
+            }
+            toReturn.put(vm.getId(), vm);
+        }
+        return toReturn;
+    }
+
+    private Map<Guid, VmTemplate> generateVmTemplatesMapByGuids(List<Guid> ids,
+            int diskCount,
+            VmTemplateStatus templateStatus,
+            ImageStatus diskStatus, Guid poolId) {
+        Map<Guid, VmTemplate> toReturn = new HashMap<Guid, VmTemplate>();
+        for (Guid id : ids) {
+            VmTemplate template = createVmTemplate(id, templateStatus);
+            for (int i = 0; i < diskCount; i++) {
+                DiskImage image = createDiskImage(diskStatus, poolId);
+                template.getDiskTemplateMap().put(image.getId(), image);
+                template.getDiskList().add(image);
+            }
+            toReturn.put(template.getId(), template);
+        }
+        return toReturn;
+    }
+
+    private DiskImage createDiskImage(ImageStatus status, Guid poolId) {
+        DiskImage disk = new DiskImage();
+        disk.setId(Guid.newGuid());
+        disk.setImageStatus(status);
+        ArrayList<Guid> storageIds = new ArrayList<>();
+        storageIds.add(poolDomainsOvfInfo.keySet().iterator().next());
+        disk.setStorageIds(storageIds);
+        return disk;
+    }
+
+    private void initTestForPool(StoragePool pool, List<Guid> vmGuids, 
List<Guid> templatesGuids, List<Guid> removedGuids) {
+        Guid poolId = pool.getId();
+        
doReturn(vmGuids).when(vmAndTemplatesGenerationsDAO).getVmsIdsForOvfUpdate(poolId);
+        
doReturn(templatesGuids).when(vmAndTemplatesGenerationsDAO).getVmTemplatesIdsForOvfUpdate(poolId);
+        
doReturn(removedGuids).when(vmAndTemplatesGenerationsDAO).getIdsForOvfDeletion(poolId);
+        pool.setStatus(StoragePoolStatus.Up);
+    }
+
+    private void verifyCorrectOvfDataUpdaterRun(StoragePool storagePool,
+            Collection<Guid> needToBeUpdated,
+            Collection<Guid> removedGuids) {
+
+        if (!command.ovfOnAnyDomainSupported(storagePool)) {
+            assertTrue("not all needed vms/templates were updated in vdsm",
+                    
CollectionUtils.isEqualCollection(executedUpdatedMetadataForStoragePool.keySet(),
+                            needToBeUpdated));
+            for (Map.Entry<Guid, KeyValuePairCompat<String, List<Guid>>> entry 
: executedUpdatedMetadataForStoragePool
+                    .entrySet()) {
+                assertEquals("wrong ovf data stored in storage for 
vm/template",
+                        entry.getKey().toString(),
+                        entry.getValue().getKey());
+            }
+        }
+        assertTrue("not all needed vms/templates were updated in db",
+                
CollectionUtils.isEqualCollection(executedUpdatedOvfGenerationIdsInDb.keySet(),
+                        needToBeUpdated));
+
+        for (Map.Entry<Guid, Long> storagePoolGenerationEntry : 
executedUpdatedOvfGenerationIdsInDb.entrySet()) {
+            boolean isCorrectVersion = false;
+            if (vms.get(storagePoolGenerationEntry.getKey()) != null) {
+                isCorrectVersion =
+                        storagePoolGenerationEntry.getValue()
+                                
.equals(vms.get(storagePoolGenerationEntry.getKey()).getDbGeneration());
+            } else if (templates.get(storagePoolGenerationEntry.getKey()) != 
null) {
+                isCorrectVersion =
+                        storagePoolGenerationEntry.getValue()
+                                
.equals(templates.get(storagePoolGenerationEntry.getKey()).getDbGeneration());
+            }
+            assertTrue("wrong new ovf version persisted for vm/template", 
isCorrectVersion);
+        }
+
+        if (!command.ovfOnAnyDomainSupported(storagePool)) {
+            assertTrue("not all needed vms/templates were removed from vdsm",
+                    CollectionUtils.isEqualCollection(removedGuids, 
executedRemovedIds));
+        }
+    }
+
+    private void addVms(List<Guid> vmGuids, int diskCount, VMStatus vmStatus, 
ImageStatus vmImageStatus, Guid poolId) {
+        vms.putAll(generateVmsMapByGuids(vmGuids, diskCount, vmStatus, 
vmImageStatus, poolId));
+
+    }
+
+    private void verifyOvfUpdatedForSupportedPools(List<Guid> 
poolsRequiredUpdate,
+            Map<Guid, List<Guid>> domainsRequiredUpdateForPool) {
+        for (Guid storagePoolId : poolsRequiredUpdate) {
+            for (Guid updatedDomainForPool : executedOvfUpdatedDomains) {
+                assertTrue("ovf update for domain has been executed with wrong 
pool",
+                        poolDomainsOvfInfo.containsKey(updatedDomainForPool));
+                if (domainsRequiredUpdateForPool.get(storagePoolId) != null) {
+                    assertTrue("ovf updated hasn't been executed on needed 
domain",
+                            
domainsRequiredUpdateForPool.get(storagePoolId).contains(updatedDomainForPool));
+                }
+            }
+        }
+    }
+
+    private void addTemplates(List<Guid> templatesGuids,
+            int diskCount,
+            VmTemplateStatus templateStatus,
+            ImageStatus templateImageStatus, Guid poolId) {
+        templates.putAll(generateVmTemplatesMapByGuids(templatesGuids,
+                diskCount,
+                templateStatus,
+                templateImageStatus,
+                poolId));
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountOnePoolOvfOnAnyDomainSupported()
 {
+        testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountOnePool(true);
+        verifyOvfUpdatedForSupportedPools(Arrays.asList(pool1.getId()), 
Collections.<Guid, List<Guid>> emptyMap());
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountOnePoolOvfOnAnyDomainUnsupported()
 {
+        testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountOnePool(false);
+    }
+
+    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveHigherThanCountOnePool(boolean 
ovfOnAnyDomainSupported) {
+        int size = 3 * ITEMS_COUNT_PER_UPDATE + 10;
+        
doReturn(ovfOnAnyDomainSupported).when(command).ovfOnAnyDomainSupported(any(StoragePool.class));
+        List<Guid> vmGuids = generateGuidList(size);
+        List<Guid> templatesGuids = generateGuidList(size);
+        List<Guid> removedGuids = generateGuidList(size);
+        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.OK, pool1.getId());
+        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool1.getId());
+
+        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
+        executeCommand();
+        verify(command, times(numberOfTimesToBeCalled(size, 
true))).performOvfUpdate(any(StoragePool.class), anyMap());
+        if (!ovfOnAnyDomainSupported) {
+            verify(ovfUpdateProcessHelper, 
times(size)).executeRemoveVmInSpm(any(Guid.class), any(Guid.class), 
any(Guid.class));
+        }
+
+        List<Guid> idsThatNeededToBeUpdated = new LinkedList<Guid>(vmGuids);
+        idsThatNeededToBeUpdated.addAll(templatesGuids);
+
+        verifyCorrectOvfDataUpdaterRun(pool1, idsThatNeededToBeUpdated, 
removedGuids);
+    }
+
+    private void executeCommand() {
+        command.executeCommand();
+        executedOvfUpdatedDomains = (Set<Guid>)command.getActionReturnValue();
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveLowerThanCountOvfOnAnyDomainSupported() 
{
+        testOvfDataUpdaterRunWithUpdateAndRemoveLowerThanCount(true);
+        verifyOvfUpdatedForSupportedPools(Arrays.asList(pool1.getId()), 
Collections.<Guid, List<Guid>> emptyMap());
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterRunWithUpdateAndRemoveLowerThanCountOvfOnAnyDomainUnupported()
 {
+        testOvfDataUpdaterRunWithUpdateAndRemoveLowerThanCount(false);
+    }
+
+    public void testOvfDataUpdaterRunWithUpdateAndRemoveLowerThanCount(boolean 
ovfOnAnyDomainSupported) {
+        int size = ITEMS_COUNT_PER_UPDATE - 1;
+
+        
doReturn(ovfOnAnyDomainSupported).when(command).ovfOnAnyDomainSupported(any(StoragePool.class));
+        List<Guid> vmGuids = generateGuidList(size);
+        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.OK, pool1.getId());
+        List<Guid> templatesGuids = generateGuidList(size);
+        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool1.getId());
+        List<Guid> removedGuids = generateGuidList(size);
+
+        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
+
+        executeCommand();
+        verify(command, times(numberOfTimesToBeCalled(size, 
true))).performOvfUpdate(any(StoragePool.class), anyMap());
+        if (!ovfOnAnyDomainSupported) {
+            verify(ovfUpdateProcessHelper, 
times(size)).executeRemoveVmInSpm(any(Guid.class), any(Guid.class), 
any(Guid.class));
+        }
+        List<Guid> needToBeUpdated = new LinkedList<Guid>(vmGuids);
+        needToBeUpdated.addAll(templatesGuids);
+        verifyCorrectOvfDataUpdaterRun(pool1, needToBeUpdated, removedGuids);
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterAllDisksAreLockedNonToRemoveOvfOnAnyDomainSupported() {
+        testOvfDataUpdaterAllDisksAreLockedNonToRemove(true);
+        verifyOvfUpdatedForSupportedPools(Collections.<Guid> emptyList(), 
Collections.<Guid, List<Guid>> emptyMap());
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterAllDisksAreLockedNonToRemoveOvfOnAnyDomainUnupported() {
+        testOvfDataUpdaterAllDisksAreLockedNonToRemove(false);
+    }
+
+    public void testOvfDataUpdaterAllDisksAreLockedNonToRemove(boolean 
ovfOnAnyDomainSupported) {
+        int size = ITEMS_COUNT_PER_UPDATE - 1;
+
+        
doReturn(ovfOnAnyDomainSupported).when(command).ovfOnAnyDomainSupported(any(StoragePool.class));
+        List<Guid> vmGuids = generateGuidList(size);
+        List<Guid> removedGuids = Collections.emptyList();
+        List<Guid> templatesGuids = generateGuidList(size);
+
+        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, 
ImageStatus.LOCKED, pool1.getId());
+        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.LOCKED, pool1.getId());
+
+        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
+
+        executeCommand();
+        verify(command, never()).performOvfUpdate(any(StoragePool.class), 
anyMap());
+        if (!ovfOnAnyDomainSupported) {
+            verify(ovfUpdateProcessHelper, 
never()).executeRemoveVmInSpm(any(Guid.class), any(Guid.class), 
any(Guid.class));
+        }
+        verifyCorrectOvfDataUpdaterRun(pool1, Collections.<Guid> emptyList(), 
removedGuids);
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterPartOfDisksAreLockedOvfOnAnyDomainSupported() {
+        testOvfDataUpdaterAllDisksAreLockedNonToRemove(true);
+        verifyOvfUpdatedForSupportedPools(Collections.<Guid> emptyList(), 
Collections.<Guid, List<Guid>> emptyMap());
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterPartOfDisksAreLockedOvfOnAnyDomainUnupported() {
+        testOvfDataUpdaterAllDisksAreLockedNonToRemove(false);
+    }
+
+    public void testOvfDataUpdaterPartOfDisksAreLocked(boolean 
ovfOnAnyDomainSupported) {
+        int size = ITEMS_COUNT_PER_UPDATE - 1;
+        // unlocked vms/templates
+        List<Guid> vmGuids = generateGuidList(size);
+        List<Guid> templatesGuids = generateGuidList(size);
+        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.OK, pool1.getId());
+        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool1.getId());
+
+        // locked vms/templates
+        List<Guid> lockedVmGuids = generateGuidList(size);
+        List<Guid> lockedTemplatesGuids = generateGuidList(size);
+        addVms(lockedVmGuids, 2, VMStatus.Down, ImageStatus.LOCKED, 
pool1.getId());
+        addTemplates(lockedTemplatesGuids, 2, VmTemplateStatus.OK, 
ImageStatus.LOCKED, pool1.getId());
+        // ids for removal
+        List<Guid> removedGuids = generateGuidList(size);
+
+        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
+
+        executeCommand();
+        verify(command, times(numberOfTimesToBeCalled(size, 
true))).performOvfUpdate(any(StoragePool.class), anyMap());
+        if (!ovfOnAnyDomainSupported) {
+            verify(ovfUpdateProcessHelper, 
times(size)).executeRemoveVmInSpm(any(Guid.class), any(Guid.class), 
any(Guid.class));
+        }
+        // list of ids that should have been updated.
+        List<Guid> needToBeUpdated = new LinkedList<Guid>(vmGuids);
+        needToBeUpdated.addAll(templatesGuids);
+        verifyCorrectOvfDataUpdaterRun(pool1, needToBeUpdated, removedGuids);
+    }
+
+    private int numberOfTimesToBeCalled(int size, boolean 
isBothVmAndTemplates) {
+        int toReturn = 0;
+        if (size % ITEMS_COUNT_PER_UPDATE != 0) {
+            toReturn++;
+        }
+        toReturn += size / ITEMS_COUNT_PER_UPDATE;
+        if (isBothVmAndTemplates) {
+            toReturn = toReturn * 2;
+        }
+        return toReturn;
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterAllVmsAndTemplatesAreLockedOvfOnAnyDomainSupported() {
+        testOvfDataUpdaterAllVmsAndTemplatesAreLocked(true);
+        verifyOvfUpdatedForSupportedPools(Collections.<Guid> emptyList(), 
Collections.<Guid, List<Guid>> emptyMap());
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterAllVmsAndTemplatesAreLockedOvfOnAnyDomainUnupported() {
+        testOvfDataUpdaterAllVmsAndTemplatesAreLocked(false);
+    }
+
+    public void testOvfDataUpdaterAllVmsAndTemplatesAreLocked(boolean 
ovfOnAnyDomainSupported) {
+        int size = ITEMS_COUNT_PER_UPDATE - 1;
+        List<Guid> vmGuids = generateGuidList(size);
+        addVms(vmGuids, 2, VMStatus.ImageLocked, ImageStatus.OK, 
pool1.getId());
+        List<Guid> removedGuids = generateGuidList(size);
+        List<Guid> templatesGuids = generateGuidList(size);
+        addTemplates(templatesGuids, 2, VmTemplateStatus.Locked, 
ImageStatus.OK, pool1.getId());
+
+        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
+
+        command.executeCommand();
+        verify(command, never()).performOvfUpdate(any(StoragePool.class), 
anyMap());
+        if (!ovfOnAnyDomainSupported) {
+            verify(ovfUpdateProcessHelper, 
times(size)).executeRemoveVmInSpm(any(Guid.class), any(Guid.class), 
any(Guid.class));
+        }
+        verifyCorrectOvfDataUpdaterRun(pool1, Collections.<Guid> emptyList(), 
removedGuids);
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterPartOfVmsAndTemplatesAreLockedOvfOnAnyDomainSupported() {
+        testOvfDataUpdaterPartOfVmsAndTemplatesAreLocked(true);
+        verifyOvfUpdatedForSupportedPools(Collections.<Guid> emptyList(), 
Collections.<Guid, List<Guid>> emptyMap());
+    }
+
+    @Test
+    public void 
testOvfDataUpdaterPartOfVmsAndTemplatesAreLockedOvfOnAnyDomainUnupported() {
+        testOvfDataUpdaterPartOfVmsAndTemplatesAreLocked(false);
+    }
+
+    public void testOvfDataUpdaterPartOfVmsAndTemplatesAreLocked(boolean 
ovfOnAnyDomainSupported) {
+        int size = ITEMS_COUNT_PER_UPDATE;
+        List<Guid> vmGuids = generateGuidList(size);
+        List<Guid> removedGuids = generateGuidList(size);
+        List<Guid> templatesGuids = generateGuidList(size);
+
+        addVms(vmGuids, 2, VMStatus.ImageLocked, ImageStatus.OK, 
pool1.getId());
+        addTemplates(templatesGuids, 2, VmTemplateStatus.Locked, 
ImageStatus.OK, pool1.getId());
+
+        List<Guid> vmGuidsUnlocked = generateGuidList(size);
+        List<Guid> templatesGuidsUnlocked = generateGuidList(size);
+
+        addVms(vmGuidsUnlocked, 2, VMStatus.Down, ImageStatus.OK, 
pool1.getId());
+        addTemplates(templatesGuidsUnlocked, 2, VmTemplateStatus.OK, 
ImageStatus.OK, pool1.getId());
+
+        vmGuids.addAll(vmGuidsUnlocked);
+        templatesGuids.addAll(templatesGuidsUnlocked);
+        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
+
+        executeCommand();
+
+        List<Guid> neededToBeUpdated = new LinkedList<Guid>(vmGuidsUnlocked);
+        neededToBeUpdated.addAll(templatesGuidsUnlocked);
+        verify(command, times(numberOfTimesToBeCalled(size, 
true))).performOvfUpdate(any(StoragePool.class), anyMap());
+        if (!ovfOnAnyDomainSupported) {
+            verify(ovfUpdateProcessHelper, 
times(size)).executeRemoveVmInSpm(any(Guid.class), any(Guid.class), 
any(Guid.class));
+        }
+        verifyCorrectOvfDataUpdaterRun(pool1, neededToBeUpdated, removedGuids);
+    }
+
+    @Test
+    public void testUpdatedDbGenerationOvfOnAnyDomainSupported() {
+        testUpdatedDbGeneration(true);
+        verifyOvfUpdatedForSupportedPools(Collections.<Guid> emptyList(), 
Collections.<Guid, List<Guid>> emptyMap());
+    }
+
+    @Test
+    public void testUpdatedDbGenerationOvfOnAnyDomainUnupported() {
+        testUpdatedDbGeneration(false);
+    }
+
+    public void testUpdatedDbGeneration(boolean ovfOnAnyDomainSupported) {
+        int size = 3 * ITEMS_COUNT_PER_UPDATE + 10;
+        List<Guid> vmGuids = generateGuidList(size);
+        List<Guid> templatesGuids = generateGuidList(size);
+        List<Guid> removedGuids = Collections.emptyList();
+        addVms(vmGuids, 2, VMStatus.Down, ImageStatus.OK, pool1.getId());
+        addTemplates(templatesGuids, 2, VmTemplateStatus.OK, ImageStatus.OK, 
pool1.getId());
+
+        initTestForPool(pool1, vmGuids, templatesGuids, removedGuids);
+
+        doReturn(2L).when(vmStaticDAO).getDbGeneration(any(Guid.class));
+
+        executeCommand();
+
+        verify(command, never()).performOvfUpdate(any(StoragePool.class), 
anyMap());
+        if (!ovfOnAnyDomainSupported) {
+            verify(ovfUpdateProcessHelper, 
never()).executeRemoveVmInSpm(any(Guid.class), any(Guid.class), 
any(Guid.class));
+        }
+
+        List<Guid> idsThatNeededToBeUpdated = new LinkedList<Guid>(vmGuids);
+        idsThatNeededToBeUpdated.addAll(templatesGuids);
+
+        verifyCorrectOvfDataUpdaterRun(pool1, Collections.<Guid> emptyList(), 
removedGuids);
+    }
+
+    @Test
+    public void testUpdateCalledForUnupdatedDomain() {
+        Guid poolId = pool1.getId();
+        StorageDomainOvfInfo ovfInfo = 
poolDomainsOvfInfo.entrySet().iterator().next().getValue().getFirst().get(0);
+        ovfInfo.setStatus(StorageDomainOvfInfoStatus.OUTDATED);
+        
doReturn(true).when(command).ovfOnAnyDomainSupported(any(StoragePool.class));
+        initTestForPool(pool1,
+                Collections.<Guid> emptyList(),
+                Collections.<Guid> emptyList(),
+                Collections.<Guid> emptyList());
+        executeCommand();
+        verify(command, never()).performOvfUpdate(any(StoragePool.class), 
anyMap());
+        Map<Guid, List<Guid>> domainsRequiredUpdateForPool =
+                Collections.singletonMap(poolId, 
Arrays.asList(ovfInfo.getStorageDomainId()));
+        verifyOvfUpdatedForSupportedPools(Arrays.asList(poolId), 
domainsRequiredUpdateForPool);
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
index 920deef..f3c1437 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
@@ -362,6 +362,7 @@
     CreateOvfVolumeForStorageDomain(1903, QuotaDependency.NONE),
     CreateOvfStoresForStorageDomain(1904, QuotaDependency.NONE),
     RetrieveImageData(1905, QuotaDependency.NONE),
+    ProcessOvfUpdateForStoragePool(1906, QuotaDependency.NONE),
 
     // Affinity Groups
     AddAffinityGroup(1950, ActionGroup.MANIPULATE_AFFINITY_GROUPS, false, 
QuotaDependency.NONE),
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
index 31ed560..da45e68 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
@@ -4,7 +4,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 import javax.transaction.Transaction;
 
 import org.apache.commons.lang.StringUtils;
@@ -29,13 +28,16 @@
 import org.ovirt.engine.core.dao.PermissionDAO;
 import org.ovirt.engine.core.dao.RoleDAO;
 import org.ovirt.engine.core.dao.RoleGroupMapDAO;
+import org.ovirt.engine.core.dao.SnapshotDao;
 import org.ovirt.engine.core.dao.StepDao;
 import org.ovirt.engine.core.dao.StorageDomainDAO;
+import org.ovirt.engine.core.dao.StorageDomainOvfInfoDao;
 import org.ovirt.engine.core.dao.StorageDomainStaticDAO;
 import org.ovirt.engine.core.dao.StoragePoolDAO;
 import org.ovirt.engine.core.dao.VdsDAO;
 import org.ovirt.engine.core.dao.VdsDynamicDAO;
 import org.ovirt.engine.core.dao.VdsGroupDAO;
+import org.ovirt.engine.core.dao.VmAndTemplatesGenerationsDAO;
 import org.ovirt.engine.core.dao.VmDAO;
 import org.ovirt.engine.core.dao.VmDynamicDAO;
 import org.ovirt.engine.core.dao.VmStaticDAO;
@@ -596,6 +598,18 @@
         return getDbFacade().getVmStaticDao();
     }
 
+    public SnapshotDao getSnapshotDAO() {
+        return getDbFacade().getSnapshotDao();
+    }
+
+    public VmAndTemplatesGenerationsDAO getVmAndTemplatesGenerationsDAO() {
+        return DbFacade.getInstance().getVmAndTemplatesGenerationsDao();
+    }
+
+    public StorageDomainOvfInfoDao getStorageDomainOvfInfoDAO() {
+        return DbFacade.getInstance().getStorageDomainOvfInfoDao();
+    }
+
     public VmDynamicDAO getVmDynamicDAO() {
         return getDbFacade().getVmDynamicDao();
     }
@@ -633,7 +647,7 @@
     }
 
     public VmNetworkInterfaceDao getVmNetworkInterfaceDao() {
-        return getDbFacade().getVmNetworkInterfaceDao();
+        return DbFacade.getInstance().getVmNetworkInterfaceDao();
     }
 
     protected VmNicDao getVmNicDao() {


-- 
To view, visit http://gerrit.ovirt.org/35815
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6780aedf2d215d08c4bed0ff4f7520c45f753f66
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: ovirt-engine-3.5
Gerrit-Owner: Liron Aravot <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to