You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2026/04/13 08:29:25 UTC

(cloudstack) 23/25: Implement/fix limit validation for secondary storage

This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch 22.0.1-fixes
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit e8d57d1b0dc173ef55c6386f91f1d77b8b8c9830
Author: Daniel Augusto Veronezi Salvador <38...@users.noreply.github.com>
AuthorDate: Sun Feb 22 10:44:24 2026 -0300

    Implement/fix limit validation for secondary storage
---
 .../manager/BareMetalTemplateAdapter.java          |   1 -
 .../cloud/storage/ImageStoreUploadMonitorImpl.java |  17 +
 .../com/cloud/storage/VolumeApiServiceImpl.java    | 551 ++++++++++-----------
 .../cloud/template/HypervisorTemplateAdapter.java  | 129 +++--
 .../com/cloud/template/TemplateAdapterBase.java    |  38 +-
 .../com/cloud/template/TemplateManagerImpl.java    | 437 ++++++++--------
 .../cloud/template/TemplateManagerImplTest.java    | 134 ++---
 7 files changed, 687 insertions(+), 620 deletions(-)

diff --git a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
index 940897de3c9..c6c38a39809 100644
--- a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
+++ b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
@@ -106,7 +106,6 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem
             }
         }
 
-        _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
         return template;
     }
 
diff --git a/server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java
index 06da14e4e1c..5c6f8dc6599 100755
--- a/server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java
+++ b/server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java
@@ -63,6 +63,7 @@ import com.cloud.configuration.Resource;
 import com.cloud.event.EventTypes;
 import com.cloud.event.UsageEventUtils;
 import com.cloud.exception.ConnectionException;
+import com.cloud.exception.ResourceAllocationException;
 import com.cloud.host.Host;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
@@ -543,6 +544,22 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
                                     break;
                                 }
                             }
+
+                            Account owner = accountDao.findById(template.getAccountId());
+                            long templateSize = answer.getVirtualSize();
+
+                            try (CheckedReservation secondaryStorageReservation = new CheckedReservation(owner, Resource.ResourceType.secondary_storage, null, null, templateSize, reservationDao, _resourceLimitMgr)) {
+                                _resourceLimitMgr.incrementResourceCount(owner.getId(), Resource.ResourceType.secondary_storage, templateSize);
+                            } catch (ResourceAllocationException e) {
+                                tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.UPLOAD_ERROR);
+                                tmpTemplateDataStore.setState(State.Failed);
+                                stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationFailed, null, _templateDao);
+                                msg = String.format("Upload of template [%s] failed because its owner [%s] does not have enough secondary storage space available.", template.getUuid(), owner.getUuid());
+                                logger.warn(msg);
+                                sendAlert = true;
+                                break;
+                            }
+
                             stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationSucceeded, null, _templateDao);
                             //publish usage event
                             String etype = EventTypes.EVENT_TEMPLATE_CREATE;
diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
index d50b0ebdf7a..5861f7ced43 100644
--- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
@@ -35,7 +35,6 @@ import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 
-import com.cloud.resourcelimit.ReservationHelper;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.InternalIdentity;
@@ -111,6 +110,7 @@ import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
 import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
 import org.apache.cloudstack.utils.identity.ManagementServerNode;
 import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
 import org.apache.cloudstack.utils.jsinterpreter.TagAsRuleHelper;
@@ -169,6 +169,7 @@ import com.cloud.projects.ProjectManager;
 import com.cloud.resource.ResourceManager;
 import com.cloud.resource.ResourceState;
 import com.cloud.resourcelimit.CheckedReservation;
+import com.cloud.resourcelimit.ReservationHelper;
 import com.cloud.serializer.GsonHelper;
 import com.cloud.server.ManagementService;
 import com.cloud.server.ResourceTag;
@@ -356,10 +357,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
     private ManagementService managementService;
     @Inject
     protected SnapshotHelper snapshotHelper;
-
     @Inject
     protected DomainDao domainDao;
-
     @Inject
     protected ProjectManager projectManager;
     @Inject
@@ -374,7 +373,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
     EndPointSelector _epSelector;
     @Inject
     private ReservationDao reservationDao;
-
     @Inject
     private VMSnapshotDetailsDao vmSnapshotDetailsDao;
 
@@ -499,76 +497,77 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         List<Reserver> reservations = new ArrayList<>();
         try {
-        validateVolume(caller, ownerId, zoneId, volumeName, null, format, diskOfferingId, reservations);
-
-        return Transaction.execute(new TransactionCallbackWithException<GetUploadParamsResponse, MalformedURLException>() {
-            @Override
-            public GetUploadParamsResponse doInTransaction(TransactionStatus status) throws MalformedURLException {
-
-                VolumeVO volume = persistVolume(owner, zoneId, volumeName, null, format, diskOfferingId, Volume.State.NotUploaded);
-
-                final DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId, volume);
-
-                VolumeInfo vol = volFactory.getVolume(volume.getId());
-
-                RegisterVolumePayload payload = new RegisterVolumePayload(null, cmd.getChecksum(), format);
-                vol.addPayload(payload);
+            validateVolume(caller, ownerId, zoneId, volumeName, null, format, diskOfferingId, reservations);
 
-                Pair<EndPoint, DataObject> pair = volService.registerVolumeForPostUpload(vol, store);
-                EndPoint ep = pair.first();
-                DataObject dataObject = pair.second();
-
-                GetUploadParamsResponse response = new GetUploadParamsResponse();
-
-                String ssvmUrlDomain = _configDao.getValue(Config.SecStorageSecureCopyCert.key());
-                String protocol = UseHttpsToUpload.value() ? "https" : "http";
-
-                String url = ImageStoreUtil.generatePostUploadUrl(ssvmUrlDomain, ep.getPublicAddr(), vol.getUuid(),  protocol);
-                response.setPostURL(new URL(url));
-
-                // set the post url, this is used in the monitoring thread to determine the SSVM
-                VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId());
-                assert (volumeStore != null) : "sincle volume is registered, volumestore cannot be null at this stage";
-                volumeStore.setExtractUrl(url);
-                _volumeStoreDao.persist(volumeStore);
-
-                response.setId(UUID.fromString(vol.getUuid()));
-
-                int timeout = ImageStoreUploadMonitorImpl.getUploadOperationTimeout();
-                DateTime currentDateTime = new DateTime(DateTimeZone.UTC);
-                String expires = currentDateTime.plusMinutes(timeout).toString();
-                response.setTimeout(expires);
-
-                String key = _configDao.getValue(Config.SSVMPSK.key());
-                /*
-                 * encoded metadata using the post upload config key
-                 */
-                TemplateOrVolumePostUploadCommand command = new TemplateOrVolumePostUploadCommand(vol.getId(), vol.getUuid(), volumeStore.getInstallPath(), cmd.getChecksum(), vol.getType().toString(),
-                        vol.getName(), vol.getFormat().toString(), dataObject.getDataStore().getUri(), dataObject.getDataStore().getRole().toString());
-                command.setLocalPath(volumeStore.getLocalDownloadPath());
-                //using the existing max upload size configuration
-                command.setProcessTimeout(NumbersUtil.parseLong(_configDao.getValue("vmware.package.ova.timeout"), 3600));
-                command.setMaxUploadSize(_configDao.getValue(Config.MaxUploadVolumeSize.key()));
-
-                long accountId = vol.getAccountId();
-                Account account = _accountDao.findById(accountId);
-                Domain domain = domainDao.findById(account.getDomainId());
-
-                // one of the two following might have to be removed
-                command.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null));
-                command.setDefaultMaxSecondaryStorageInBytes(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null));
-                command.setAccountId(accountId);
-                Gson gson = new GsonBuilder().create();
-                String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
-                response.setMetadata(metadata);
-
-                /*
-                 * signature calculated on the url, expiry, metadata.
-                 */
-                response.setSignature(EncryptionUtil.generateSignature(metadata + url + expires, key));
-                return response;
-            }
-        });
+            return Transaction.execute(new TransactionCallbackWithException<GetUploadParamsResponse, MalformedURLException>() {
+                @Override
+                public GetUploadParamsResponse doInTransaction(TransactionStatus status) throws MalformedURLException {
+
+                    VolumeVO volume = persistVolume(owner, zoneId, volumeName, null, format, diskOfferingId, Volume.State.NotUploaded);
+
+                    final DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId, volume);
+
+                    VolumeInfo vol = volFactory.getVolume(volume.getId());
+
+                    RegisterVolumePayload payload = new RegisterVolumePayload(null, cmd.getChecksum(), format);
+                    vol.addPayload(payload);
+
+                    Pair<EndPoint, DataObject> pair = volService.registerVolumeForPostUpload(vol, store);
+                    EndPoint ep = pair.first();
+                    DataObject dataObject = pair.second();
+
+                    GetUploadParamsResponse response = new GetUploadParamsResponse();
+
+                    String ssvmUrlDomain = _configDao.getValue(Config.SecStorageSecureCopyCert.key());
+                    String protocol = UseHttpsToUpload.value() ? "https" : "http";
+
+                    String url = ImageStoreUtil.generatePostUploadUrl(ssvmUrlDomain, ep.getPublicAddr(), vol.getUuid(),  protocol);
+                    response.setPostURL(new URL(url));
+
+                    // set the post url, this is used in the monitoring thread to determine the SSVM
+                    VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId());
+                    assert (volumeStore != null) : "sincle volume is registered, volumestore cannot be null at this stage";
+                    volumeStore.setExtractUrl(url);
+                    _volumeStoreDao.persist(volumeStore);
+
+                    response.setId(UUID.fromString(vol.getUuid()));
+
+                    int timeout = ImageStoreUploadMonitorImpl.getUploadOperationTimeout();
+                    DateTime currentDateTime = new DateTime(DateTimeZone.UTC);
+                    String expires = currentDateTime.plusMinutes(timeout).toString();
+                    response.setTimeout(expires);
+
+                    String key = _configDao.getValue(Config.SSVMPSK.key());
+                    /*
+                     * encoded metadata using the post upload config key
+                     */
+                    TemplateOrVolumePostUploadCommand command = new TemplateOrVolumePostUploadCommand(vol.getId(), vol.getUuid(), volumeStore.getInstallPath(), cmd.getChecksum(), vol.getType().toString(),
+                            vol.getName(), vol.getFormat().toString(), dataObject.getDataStore().getUri(), dataObject.getDataStore().getRole().toString());
+                    command.setLocalPath(volumeStore.getLocalDownloadPath());
+                    //using the existing max upload size configuration
+                    command.setProcessTimeout(NumbersUtil.parseLong(_configDao.getValue("vmware.package.ova.timeout"), 3600));
+                    command.setMaxUploadSize(_configDao.getValue(Config.MaxUploadVolumeSize.key()));
+
+                    long accountId = vol.getAccountId();
+                    Account account = _accountDao.findById(accountId);
+                    Domain domain = domainDao.findById(account.getDomainId());
+
+                    // one of the two following might have to be removed
+                    command.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null));
+                    command.setDefaultMaxSecondaryStorageInGB(ByteScaleUtils.bytesToGibibytes(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null)));
+                    command.setDefaultMaxSecondaryStorageInBytes(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null));
+                    command.setAccountId(accountId);
+                    Gson gson = new GsonBuilder().create();
+                    String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
+                    response.setMetadata(metadata);
+
+                    /*
+                     * signature calculated on the url, expiry, metadata.
+                     */
+                    response.setSignature(EncryptionUtil.generateSignature(metadata + url + expires, key));
+                    return response;
+                }
+            });
 
         } finally {
             ReservationHelper.closeAll(reservations);
@@ -967,29 +966,29 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         List<Reserver> reservations = new ArrayList<>();
         try {
-        _resourceLimitMgr.checkVolumeResourceLimit(owner, displayVolume, size, diskOffering, reservations);
+            _resourceLimitMgr.checkVolumeResourceLimit(owner, displayVolume, size, diskOffering, reservations);
 
-        // Verify that zone exists
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
-        }
+            // Verify that zone exists
+            DataCenterVO zone = _dcDao.findById(zoneId);
+            if (zone == null) {
+                throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
+            }
 
-        // Check if zone is disabled
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-            throw new PermissionDeniedException(String.format("Cannot perform this operation, Zone: %s is currently disabled", zone));
-        }
+            // Check if zone is disabled
+            if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+                throw new PermissionDeniedException(String.format("Cannot perform this operation, Zone: %s is currently disabled", zone));
+            }
 
-        // If local storage is disabled then creation of volume with local disk
-        // offering not allowed
-        if (!zone.isLocalStorageEnabled() && diskOffering.isUseLocalStorage()) {
-            throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
-        }
+            // If local storage is disabled then creation of volume with local disk
+            // offering not allowed
+            if (!zone.isLocalStorageEnabled() && diskOffering.isUseLocalStorage()) {
+                throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+            }
 
-        String userSpecifiedName = getVolumeNameFromCommand(cmd);
+            String userSpecifiedName = getVolumeNameFromCommand(cmd);
 
-        return commitVolume(cmd.getSnapshotId(), caller, owner, displayVolume, zoneId, diskOfferingId, provisioningType, size, minIops, maxIops, parentVolume, userSpecifiedName,
-                _uuidMgr.generateUuid(Volume.class, cmd.getCustomId()), details);
+            return commitVolume(cmd.getSnapshotId(), caller, owner, displayVolume, zoneId, diskOfferingId, provisioningType, size, minIops, maxIops, parentVolume, userSpecifiedName,
+                    _uuidMgr.generateUuid(Volume.class, cmd.getCustomId()), details);
         } finally {
             ReservationHelper.closeAll(reservations);
         }
@@ -1320,134 +1319,134 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         List<Reserver> reservations = new ArrayList<>();
         try {
-        validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk, diskOffering, newDiskOffering, reservations);
+            validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk, diskOffering, newDiskOffering, reservations);
 
-        // Note: The storage plug-in in question should perform validation on the IOPS to check if a sufficient number of IOPS is available to perform
-        // the requested change
+            // Note: The storage plug-in in question should perform validation on the IOPS to check if a sufficient number of IOPS is available to perform
+            // the requested change
 
-        /* If this volume has never been beyond allocated state, short circuit everything and simply update the database. */
-        // We need to publish this event to usage_volume table
-        if (volume.getState() == Volume.State.Allocated) {
-            logger.debug("Volume is in the allocated state, but has never been created. Simply updating database with new size and IOPS.");
+            /* If this volume has never been beyond allocated state, short circuit everything and simply update the database. */
+            // We need to publish this event to usage_volume table
+            if (volume.getState() == Volume.State.Allocated) {
+                logger.debug("Volume is in the allocated state, but has never been created. Simply updating database with new size and IOPS.");
 
-            volume.setSize(newSize);
-            volume.setMinIops(newMinIops);
-            volume.setMaxIops(newMaxIops);
-            volume.setHypervisorSnapshotReserve(newHypervisorSnapshotReserve);
+                volume.setSize(newSize);
+                volume.setMinIops(newMinIops);
+                volume.setMaxIops(newMaxIops);
+                volume.setHypervisorSnapshotReserve(newHypervisorSnapshotReserve);
 
-            if (newDiskOffering != null) {
-                volume.setDiskOfferingId(cmd.getNewDiskOfferingId());
-            }
+                if (newDiskOffering != null) {
+                    volume.setDiskOfferingId(cmd.getNewDiskOfferingId());
+                }
 
-            _volsDao.update(volume.getId(), volume);
-            _resourceLimitMgr.updateVolumeResourceCountForDiskOfferingChange(volume.getAccountId(), volume.isDisplayVolume(), currentSize, newSize,
-                    diskOffering, newDiskOffering);
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                    volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
-            return volume;
-        }
+                _volsDao.update(volume.getId(), volume);
+                _resourceLimitMgr.updateVolumeResourceCountForDiskOfferingChange(volume.getAccountId(), volume.isDisplayVolume(), currentSize, newSize,
+                        diskOffering, newDiskOffering);
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                        volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
+                return volume;
+            }
 
-        Long newDiskOfferingId = newDiskOffering != null ? newDiskOffering.getId() : diskOffering.getId();
+            Long newDiskOfferingId = newDiskOffering != null ? newDiskOffering.getId() : diskOffering.getId();
 
-        boolean volumeMigrateRequired = false;
-        List<? extends StoragePool> suitableStoragePoolsWithEnoughSpace = null;
-        StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
-        if (!storageMgr.storagePoolHasEnoughSpaceForResize(storagePool, currentSize, newSize)) {
-            if (!autoMigrateVolume) {
-                throw new CloudRuntimeException(String.format("Failed to resize volume %s since the storage pool does not have enough space to accommodate new size for the volume %s, try with automigrate set to true in order to check in the other suitable pools for the new size and then migrate & resize volume there.", volume.getUuid(), volume.getName()));
-            }
-            Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForSystemMigrationOfVolume(volume.getId(), newDiskOfferingId, currentSize, newMinIops, newMaxIops, true, false);
-            List<? extends StoragePool> suitableStoragePools = poolsPair.second();
-            if (CollectionUtils.isEmpty(poolsPair.first()) && CollectionUtils.isEmpty(poolsPair.second())) {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume resize failed for volume ID: %s as no suitable pool(s) found for migrating to support new disk offering or new size", volume.getUuid()));
-            }
-            final Long newSizeFinal = newSize;
-            suitableStoragePoolsWithEnoughSpace = suitableStoragePools.stream().filter(pool -> storageMgr.storagePoolHasEnoughSpaceForResize(pool, 0L, newSizeFinal)).collect(Collectors.toList());
-            if (CollectionUtils.isEmpty(suitableStoragePoolsWithEnoughSpace)) {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume resize failed for volume ID: %s as no suitable pool(s) with enough space found.", volume.getUuid()));
+            boolean volumeMigrateRequired = false;
+            List<? extends StoragePool> suitableStoragePoolsWithEnoughSpace = null;
+            StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
+            if (!storageMgr.storagePoolHasEnoughSpaceForResize(storagePool, currentSize, newSize)) {
+                if (!autoMigrateVolume) {
+                    throw new CloudRuntimeException(String.format("Failed to resize volume %s since the storage pool does not have enough space to accommodate new size for the volume %s, try with automigrate set to true in order to check in the other suitable pools for the new size and then migrate & resize volume there.", volume.getUuid(), volume.getName()));
+                }
+                Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForSystemMigrationOfVolume(volume.getId(), newDiskOfferingId, currentSize, newMinIops, newMaxIops, true, false);
+                List<? extends StoragePool> suitableStoragePools = poolsPair.second();
+                if (CollectionUtils.isEmpty(poolsPair.first()) && CollectionUtils.isEmpty(poolsPair.second())) {
+                    throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume resize failed for volume ID: %s as no suitable pool(s) found for migrating to support new disk offering or new size", volume.getUuid()));
+                }
+                final Long newSizeFinal = newSize;
+                suitableStoragePoolsWithEnoughSpace = suitableStoragePools.stream().filter(pool -> storageMgr.storagePoolHasEnoughSpaceForResize(pool, 0L, newSizeFinal)).collect(Collectors.toList());
+                if (CollectionUtils.isEmpty(suitableStoragePoolsWithEnoughSpace)) {
+                    throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume resize failed for volume ID: %s as no suitable pool(s) with enough space found.", volume.getUuid()));
+                }
+                Collections.shuffle(suitableStoragePoolsWithEnoughSpace);
+                volumeMigrateRequired = true;
             }
-            Collections.shuffle(suitableStoragePoolsWithEnoughSpace);
-            volumeMigrateRequired = true;
-        }
 
-        boolean volumeResizeRequired = false;
-        if (currentSize != newSize || !compareEqualsIncludingNullOrZero(newMaxIops, volume.getMaxIops()) || !compareEqualsIncludingNullOrZero(newMinIops, volume.getMinIops())) {
-            volumeResizeRequired = true;
-        }
-        if (!volumeMigrateRequired && !volumeResizeRequired && newDiskOffering != null) {
-            _volsDao.updateDiskOffering(volume.getId(), newDiskOffering.getId());
-            volume = _volsDao.findById(volume.getId());
-            updateStorageWithTheNewDiskOffering(volume, newDiskOffering);
+            boolean volumeResizeRequired = false;
+            if (currentSize != newSize || !compareEqualsIncludingNullOrZero(newMaxIops, volume.getMaxIops()) || !compareEqualsIncludingNullOrZero(newMinIops, volume.getMinIops())) {
+                volumeResizeRequired = true;
+            }
+            if (!volumeMigrateRequired && !volumeResizeRequired && newDiskOffering != null) {
+                _volsDao.updateDiskOffering(volume.getId(), newDiskOffering.getId());
+                volume = _volsDao.findById(volume.getId());
+                updateStorageWithTheNewDiskOffering(volume, newDiskOffering);
 
-            return volume;
-        }
+                return volume;
+            }
 
-        if (volumeMigrateRequired) {
-            MigrateVolumeCmd migrateVolumeCmd = new MigrateVolumeCmd(volume.getId(), suitableStoragePoolsWithEnoughSpace.get(0).getId(), newDiskOfferingId, true);
-            try {
-                Volume result = migrateVolume(migrateVolumeCmd);
-                volume = (result != null) ? _volsDao.findById(result.getId()) : null;
-                if (volume == null) {
+            if (volumeMigrateRequired) {
+                MigrateVolumeCmd migrateVolumeCmd = new MigrateVolumeCmd(volume.getId(), suitableStoragePoolsWithEnoughSpace.get(0).getId(), newDiskOfferingId, true);
+                try {
+                    Volume result = migrateVolume(migrateVolumeCmd);
+                    volume = (result != null) ? _volsDao.findById(result.getId()) : null;
+                    if (volume == null) {
+                        throw new CloudRuntimeException(String.format("Volume resize operation failed for volume ID: %s as migration failed to storage pool %s accommodating new size", volume.getUuid(), suitableStoragePoolsWithEnoughSpace.get(0).getId()));
+                    }
+                } catch (Exception e) {
                     throw new CloudRuntimeException(String.format("Volume resize operation failed for volume ID: %s as migration failed to storage pool %s accommodating new size", volume.getUuid(), suitableStoragePoolsWithEnoughSpace.get(0).getId()));
                 }
-            } catch (Exception e) {
-                throw new CloudRuntimeException(String.format("Volume resize operation failed for volume ID: %s as migration failed to storage pool %s accommodating new size", volume.getUuid(), suitableStoragePoolsWithEnoughSpace.get(0).getId()));
             }
-        }
 
-        UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
+            UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
 
-        if (userVm != null) {
-            // serialize VM operation
-            AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+            if (userVm != null) {
+                // serialize VM operation
+                AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
 
-            if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-                // avoid re-entrance
+                if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+                    // avoid re-entrance
 
-                VmWorkJobVO placeHolder = null;
+                    VmWorkJobVO placeHolder = null;
 
-                placeHolder = createPlaceHolderWork(userVm.getId());
+                    placeHolder = createPlaceHolderWork(userVm.getId());
 
-                try {
-                    return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve,
+                    try {
+                        return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve,
+                                newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk);
+                    } finally {
+                        _workJobDao.expunge(placeHolder.getId());
+                    }
+                } else {
+                    Outcome<Volume> outcome = resizeVolumeThroughJobQueue(userVm.getId(), volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve,
                             newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk);
-                } finally {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            } else {
-                Outcome<Volume> outcome = resizeVolumeThroughJobQueue(userVm.getId(), volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve,
-                        newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk);
 
-                try {
-                    outcome.get();
-                } catch (InterruptedException e) {
-                    throw new RuntimeException("Operation was interrupted", e);
-                } catch (ExecutionException e) {
-                    throw new RuntimeException("Execution exception", e);
-                }
-
-                Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+                    try {
+                        outcome.get();
+                    } catch (InterruptedException e) {
+                        throw new RuntimeException("Operation was interrupted", e);
+                    } catch (ExecutionException e) {
+                        throw new RuntimeException("Execution exception", e);
+                    }
 
-                if (jobResult != null) {
-                    if (jobResult instanceof ConcurrentOperationException) {
-                        throw (ConcurrentOperationException) jobResult;
-                    } else if (jobResult instanceof ResourceAllocationException) {
-                        throw (ResourceAllocationException) jobResult;
-                    } else if (jobResult instanceof RuntimeException) {
-                        throw (RuntimeException) jobResult;
-                    } else if (jobResult instanceof Throwable) {
-                        throw new RuntimeException("Unexpected exception", (Throwable) jobResult);
-                    } else if (jobResult instanceof Long) {
-                        return _volsDao.findById((Long) jobResult);
+                    Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+
+                    if (jobResult != null) {
+                        if (jobResult instanceof ConcurrentOperationException) {
+                            throw (ConcurrentOperationException) jobResult;
+                        } else if (jobResult instanceof ResourceAllocationException) {
+                            throw (ResourceAllocationException) jobResult;
+                        } else if (jobResult instanceof RuntimeException) {
+                            throw (RuntimeException) jobResult;
+                        } else if (jobResult instanceof Throwable) {
+                            throw new RuntimeException("Unexpected exception", (Throwable) jobResult);
+                        } else if (jobResult instanceof Long) {
+                            return _volsDao.findById((Long) jobResult);
+                        }
                     }
-                }
 
-                return volume;
+                    return volume;
+                }
             }
-        }
 
-        return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, newDiskOffering != null ? cmd.getNewDiskOfferingId() : null,
-                shrinkOk);
+            return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, newDiskOffering != null ? cmd.getNewDiskOfferingId() : null,
+                    shrinkOk);
 
         } finally {
             ReservationHelper.closeAll(reservations);
@@ -1912,17 +1911,17 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         List<Reserver> reservations = new ArrayList<>();
         try {
-        _resourceLimitMgr.checkVolumeResourceLimit(_accountMgr.getAccount(volume.getAccountId()), volume.isDisplayVolume(), volume.getSize(), diskOffering, reservations);
+            _resourceLimitMgr.checkVolumeResourceLimit(_accountMgr.getAccount(volume.getAccountId()), volume.isDisplayVolume(), volume.getSize(), diskOffering, reservations);
 
-        try {
-            _volsDao.detachVolume(volume.getId());
-            stateTransitTo(volume, Volume.Event.RecoverRequested);
-        } catch (NoTransitionException e) {
-            logger.debug("Failed to recover volume {}", volume, e);
-            throw new CloudRuntimeException(String.format("Failed to recover volume %s", volume), e);
-        }
-        _resourceLimitMgr.incrementVolumeResourceCount(volume.getAccountId(), volume.isDisplay(),
-                volume.getSize(), _diskOfferingDao.findById(volume.getDiskOfferingId()));
+            try {
+                _volsDao.detachVolume(volume.getId());
+                stateTransitTo(volume, Volume.Event.RecoverRequested);
+            } catch (NoTransitionException e) {
+                logger.debug("Failed to recover volume {}", volume, e);
+                throw new CloudRuntimeException(String.format("Failed to recover volume %s", volume), e);
+            }
+            _resourceLimitMgr.incrementVolumeResourceCount(volume.getAccountId(), volume.isDisplay(),
+                    volume.getSize(), _diskOfferingDao.findById(volume.getDiskOfferingId()));
 
         } catch (ResourceAllocationException e) {
             logger.error("primary storage resource limit check failed", e);
@@ -2161,96 +2160,96 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         List<Reserver> reservations = new ArrayList<>();
         try {
-        validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk, existingDiskOffering, newDiskOffering, reservations);
+            validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk, existingDiskOffering, newDiskOffering, reservations);
 
-        /* If this volume has never been beyond allocated state, short circuit everything and simply update the database. */
-        // We need to publish this event to usage_volume table
-        if (volume.getState() == Volume.State.Allocated) {
-            logger.debug("Volume {} is in the allocated state, but has never been created. Simply updating database with new size and IOPS.", volume);
+            /* If this volume has never been beyond allocated state, short circuit everything and simply update the database. */
+            // We need to publish this event to usage_volume table
+            if (volume.getState() == Volume.State.Allocated) {
+                logger.debug("Volume {} is in the allocated state, but has never been created. Simply updating database with new size and IOPS.", volume);
 
-            volume.setSize(newSize);
-            volume.setMinIops(newMinIops);
-            volume.setMaxIops(newMaxIops);
-            volume.setHypervisorSnapshotReserve(newHypervisorSnapshotReserve);
+                volume.setSize(newSize);
+                volume.setMinIops(newMinIops);
+                volume.setMaxIops(newMaxIops);
+                volume.setHypervisorSnapshotReserve(newHypervisorSnapshotReserve);
 
-            if (newDiskOffering != null) {
-                volume.setDiskOfferingId(newDiskOfferingId);
-                _volumeMgr.saveVolumeDetails(newDiskOfferingId, volume.getId());
-            }
+                if (newDiskOffering != null) {
+                    volume.setDiskOfferingId(newDiskOfferingId);
+                    _volumeMgr.saveVolumeDetails(newDiskOfferingId, volume.getId());
+                }
 
-            _volsDao.update(volume.getId(), volume);
-            _resourceLimitMgr.updateVolumeResourceCountForDiskOfferingChange(volume.getAccountId(), volume.isDisplayVolume(), currentSize, newSize,
-                    existingDiskOffering, newDiskOffering);
+                _volsDao.update(volume.getId(), volume);
+                _resourceLimitMgr.updateVolumeResourceCountForDiskOfferingChange(volume.getAccountId(), volume.isDisplayVolume(), currentSize, newSize,
+                        existingDiskOffering, newDiskOffering);
 
-            if (currentSize != newSize) {
-                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                        volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
+                if (currentSize != newSize) {
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                            volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
+                }
+                return volume;
             }
-            return volume;
-        }
 
-        if (currentSize != newSize || !compareEqualsIncludingNullOrZero(newMaxIops, volume.getMaxIops()) || !compareEqualsIncludingNullOrZero(newMinIops, volume.getMinIops())) {
-            volumeResizeRequired = true;
-            validateVolumeReadyStateAndHypervisorChecks(volume, currentSize, newSize);
-        }
+            if (currentSize != newSize || !compareEqualsIncludingNullOrZero(newMaxIops, volume.getMaxIops()) || !compareEqualsIncludingNullOrZero(newMinIops, volume.getMinIops())) {
+                volumeResizeRequired = true;
+                validateVolumeReadyStateAndHypervisorChecks(volume, currentSize, newSize);
+            }
 
-        StoragePoolVO existingStoragePool = _storagePoolDao.findById(volume.getPoolId());
+            StoragePoolVO existingStoragePool = _storagePoolDao.findById(volume.getPoolId());
 
-        Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForSystemMigrationOfVolume(volume.getId(), newDiskOffering.getId(), currentSize, newMinIops, newMaxIops, true, false);
-        List<? extends StoragePool> suitableStoragePools = poolsPair.second();
+            Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForSystemMigrationOfVolume(volume.getId(), newDiskOffering.getId(), currentSize, newMinIops, newMaxIops, true, false);
+            List<? extends StoragePool> suitableStoragePools = poolsPair.second();
 
-        if (!suitableStoragePools.stream().anyMatch(p -> (p.getId() == existingStoragePool.getId()))) {
-            volumeMigrateRequired = true;
-            if (!autoMigrateVolume) {
-                throw new InvalidParameterValueException(String.format("Failed to change offering for volume %s since automigrate is set to false but volume needs to migrated", volume.getUuid()));
+            if (!suitableStoragePools.stream().anyMatch(p -> (p.getId() == existingStoragePool.getId()))) {
+                volumeMigrateRequired = true;
+                if (!autoMigrateVolume) {
+                    throw new InvalidParameterValueException(String.format("Failed to change offering for volume %s since automigrate is set to false but volume needs to migrated", volume.getUuid()));
+                }
             }
-        }
-
-        if (!volumeMigrateRequired && !volumeResizeRequired) {
-            _volsDao.updateDiskOffering(volume.getId(), newDiskOffering.getId());
-            volume = _volsDao.findById(volume.getId());
-            updateStorageWithTheNewDiskOffering(volume, newDiskOffering);
 
-            return volume;
-        }
+            if (!volumeMigrateRequired && !volumeResizeRequired) {
+                _volsDao.updateDiskOffering(volume.getId(), newDiskOffering.getId());
+                volume = _volsDao.findById(volume.getId());
+                updateStorageWithTheNewDiskOffering(volume, newDiskOffering);
 
-        if (volumeMigrateRequired) {
-            if (CollectionUtils.isEmpty(poolsPair.first()) && CollectionUtils.isEmpty(poolsPair.second())) {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume change offering operation failed for volume: %s as no suitable pool(s) found for migrating to support new disk offering", volume));
-            }
-            final Long newSizeFinal = newSize;
-            List<? extends StoragePool> suitableStoragePoolsWithEnoughSpace = suitableStoragePools.stream().filter(pool -> storageMgr.storagePoolHasEnoughSpaceForResize(pool, 0L, newSizeFinal)).collect(Collectors.toList());
-            if (CollectionUtils.isEmpty(suitableStoragePoolsWithEnoughSpace)) {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume change offering operation failed for volume: %s as no suitable pool(s) with enough space found for volume migration.", volume));
+                return volume;
             }
-            Collections.shuffle(suitableStoragePoolsWithEnoughSpace);
-            MigrateVolumeCmd migrateVolumeCmd = new MigrateVolumeCmd(volume.getId(), suitableStoragePoolsWithEnoughSpace.get(0).getId(), newDiskOffering.getId(), true);
-            try {
-                Volume result = migrateVolume(migrateVolumeCmd);
-                volume = (result != null) ? _volsDao.findById(result.getId()) : null;
-                if (volume == null) {
-                    throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume: %s migration failed to storage pool %s", volume, suitableStoragePools.get(0)));
+
+            if (volumeMigrateRequired) {
+                if (CollectionUtils.isEmpty(poolsPair.first()) && CollectionUtils.isEmpty(poolsPair.second())) {
+                    throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume change offering operation failed for volume: %s as no suitable pool(s) found for migrating to support new disk offering", volume));
+                }
+                final Long newSizeFinal = newSize;
+                List<? extends StoragePool> suitableStoragePoolsWithEnoughSpace = suitableStoragePools.stream().filter(pool -> storageMgr.storagePoolHasEnoughSpaceForResize(pool, 0L, newSizeFinal)).collect(Collectors.toList());
+                if (CollectionUtils.isEmpty(suitableStoragePoolsWithEnoughSpace)) {
+                    throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume change offering operation failed for volume: %s as no suitable pool(s) with enough space found for volume migration.", volume));
+                }
+                Collections.shuffle(suitableStoragePoolsWithEnoughSpace);
+                MigrateVolumeCmd migrateVolumeCmd = new MigrateVolumeCmd(volume.getId(), suitableStoragePoolsWithEnoughSpace.get(0).getId(), newDiskOffering.getId(), true);
+                try {
+                    Volume result = migrateVolume(migrateVolumeCmd);
+                    volume = (result != null) ? _volsDao.findById(result.getId()) : null;
+                    if (volume == null) {
+                        throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume: %s migration failed to storage pool %s", volume, suitableStoragePools.get(0)));
+                    }
+                } catch (Exception e) {
+                    throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume: %s migration failed to storage pool %s due to %s", volume, suitableStoragePools.get(0), e.getMessage()));
                 }
-            } catch (Exception e) {
-                throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume: %s migration failed to storage pool %s due to %s", volume, suitableStoragePools.get(0), e.getMessage()));
             }
-        }
 
-        if (volumeResizeRequired) {
-            // refresh volume data
-            volume = _volsDao.findById(volume.getId());
-            try {
-                volume = resizeVolumeInternal(volume, newDiskOffering, currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, shrinkOk);
-            } catch (Exception e) {
-                if (volumeMigrateRequired) {
-                    logger.warn(String.format("Volume change offering operation succeeded for volume ID: %s but volume resize operation failed, so please try resize volume operation separately", volume.getUuid()));
-                } else {
-                    throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume ID: %s due to resize volume operation failed", volume.getUuid()));
+            if (volumeResizeRequired) {
+                // refresh volume data
+                volume = _volsDao.findById(volume.getId());
+                try {
+                    volume = resizeVolumeInternal(volume, newDiskOffering, currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, shrinkOk);
+                } catch (Exception e) {
+                    if (volumeMigrateRequired) {
+                        logger.warn(String.format("Volume change offering operation succeeded for volume ID: %s but volume resize operation failed, so please try resize volume operation separately", volume.getUuid()));
+                    } else {
+                        throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume ID: %s due to resize volume operation failed", volume.getUuid()));
+                    }
                 }
             }
-        }
 
-        return volume;
+            return volume;
 
         } finally {
             ReservationHelper.closeAll(reservations);
@@ -2807,7 +2806,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
         // if target VM has associated VM snapshots
         List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
         if (vmSnapshots.size() > 0) {
-            throw new InvalidParameterValueException(String.format("Unable to attach volume to VM %s/%s, please specify a VM that does not have VM snapshots", vm.getName(), vm.getUuid()));
+            throw new InvalidParameterValueException(String.format("Unable to attach volume to Instance %s/%s, please specify an Instance that does not have Instance Snapshots", vm.getName(), vm.getUuid()));
         }
     }
 
@@ -3130,7 +3129,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
         // Don't allow detach if target VM has associated VM snapshots
         List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
         if (CollectionUtils.isNotEmpty(vmSnapshots)) {
-            throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots");
+            throw new InvalidParameterValueException("Unable to detach volume, please specify an Instance that does not have Instance Snapshots");
         }
 
         checkForBackups(vm, false);
@@ -3426,7 +3425,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
         // Check that Vm to which this volume is attached does not have VM Snapshots
         // OfflineVmwareMigration: consider if this is needed and desirable
         if (vm != null && _vmSnapshotDao.findByVm(vm.getId()).size() > 0) {
-            throw new InvalidParameterValueException("Volume cannot be migrated, please remove all VM snapshots for VM to which this volume is attached");
+            throw new InvalidParameterValueException("Volume cannot be migrated, please remove all Instance Snapshots for Instance to which this volume is attached");
         }
 
         StoragePoolVO srcStoragePoolVO = _storagePoolDao.findById(vol.getPoolId());
@@ -3435,7 +3434,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
         if (vm != null && State.Running.equals(vm.getState())) {
             // Check if the VM is GPU enabled.
             if (_serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
-                throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
+                throw new InvalidParameterValueException("Live Migration of GPU enabled Instance is not supported");
             }
 
             // Check if the underlying hypervisor supports storage motion.
diff --git a/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
index 6084987e29c..2599d64f82f 100644
--- a/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
@@ -34,14 +34,14 @@ import org.apache.cloudstack.annotation.AnnotationService;
 import org.apache.cloudstack.annotation.dao.AnnotationDao;
 import org.apache.cloudstack.api.ApiCommandResourceType;
 import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.GetUploadParamsForIsoCmd;
 import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
 import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
 import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.direct.download.DirectDownloadManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
@@ -57,15 +57,18 @@ import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
+import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
 import org.apache.cloudstack.utils.security.DigestHelper;
 import org.apache.commons.collections.CollectionUtils;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.alert.AlertManager;
+import com.cloud.configuration.Config;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.domain.Domain;
 import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
 import com.cloud.event.EventTypes;
 import com.cloud.event.UsageEventUtils;
@@ -73,6 +76,7 @@ import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.host.HostVO;
 import com.cloud.hypervisor.Hypervisor;
+import com.cloud.org.Grouping;
 import com.cloud.resource.ResourceManager;
 import com.cloud.storage.ScopeType;
 import com.cloud.storage.Storage.ImageFormat;
@@ -197,19 +201,6 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
             profile.setSize(templateSize);
         }
         profile.setUrl(url);
-        // Check that the resource limit for secondary storage won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()),
-                ResourceType.secondary_storage,
-                UriUtils.getRemoteSize(url, followRedirects));
-        return profile;
-    }
-
-    @Override
-    public TemplateProfile prepare(GetUploadParamsForIsoCmd cmd) throws ResourceAllocationException {
-        TemplateProfile profile = super.prepare(cmd);
-
-        // Check that the resource limit for secondary storage won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()), ResourceType.secondary_storage);
         return profile;
     }
 
@@ -228,19 +219,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
             profile.setForCks(cmd.isForCks());
         }
         profile.setUrl(url);
-        // Check that the resource limit for secondary storage won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()),
-                ResourceType.secondary_storage,
-                UriUtils.getRemoteSize(url, followRedirects));
-        return profile;
-    }
-
-    @Override
-    public TemplateProfile prepare(GetUploadParamsForTemplateCmd cmd) throws ResourceAllocationException {
-        TemplateProfile profile = super.prepare(cmd);
 
-        // Check that the resource limit for secondary storage won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()), ResourceType.secondary_storage);
         return profile;
     }
 
@@ -268,7 +247,6 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
             persistDirectDownloadTemplate(template.getId(), profile.getSize());
         }
 
-        _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
         return template;
     }
 
@@ -322,6 +300,44 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
         }
     }
 
+    protected boolean isZoneAndImageStoreAvailable(DataStore imageStore, Long zoneId, Set<Long> zoneSet, boolean isTemplatePrivate) {
+        if (zoneId == null) {
+            logger.warn(String.format("Zone ID is null, cannot allocate ISO/template in image store [%s].", imageStore));
+            return false;
+        }
+
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        if (zone == null) {
+            logger.warn("Unable to find zone by id [{}], so skip downloading template to its image store [{}].", zoneId, imageStore);
+            return false;
+        }
+
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState()) {
+            logger.info("Zone [{}] is disabled. Skip downloading template to its image store [{}].", zone, imageStore);
+            return false;
+        }
+
+        if (!_statsCollector.imageStoreHasEnoughCapacity(imageStore)) {
+            logger.info("Image store doesn't have enough capacity. Skip downloading template to this image store [{}].", imageStore);
+            return false;
+        }
+
+        if (zoneSet == null) {
+            logger.info(String.format("Zone set is null; therefore, the ISO/template should be allocated in every secondary storage of zone [%s].", zone));
+            return true;
+        }
+
+        if (isTemplatePrivate && zoneSet.contains(zoneId)) {
+            logger.info(String.format("The template is private and it is already allocated in a secondary storage in zone [%s]; therefore, image store [%s] will be skipped.",
+                    zone, imageStore));
+            return false;
+        }
+
+        logger.info(String.format("Private template will be allocated in image store [%s] in zone [%s].", imageStore, zone));
+        zoneSet.add(zoneId);
+        return true;
+    }
+
     @Override
     public List<TemplateOrVolumePostUploadCommand> createTemplateForPostUpload(final TemplateProfile profile) {
         // persist entry in vm_template, vm_template_details and template_zone_ref tables, not that entry at template_store_ref is not created here, and created in createTemplateAsync.
@@ -369,12 +385,67 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
                 if(payloads.isEmpty()) {
                     throw new CloudRuntimeException("unable to find zone or an image store with enough capacity");
                 }
-                _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
+
                 return payloads;
             }
         });
     }
 
+    /**
+     * If the template/ISO is marked as private, then it is allocated to a random secondary storage; otherwise, allocates to every storage pool in every zone given by the
+     * {@link TemplateProfile#getZoneIdList()}.
+     */
+    protected void postUploadAllocation(List<DataStore> imageStores, VMTemplateVO template, List<TemplateOrVolumePostUploadCommand> payloads) {
+        Set<Long> zoneSet = new HashSet<>();
+        Collections.shuffle(imageStores);
+        for (DataStore imageStore : imageStores) {
+            Long zoneId_is = imageStore.getScope().getScopeId();
+
+            if (!isZoneAndImageStoreAvailable(imageStore, zoneId_is, zoneSet, isPrivateTemplate(template))) {
+                continue;
+            }
+
+            TemplateInfo tmpl = imageFactory.getTemplate(template.getId(), imageStore);
+
+            // persist template_store_ref entry
+            DataObject templateOnStore = imageStore.create(tmpl);
+
+            // update template_store_ref and template state
+            EndPoint ep = _epSelector.select(templateOnStore);
+            if (ep == null) {
+                String errMsg = String.format("There is no secondary storage VM for downloading template to image store %s", imageStore);
+                logger.warn(errMsg);
+                throw new CloudRuntimeException(errMsg);
+            }
+
+            TemplateOrVolumePostUploadCommand payload = new TemplateOrVolumePostUploadCommand(template.getId(), template.getUuid(), tmpl.getInstallPath(), tmpl
+                    .getChecksum(), tmpl.getType().toString(), template.getUniqueName(), template.getFormat().toString(), templateOnStore.getDataStore().getUri(),
+                    templateOnStore.getDataStore().getRole().toString());
+            //using the existing max template size configuration
+            payload.setMaxUploadSize(_configDao.getValue(Config.MaxTemplateAndIsoSize.key()));
+
+            Long accountId = template.getAccountId();
+            Account account = _accountDao.findById(accountId);
+            Domain domain = _domainDao.findById(account.getDomainId());
+
+            payload.setDefaultMaxSecondaryStorageInGB(ByteScaleUtils.bytesToGibibytes(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null)));
+            payload.setAccountId(accountId);
+            payload.setRemoteEndPoint(ep.getPublicAddr());
+            payload.setRequiresHvm(template.requiresHvm());
+            payload.setDescription(template.getDisplayText());
+            payloads.add(payload);
+        }
+    }
+
+    protected boolean isPrivateTemplate(VMTemplateVO template){
+
+        // if public OR featured OR system template
+        if(template.isPublicTemplate() || template.isFeatured() || template.getTemplateType() == TemplateType.SYSTEM)
+            return false;
+        else
+            return true;
+    }
+
     private class CreateTemplateContext<T> extends AsyncRpcContext<T> {
         final TemplateInfo template;
 
diff --git a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java
index a9adfa93236..d650ef98db7 100644
--- a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java
+++ b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java
@@ -293,7 +293,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
             }
             GuestOS noneGuestOs = ApiDBUtils.findGuestOSByDisplayName(ApiConstants.ISO_GUEST_OS_NONE);
             if ((guestOSId == null || guestOSId == noneGuestOs.getId()) && bootable == true) {
-                throw new InvalidParameterValueException("Please pass a valid GuestOS Id");
+                throw new InvalidParameterValueException("Please pass a valid GuestOS ID");
             }
             if (bootable == false) {
                 guestOSId = noneGuestOs.getId(); //Guest os id of None.
@@ -309,7 +309,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
                 requiresHVM = true;
             }
             if (deployAsIs) {
-                logger.info("Setting default guest OS for deploy-as-is template while the template registration is not completed");
+                logger.info("Setting default guest OS for deploy-as-is Template while the Template registration is not completed");
                 guestOSId = getDefaultDeployAsIsGuestOsId();
             }
         }
@@ -342,7 +342,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
         // check whether owner can create public templates
         boolean allowPublicUserTemplates = TemplateManager.AllowPublicUserTemplates.valueIn(templateOwner.getId());
         if (!isAdmin && !allowPublicUserTemplates && isPublic) {
-            throw new InvalidParameterValueException("Only private templates/ISO can be created.");
+            throw new InvalidParameterValueException("Only private Templates/ISO can be created.");
         }
 
         if (!isAdmin || featured == null) {
@@ -363,8 +363,6 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
             throw new IllegalArgumentException("Unable to find user with id " + userId);
         }
 
-        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);
-
         // If a zoneId is specified, make sure it is valid
         if (zoneIdList != null) {
             for (Long zoneId :zoneIdList) {
@@ -386,7 +384,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
                     Objects.equals(template.getArch(), arch)) {
                 logger.error("{} for same arch {} is having same name or description", template,
                         template.getArch());
-                throw new IllegalArgumentException("Cannot use reserved names for templates");
+                throw new IllegalArgumentException("Cannot use reserved names for Templates");
             }
         }
 
@@ -442,11 +440,11 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
         if (cmd.isDeployAsIs()) {
             if (MapUtils.isNotEmpty(details)) {
                 if (details.containsKey(VmDetailConstants.ROOT_DISK_CONTROLLER)) {
-                    logger.info("Ignoring the rootDiskController detail provided, as we honour what is defined in the template");
+                    logger.info("Ignoring the rootDiskController detail provided, as we honour what is defined in the Template");
                     details.remove(VmDetailConstants.ROOT_DISK_CONTROLLER);
                 }
                 if (details.containsKey(VmDetailConstants.NIC_ADAPTER)) {
-                    logger.info("Ignoring the nicAdapter detail provided, as we honour what is defined in the template");
+                    logger.info("Ignoring the nicAdapter detail provided, as we honour what is defined in the Template");
                     details.remove(VmDetailConstants.NIC_ADAPTER);
                 }
             }
@@ -512,7 +510,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
     public TemplateProfile prepare(GetUploadParamsForTemplateCmd cmd) throws ResourceAllocationException {
         Long osTypeId = cmd.getOsTypeId();
         if (osTypeId == null) {
-            logger.info("Setting the default guest OS for deploy-as-is templates while the template upload is not completed");
+            logger.info("Setting the default guest OS for deploy-as-is Templates while the Template upload is not completed");
             osTypeId = getDefaultDeployAsIsGuestOsId();
         }
         UploadParams params = new TemplateUploadParams(CallContext.current().getCallingUserId(), cmd.getName(),
@@ -574,7 +572,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
             List<DataCenterVO> dcs = _dcDao.listAll();
 
             if (dcs.isEmpty()) {
-                throw new CloudRuntimeException("No zones are present in the system, can't add template");
+                throw new CloudRuntimeException("No zones are present in the system, can't add Template");
             }
 
             template.setCrossZones(true);
@@ -604,7 +602,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
                     Account owner = _accountMgr.getAccount(template.getAccountId());
                     if (owner.getType() == Account.Type.PROJECT) {
                         if (!_projectMgr.canAccessProjectAccount(account, owner.getId())) {
-                            throw new PermissionDeniedException(msg + ". Permission denied. The caller can't access project's template");
+                            throw new PermissionDeniedException(msg + ". Permission denied. The caller can't access project's Template");
                         }
                     } else {
                         throw new PermissionDeniedException(msg + ". Permission denied.");
@@ -638,10 +636,10 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
 
         VMTemplateVO template = _tmpltDao.findById(templateId);
         if (template == null) {
-            throw new InvalidParameterValueException("unable to find template with id " + templateId);
+            throw new InvalidParameterValueException("Unable to find Template with ID " + templateId);
         }
 
-        userId = accountAndUserValidation(account, userId, null, template, "Unable to delete template ");
+        userId = accountAndUserValidation(account, userId, null, template, "Unable to delete Template ");
 
         UserVO user = _userDao.findById(userId);
         if (user == null) {
@@ -649,11 +647,11 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
         }
 
         if (template.getFormat() == ImageFormat.ISO) {
-            throw new InvalidParameterValueException("Please specify a valid template.");
+            throw new InvalidParameterValueException("Please specify a valid Template.");
         }
 
         if (template.getState() == VirtualMachineTemplate.State.NotUploaded || template.getState() == VirtualMachineTemplate.State.UploadInProgress) {
-            throw new InvalidParameterValueException("The template is either getting uploaded or it may be initiated shortly, please wait for it to be completed");
+            throw new InvalidParameterValueException("The Template is either getting uploaded or it may be initiated shortly, please wait for it to be completed");
         }
 
         return new TemplateProfile(userId, template, zoneId);
@@ -667,7 +665,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
 
         VMTemplateVO template = _tmpltDao.findById(templateId);
         if (template == null) {
-            throw new InvalidParameterValueException("unable to find template with id " + templateId);
+            throw new InvalidParameterValueException("Unable to find Template with ID " + templateId);
         }
         return new TemplateProfile(userId, template, zoneId);
     }
@@ -681,10 +679,10 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
 
         VMTemplateVO template = _tmpltDao.findById(templateId);
         if (template == null) {
-            throw new InvalidParameterValueException("unable to find iso with id " + templateId);
+            throw new InvalidParameterValueException("Unable to find ISO with ID " + templateId);
         }
 
-        userId = accountAndUserValidation(account, userId, null, template, "Unable to delete iso ");
+        userId = accountAndUserValidation(account, userId, null, template, "Unable to delete ISO ");
 
         UserVO user = _userDao.findById(userId);
         if (user == null) {
@@ -692,11 +690,11 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
         }
 
         if (template.getFormat() != ImageFormat.ISO) {
-            throw new InvalidParameterValueException("Please specify a valid iso.");
+            throw new InvalidParameterValueException("Please specify a valid ISO.");
         }
 
         if (template.getState() == VirtualMachineTemplate.State.NotUploaded || template.getState() == VirtualMachineTemplate.State.UploadInProgress) {
-            throw new InvalidParameterValueException("The iso is either getting uploaded or it may be initiated shortly, please wait for it to be completed");
+            throw new InvalidParameterValueException("The ISO is either getting uploaded or it may be initiated shortly, please wait for it to be completed");
         }
 
         return new TemplateProfile(userId, template, zoneId);
diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java
index 3ff374e273f..38fd9ab205b 100755
--- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java
@@ -132,6 +132,7 @@ import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.deploy.DeployDestination;
+import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
 import com.cloud.domain.Domain;
 import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.ActionEvent;
@@ -306,27 +307,25 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     private HypervisorGuruManager _hvGuruMgr;
     @Inject
     ReservationDao reservationDao;
-
-    private List<TemplateAdapter> _adapters;
-
-    ExecutorService _preloadExecutor;
-
     @Inject
     private StorageCacheManager cacheMgr;
     @Inject
     private EndPointSelector selector;
-
     @Inject
     protected SnapshotHelper snapshotHelper;
     @Inject
     VnfTemplateManager vnfTemplateManager;
-
+    @Inject
+    TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
     @Inject
     private SecondaryStorageHeuristicDao secondaryStorageHeuristicDao;
-
     @Inject
     private HeuristicRuleHelper heuristicRuleHelper;
 
+    private List<TemplateAdapter> _adapters;
+
+    ExecutorService _preloadExecutor;
+
     protected boolean backupSnapshotAfterTakingSnapshot = SnapshotInfo.BackupSnapshotAfterTakingSnapshot.value();
 
     private TemplateAdapter getAdapter(HypervisorType type) {
@@ -345,14 +344,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         }
 
         if (adapter == null) {
-            throw new CloudRuntimeException("Cannot find template adapter for " + type.toString());
+            throw new CloudRuntimeException("Cannot find Template adapter for " + type.toString());
         }
 
         return adapter;
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "creating iso")
+    @ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "Creating ISO")
     public VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException {
         TemplateAdapter adapter = getAdapter(HypervisorType.None);
         Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
@@ -383,7 +382,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template")
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "Creating Template")
     public VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException {
         Account account = CallContext.current().getCallingAccount();
         if (cmd.getTemplateTag() != null) {
@@ -408,7 +407,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             TemplateProfile profile = adapter.prepare(cmd);
             VMTemplateVO template = adapter.create(profile);
 
-            // Secondary storage resource usage will be incremented in com.cloud.template.HypervisorTemplateAdapter.createTemplateAsyncCallBack
+            // Secondary storage resource usage will be recalculated in com.cloud.template.HypervisorTemplateAdapter.createTemplateAsyncCallBack
             // for HypervisorTemplateAdapter
             _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
             if (secondaryStorageUsage > 0) {
@@ -422,7 +421,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
                 }
                 return template;
             } else {
-                throw new CloudRuntimeException("Failed to create a template");
+                throw new CloudRuntimeException("Failed to create a Template");
             }
         }
     }
@@ -481,24 +480,42 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
             return response;
         } else {
-            throw new CloudRuntimeException("Unable to register template.");
+            throw new CloudRuntimeException("Unable to register Template.");
         }
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "creating post upload iso")
+    @ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "Creating post upload ISO")
     public GetUploadParamsResponse registerIsoForPostUpload(GetUploadParamsForIsoCmd cmd) throws ResourceAllocationException, MalformedURLException {
-        TemplateAdapter adapter = getAdapter(HypervisorType.None);
-        TemplateProfile profile = adapter.prepare(cmd);
-        return registerPostUploadInternal(adapter, profile);
+        Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
+
+        try (CheckedReservation templateReservation = new CheckedReservation(owner, ResourceType.template, null, null, 1L, reservationDao, _resourceLimitMgr)) {
+            TemplateAdapter adapter = getAdapter(HypervisorType.None);
+            TemplateProfile profile = adapter.prepare(cmd);
+
+            GetUploadParamsResponse response = registerPostUploadInternal(adapter, profile);
+
+            _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
+
+            return response;
+        }
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating post upload template")
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "Creating post upload Template")
     public GetUploadParamsResponse registerTemplateForPostUpload(GetUploadParamsForTemplateCmd cmd) throws ResourceAllocationException, MalformedURLException {
-        TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
-        TemplateProfile profile = adapter.prepare(cmd);
-        return registerPostUploadInternal(adapter, profile);
+        Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
+
+        try (CheckedReservation templateReservation = new CheckedReservation(owner, ResourceType.template, null, null, 1L, reservationDao, _resourceLimitMgr)) {
+            TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
+            TemplateProfile profile = adapter.prepare(cmd);
+
+            GetUploadParamsResponse response = registerPostUploadInternal(adapter, profile);
+
+            _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
+
+            return response;
+        }
     }
 
     @Override
@@ -536,7 +553,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_EXTRACT, eventDescription = "extracting template", async = true)
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_EXTRACT, eventDescription = "Extracting Template", async = true)
     public String extract(ExtractTemplateCmd cmd) {
         Account caller = CallContext.current().getCallingAccount();
         Long templateId = cmd.getId();
@@ -547,7 +564,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
         VirtualMachineTemplate template = _tmpltDao.findById(templateId);
         if (template == null) {
-            throw new InvalidParameterValueException("unable to find template with id " + templateId);
+            throw new InvalidParameterValueException("Unable to find Template with id " + templateId);
         }
 
         String extractUrl = extract(caller, templateId, url, zoneId, mode, eventId, false);
@@ -560,7 +577,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
         VMTemplateVO vmTemplate = _tmpltDao.findById(templateId);
         if (vmTemplate == null) {
-            throw new InvalidParameterValueException("Unable to find template id=" + templateId);
+            throw new InvalidParameterValueException("Unable to find Template ID=" + templateId);
         }
 
         _accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.OperateEntry, true, vmTemplate);
@@ -571,7 +588,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
                 if (pool.getStatus() == StoragePoolStatus.Up && pool.getDataCenterId() == zoneId) {
                     prepareTemplateInOneStoragePool(vmTemplate, pool);
                 } else {
-                    logger.warn("Skip loading template {} into primary storage {} as " +
+                    logger.warn("Skip loading Template {} into primary storage {} as " +
                             "either the pool zone {} is different from the requested zone {} or " +
                             "the pool is currently not available.",
                             vmTemplate::toString, pool::toString, () -> _dcDao.findById(pool.getDataCenterId()), () -> _dcDao.findById(zoneId));
@@ -607,7 +624,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             }
         } else {
             if (template.getFormat() == ImageFormat.ISO) {
-                throw new InvalidParameterValueException("Unsupported format, could not extract the template");
+                throw new InvalidParameterValueException("Unsupported format, could not extract the Template");
             }
         }
 
@@ -616,7 +633,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         }
 
         if (!_accountMgr.isRootAdmin(caller.getId()) && !template.isExtractable()) {
-            throw new InvalidParameterValueException(String.format("Unable to extract template %s as it's not extractable", template));
+            throw new InvalidParameterValueException(String.format("Unable to extract Template %s as it's not extractable", template));
         }
 
         _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
@@ -670,7 +687,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             if (MapUtils.isNotEmpty(storageForDisks)) {
                 for (StoragePool storagePool : storageForDisks.values()) {
                     if (poolId != null && storagePool.getId() != poolId) {
-                        throw new CloudRuntimeException("Cannot determine where to download iso");
+                        throw new CloudRuntimeException("Cannot determine where to download ISO");
                     }
                     poolId = storagePool.getId();
                 }
@@ -705,10 +722,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     }
 
     private void prepareTemplateInOneStoragePool(final VMTemplateVO template, final StoragePoolVO pool) {
-        logger.info("Schedule to preload template {} into primary storage {}", template, pool);
+        logger.info("Schedule to preload Template {} into primary storage {}", template, pool);
         if (pool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
             List<StoragePoolVO> childDataStores = _poolDao.listChildStoragePoolsInDatastoreCluster(pool.getId());
-            logger.debug("Schedule to preload template {} into child datastores of DataStore cluster: {}", template, pool);
+            logger.debug("Schedule to preload Template {} into child datastores of DataStore cluster: {}", template, pool);
             for (StoragePoolVO childDataStore :  childDataStores) {
                 prepareTemplateInOneStoragePoolInternal(template, childDataStore);
             }
@@ -729,10 +746,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             }
 
             private void reallyRun() {
-                logger.info("Start to preload template {} into primary storage {}", template, pool);
+                logger.info("Start to preload Template {} into primary storage {}", template, pool);
                 StoragePool pol = (StoragePool)_dataStoreMgr.getPrimaryDataStore(pool.getId());
                 prepareTemplateForCreate(template, pol);
-                logger.info("End of preloading template {} into primary storage {}", template, pool);
+                logger.info("End of preloading Template {} into primary storage {}", template, pool);
             }
         });
     }
@@ -743,7 +760,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             if (pool.getDataCenterId() == zoneId) {
                 prepareTemplateInOneStoragePool(template, pool);
             } else {
-                logger.info("Skip loading template {} into primary storage {} as pool " +
+                logger.info("Skip loading Template {} into primary storage {} as pool " +
                         "zone {} is different from the requested zone {}", template::toString, pool::toString,
                         () -> _dcDao.findById(pool.getDataCenterId()), () -> _dcDao.findById(zoneId));
             }
@@ -776,7 +793,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
         templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, pool.getDataCenterId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
         if (templateStoreRef == null) {
-            logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
+            logger.error("Unable to find a secondary storage host who has completely downloaded the Template.");
             return null;
         }
 
@@ -787,7 +804,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
         if (templateStoragePoolRef == null) {
             if (logger.isDebugEnabled()) {
-                logger.debug("Downloading template {} to pool {}", template, pool);
+                logger.debug("Downloading Template {} to pool {}", template, pool);
             }
             DataStore srcSecStore = _dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image);
             TemplateInfo srcTemplate = _tmplFactory.getTemplate(templateId, srcSecStore);
@@ -796,13 +813,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             try {
                 TemplateApiResult result = future.get();
                 if (result.isFailed()) {
-                    logger.debug("prepare template failed:" + result.getResult());
+                    logger.debug("Prepare Template failed:" + result.getResult());
                     return null;
                 }
 
                 return _tmpltPoolDao.findByPoolTemplate(poolId, templateId, null);
             } catch (Exception ex) {
-                logger.debug("failed to copy template from image store {} to primary storage", srcSecStore);
+                logger.debug("Failed to copy Template from image store {} to primary storage", srcSecStore);
             }
         }
 
@@ -865,9 +882,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         // find the size of the template to be copied
         TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(srcSecStore.getId(), tmpltId);
 
-        _resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
-        _resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltStore.getSize()).longValue());
-
         // Event details
         String copyEventType;
         if (template.getFormat().equals(ImageFormat.ISO)) {
@@ -893,7 +907,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             try {
                 TemplateApiResult result = future.get();
                 if (result.isFailed()) {
-                    logger.debug("copy template failed for image store {}: {}", dstSecStore, result.getResult());
+                    logger.debug("Copy Template failed for image store {}: {}", dstSecStore, result.getResult());
+                    _tmplStoreDao.removeByTemplateStore(tmpltId, dstSecStore.getId());
                     continue; // try next image store
                 }
 
@@ -908,32 +923,31 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
                 List<VMTemplateVO> dataDiskTemplates = _tmpltDao.listByParentTemplatetId(template.getId());
                 if (dataDiskTemplates != null && !dataDiskTemplates.isEmpty()) {
                     for (VMTemplateVO dataDiskTemplate : dataDiskTemplates) {
-                        logger.debug("Copying {} for source template {}. Copy all Datadisk templates to destination datastore {}", dataDiskTemplates.size(), template, dstSecStore);
+                        logger.debug("Copying {} for source Template {}. Copy all Datadisk Templates to destination datastore {}", dataDiskTemplates.size(), template, dstSecStore);
                         TemplateInfo srcDataDiskTemplate = _tmplFactory.getTemplate(dataDiskTemplate.getId(), srcSecStore);
                         AsyncCallFuture<TemplateApiResult> dataDiskCopyFuture = _tmpltSvr.copyTemplate(srcDataDiskTemplate, dstSecStore);
                         try {
                             TemplateApiResult dataDiskCopyResult = dataDiskCopyFuture.get();
                             if (dataDiskCopyResult.isFailed()) {
-                                logger.error("Copy of datadisk template: {} to image store: {} failed with error: {} , will try copying the next one", srcDataDiskTemplate, dstSecStore, dataDiskCopyResult.getResult());
+                                logger.error("Copy of datadisk Template: {} to image store: {} failed with error: {} , will try copying the next one", srcDataDiskTemplate, dstSecStore, dataDiskCopyResult.getResult());
                                 continue; // Continue to copy next Datadisk template
                             }
                             _tmpltDao.addTemplateToZone(dataDiskTemplate, dstZoneId);
                             _resourceLimitMgr.incrementResourceCount(dataDiskTemplate.getAccountId(), ResourceType.secondary_storage, dataDiskTemplate.getSize());
                         } catch (Exception ex) {
-                            logger.error("Failed to copy datadisk template: {} to image store: {} , will try copying the next one", srcDataDiskTemplate, dstSecStore);
+                            logger.error("Failed to copy datadisk Template: {} to image store: {} , will try copying the next one", srcDataDiskTemplate, dstSecStore);
                         }
                     }
                 }
             } catch (Exception ex) {
-                logger.debug("failed to copy template to image store:{} ,will try next one", dstSecStore);
+                logger.debug("Failed to copy Template to image store:{} ,will try next one", dstSecStore, ex);
             }
         }
         return true;
-
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "copying template", async = true)
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "Copying Template", async = true)
     public VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException {
         Long templateId = cmd.getId();
         Long userId = CallContext.current().getCallingUserId();
@@ -944,12 +958,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         // Verify parameters
         VMTemplateVO template = _tmpltDao.findById(templateId);
         if (template == null || template.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find template with id");
+            throw new InvalidParameterValueException("Unable to find Template with id");
         }
 
         // Verify template is not Datadisk template
         if (template.getTemplateType().equals(TemplateType.DATADISK)) {
-            throw new InvalidParameterValueException(String.format("Template %s is of type Datadisk. Cannot copy Datadisk templates.", template));
+            throw new InvalidParameterValueException(String.format("Template %s is of type Datadisk. Cannot copy Datadisk Templates.", template));
         }
 
         if (sourceZoneId != null) {
@@ -999,40 +1013,40 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             }
 
             if (srcSecStore == null) {
-                throw new InvalidParameterValueException(String.format("There is no template %s ready on image store.", template));
+                throw new InvalidParameterValueException(String.format("There is no Template %s ready on image store.", template));
             }
 
             if (template.isCrossZones()) {
                 // sync template from cache store to region store if it is not there, for cases where we are going to migrate existing NFS to S3.
                 _tmpltSvr.syncTemplateToRegionStore(template, srcSecStore);
             }
+
+            AccountVO templateOwner = _accountDao.findById(template.getAccountId());
+
             for (Long destZoneId : destZoneIds) {
                 DataStore dstSecStore = getImageStore(destZoneId, templateId);
                 if (dstSecStore != null) {
-                    logger.debug("There is template {} in secondary storage {} in zone {} , don't need to copy", template, dstSecStore, dataCenterVOs.get(destZoneId));
+                    logger.debug("There is Template {} in secondary storage {} in zone {} , don't need to copy", template, dstSecStore, dataCenterVOs.get(destZoneId));
                     continue;
                 }
-                if (!copy(userId, template, srcSecStore, dataCenterVOs.get(destZoneId))) {
-                    failedZones.add(dataCenterVOs.get(destZoneId).getName());
-                }
-                else{
-                    if (template.getSize() != null) {
-                        // increase resource count
-                        long accountId = template.getAccountId();
-                        _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, template.getSize());
+                try (CheckedReservation secondaryStorageReservation = new CheckedReservation(templateOwner, ResourceType.secondary_storage, null, null, template.getSize(), reservationDao, _resourceLimitMgr)) {
+                    if (!copy(userId, template, srcSecStore, dataCenterVOs.get(destZoneId))) {
+                        failedZones.add(dataCenterVOs.get(destZoneId).getName());
+                        continue;
                     }
+                    _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage, template.getSize());
                 }
             }
         }
 
         if ((destZoneIds != null) && (destZoneIds.size() > failedZones.size())){
             if (!failedZones.isEmpty()) {
-                logger.debug("There were failures when copying template to zones: " +
+                logger.debug("There were failures when copying Template to zones: " +
                         StringUtils.listToCsvTags(failedZones));
             }
             return template;
         } else {
-            throw new CloudRuntimeException("Failed to copy template");
+            throw new CloudRuntimeException("Failed to copy Template");
         }
     }
 
@@ -1043,14 +1057,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
         AccountVO account = _accountDao.findById(template.getAccountId());
 
-
-        _resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
-
         try {
             _tmpltDao.addTemplateToZone(template, dstZoneId);
             return true;
         } catch (Exception ex) {
-            logger.debug("failed to copy template from Zone: {} to Zone: {}", sourceZone, dstZone);
+            logger.debug("Failed to copy Template from Zone: {} to Zone: {}", sourceZone, dstZone);
         }
         return false;
     }
@@ -1059,7 +1070,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     public boolean delete(long userId, long templateId, Long zoneId) {
         VMTemplateVO template = _tmpltDao.findById(templateId);
         if (template == null || template.getRemoved() != null) {
-            throw new InvalidParameterValueException("Please specify a valid template.");
+            throw new InvalidParameterValueException("Please specify a valid Template.");
         }
 
         TemplateAdapter adapter = getAdapter(template.getHypervisorType());
@@ -1121,7 +1132,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolVO.getId());
 
         if (templatePoolRef == null) {
-            logger.debug("Can't acquire the lock for template pool ref: {}", templatePoolVO);
+            logger.debug("Can't acquire the lock for Template pool ref: {}", templatePoolVO);
 
             return;
         }
@@ -1140,11 +1151,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
                 TemplateApiResult result = future.get();
 
                 if (result.isFailed()) {
-                    logger.debug("Failed to delete template {} from storage pool {}", template, pool);
+                    logger.debug("Failed to delete Template {} from storage pool {}", template, pool);
                 } else {
                     // Remove the templatePoolVO.
                     if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
-                        logger.debug("Successfully evicted template {} from storage pool {}", template, pool);
+                        logger.debug("Successfully evicted Template {} from storage pool {}", template, pool);
                     }
                 }
             } else {
@@ -1154,14 +1165,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
                 if (answer != null && answer.getResult()) {
                     // Remove the templatePoolVO.
                     if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
-                        logger.debug("Successfully evicted template {} from storage pool {}", template, pool);
+                        logger.debug("Successfully evicted Template {} from storage pool {}", template, pool);
                     }
                 } else {
-                    logger.info("Will retry evict template {} from storage pool {}", template, pool);
+                    logger.info("Will retry evict Template {} from storage pool {}", template, pool);
                 }
             }
         } catch (StorageUnavailableException | InterruptedException | ExecutionException e) {
-            logger.info("Storage is unavailable currently. Will retry evicte template {} from storage pool {}", template, pool);
+            logger.info("Storage is unavailable currently. Will retry evicte Template {} from storage pool {}", template, pool);
         } finally {
             _tmpltPoolDao.releaseFromLockTable(templatePoolRef.getId());
         }
@@ -1196,7 +1207,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         // always be copied to
         // primary storage before deploying VM.
         if (!userVmUsingIso.isEmpty()) {
-            logger.debug("ISO " + templateId + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs");
+            logger.debug("ISO " + templateId + " is not deleteable because it is attached to " + userVmUsingIso.size() + " Instances");
             return false;
         }
 
@@ -1222,7 +1233,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
         Long isoId = !isVirtualRouter ? ((UserVm) virtualMachine).getIsoId() : isoParamId;
         if (isoId == null) {
-            throw new InvalidParameterValueException("The specified VM has no ISO attached to it.");
+            throw new InvalidParameterValueException("The specified instance has no ISO attached to it.");
         }
         CallContext.current().setEventDetails("Vm Id: " + virtualMachine.getUuid() + " ISO Id: " + isoId);
 
@@ -1236,7 +1247,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         if (result) {
             return result;
         } else {
-            throw new CloudRuntimeException("Failed to detach iso");
+            throw new CloudRuntimeException("Failed to detach ISO");
         }
     }
 
@@ -1308,7 +1319,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         if (result) {
             return result;
         } else {
-            throw new CloudRuntimeException("Failed to attach iso");
+            throw new CloudRuntimeException("Failed to attach ISO");
         }
     }
 
@@ -1334,7 +1345,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             Scope destScope = new ZoneScope(dcId);
             TemplateInfo cacheData = (TemplateInfo)cacheMgr.createCacheObject(tmplt, destScope);
             if (cacheData == null) {
-                logger.error("Failed in copy iso from S3 to cache storage");
+                logger.error("Failed in copy ISO from S3 to cache storage");
                 return null;
             }
             return cacheData;
@@ -1402,14 +1413,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_DELETE, eventDescription = "deleting template", async = true)
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_DELETE, eventDescription = "Deleting Template", async = true)
     public boolean deleteTemplate(DeleteTemplateCmd cmd) {
         Long templateId = cmd.getId();
         Account caller = CallContext.current().getCallingAccount();
 
         VMTemplateVO template = _tmpltDao.findById(templateId);
         if (template == null) {
-            throw new InvalidParameterValueException("unable to find template with id " + templateId);
+            throw new InvalidParameterValueException("Unable to find Template with id " + templateId);
         }
 
         List<VMInstanceVO> vmInstanceVOList;
@@ -1420,7 +1431,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             vmInstanceVOList = _vmInstanceDao.listNonExpungedByTemplate(templateId);
         }
         if(!cmd.isForced() && CollectionUtils.isNotEmpty(vmInstanceVOList)) {
-            final String message = String.format("Unable to delete template: %s because VM instances: [%s] are using it.",  template, Joiner.on(",").join(vmInstanceVOList));
+            final String message = String.format("Unable to delete Template: %s because Instance: [%s] are using it.",  template, Joiner.on(",").join(vmInstanceVOList));
             logger.warn(message);
             throw new InvalidParameterValueException(message);
         }
@@ -1428,7 +1439,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
 
         if (template.getFormat() == ImageFormat.ISO) {
-            throw new InvalidParameterValueException("Please specify a valid template.");
+            throw new InvalidParameterValueException("Please specify a valid Template.");
         }
 
         VnfTemplateUtils.validateApiCommandParams(cmd, template);
@@ -1439,7 +1450,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ISO_DELETE, eventDescription = "deleting iso", async = true)
+    @ActionEvent(eventType = EventTypes.EVENT_ISO_DELETE, eventDescription = "Deleting ISO", async = true)
     public boolean deleteIso(DeleteIsoCmd cmd) {
         Long templateId = cmd.getId();
         Account caller = CallContext.current().getCallingAccount();
@@ -1447,18 +1458,18 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
         VMTemplateVO template = _tmpltDao.findById(templateId);
         if (template == null) {
-            throw new InvalidParameterValueException("unable to find iso with id " + templateId);
+            throw new InvalidParameterValueException("Unable to find ISO with id " + templateId);
         }
 
         _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
 
         if (template.getFormat() != ImageFormat.ISO) {
-            throw new InvalidParameterValueException("Please specify a valid iso.");
+            throw new InvalidParameterValueException("Please specify a valid ISO.");
         }
 
         // check if there is any VM using this ISO.
         if (!templateIsDeleteable(templateId)) {
-            throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms");
+            throw new InvalidParameterValueException("Unable to delete ISO, as it's used by other instances");
         }
 
         if (zoneId != null && (_dataStoreMgr.getImageStoreWithFreeCapacity(zoneId) == null)) {
@@ -1491,11 +1502,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
         if (cmd instanceof ListTemplatePermissionsCmd) {
             if (template.getFormat().equals(ImageFormat.ISO)) {
-                throw new InvalidParameterValueException("Please provide a valid template");
+                throw new InvalidParameterValueException("Please provide a valid Template");
             }
         } else if (cmd instanceof ListIsoPermissionsCmd) {
             if (!template.getFormat().equals(ImageFormat.ISO)) {
-                throw new InvalidParameterValueException("Please provide a valid iso");
+                throw new InvalidParameterValueException("Please provide a valid ISO");
             }
         }
 
@@ -1545,13 +1556,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         if (cmd instanceof UpdateTemplatePermissionsCmd) {
             mediaType = "template";
             if (template.getFormat().equals(ImageFormat.ISO)) {
-                throw new InvalidParameterValueException("Please provide a valid template");
+                throw new InvalidParameterValueException("Please provide a valid Template");
             }
         }
         if (cmd instanceof UpdateIsoPermissionsCmd) {
             mediaType = "iso";
             if (!template.getFormat().equals(ImageFormat.ISO)) {
-                throw new InvalidParameterValueException("Please provide a valid iso");
+                throw new InvalidParameterValueException("Please provide a valid ISO");
             }
         }
 
@@ -1593,7 +1604,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             // if there is no owner of the template then it's probably already a
             // public template (or domain private template) so
             // publishing to individual users is irrelevant
-            throw new InvalidParameterValueException("Update template permissions is an invalid operation on template " + template.getName());
+            throw new InvalidParameterValueException("Update Template permissions is an invalid operation on Template " + template.getName());
         }
 
         if (owner.getType() == Account.Type.PROJECT) {
@@ -1612,14 +1623,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         if (accountNames != null) {
             if ((operation == null) || (!operation.equalsIgnoreCase("add") && !operation.equalsIgnoreCase("remove") && !operation.equalsIgnoreCase("reset"))) {
                 throw new InvalidParameterValueException(
-                    "Invalid operation on accounts, the operation must be either 'add' or 'remove' in order to modify launch permissions." + "  Given operation is: '" +
+                    "Invalid operation on Accounts, the operation must be either 'add' or 'remove' in order to modify launch permissions." + "  Given operation is: '" +
                         operation + "'");
             }
         }
 
         //Only admin or owner of the template should be able to change its permissions
         if (caller.getId() != ownerId && !isAdmin) {
-            throw new InvalidParameterValueException("Unable to grant permission to account " + caller.getAccountName() + " as it is neither admin nor owner or the template");
+            throw new InvalidParameterValueException("Unable to grant permission to Account " + caller.getAccountName() + " as it is neither admin nor owner or the Template");
         }
 
         VMTemplateVO updatedTemplate = _tmpltDao.createForUpdate();
@@ -1635,7 +1646,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         if (isExtractable != null) {
             // Only Root admins and owners are allowed to change it for templates
             if (!template.getFormat().equals(ImageFormat.ISO) && caller.getId() != ownerId && !isAdmin) {
-                throw new InvalidParameterValueException("Only ROOT admins and template owners are allowed to modify isExtractable attribute.");
+                throw new InvalidParameterValueException("Only ROOT admins and Template owners are allowed to modify isExtractable attribute.");
             } else {
                 // For Isos normal user can change it, as their are no derivatives.
                 updatedTemplate.setExtractable(isExtractable.booleanValue());
@@ -1646,7 +1657,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
         //when operation is add/remove, accountNames can not be null
         if (("add".equalsIgnoreCase(operation) || "remove".equalsIgnoreCase(operation)) && accountNames == null) {
-            throw new InvalidParameterValueException("Operation " + operation + " requires accounts or projectIds to be passed in");
+            throw new InvalidParameterValueException("Operation " + operation + " requires Accounts or projectIds to be passed in");
         }
 
         //Derive the domain id from the template owner as updateTemplatePermissions is not cross domain operation
@@ -1671,8 +1682,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
                                 _launchPermissionDao.persist(launchPermission);
                             }
                         } else {
-                            throw new InvalidParameterValueException("Unable to grant a launch permission to account " + accountName + " in domain id=" +
-                                domain.getUuid() + ", account not found.  " + "No permissions updated, please verify the account names and retry.");
+                            throw new InvalidParameterValueException("Unable to grant a launch permission to Account " + accountName + " in domain id=" +
+                                domain.getUuid() + ", Account not found.  " + "No permissions updated, please verify the Account names and retry.");
                 }
             }
                 }
@@ -1716,7 +1727,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
     @Override
     @DB
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", async = true)
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "Creating Template", async = true)
     public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) throws CloudRuntimeException {
         final long templateId = command.getEntityId();
         Long volumeId = command.getVolumeId();
@@ -1809,8 +1820,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
                 if (result.isFailed()) {
                     privateTemplate = null;
-                    logger.debug("Failed to create template" + result.getResult());
-                    throw new CloudRuntimeException("Failed to create template" + result.getResult());
+                    logger.debug("Failed to create Template" + result.getResult());
+                    throw new CloudRuntimeException("Failed to create Template" + result.getResult());
                 }
 
                 // create entries in template_zone_ref table
@@ -1829,11 +1840,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
                                 privateTemplate.getSourceTemplateId(), srcTmpltStore.getPhysicalSize(), privateTemplate.getSize());
                 _usageEventDao.persist(usageEvent);
             } catch (InterruptedException e) {
-                logger.debug("Failed to create template", e);
-                throw new CloudRuntimeException("Failed to create template", e);
+                logger.debug("Failed to create Template", e);
+                throw new CloudRuntimeException("Failed to create Template", e);
             } catch (ExecutionException e) {
-                logger.debug("Failed to create template", e);
-                throw new CloudRuntimeException("Failed to create template", e);
+                logger.debug("Failed to create Template", e);
+                throw new CloudRuntimeException("Failed to create Template", e);
             }
 
         } finally {
@@ -1857,7 +1868,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
                         // decrement resource count
                         if (accountId != null) {
                             _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
-                            _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(volumeFinal != null ? volumeFinal.getSize()
+                            _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, (long)(volumeFinal != null ? volumeFinal.getSize()
                                     : snapshotFinal.getSize()));
                         }
                     }
@@ -1873,12 +1884,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         if (privateTemplate != null) {
             return privateTemplate;
         } else {
-            throw new CloudRuntimeException("Failed to create a template");
+            throw new CloudRuntimeException("Failed to create a Template");
         }
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", create = true)
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "Creating Template", create = true)
     public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, Account templateOwner) throws ResourceAllocationException {
         Account caller = CallContext.current().getCallingAccount();
         boolean isAdmin = (_accountMgr.isAdmin(caller.getId()));
@@ -1916,7 +1927,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         boolean allowPublicUserTemplates = AllowPublicUserTemplates.valueIn(templateOwner.getId());
         final Long zoneId = cmd.getZoneId();
         if (!isAdmin && !allowPublicUserTemplates && isPublic) {
-            throw new PermissionDeniedException("Failed to create template " + name + ", only private templates can be created.");
+            throw new PermissionDeniedException("Failed to create Template " + name + ", only private Templates can be created.");
         }
 
         Long volumeId = cmd.getVolumeId();
@@ -1925,11 +1936,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             throw new InvalidParameterValueException("Failed to create private template record, zone ID can only be specified together with snapshot ID.");
         }
         if ((volumeId == null) && (snapshotId == null)) {
-            throw new InvalidParameterValueException("Failed to create private template record, neither volume ID nor snapshot ID were specified.");
+            throw new InvalidParameterValueException("Failed to create private Template record, neither volume ID nor Snapshot ID were specified.");
         }
         if ((volumeId != null) && (snapshotId != null)) {
-            throw new InvalidParameterValueException("Failed to create private template record, please specify only one of volume ID (" + volumeId +
-                    ") and snapshot ID (" + snapshotId + ")");
+            throw new InvalidParameterValueException("Failed to create private Template record, please specify only one of volume ID (" + volumeId +
+                    ") and Snapshot ID (" + snapshotId + ")");
         }
         CPU.CPUArch arch = cmd.getArch();
 
@@ -1940,21 +1951,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         if (volumeId != null) { // create template from volume
             volume = _volumeDao.findById(volumeId);
             if (volume == null) {
-                throw new InvalidParameterValueException("Failed to create private template record, unable to find volume " + volumeId);
+                throw new InvalidParameterValueException("Failed to create private Template record, unable to find volume " + volumeId);
             }
             // check permissions
             _accountMgr.checkAccess(caller, null, true, volume);
 
             // Don't support creating templates from encrypted volumes (yet)
             if (volume.getPassphraseId() != null) {
-                throw new UnsupportedOperationException("Cannot create templates from encrypted volumes");
+                throw new UnsupportedOperationException("Cannot create Templates from encrypted volumes");
             }
 
             // If private template is created from Volume, check that the volume
             // will not be active when the private template is
             // created
             if (!_volumeMgr.volumeInactive(volume)) {
-                String msg = String.format("Unable to create private template for volume: %s; volume is attached to a non-stopped VM, please stop the VM first", volume);
+                String msg = String.format("Unable to create private Template for volume: %s; volume is attached to a non-stopped Instance, please stop the Instance first", volume);
                 if (logger.isInfoEnabled()) {
                     logger.info(msg);
                 }
@@ -1968,21 +1979,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         } else { // create template from snapshot
             snapshot = _snapshotDao.findById(snapshotId);
             if (snapshot == null) {
-                throw new InvalidParameterValueException("Failed to create private template record, unable to find snapshot " + snapshotId);
+                throw new InvalidParameterValueException("Failed to create private Template record, unable to find Snapshot " + snapshotId);
             }
             // Volume could be removed so find including removed to record source template id.
             volume = _volumeDao.findByIdIncludingRemoved(snapshot.getVolumeId());
 
             // Don't support creating templates from encrypted volumes (yet)
             if (volume != null && volume.getPassphraseId() != null) {
-                throw new UnsupportedOperationException("Cannot create templates from snapshots of encrypted volumes");
+                throw new UnsupportedOperationException("Cannot create Templates from Snapshots of encrypted volumes");
             }
 
             // check permissions
             _accountMgr.checkAccess(caller, null, true, snapshot);
 
             if (snapshot.getState() != Snapshot.State.BackedUp) {
-                throw new InvalidParameterValueException(String.format("Snapshot %s is not in %s state yet and can't be used for template creation",
+                throw new InvalidParameterValueException(String.format("Snapshot %s is not in %s state yet and can't be used for Template creation",
                         snapshot, Snapshot.State.BackedUp));
             }
 
@@ -2008,107 +2019,106 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             }
         }
 
-        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);
-        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.secondary_storage, new Long(volume != null ? volume.getSize() : snapshot.getSize()).longValue());
+        long templateSize = volume != null ? volume.getSize() : snapshot.getSize();
+        try (CheckedReservation templateReservation = new CheckedReservation(templateOwner, ResourceType.template, null, null, 1L, reservationDao, _resourceLimitMgr);
+             CheckedReservation secondaryStorageReservation = new CheckedReservation(templateOwner, ResourceType.secondary_storage, null, null, templateSize, reservationDao, _resourceLimitMgr)) {
 
-        if (!isAdmin || featured == null) {
-            featured = Boolean.FALSE;
-        }
-        Long guestOSId = cmd.getOsTypeId();
-        GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
-        if (guestOS == null) {
-            throw new InvalidParameterValueException("GuestOS with ID: " + guestOSId + " does not exist.");
-        }
-
-        Long nextTemplateId = _tmpltDao.getNextInSequence(Long.class, "id");
-        String description = cmd.getDisplayText();
-        boolean isExtractable = false;
-        Long sourceTemplateId = null;
-        if (volume != null) {
-            VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
-            isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
-            if (template != null) {
-                arch = template.getArch();
-            }
-            if (volume.getIsoId() != null && volume.getIsoId() != 0) {
-                sourceTemplateId = volume.getIsoId();
-            } else if (volume.getTemplateId() != null) {
-                sourceTemplateId = volume.getTemplateId();
+            if (!isAdmin || featured == null) {
+                featured = Boolean.FALSE;
             }
-        }
-        String templateTag = cmd.getTemplateTag();
-        if (templateTag != null) {
-            if (logger.isDebugEnabled()) {
-                logger.debug("Adding template tag: " + templateTag);
+            Long guestOSId = cmd.getOsTypeId();
+            GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
+            if (guestOS == null) {
+                throw new InvalidParameterValueException("GuestOS with ID: " + guestOSId + " does not exist.");
             }
-        }
-        privateTemplate = new VMTemplateVO(nextTemplateId, name, ImageFormat.RAW, isPublic, featured, isExtractable,
-                TemplateType.USER, null, requiresHvmValue, bitsValue, templateOwner.getId(), null, description,
-                passwordEnabledValue, guestOS.getId(), true, hyperType, templateTag, cmd.getDetails(), sshKeyEnabledValue, isDynamicScalingEnabled, false, false, arch, null);
 
-        if (sourceTemplateId != null) {
-            if (logger.isDebugEnabled()) {
-                logger.debug("This template is getting created from other template, setting source template Id to: " + sourceTemplateId);
+            Long nextTemplateId = _tmpltDao.getNextInSequence(Long.class, "id");
+            String description = cmd.getDisplayText();
+            boolean isExtractable = false;
+            Long sourceTemplateId = null;
+            if (volume != null) {
+                VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
+                isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
+                if (template != null) {
+                    arch = template.getArch();
+                }
+                if (volume.getIsoId() != null && volume.getIsoId() != 0) {
+                    sourceTemplateId = volume.getIsoId();
+                } else if (volume.getTemplateId() != null) {
+                    sourceTemplateId = volume.getTemplateId();
+                }
             }
-        }
+            String templateTag = cmd.getTemplateTag();
+            if (templateTag != null) {
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Adding Template tag: " + templateTag);
+                }
+            }
+            privateTemplate = new VMTemplateVO(nextTemplateId, name, ImageFormat.RAW, isPublic, featured, isExtractable,
+                    TemplateType.USER, null, requiresHvmValue, bitsValue, templateOwner.getId(), null, description,
+                    passwordEnabledValue, guestOS.getId(), true, hyperType, templateTag, cmd.getDetails(), sshKeyEnabledValue, isDynamicScalingEnabled, false, false, arch, null);
 
+            if (sourceTemplateId != null) {
+                if (logger.isDebugEnabled()) {
+                    logger.debug("This Template is getting created from other Template, setting source Template ID to: " + sourceTemplateId);
+                }
+            }
 
-        // for region wide storage, set cross zones flag
-        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
-        if (!CollectionUtils.isEmpty(stores)) {
-            privateTemplate.setCrossZones(true);
-        }
+            // for region wide storage, set cross zones flag
+            List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
+            if (!CollectionUtils.isEmpty(stores)) {
+                privateTemplate.setCrossZones(true);
+            }
 
-        privateTemplate.setSourceTemplateId(sourceTemplateId);
+            privateTemplate.setSourceTemplateId(sourceTemplateId);
 
-        VMTemplateVO template = _tmpltDao.persist(privateTemplate);
-        // Increment the number of templates
-        if (template != null) {
-            Map<String, String> details = new HashMap<String, String>();
+            VMTemplateVO template = _tmpltDao.persist(privateTemplate);
+            // Increment the number of templates
+            if (template != null) {
+                Map<String, String> details = new HashMap<String, String>();
 
-            if (sourceTemplateId != null) {
-                VMTemplateVO sourceTemplate = _tmpltDao.findById(sourceTemplateId);
-                if (sourceTemplate != null && sourceTemplate.getDetails() != null) {
-                    details.putAll(sourceTemplate.getDetails());
+                if (sourceTemplateId != null) {
+                    VMTemplateVO sourceTemplate = _tmpltDao.findById(sourceTemplateId);
+                    if (sourceTemplate != null && sourceTemplate.getDetails() != null) {
+                        details.putAll(sourceTemplate.getDetails());
+                    }
                 }
-            }
 
-            if (volume != null) {
-                Long vmId = volume.getInstanceId();
-                if (vmId != null) {
-                    UserVmVO userVm = _userVmDao.findById(vmId);
-                    if (userVm != null) {
-                        _userVmDao.loadDetails(userVm);
-                        Map<String, String> vmDetails = userVm.getDetails();
-                        vmDetails = vmDetails.entrySet()
-                                .stream()
-                                .filter(map -> map.getValue() != null)
-                                .collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()));
-                        details.putAll(vmDetails);
+                if (volume != null) {
+                    Long vmId = volume.getInstanceId();
+                    if (vmId != null) {
+                        UserVmVO userVm = _userVmDao.findById(vmId);
+                        if (userVm != null) {
+                            _userVmDao.loadDetails(userVm);
+                            Map<String, String> vmDetails = userVm.getDetails();
+                            vmDetails = vmDetails.entrySet()
+                                    .stream()
+                                    .filter(map -> map.getValue() != null)
+                                    .collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()));
+                            details.putAll(vmDetails);
+                        }
                     }
                 }
-            }
-            if (cmd.getDetails() != null) {
-                details.remove(VmDetailConstants.ENCRYPTED_PASSWORD); // new password will be generated during vm deployment from password enabled template
-                details.putAll(cmd.getDetails());
-            }
-            if (!details.isEmpty()) {
-                privateTemplate.setDetails(details);
-                _tmpltDao.saveDetails(privateTemplate);
-            }
+                if (cmd.getDetails() != null) {
+                    details.remove(VmDetailConstants.ENCRYPTED_PASSWORD); // new password will be generated during vm deployment from password enabled template
+                    details.putAll(cmd.getDetails());
+                }
+                if (!details.isEmpty()) {
+                    privateTemplate.setDetails(details);
+                    _tmpltDao.saveDetails(privateTemplate);
+                }
 
-            _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template);
-            _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage,
-                    new Long(volume != null ? volume.getSize() : snapshot.getSize()));
-        }
+                _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template);
+                _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage, templateSize);
+            }
 
-        if (template != null) {
-            CallContext.current().putContextParameter(VirtualMachineTemplate.class, template.getUuid());
-            return template;
-        } else {
-            throw new CloudRuntimeException("Failed to create a template");
+            if (template != null) {
+                CallContext.current().putContextParameter(VirtualMachineTemplate.class, template.getUuid());
+                return template;
+            } else {
+                throw new CloudRuntimeException("Failed to create a Template");
+            }
         }
-
     }
 
     @Override
@@ -2196,13 +2206,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ISO_UPDATE, eventDescription = "updating iso", async = false)
+    @ActionEvent(eventType = EventTypes.EVENT_ISO_UPDATE, eventDescription = "Updating ISO", async = false)
     public VMTemplateVO updateTemplate(UpdateIsoCmd cmd) {
         return updateTemplateOrIso(cmd);
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_UPDATE, eventDescription = "updating template", async = false)
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_UPDATE, eventDescription = "Updating Template", async = false)
     public VMTemplateVO updateTemplate(UpdateTemplateCmd cmd) {
         return updateTemplateOrIso(cmd);
     }
@@ -2229,7 +2239,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         // verify that template exists
         VMTemplateVO template = _tmpltDao.findById(id);
         if (template == null || template.getRemoved() != null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("unable to find template/iso with specified id");
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Template/ISO with specified id");
             ex.addProxyObject(String.valueOf(id), "templateId");
             throw ex;
         }
@@ -2275,7 +2285,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
                   templateTag == null &&
                   forCks == null &&
                   arch == null &&
-                  (! cleanupDetails && details == null) //update details in every case except this one
+                  (! cleanupDetails && details == null) // update details in every case except this one
                   );
         if (!updateNeeded) {
             return template;
@@ -2434,9 +2444,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         validateExternalHypervisorTemplateType(hypervisorType, templateType);
         if (templateType != null && !isAdmin && !Arrays.asList(TemplateType.USER, TemplateType.VNF).contains(templateType)) {
             if (cmd instanceof RegisterTemplateCmd) {
-                throw new InvalidParameterValueException(String.format("Users can not register template with template type %s.", templateType));
+                throw new InvalidParameterValueException(String.format("Users can not register Template with template type %s.", templateType));
             } else if (cmd instanceof UpdateTemplateCmd) {
-                throw new InvalidParameterValueException(String.format("Users can not update template to template type %s.", templateType));
+                throw new InvalidParameterValueException(String.format("Users can not update Template to template type %s.", templateType));
             }
         }
         return templateType;
@@ -2455,13 +2465,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         if (MapUtils.isEmpty(details)) {
             return;
         }
-
         String bootMode = details.get(ApiConstants.BootType.UEFI.toString());
         if (bootMode == null) {
             return;
         }
         if (template.isDeployAsIs()) {
-            String msg = String.format("Deploy-as-is template %s can not have the UEFI setting. Settings are read directly from the template", template);
+            String msg = String.format("Deploy-as-is Template %s can not have the UEFI setting. Settings are read directly from the Template", template);
             throw new InvalidParameterValueException(msg);
         }
         try {
@@ -2480,7 +2489,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     void verifyTemplateId(Long id) {
         // Don't allow to modify system template
         if (id.equals(Long.valueOf(1))) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id");
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update Template/ISO of specified ID");
             ex.addProxyObject(String.valueOf(id), "templateId");
             throw ex;
         }
@@ -2513,7 +2522,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         long templateId = template.getId();
         TemplateInfo templateObject = _tmplFactory.getTemplate(templateId, role);
         if (templateObject == null) {
-            String msg = String.format("Could not find template %s downloaded on store with role %s", template, role.toString());
+            String msg = String.format("Could not find Template %s downloaded on store with role %s", template, role.toString());
             logger.error(msg);
             throw new CloudRuntimeException(msg);
         }
@@ -2529,10 +2538,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         Account caller = CallContext.current().getCallingAccount();
 
         if (templateId != null && isoId != null) {
-            throw new InvalidParameterValueException("Both template ID and ISO ID are passed, API accepts only one");
+            throw new InvalidParameterValueException("Both Template ID and ISO ID are passed, API accepts only one");
         }
         if (templateId == null && isoId == null) {
-            throw new InvalidParameterValueException("Atleast one of template ID or ISO ID needs to be passed");
+            throw new InvalidParameterValueException("At least one of Template ID or ISO ID needs to be passed");
         }
 
         VMTemplateVO template = null;
@@ -2542,7 +2551,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             template = _tmpltDao.findById(isoId);
         }
         if (template == null) {
-            throw new InvalidParameterValueException(String.format("unable to find template/ISO with id %s", templateId == null? isoId : templateId));
+            throw new InvalidParameterValueException(String.format("Unable to find Template/ISO with ID %s", templateId == null? isoId : templateId));
         }
 
         _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
diff --git a/server/src/test/java/com/cloud/template/TemplateManagerImplTest.java b/server/src/test/java/com/cloud/template/TemplateManagerImplTest.java
index 99e4512ccef..f5e281a9516 100755
--- a/server/src/test/java/com/cloud/template/TemplateManagerImplTest.java
+++ b/server/src/test/java/com/cloud/template/TemplateManagerImplTest.java
@@ -22,8 +22,8 @@ package com.cloud.template;
 import com.cloud.agent.AgentManager;
 import com.cloud.api.query.dao.SnapshotJoinDao;
 import com.cloud.api.query.dao.UserVmJoinDao;
-import com.cloud.configuration.Resource;
 import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
 import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.dao.UsageEventDao;
 import com.cloud.exception.InvalidParameterValueException;
@@ -33,6 +33,7 @@ import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor;
 import com.cloud.hypervisor.HypervisorGuruManager;
 import com.cloud.projects.ProjectManager;
+import com.cloud.resourcelimit.CheckedReservation;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.GuestOSVO;
 import com.cloud.storage.Snapshot;
@@ -63,12 +64,14 @@ import com.cloud.user.User;
 import com.cloud.user.UserData;
 import com.cloud.user.UserVO;
 import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.VMInstanceDao;
+
+import junit.framework.TestCase;
+
 import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
 import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
 import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
@@ -104,14 +107,21 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.cloudstack.storage.heuristics.HeuristicRuleHelper;
 import org.apache.cloudstack.storage.template.VnfTemplateManager;
+
 import org.apache.cloudstack.test.utils.SpringUtils;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedConstruction;
 import org.mockito.Mockito;
+import org.mockito.Spy;
 import org.mockito.invocation.InvocationOnMock;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
@@ -120,11 +130,7 @@ import org.springframework.context.annotation.FilterType;
 import org.springframework.core.type.classreading.MetadataReader;
 import org.springframework.core.type.classreading.MetadataReaderFactory;
 import org.springframework.core.type.filter.TypeFilter;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
 
-import javax.inject.Inject;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -137,81 +143,81 @@ import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
-public class TemplateManagerImplTest {
+@RunWith(MockitoJUnitRunner.class)
+public class TemplateManagerImplTest extends TestCase {
 
-    @Inject
-    TemplateManagerImpl templateManager = new TemplateManagerImpl();
+    @Spy
+    @InjectMocks
+    TemplateManagerImpl templateManager;
 
-    @Inject
+    @Mock
     DataStoreManager dataStoreManager;
 
-    @Inject
+    @Mock
     VMTemplateDao vmTemplateDao;
 
-    @Inject
+    @Mock
     VMTemplatePoolDao vmTemplatePoolDao;
 
-    @Inject
+    @Mock
     TemplateDataStoreDao templateDataStoreDao;
 
-    @Inject
+    @Mock
     StoragePoolHostDao storagePoolHostDao;
 
-    @Inject
+    @Mock
     PrimaryDataStoreDao primaryDataStoreDao;
 
-    @Inject
+    @Mock
     ResourceLimitService resourceLimitMgr;
 
-    @Inject
+    @Mock
     ImageStoreDao imgStoreDao;
 
-    @Inject
+    @Mock
     GuestOSDao guestOSDao;
 
-    @Inject
-    VMTemplateDao tmpltDao;
-
-    @Inject
+    @Mock
     SnapshotDao snapshotDao;
 
-    @Inject
+    @Mock
+    VolumeDao volumeDao;
+
+    @Mock
     VMTemplateDetailsDao tmpltDetailsDao;
 
-    @Inject
+    @Mock
     StorageStrategyFactory storageStrategyFactory;
 
-    @Inject
+    @Mock
     VMInstanceDao _vmInstanceDao;
 
-    @Inject
-    private VMTemplateDao _tmpltDao;
+    @Mock
+    ReservationDao reservationDao;
 
-    @Inject
+    @Mock
     HypervisorGuruManager _hvGuruMgr;
 
-    @Inject
+    @Mock
     AccountManager _accountMgr;
-    @Inject
+
+    @Mock
     VnfTemplateManager vnfTemplateManager;
-    @Inject
+    @Mock
     SnapshotJoinDao snapshotJoinDao;
-    @Inject
-    ReservationDao reservationDao;
+    @Mock
+    TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
 
-    @Inject
+    @Mock
     HeuristicRuleHelper heuristicRuleHelperMock;
 
     public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
@@ -241,7 +247,6 @@ public class TemplateManagerImplTest {
 
     @Before
     public void setUp() {
-        ComponentContext.initComponentsLifeCycle();
         AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.Type.NORMAL, "uuid");
         UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
         CallContext.register(user, account);
@@ -275,7 +280,7 @@ public class TemplateManagerImplTest {
         List<TemplateAdapter> adapters  = new ArrayList<TemplateAdapter>();
         adapters.add(templateAdapter);
         when(cmd.getId()).thenReturn(0L);
-        when(_tmpltDao.findById(cmd.getId())).thenReturn(template);
+        when(vmTemplateDao.findById(cmd.getId())).thenReturn(template);
         when(cmd.getZoneId()).thenReturn(null);
 
         when(template.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.None);
@@ -296,7 +301,6 @@ public class TemplateManagerImplTest {
         //case 2.2: When Force delete flag is 'false' and VM instance VO list is non empty.
         when(cmd.isForced()).thenReturn(false);
         VMInstanceVO vmInstanceVO = mock(VMInstanceVO.class);
-        when(vmInstanceVO.getInstanceName()).thenReturn("mydDummyVM");
         vmInstanceVOList.add(vmInstanceVO);
         when(_vmInstanceDao.listNonExpungedByTemplate(anyLong())).thenReturn(vmInstanceVOList);
         try {
@@ -311,7 +315,6 @@ public class TemplateManagerImplTest {
         when(mockTemplate.getId()).thenReturn(202l);
 
         StoragePoolVO mockPool = mock(StoragePoolVO.class);
-        when(mockPool.getId()).thenReturn(2l);
 
         PrimaryDataStore mockPrimaryDataStore = mock(PrimaryDataStore.class);
         when(mockPrimaryDataStore.getId()).thenReturn(2l);
@@ -319,7 +322,6 @@ public class TemplateManagerImplTest {
         VMTemplateStoragePoolVO mockTemplateStore = mock(VMTemplateStoragePoolVO.class);
         when(mockTemplateStore.getDownloadState()).thenReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
 
-        when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
         when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
         when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(mockTemplateStore);
 
@@ -335,13 +337,11 @@ public class TemplateManagerImplTest {
         when(mockTemplate.getId()).thenReturn(202l);
 
         StoragePoolVO mockPool = mock(StoragePoolVO.class);
-        when(mockPool.getId()).thenReturn(2l);
 
         PrimaryDataStore mockPrimaryDataStore = mock(PrimaryDataStore.class);
         when(mockPrimaryDataStore.getId()).thenReturn(2l);
         when(mockPrimaryDataStore.getDataCenterId()).thenReturn(1l);
 
-        when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
         when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
         when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(null);
         when(templateDataStoreDao.findByTemplateZoneDownloadStatus(202l, 1l, VMTemplateStorageResourceAssoc.Status.DOWNLOADED)).thenReturn(null);
@@ -356,7 +356,6 @@ public class TemplateManagerImplTest {
         when(mockTemplate.getId()).thenReturn(202l);
 
         StoragePoolVO mockPool = mock(StoragePoolVO.class);
-        when(mockPool.getId()).thenReturn(2l);
 
         PrimaryDataStore mockPrimaryDataStore = mock(PrimaryDataStore.class);
         when(mockPrimaryDataStore.getId()).thenReturn(2l);
@@ -364,7 +363,6 @@ public class TemplateManagerImplTest {
 
         TemplateDataStoreVO mockTemplateDataStore = mock(TemplateDataStoreVO.class);
 
-        when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
         when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
         when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(null);
         when(templateDataStoreDao.findByTemplateZoneDownloadStatus(202l, 1l, VMTemplateStorageResourceAssoc.Status.DOWNLOADED)).thenReturn(mockTemplateDataStore);
@@ -415,20 +413,10 @@ public class TemplateManagerImplTest {
         PrimaryDataStore mockPrimaryDataStore = mock(PrimaryDataStore.class);
         VMTemplateStoragePoolVO mockTemplateStore = mock(VMTemplateStoragePoolVO.class);
 
-        when(mockPrimaryDataStore.getId()).thenReturn(2l);
-        when(mockPool.getId()).thenReturn(2l);
         when(mockPool.getStatus()).thenReturn(StoragePoolStatus.Disabled);
-        when(mockPool.getDataCenterId()).thenReturn(1l);
-        when(mockTemplate.getId()).thenReturn(202l);
-        when(mockTemplateStore.getDownloadState()).thenReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
         when(vmTemplateDao.findById(anyLong())).thenReturn(mockTemplate);
-        when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
-        when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
-        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(mockTemplateStore);
         when(primaryDataStoreDao.findById(anyLong())).thenReturn(mockPool);
 
-        doNothing().when(mockTemplateStore).setMarkedForGC(anyBoolean());
-
         ExecutorService preloadExecutor = new CustomThreadPoolExecutor(8, 8, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(),
                 new NamedThreadFactory("Template-Preloader"));
         templateManager._preloadExecutor = preloadExecutor;
@@ -446,15 +434,10 @@ public class TemplateManagerImplTest {
 
         StoragePoolVO mockPool1 = mock(StoragePoolVO.class);
         when(mockPool1.getId()).thenReturn(2l);
-        when(mockPool1.getStatus()).thenReturn(StoragePoolStatus.Up);
         when(mockPool1.getDataCenterId()).thenReturn(1l);
         StoragePoolVO mockPool2 = mock(StoragePoolVO.class);
-        when(mockPool2.getId()).thenReturn(3l);
-        when(mockPool2.getStatus()).thenReturn(StoragePoolStatus.Up);
         when(mockPool2.getDataCenterId()).thenReturn(1l);
         StoragePoolVO mockPool3 = mock(StoragePoolVO.class);
-        when(mockPool3.getId()).thenReturn(4l);
-        when(mockPool3.getStatus()).thenReturn(StoragePoolStatus.Up);
         when(mockPool3.getDataCenterId()).thenReturn(2l);
         pools.add(mockPool1);
         pools.add(mockPool2);
@@ -467,9 +450,6 @@ public class TemplateManagerImplTest {
         when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
         when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
         when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(mockTemplateStore);
-        when(primaryDataStoreDao.findById(2l)).thenReturn(mockPool1);
-        when(primaryDataStoreDao.findById(3l)).thenReturn(mockPool2);
-        when(primaryDataStoreDao.findById(4l)).thenReturn(mockPool3);
         when(primaryDataStoreDao.listByStatus(StoragePoolStatus.Up)).thenReturn(pools);
 
         doNothing().when(mockTemplateStore).setMarkedForGC(anyBoolean());
@@ -497,7 +477,6 @@ public class TemplateManagerImplTest {
         when(mockCreateCmd.getVolumeId()).thenReturn(null);
         when(mockCreateCmd.getSnapshotId()).thenReturn(1L);
         when(mockCreateCmd.getOsTypeId()).thenReturn(1L);
-        when(mockCreateCmd.getEventDescription()).thenReturn("test");
         when(mockCreateCmd.getDetails()).thenReturn(null);
         when(mockCreateCmd.getZoneId()).thenReturn(null);
 
@@ -510,20 +489,17 @@ public class TemplateManagerImplTest {
         when(mockSnapshot.getState()).thenReturn(Snapshot.State.BackedUp);
         when(mockSnapshot.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.XenServer);
 
-        doNothing().when(resourceLimitMgr).checkResourceLimit(any(Account.class), eq(Resource.ResourceType.template));
-        doNothing().when(resourceLimitMgr).checkResourceLimit(any(Account.class), eq(Resource.ResourceType.secondary_storage), anyLong());
-
         GuestOSVO mockGuestOS = mock(GuestOSVO.class);
         when(guestOSDao.findById(anyLong())).thenReturn(mockGuestOS);
 
-        when(tmpltDao.getNextInSequence(eq(Long.class), eq("id"))).thenReturn(1L);
+        when(vmTemplateDao.getNextInSequence(eq(Long.class), eq("id"))).thenReturn(1L);
 
         List<ImageStoreVO> mockRegionStores = new ArrayList<>();
         ImageStoreVO mockRegionStore = mock(ImageStoreVO.class);
         mockRegionStores.add(mockRegionStore);
         when(imgStoreDao.findRegionImageStores()).thenReturn(mockRegionStores);
 
-        when(tmpltDao.persist(any(VMTemplateVO.class))).thenAnswer(new Answer<VMTemplateVO>() {
+        when(vmTemplateDao.persist(any(VMTemplateVO.class))).thenAnswer(new Answer<VMTemplateVO>() {
             @Override
             public VMTemplateVO answer(InvocationOnMock invocationOnMock) throws Throwable {
                 Object[] args = invocationOnMock.getArguments();
@@ -531,8 +507,10 @@ public class TemplateManagerImplTest {
             }
         });
 
-        VMTemplateVO template = templateManager.createPrivateTemplateRecord(mockCreateCmd, mockTemplateOwner);
-        assertTrue("Template in a region store should have cross zones set", template.isCrossZones());
+        try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
+            VMTemplateVO template = templateManager.createPrivateTemplateRecord(mockCreateCmd, mockTemplateOwner);
+            assertTrue("Template in a region store should have cross zones set", template.isCrossZones());
+        }
     }
 
     @Test
@@ -544,7 +522,7 @@ public class TemplateManagerImplTest {
         when(cmd.getUserdataPolicy()).thenReturn(UserData.UserDataOverridePolicy.ALLOWOVERRIDE);
 
         VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
-        when(_tmpltDao.findById(anyLong())).thenReturn(template);
+        when(vmTemplateDao.findById(anyLong())).thenReturn(template);
 
         VirtualMachineTemplate resultTemplate = templateManager.linkUserDataToTemplate(cmd);
 
@@ -560,7 +538,6 @@ public class TemplateManagerImplTest {
         when(cmd.getUserdataPolicy()).thenReturn(UserData.UserDataOverridePolicy.ALLOWOVERRIDE);
 
         VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
-        when(_tmpltDao.findById(1L)).thenReturn(template);
 
         templateManager.linkUserDataToTemplate(cmd);
     }
@@ -574,7 +551,6 @@ public class TemplateManagerImplTest {
         when(cmd.getUserdataPolicy()).thenReturn(UserData.UserDataOverridePolicy.ALLOWOVERRIDE);
 
         VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
-        when(_tmpltDao.findById(1L)).thenReturn(template);
 
         templateManager.linkUserDataToTemplate(cmd);
     }
@@ -587,7 +563,7 @@ public class TemplateManagerImplTest {
         when(cmd.getUserdataId()).thenReturn(2L);
         when(cmd.getUserdataPolicy()).thenReturn(UserData.UserDataOverridePolicy.ALLOWOVERRIDE);
 
-        when(_tmpltDao.findById(anyLong())).thenReturn(null);
+        when(vmTemplateDao.findById(anyLong())).thenReturn(null);
 
         templateManager.linkUserDataToTemplate(cmd);
     }
@@ -602,7 +578,7 @@ public class TemplateManagerImplTest {
 
         VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
         when(template.getId()).thenReturn(1L);
-        when(_tmpltDao.findById(1L)).thenReturn(template);
+        when(vmTemplateDao.findById(1L)).thenReturn(template);
 
         VirtualMachineTemplate resultTemplate = templateManager.linkUserDataToTemplate(cmd);
 
@@ -633,7 +609,6 @@ public class TemplateManagerImplTest {
         DataStore dataStore = Mockito.mock(DataStore.class);
         VolumeVO volumeVO = Mockito.mock(VolumeVO.class);
 
-        Mockito.when(dataStoreManager.getDataStore(Mockito.anyString(), Mockito.any(DataStoreRole.class))).thenReturn(null);
         Mockito.when(heuristicRuleHelperMock.getImageStoreIfThereIsHeuristicRule(Mockito.anyLong(), Mockito.any(HeuristicType.class), Mockito.any(VolumeVO.class))).thenReturn(null);
         Mockito.when(dataStoreManager.getImageStoreWithFreeCapacity(Mockito.anyLong())).thenReturn(dataStore);
 
@@ -646,7 +621,6 @@ public class TemplateManagerImplTest {
         DataStore dataStore = Mockito.mock(DataStore.class);
         VolumeVO volumeVO = Mockito.mock(VolumeVO.class);
 
-        Mockito.when(dataStoreManager.getDataStore(Mockito.anyString(), Mockito.any(DataStoreRole.class))).thenReturn(null);
         Mockito.when(heuristicRuleHelperMock.getImageStoreIfThereIsHeuristicRule(Mockito.anyLong(), Mockito.any(HeuristicType.class), Mockito.any(VolumeVO.class))).thenReturn(dataStore);
 
         templateManager.getImageStore(null, 1L, volumeVO);