Maor Lipchuk has uploaded a new change for review.

Change subject: core: Refactor register of OVF_STORE disks
......................................................................

core: Refactor register of OVF_STORE disks

Refactor the OVF_STORE disks' registration on attach Storage Domain
process, by moving the code to StorageHandlingCommandBase,
so it can be used also for initializing a new Data Center.

Change-Id: I0d24f059c0073d8744b46b0d0697e323f63ce119
Bug-Url: https://bugzilla.redhat.com/1214408
Signed-off-by: Maor Lipchuk <mlipc...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/StorageHandlingCommandBase.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommandTest.java
3 files changed, 224 insertions(+), 210 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/49/40349/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommand.java
index 9d27831..228d770 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommand.java
@@ -1,17 +1,13 @@
 package org.ovirt.engine.core.bll.storage;
 
-import java.io.IOException;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
 import org.ovirt.engine.core.bll.LockMessagesMatchUtil;
 import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute;
-import org.ovirt.engine.core.bll.RetrieveImageDataParameters;
 import org.ovirt.engine.core.bll.context.CommandContext;
 import org.ovirt.engine.core.bll.profiles.DiskProfileHelper;
 import org.ovirt.engine.core.bll.utils.PermissionSubject;
@@ -22,14 +18,11 @@
 import org.ovirt.engine.core.common.VdcObjectType;
 import org.ovirt.engine.core.common.action.AttachStorageDomainToPoolParameters;
 import org.ovirt.engine.core.common.action.LockProperties;
-import org.ovirt.engine.core.common.action.RegisterDiskParameters;
 import org.ovirt.engine.core.common.action.StorageDomainPoolParametersBase;
 import org.ovirt.engine.core.common.action.StoragePoolWithStoragesParameter;
 import org.ovirt.engine.core.common.action.VdcActionType;
 import org.ovirt.engine.core.common.action.VdcReturnValueBase;
 import org.ovirt.engine.core.common.businessentities.OvfEntityData;
-import org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfo;
-import 
org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfoStatus;
 import org.ovirt.engine.core.common.businessentities.StorageDomainStatic;
 import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
 import org.ovirt.engine.core.common.businessentities.StorageDomainType;
@@ -37,14 +30,11 @@
 import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMapId;
 import org.ovirt.engine.core.common.businessentities.StoragePoolStatus;
 import org.ovirt.engine.core.common.businessentities.profiles.DiskProfile;
-import org.ovirt.engine.core.common.businessentities.storage.Disk;
 import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
 import org.ovirt.engine.core.common.errors.VdcBLLException;
 import org.ovirt.engine.core.common.errors.VdcBllErrors;
 import org.ovirt.engine.core.common.errors.VdcBllMessages;
 import org.ovirt.engine.core.common.locks.LockingGroup;
-import 
org.ovirt.engine.core.common.queries.GetUnregisteredDisksQueryParameters;
-import org.ovirt.engine.core.common.queries.VdcQueryType;
 import org.ovirt.engine.core.common.utils.Pair;
 import 
org.ovirt.engine.core.common.vdscommands.AttachStorageDomainVDSCommandParameters;
 import 
org.ovirt.engine.core.common.vdscommands.DetachStorageDomainVDSCommandParameters;
@@ -53,10 +43,6 @@
 import org.ovirt.engine.core.common.vdscommands.VDSReturnValue;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.compat.TransactionScopeOption;
-import org.ovirt.engine.core.utils.JsonHelper;
-import org.ovirt.engine.core.utils.OvfUtils;
-import org.ovirt.engine.core.utils.ovf.OvfInfoFileConstants;
-import org.ovirt.engine.core.utils.ovf.OvfParser;
 import org.ovirt.engine.core.utils.transaction.TransactionMethod;
 
 
@@ -64,7 +50,6 @@
 public class AttachStorageDomainToPoolCommand<T extends 
AttachStorageDomainToPoolParameters> extends
         StorageDomainCommandBase<T> {
     private StoragePoolIsoMap map;
-    private List<DiskImage> ovfDisks;
 
     public AttachStorageDomainToPoolCommand(T parameters) {
         this(parameters, null);
@@ -145,7 +130,7 @@
                                 // DetachStorageDomainVdsCommand does not use 
it.
                                 // Storage pool id can be empty
                                 DetachStorageDomainVDSCommandParameters 
detachParams =
-                                        new 
DetachStorageDomainVDSCommandParameters(getVds().getStoragePoolId(),
+                                        new 
DetachStorageDomainVDSCommandParameters(getStoragePoolIdFromVds(),
                                                 
getParameters().getStorageDomainId(),
                                                 Guid.Empty,
                                                 0);
@@ -173,7 +158,9 @@
                     runVdsCommand(VDSCommandType.AttachStorageDomain,
                             new 
AttachStorageDomainVDSCommandParameters(getParameters().getStoragePoolId(),
                                     getParameters().getStorageDomainId()));
-                    final List<OvfEntityData> unregisteredEntitiesFromOvfDisk 
= getEntitiesFromStorageOvfDisk();
+                    final List<OvfEntityData> unregisteredEntitiesFromOvfDisk =
+                            
getEntitiesFromStorageOvfDisk(getParameters().getStorageDomainId(),
+                                    getStoragePoolIdFromVds());
                     executeInNewTransaction(new TransactionMethod<Object>() {
                         @Override
                         public Object runInTransaction() {
@@ -187,8 +174,10 @@
 
                             // upgrade the domain format to the storage pool 
format
                             
updateStorageDomainFormatIfNeeded(getStorageDomain());
+                            List<DiskImage> ovfStoreDiskImages =
+                                    
getAllOVFDisks(getParameters().getStorageDomainId(), getStoragePoolIdFromVds());
+                            registerAllOvfDisks(ovfStoreDiskImages, 
getParameters().getStorageDomainId());
 
-                            registerAllOvfDisks(getAllOVFDisks());
                             // Update unregistered entities
                             for (OvfEntityData ovf : 
unregisteredEntitiesFromOvfDisk) {
                                 
getUnregisteredOVFDataDao().removeEntity(ovf.getEntityId(),
@@ -242,198 +231,10 @@
         }
     }
 
-    protected List<OvfEntityData> getEntitiesFromStorageOvfDisk() {
-        // Initialize a new ArrayList with all the ovfDisks in the specified 
Storage Domain,
-        // so the entities can be removed from the list every time we register 
the latest OVF disk and we can keep the
-        // ovfDisks cache list updated.
-        List<DiskImage> ovfStoreDiskImages = new ArrayList(getAllOVFDisks());
-        if (!ovfStoreDiskImages.isEmpty()) {
-            if 
(!FeatureSupported.ovfStoreOnAnyDomain(getStoragePool().getCompatibilityVersion()))
 {
-                auditLogDirector.log(this, 
AuditLogType.RETRIEVE_UNREGISTERED_ENTITIES_NOT_SUPPORTED_IN_DC_VERSION);
-                return Collections.emptyList();
-            }
-            while (!ovfStoreDiskImages.isEmpty()) {
-                Pair<DiskImage, Long> ovfDiskAndSize = 
getLatestOVFDisk(ovfStoreDiskImages);
-                DiskImage ovfDisk = ovfDiskAndSize.getFirst();
-                if (ovfDisk != null) {
-                    try {
-                        VdcReturnValueBase vdcReturnValue = 
runInternalAction(VdcActionType.RetrieveImageData,
-                                new 
RetrieveImageDataParameters(getParameters().getStoragePoolId(),
-                                        getParameters().getStorageDomainId(),
-                                        ovfDisk.getId(),
-                                        ovfDisk.getImage().getId(),
-                                        ovfDiskAndSize.getSecond()), 
cloneContextAndDetachFromParent());
-
-                        
getReturnValue().getVdsmTaskIdList().addAll(vdcReturnValue.getInternalVdsmTaskIdList());
-                        if (vdcReturnValue.getSucceeded()) {
-                            return OvfUtils.getOvfEntities((byte[]) 
vdcReturnValue.getActionReturnValue(),
-                                    getParameters().getStorageDomainId());
-                        } else {
-                            log.error("Image data could not be retrieved for 
disk id '{}' in storage domain id '{}'",
-                                    ovfDisk.getId(),
-                                    getParameters().getStorageDomainId());
-                        }
-                    } catch (RuntimeException e) {
-                        // We are catching RuntimeException, since the call 
for OvfUtils.getOvfEntities will throw
-                        // a RuntimeException if there is a problem to untar 
the file.
-                        log.error("Image data could not be retrieved for disk 
id '{}' in storage domain id '{}': {}",
-                                ovfDisk.getId(),
-                                getParameters().getStorageDomainId(),
-                                e.getMessage());
-                        log.debug("Exception", e);
-                    }
-                    ovfStoreDiskImages.remove(ovfDisk);
-                }
-            }
-            auditLogDirector.log(this, AuditLogType.RETRIEVE_OVF_STORE_FAILED);
-        } else {
-            log.warn("There are no OVF_STORE disks on storage domain id {}",
-                    getParameters().getStorageDomainId());
-            auditLogDirector.log(this, AuditLogType.OVF_STORE_DOES_NOT_EXISTS);
-        }
-        return Collections.emptyList();
-    }
-
-    /**
-     * Register all the OVF_STORE disks as floating disks in the engine.
-     */
-    private void addOvfStoreDiskToDomain(DiskImage ovfDisk) {
-        // Setting OVF_STORE disk to be outdated so it will be updated.
-        StorageDomainOvfInfo storageDomainOvfInfo =
-                new StorageDomainOvfInfo(getStorageDomainId(),
-                        null,
-                        ovfDisk.getId(),
-                        StorageDomainOvfInfoStatus.OUTDATED,
-                        null);
-        getDbFacade().getStorageDomainOvfInfoDao().save(storageDomainOvfInfo);
-    }
-
-    private void registerAllOvfDisks(List<DiskImage> ovfStoreDiskImages) {
-        for (DiskImage ovfStoreDiskImage : ovfStoreDiskImages) {
-            
ovfStoreDiskImage.setDiskAlias(OvfInfoFileConstants.OvfStoreDescriptionLabel);
-            
ovfStoreDiskImage.setDiskDescription(OvfInfoFileConstants.OvfStoreDescriptionLabel);
-            ovfStoreDiskImage.setShareable(true);
-            RegisterDiskParameters registerDiskParams =
-                    new RegisterDiskParameters(ovfStoreDiskImage, 
getParameters().getStorageDomainId());
-
-            boolean registerDiskResult = 
runInternalAction(VdcActionType.RegisterDisk, registerDiskParams,
-                    cloneContext()).getSucceeded();
-
-            log.info("Register new floating OVF_STORE disk with disk id '{}' 
for storage domain '{}' has {}",
-                    ovfStoreDiskImage.getId(),
-                    getParameters().getStorageDomainId(),
-                    registerDiskResult ? "succeeded" : "failed");
-
-            if (registerDiskResult) {
-                addOvfStoreDiskToDomain(ovfStoreDiskImage);
-            }
-        }
-    }
-
-    protected List<DiskImage> getAllOVFDisks() {
-        if (ovfDisks == null) {
-            ovfDisks = new ArrayList<>();
-
-            // Get all unregistered disks.
-            List<Disk> unregisteredDisks = 
getBackend().runInternalQuery(VdcQueryType.GetUnregisteredDisks,
-                    new 
GetUnregisteredDisksQueryParameters(getParameters().getStorageDomainId(),
-                            getVds().getStoragePoolId())).getReturnValue();
-            for (Disk disk : unregisteredDisks) {
-                DiskImage ovfStoreDisk = (DiskImage) disk;
-                String diskDecription = ovfStoreDisk.getDescription();
-                if 
(diskDecription.contains(OvfInfoFileConstants.OvfStoreDescriptionLabel)) {
-                    Map<String, Object> diskDescriptionMap;
-                    try {
-                        diskDescriptionMap = 
JsonHelper.jsonToMap(diskDecription);
-                    } catch (IOException e) {
-                        log.warn("Exception while generating json containing 
ovf store info: {}", e.getMessage());
-                        log.debug("Exception", e);
-                        continue;
-                    }
-
-                    // The purpose of this check is to verify that it's an OVF 
store with data related to the Storage
-                    // Domain.
-                    if (!isDomainExistsInDiskDescription(diskDescriptionMap, 
getParameters().getStorageDomainId())) {
-                        log.warn("The disk description does not contain the 
storage domain id '{}'",
-                                getParameters().getStorageDomainId());
-                        continue;
-                    }
-                    ovfDisks.add(ovfStoreDisk);
-                }
-            }
-        }
-        return ovfDisks;
-    }
-
-    /**
-     * Returns the best match for OVF disk from all the disks. If no OVF disk 
was found, it returns null for disk and
-     * size 0. If there are OVF disks, we first match the updated ones, and 
from them we retrieve the one which was last
-     * updated.
-     *
-     * @param ovfStoreDiskImages
-     *            - A list of OVF_STORE disks
-     * @return A Pair which contains the best OVF disk to retrieve data from 
and its size.
-     */
-    private Pair<DiskImage, Long> getLatestOVFDisk(List<DiskImage> 
ovfStoreDiskImages) {
-        Date foundOvfDiskUpdateDate = new Date();
-        boolean isFoundOvfDiskUpdated = false;
-        Long size = 0L;
-        Disk ovfDisk = null;
-        for (DiskImage ovfStoreDisk : ovfStoreDiskImages) {
-            boolean isBetterOvfDiskFound = false;
-            Map<String, Object> diskDescriptionMap;
-            try {
-                diskDescriptionMap = 
JsonHelper.jsonToMap(ovfStoreDisk.getDescription());
-            } catch (IOException e) {
-                log.warn("Exception while generating json containing ovf store 
info: {}", e.getMessage());
-                log.debug("Exception", e);
-                continue;
-            }
-
-            boolean isUpdated = 
Boolean.valueOf(diskDescriptionMap.get(OvfInfoFileConstants.IsUpdated).toString());
-            Date date = getDateFromDiskDescription(diskDescriptionMap);
-            if (date == null) {
-                continue;
-            }
-            if (isFoundOvfDiskUpdated && !isUpdated) {
-                continue;
-            }
-            if ((isUpdated && !isFoundOvfDiskUpdated) || 
date.after(foundOvfDiskUpdateDate)) {
-                isBetterOvfDiskFound = true;
-            }
-            if (isBetterOvfDiskFound) {
-                isFoundOvfDiskUpdated = isUpdated;
-                foundOvfDiskUpdateDate = date;
-                ovfDisk = ovfStoreDisk;
-                size = new 
Long(diskDescriptionMap.get(OvfInfoFileConstants.Size).toString());
-            }
-        }
-        return new Pair<>((DiskImage)ovfDisk, size);
-    }
-
-    private Date getDateFromDiskDescription(Map<String, Object> map) {
-        try {
-            Object lastUpdate = map.get(OvfInfoFileConstants.LastUpdated);
-            if (lastUpdate != null) {
-                return new 
SimpleDateFormat(OvfParser.formatStrFromDiskDescription).parse(lastUpdate.toString());
-            } else {
-                log.info("LastUpdate Date is not initialized in the OVF_STORE 
disk.");
-            }
-        } catch (java.text.ParseException e) {
-            log.error("LastUpdate Date could not be parsed from disk 
description: {}", e.getMessage());
-            log.debug("Exception", e);
-        }
-        return null;
-    }
-
     @Override
     protected Map<String, Pair<String, String>> getExclusiveLocks() {
         return 
Collections.singletonMap(getParameters().getStorageDomainId().toString(),
                 LockMessagesMatchUtil.makeLockingPair(LockingGroup.STORAGE, 
VdcBllMessages.ACTION_TYPE_FAILED_OBJECT_LOCKED));
-    }
-
-    private boolean isDomainExistsInDiskDescription(Map<String, Object> map, 
Guid storageDomainId) {
-        return 
map.get(OvfInfoFileConstants.Domains).toString().contains(storageDomainId.toString());
     }
 
     protected void attemptToActivateDomain() {
@@ -499,4 +300,8 @@
                 getActionType().getActionGroup()));
         return permissionList;
     }
+
+    protected Guid getStoragePoolIdFromVds() {
+        return getVds().getStoragePoolId();
+    }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/StorageHandlingCommandBase.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/StorageHandlingCommandBase.java
index d74c62f..8cfe6cf 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/StorageHandlingCommandBase.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/StorageHandlingCommandBase.java
@@ -1,22 +1,33 @@
 package org.ovirt.engine.core.bll.storage;
 
+import java.io.IOException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
 
 import org.apache.commons.lang.StringUtils;
 import org.ovirt.engine.core.bll.CommandBase;
+import org.ovirt.engine.core.bll.RetrieveImageDataParameters;
 import org.ovirt.engine.core.bll.context.CommandContext;
 import org.ovirt.engine.core.bll.interfaces.BackendInternal;
 import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator;
 import org.ovirt.engine.core.bll.utils.PermissionSubject;
+import org.ovirt.engine.core.common.AuditLogType;
+import org.ovirt.engine.core.common.FeatureSupported;
 import org.ovirt.engine.core.common.VdcObjectType;
+import org.ovirt.engine.core.common.action.RegisterDiskParameters;
 import org.ovirt.engine.core.common.action.StoragePoolParametersBase;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.action.VdcReturnValueBase;
 import org.ovirt.engine.core.common.businessentities.OvfEntityData;
 import org.ovirt.engine.core.common.businessentities.StorageDomain;
+import org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfo;
+import 
org.ovirt.engine.core.common.businessentities.StorageDomainOvfInfoStatus;
 import org.ovirt.engine.core.common.businessentities.StorageDomainStatic;
 import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
 import org.ovirt.engine.core.common.businessentities.StorageDomainType;
@@ -28,11 +39,15 @@
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.VmEntityType;
 import org.ovirt.engine.core.common.businessentities.VmTemplate;
+import org.ovirt.engine.core.common.businessentities.storage.Disk;
 import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
 import org.ovirt.engine.core.common.config.Config;
 import org.ovirt.engine.core.common.config.ConfigValues;
 import org.ovirt.engine.core.common.errors.VdcBLLException;
 import org.ovirt.engine.core.common.errors.VdcBllMessages;
+import 
org.ovirt.engine.core.common.queries.GetUnregisteredDisksQueryParameters;
+import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
 import org.ovirt.engine.core.common.vdscommands.VDSParametersBase;
 import org.ovirt.engine.core.common.vdscommands.VDSReturnValue;
@@ -42,15 +57,20 @@
 import org.ovirt.engine.core.dao.DiskImageDAO;
 import org.ovirt.engine.core.dao.StoragePoolIsoMapDAO;
 import org.ovirt.engine.core.dao.UnregisteredOVFDataDAO;
+import org.ovirt.engine.core.utils.JsonHelper;
+import org.ovirt.engine.core.utils.OvfUtils;
 import org.ovirt.engine.core.utils.SyncronizeNumberOfAsyncOperations;
 import org.ovirt.engine.core.utils.linq.LinqUtils;
 import org.ovirt.engine.core.utils.linq.Predicate;
+import org.ovirt.engine.core.utils.ovf.OvfInfoFileConstants;
+import org.ovirt.engine.core.utils.ovf.OvfParser;
 import org.ovirt.engine.core.utils.transaction.TransactionMethod;
 import org.ovirt.engine.core.utils.transaction.TransactionSupport;
 
 public abstract class StorageHandlingCommandBase<T extends 
StoragePoolParametersBase> extends CommandBase<T> {
 
     private CinderBroker cinderBroker;
+    protected List<DiskImage> ovfDisks;
 
     protected StorageHandlingCommandBase(T parameters, CommandContext 
commandContext) {
         super(parameters, commandContext);
@@ -343,6 +363,42 @@
         }
     }
 
+    protected void registerAllOvfDisks(List<DiskImage> ovfStoreDiskImages, 
Guid storageDomainId) {
+        for (DiskImage ovfStoreDiskImage : ovfStoreDiskImages) {
+            
ovfStoreDiskImage.setDiskAlias(OvfInfoFileConstants.OvfStoreDescriptionLabel);
+            
ovfStoreDiskImage.setDiskDescription(OvfInfoFileConstants.OvfStoreDescriptionLabel);
+            ovfStoreDiskImage.setShareable(true);
+            RegisterDiskParameters registerDiskParams =
+                    new RegisterDiskParameters(ovfStoreDiskImage, 
storageDomainId);
+
+            boolean registerDiskResult = 
runInternalAction(VdcActionType.RegisterDisk, registerDiskParams,
+                    cloneContext()).getSucceeded();
+
+            log.info("Register new floating OVF_STORE disk with disk id '{}' 
for storage domain '{}' has {}",
+                    ovfStoreDiskImage.getId(),
+                    storageDomainId,
+                    registerDiskResult ? "succeeded" : "failed");
+
+            if (registerDiskResult) {
+                addOvfStoreDiskToDomain(ovfStoreDiskImage);
+            }
+        }
+    }
+
+    /**
+     * Register all the OVF_STORE disks as floating disks in the engine.
+     */
+    private void addOvfStoreDiskToDomain(DiskImage ovfDisk) {
+        // Setting OVF_STORE disk to be outdated so it will be updated.
+        StorageDomainOvfInfo storageDomainOvfInfo =
+                new StorageDomainOvfInfo(getStorageDomainId(),
+                        null,
+                        ovfDisk.getId(),
+                        StorageDomainOvfInfoStatus.OUTDATED,
+                        null);
+        getDbFacade().getStorageDomainOvfInfoDao().save(storageDomainOvfInfo);
+    }
+
     protected void updateStorageDomainFormatIfNeeded(StorageDomain domain) {
         final StorageDomainType sdType = domain.getStorageDomainType();
 
@@ -366,6 +422,137 @@
         }
     }
 
+    protected List<DiskImage> getAllOVFDisks(Guid storageDomainId, Guid 
storagePoolId) {
+        if (ovfDisks == null) {
+            ovfDisks = new ArrayList<>();
+
+            // Get all unregistered disks.
+            List<Disk> unregisteredDisks = 
getBackend().runInternalQuery(VdcQueryType.GetUnregisteredDisks,
+                    new GetUnregisteredDisksQueryParameters(storageDomainId,
+                            storagePoolId)).getReturnValue();
+            for (Disk disk : unregisteredDisks) {
+                DiskImage ovfStoreDisk = (DiskImage) disk;
+                String diskDecription = ovfStoreDisk.getDescription();
+                if 
(diskDecription.contains(OvfInfoFileConstants.OvfStoreDescriptionLabel)) {
+                    Map<String, Object> diskDescriptionMap;
+                    try {
+                        diskDescriptionMap = 
JsonHelper.jsonToMap(diskDecription);
+                    } catch (IOException e) {
+                        log.warn("Exception while generating json containing 
ovf store info: {}", e.getMessage());
+                        log.debug("Exception", e);
+                        continue;
+                    }
+
+                    // The purpose of this check is to verify that it's an OVF 
store with data related to the Storage
+                    // Domain.
+                    if (!isDomainExistsInDiskDescription(diskDescriptionMap, 
storageDomainId)) {
+                        log.warn("The disk description does not contain the 
storage domain id '{}'", storageDomainId);
+                        continue;
+                    }
+                    ovfDisks.add(ovfStoreDisk);
+                }
+            }
+        }
+        return ovfDisks;
+    }
+
+    /**
+     * Returns the best match for OVF disk from all the disks. If no OVF disk 
was found, it returns null for disk and
+     * size 0. If there are OVF disks, we first match the updated ones, and 
from them we retrieve the one which was last
+     * updated.
+     *
+     * @param ovfStoreDiskImages
+     *            - A list of OVF_STORE disks
+     * @return A Pair which contains the best OVF disk to retrieve data from 
and its size.
+     */
+    private Pair<DiskImage, Long> getLatestOVFDisk(List<DiskImage> 
ovfStoreDiskImages) {
+        Date foundOvfDiskUpdateDate = new Date();
+        boolean isFoundOvfDiskUpdated = false;
+        Long size = 0L;
+        Disk ovfDisk = null;
+        for (DiskImage ovfStoreDisk : ovfStoreDiskImages) {
+            boolean isBetterOvfDiskFound = false;
+            Map<String, Object> diskDescriptionMap;
+            try {
+                diskDescriptionMap = 
JsonHelper.jsonToMap(ovfStoreDisk.getDescription());
+            } catch (IOException e) {
+                log.warn("Exception while generating json containing ovf store 
info: {}", e.getMessage());
+                log.debug("Exception", e);
+                continue;
+            }
+
+            boolean isUpdated = 
Boolean.valueOf(diskDescriptionMap.get(OvfInfoFileConstants.IsUpdated).toString());
+            Date date = getDateFromDiskDescription(diskDescriptionMap);
+            if (date == null) {
+                continue;
+            }
+            if (isFoundOvfDiskUpdated && !isUpdated) {
+                continue;
+            }
+            if ((isUpdated && !isFoundOvfDiskUpdated) || 
date.after(foundOvfDiskUpdateDate)) {
+                isBetterOvfDiskFound = true;
+            }
+            if (isBetterOvfDiskFound) {
+                isFoundOvfDiskUpdated = isUpdated;
+                foundOvfDiskUpdateDate = date;
+                ovfDisk = ovfStoreDisk;
+                size = new 
Long(diskDescriptionMap.get(OvfInfoFileConstants.Size).toString());
+            }
+        }
+        return new Pair<>((DiskImage)ovfDisk, size);
+    }
+
+    protected List<OvfEntityData> getEntitiesFromStorageOvfDisk(Guid 
storageDomainId, Guid storagePoolId) {
+        // Initialize a new ArrayList with all the ovfDisks in the specified 
Storage Domain,
+        // so the entities can be removed from the list every time we register 
the latest OVF disk and we can keep the
+        // ovfDisks cache list updated.
+        List<DiskImage> ovfStoreDiskImages = new 
ArrayList(getAllOVFDisks(storageDomainId, storagePoolId));
+        if (!ovfStoreDiskImages.isEmpty()) {
+            if 
(!FeatureSupported.ovfStoreOnAnyDomain(getStoragePool().getCompatibilityVersion()))
 {
+                auditLogDirector.log(this, 
AuditLogType.RETRIEVE_UNREGISTERED_ENTITIES_NOT_SUPPORTED_IN_DC_VERSION);
+                return Collections.emptyList();
+            }
+            while (!ovfStoreDiskImages.isEmpty()) {
+                Pair<DiskImage, Long> ovfDiskAndSize = 
getLatestOVFDisk(ovfStoreDiskImages);
+                DiskImage ovfDisk = ovfDiskAndSize.getFirst();
+                if (ovfDisk != null) {
+                    try {
+                        VdcReturnValueBase vdcReturnValue = 
runInternalAction(VdcActionType.RetrieveImageData,
+                                new 
RetrieveImageDataParameters(getParameters().getStoragePoolId(),
+                                        storageDomainId,
+                                        ovfDisk.getId(),
+                                        ovfDisk.getImage().getId(),
+                                        ovfDiskAndSize.getSecond()), 
cloneContextAndDetachFromParent());
+
+                        
getReturnValue().getVdsmTaskIdList().addAll(vdcReturnValue.getInternalVdsmTaskIdList());
+                        if (vdcReturnValue.getSucceeded()) {
+                            return OvfUtils.getOvfEntities((byte[]) 
vdcReturnValue.getActionReturnValue(),
+                                    storageDomainId);
+                        } else {
+                            log.error("Image data could not be retrieved for 
disk id '{}' in storage domain id '{}'",
+                                    ovfDisk.getId(),
+                                    storageDomainId);
+                        }
+                    } catch (RuntimeException e) {
+                        // We are catching RuntimeException, since the call 
for OvfUtils.getOvfEntities will throw
+                        // a RuntimeException if there is a problem to untar 
the file.
+                        log.error("Image data could not be retrieved for disk 
id '{}' in storage domain id '{}': {}",
+                                ovfDisk.getId(),
+                                storageDomainId,
+                                e.getMessage());
+                        log.debug("Exception", e);
+                    }
+                    ovfStoreDiskImages.remove(ovfDisk);
+                }
+            }
+            auditLogDirector.log(this, AuditLogType.RETRIEVE_OVF_STORE_FAILED);
+        } else {
+            log.warn("There are no OVF_STORE disks on storage domain id {}", 
storageDomainId);
+            auditLogDirector.log(this, AuditLogType.OVF_STORE_DOES_NOT_EXISTS);
+        }
+        return Collections.emptyList();
+    }
+
     protected boolean checkStoragePoolNameLengthValid() {
         boolean result = true;
         if (getStoragePool().getName().length() > 
getStoragePoolNameSizeLimit()) {
@@ -373,6 +560,21 @@
             
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_NAME_LENGTH_IS_TOO_LONG);
         }
         return result;
+    }
+
+    private Date getDateFromDiskDescription(Map<String, Object> map) {
+        try {
+            Object lastUpdate = map.get(OvfInfoFileConstants.LastUpdated);
+            if (lastUpdate != null) {
+                return new 
SimpleDateFormat(OvfParser.formatStrFromDiskDescription).parse(lastUpdate.toString());
+            } else {
+                log.info("LastUpdate Date is not initialized in the OVF_STORE 
disk.");
+            }
+        } catch (java.text.ParseException e) {
+            log.error("LastUpdate Date could not be parsed from disk 
description: {}", e.getMessage());
+            log.debug("Exception", e);
+        }
+        return null;
     }
 
     protected void 
runSynchronizeOperation(ActivateDeactivateSingleAsyncOperationFactory factory,
@@ -395,6 +597,10 @@
         return parameters;
     }
 
+    private boolean isDomainExistsInDiskDescription(Map<String, Object> map, 
Guid storageDomainId) {
+        return 
map.get(OvfInfoFileConstants.Domains).toString().contains(storageDomainId.toString());
+    }
+
     @Override
     public List<PermissionSubject> getPermissionCheckSubjects() {
         return Collections.singletonList(new 
PermissionSubject(getStoragePoolId(),
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommandTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommandTest.java
index e3e90c4..178a05b 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommandTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommandTest.java
@@ -83,8 +83,10 @@
 
     @Test
     public void statusSetInMap() {
+        Guid storageDomainId = Guid.newGuid();
+        Guid poolId = Guid.newGuid();
         AttachStorageDomainToPoolParameters params =
-                new AttachStorageDomainToPoolParameters(Guid.newGuid(), 
Guid.newGuid());
+                new AttachStorageDomainToPoolParameters(storageDomainId, 
poolId);
         AttachStorageDomainToPoolCommand<AttachStorageDomainToPoolParameters> 
cmd =
                 spy(new 
AttachStorageDomainToPoolCommand<AttachStorageDomainToPoolParameters>(params));
 
@@ -97,12 +99,13 @@
         when(dbFacade.getStorageDomainDao()).thenReturn(storageDomainDAO);
         
when(dbFacade.getStorageDomainStaticDao()).thenReturn(storageDomainStaticDAO);
         StoragePool pool = new StoragePool();
+        pool.setId(poolId);
         pool.setStatus(StoragePoolStatus.Up);
         when(storagePoolDAO.get(any(Guid.class))).thenReturn(pool);
         when(isoMapDAO.get(any(StoragePoolIsoMapId.class))).thenReturn(map);
         when(storageDomainDAO.getForStoragePool(any(Guid.class), 
any(Guid.class))).thenReturn(new StorageDomain());
         when(storageDomainStaticDAO.get(any(Guid.class))).thenReturn(new 
StorageDomainStatic());
-
+        doReturn(pool.getId()).when(cmd).getStoragePoolIdFromVds();
         doReturn(backendInternal).when(cmd).getBackend();
         
when(backendInternal.getResourceManager()).thenReturn(vdsBrokerFrontend);
         VdcReturnValueBase vdcReturnValue = new VdcReturnValueBase();
@@ -116,8 +119,8 @@
         mockGetStorageDomainInfoVdsCommand(storageDomain);
         mockAttachStorageDomainVdsCommand();
         when(vdsDAO.get(any(Guid.class))).thenReturn(vds);
-        
doReturn(getUnregisteredList()).when(cmd).getEntitiesFromStorageOvfDisk();
-        
doReturn(Collections.<DiskImage>emptyList()).when(cmd).getAllOVFDisks();
+        
doReturn(getUnregisteredList()).when(cmd).getEntitiesFromStorageOvfDisk(storageDomainId,
 pool.getId());
+        
doReturn(Collections.<DiskImage>emptyList()).when(cmd).getAllOVFDisks(storageDomainId,
 pool.getId());
         doAnswer(new Answer<Object>() {
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable 
{


-- 
To view, visit https://gerrit.ovirt.org/40349
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I0d24f059c0073d8744b46b0d0697e323f63ce119
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Maor Lipchuk <mlipc...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to