Maor Lipchuk has uploaded a new change for review.

Change subject: core: Initialize entities in DB from OVF disk on attach
......................................................................

core: Initialize entities in DB from OVF disk on attach

Adding VMs and Templates from the most updated OVF store disk into the
unregistered entity table.
The operation of this is being done when the user attach a Storage Domain to 
the DC.

Change-Id: Ica68974916821ac1c9fbe6f43400170d19d716c9
Signed-off-by: Maor Lipchuk <[email protected]>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommand.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/storage/AttachStorageDomainToPoolCommandTest.java
M 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ovf/OvfParser.java
3 files changed, 141 insertions(+), 6 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/41/29041/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 144cfcb..8342308 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,6 +1,12 @@
 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.Date;
+import java.util.List;
+import java.util.Map;
 
 import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute;
 import org.ovirt.engine.core.bll.context.CommandContext;
@@ -10,16 +16,28 @@
 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.Disk;
+import org.ovirt.engine.core.common.businessentities.DiskImage;
+import org.ovirt.engine.core.common.businessentities.OvfEntityData;
 import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
 import org.ovirt.engine.core.common.businessentities.StorageDomainType;
 import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMap;
 import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMapId;
 import org.ovirt.engine.core.common.businessentities.StoragePoolStatus;
 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.AttachStorageDomainVDSCommandParameters;
+import 
org.ovirt.engine.core.common.vdscommands.ImageHttpAccessVDSCommandParameters;
 import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
+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.archivers.tar.OutMemoryTar;
+import org.ovirt.engine.core.utils.ovf.OvfInfoFileConstants;
+import org.ovirt.engine.core.utils.ovf.OvfParser;
 import org.ovirt.engine.core.utils.transaction.TransactionMethod;
 
 @NonTransactiveCommandAttribute(forceCompensation = true)
@@ -79,6 +97,7 @@
                     runVdsCommand(VDSCommandType.AttachStorageDomain,
                             new 
AttachStorageDomainVDSCommandParameters(getParameters().getStoragePoolId(),
                                     getParameters().getStorageDomainId()));
+                    final List<OvfEntityData> unregisteredEntitiesFromOvfDisk 
= getEntitiesFromStorageOvfDisk();
                     executeInNewTransaction(new TransactionMethod<Object>() {
                         @Override
                         public Object runInTransaction() {
@@ -94,9 +113,20 @@
                             if (sdType == StorageDomainType.Data || sdType == 
StorageDomainType.Master) {
                                 updateStorageDomainFormat(getStorageDomain());
                             }
+
+                            // Update unregistered entities
+                            for (OvfEntityData ovf : 
unregisteredEntitiesFromOvfDisk) {
+                                
getUnregisteredOVFDataDao().removeEntity(ovf.getEntityId(),
+                                        getParameters().getStorageDomainId());
+                                getUnregisteredOVFDataDao().saveOVFData(ovf);
+                                log.infoFormat("Adding OVF data of entity id 
{0} and entity name {1}",
+                                        ovf.getEntityId(),
+                                        ovf.getEntityName());
+                            }
                             return null;
                         }
                     });
+
                     if (getParameters().getActivate()) {
                         attemptToActivateDomain();
                     }
@@ -104,7 +134,105 @@
                 }
             }
         }
+    }
 
+    protected List<OvfEntityData> getEntitiesFromStorageOvfDisk() {
+        List<OvfEntityData> ovfEntitiesFromTar = new ArrayList<>();
+
+        // Get all unregistered disks.
+        List<Disk> unregisteredDisks = 
getBackend().runInternalQuery(VdcQueryType.GetUnregisteredDisks,
+                new 
GetUnregisteredDisksQueryParameters(getParameters().getStorageDomainId(),
+                        getVds().getStoragePoolId())).getReturnValue();
+
+        Pair<DiskImage, Long> ovfDiskAndSize = 
getLatestOVFDisk(unregisteredDisks);
+        DiskImage ovfDisk = ovfDiskAndSize.getFirst();
+        if (ovfDisk != null) {
+            VDSReturnValue retrievedByteData =
+                    runVdsCommand(VDSCommandType.RetrieveImageData, new 
ImageHttpAccessVDSCommandParameters(getVdsId(),
+                            getParameters().getStoragePoolId(),
+                            getParameters().getStorageDomainId(),
+                            ovfDisk.getId(),
+                            ovfDisk.getImage().getId(),
+                            ovfDiskAndSize.getSecond()));
+            if (retrievedByteData.getSucceeded()) {
+                ovfEntitiesFromTar =
+                        OutMemoryTar.unTar((byte[]) 
retrievedByteData.getReturnValue(),
+                                getParameters().getStorageDomainId());
+            }
+        }
+        return ovfEntitiesFromTar;
+    }
+
+    /**
+     * 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 disks
+     *            - A list of disks
+     * @return A Pair which contains the best OVF disk to retrieve data from 
and its size.
+     */
+    private Pair<DiskImage, Long> getLatestOVFDisk(List<Disk> disks) {
+        Date lastUpdate = new Date();
+        boolean lastIsUpdated = false;
+        Long size = 0L;
+        Disk diskToGetOVF = null;
+        for (Disk disk : disks) {
+            boolean isDiskLastUpdated = false;
+            // Check which disks are of OVF_STORE
+            String diskDecription = ((DiskImage) disk).getDescription();
+            if 
(diskDecription.contains(OvfInfoFileConstants.OvfStoreDescriptionLabel)) {
+                Map<String, Object> diskDescriptionMap = 
buildJson(diskDecription);
+                if (!isDomainExistsInDiskDescription(diskDescriptionMap, 
getParameters().getStorageDomainId())) {
+                    break;
+                }
+
+                boolean isUpdated = 
Boolean.valueOf(diskDescriptionMap.get(OvfInfoFileConstants.IsUpdated).toString());
+                Date date = getDateFromDiskDescription(diskDescriptionMap);
+                // If last is updated is false, and the current disk was 
updated, then the current disk is what we are
+                // about to update from.
+                if (!lastIsUpdated && isUpdated) {
+                    isDiskLastUpdated = true;
+                    // If also the current disk was not updated, then check 
which disk has the latest update date.
+                } else if (!isUpdated && date.after(lastUpdate)) {
+                    isDiskLastUpdated = true;
+                    // If also the current disk was updated, then check which 
disk has the latest update date.
+                } else if (lastIsUpdated && isUpdated && 
date.after(lastUpdate)) {
+                    isDiskLastUpdated = true;
+                }
+
+                if (isDiskLastUpdated) {
+                    lastIsUpdated = isUpdated;
+                    lastUpdate = date;
+                    diskToGetOVF = disk;
+                    size = new 
Long(diskDescriptionMap.get(OvfInfoFileConstants.Size).toString());
+                }
+            }
+        }
+        return new Pair<>((DiskImage)diskToGetOVF, size);
+    }
+
+    private Date getDateFromDiskDescription(Map<String, Object> map) {
+        try {
+            return new 
SimpleDateFormat(OvfParser.formatStrFromDiskDescription).parse(map.get(OvfInfoFileConstants.LastUpdated)
+                    .toString());
+        } catch (java.text.ParseException e) {
+            log.errorFormat("LastUpdate Date could not be parsed from disk 
desscription");
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    private boolean isDomainExistsInDiskDescription(Map<String, Object> map, 
Guid storageDomainId) {
+        return 
map.get(OvfInfoFileConstants.Domains).toString().contains(storageDomainId.toString());
+    }
+
+    private Map<String, Object> buildJson(String json) {
+        try {
+            return JsonHelper.jsonToMap(json);
+        } catch (IOException e) {
+            throw new RuntimeException("Exception while generating json 
containing ovf store info", e);
+        }
     }
 
     protected void attemptToActivateDomain() {
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 04364f5..98a8aa5 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
@@ -4,13 +4,14 @@
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import java.util.ArrayList;
+import java.util.List;
 
 import org.junit.ClassRule;
 import org.junit.Test;
@@ -26,15 +27,16 @@
 import org.ovirt.engine.core.common.action.VdcActionParametersBase;
 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.StorageDomainStatic;
 import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
+import org.ovirt.engine.core.common.businessentities.StoragePool;
+import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMap;
 import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMapId;
 import org.ovirt.engine.core.common.businessentities.StoragePoolStatus;
 import org.ovirt.engine.core.common.businessentities.VDS;
 import org.ovirt.engine.core.common.businessentities.VDSStatus;
-import org.ovirt.engine.core.common.businessentities.StorageDomainStatic;
-import org.ovirt.engine.core.common.businessentities.StorageDomain;
-import org.ovirt.engine.core.common.businessentities.StoragePool;
-import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMap;
 import org.ovirt.engine.core.common.interfaces.VDSBrokerFrontend;
 import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
 import org.ovirt.engine.core.common.vdscommands.VDSParametersBase;
@@ -107,6 +109,7 @@
         when(vdsBrokerFrontend.RunVdsCommand(any(VDSCommandType.class), 
any(VDSParametersBase.class)))
                 .thenReturn(returnValue);
         when(vdsDAO.get(any(Guid.class))).thenReturn(vds);
+        
doReturn(getUnregisteredList()).when(cmd).getEntitiesFromStorageOvfDisk();
         doAnswer(new Answer<Object>() {
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable 
{
@@ -120,4 +123,8 @@
         assertNotNull(map);
         assertEquals(StorageDomainStatus.Maintenance, map.getStatus());
     }
+
+    private List<OvfEntityData> getUnregisteredList() {
+        return new ArrayList<OvfEntityData>();
+    }
 }
diff --git 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ovf/OvfParser.java
 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ovf/OvfParser.java
index fb8dbbb..63d7e76 100644
--- 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ovf/OvfParser.java
+++ 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ovf/OvfParser.java
@@ -17,9 +17,9 @@
 import org.ovirt.engine.core.utils.log.LogFactory;
 
 public class OvfParser {
-
     private static final String utcFallbackDateFormatStr = "yyyy.MM.dd 
HH:mm:ss";
     private static final String utcDateFormatStr = "yyyy/MM/dd HH:mm:ss";
+    public static final String formatStrFromDiskDescription = "EEE MMM d 
HH:mm:ss zzz yyyy";
     protected XmlDocument _document;
     protected XmlNamespaceManager _xmlNS;
 


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

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

Reply via email to