Frank Kobzik has uploaded a new change for review.

Change subject: core: Implement optimized vm data retrieval
......................................................................

core: Implement optimized vm data retrieval

This draft makes use of optimized data retrieval mechanism implemented
in VDSM (http://gerrit.ovirt.org/14541).

Change-Id: Ifff9d828c67e51a5e80388fdc77355d4b6415f34
Signed-off-by: Frantisek Kobzik <fkob...@redhat.com>
---
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java
A 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/AllVmRuntimeStats.java
A 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/GetAllVmRuntimeStatsVDSCommand.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java
A 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/InnerVmRuntimeStats.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java
8 files changed, 311 insertions(+), 7 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/26/19126/1

diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java
index f700a11..f1de3b9 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsUpdateRunTimeInfo.java
@@ -13,7 +13,6 @@
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
-
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
@@ -71,6 +70,7 @@
 import org.ovirt.engine.core.vdsbroker.irsbroker.IRSErrorException;
 import org.ovirt.engine.core.vdsbroker.vdsbroker.DestroyVDSCommand;
 import org.ovirt.engine.core.vdsbroker.vdsbroker.FullListVdsCommand;
+import 
org.ovirt.engine.core.vdsbroker.vdsbroker.GetAllVmRuntimeStatsVDSCommand;
 import org.ovirt.engine.core.vdsbroker.vdsbroker.GetAllVmStatsVDSCommand;
 import org.ovirt.engine.core.vdsbroker.vdsbroker.GetStatsVDSCommand;
 import org.ovirt.engine.core.vdsbroker.vdsbroker.GetVmStatsVDSCommand;
@@ -949,14 +949,23 @@
         }
 
         VdsBrokerCommand<VdsIdAndVdsVDSCommandParametersBase> command;
-        if (!_vdsManager.getRefreshStatistics()) {
-            command = new ListVDSCommand<VdsIdAndVdsVDSCommandParametersBase>(
+
+        if (_vdsManager.getRefreshStatistics()) {
+            command = new GetAllVmStatsVDSCommand<>(
                     new VdsIdAndVdsVDSCommandParametersBase(_vds));
+            _runningVms = (Map<Guid, VmInternalData>) 
command.executeWithReturnValue();
         } else {
-            command = new 
GetAllVmStatsVDSCommand<VdsIdAndVdsVDSCommandParametersBase>(
+            command = new GetAllVmRuntimeStatsVDSCommand<>(
                     new VdsIdAndVdsVDSCommandParametersBase(_vds));
+            _runningVms = (Map<Guid, VmInternalData>) 
command.executeWithReturnValue();
+
+            if (!command.getVDSReturnValue().getSucceeded()) { // fallback to 
list command
+                log.info(String.format("Data optimization not enabled for host 
%s. Falling back to list command.", _vds.getName()));
+                command = new ListVDSCommand<>(
+                    new VdsIdAndVdsVDSCommandParametersBase(_vds));
+                _runningVms = (Map<Guid, VmInternalData>) 
command.executeWithReturnValue();
+            }
         }
-        _runningVms = (Map<Guid, VmInternalData>) 
command.executeWithReturnValue();
 
         if (command.getVDSReturnValue().getSucceeded()) {
             List<VM> running = checkVmsStatusChanged();
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/AllVmRuntimeStats.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/AllVmRuntimeStats.java
new file mode 100644
index 0000000..ff5be47
--- /dev/null
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/AllVmRuntimeStats.java
@@ -0,0 +1,36 @@
+package org.ovirt.engine.core.vdsbroker.vdsbroker;
+
+import java.io.Serializable;
+import java.util.Map;
+
+public class AllVmRuntimeStats implements Serializable {
+    private static final String STATUS = "status";
+    private static final String HASHES = "hashes";
+    private static final String RUNTIME_STATS = "runtimeStats";
+
+    private StatusForXmlRpc status;
+    private Map<String, Map<String, Object>> infoMap; // guid -> propKey -> 
propVal
+
+    public AllVmRuntimeStats(Map<String, Object> innerMap) {
+        status = new StatusForXmlRpc((Map<String, Object>) 
innerMap.get(STATUS));
+        infoMap = (Map<String, Map<String, Object>>) 
innerMap.get(RUNTIME_STATS);
+    }
+
+    public Map<String, Map<String, Object>> getAllRuntimeStats() {
+        return infoMap;
+    }
+
+    public Map<String, Object> getAllRuntimeStatsForVm(String vmId) {
+        return infoMap.get(vmId);
+    }
+
+    public Map<GetAllVmRuntimeStatsVDSCommand.Hash, String> 
getHashesForVm(String vmId) {
+        return (Map<GetAllVmRuntimeStatsVDSCommand.Hash, String>) 
infoMap.get(vmId).get(HASHES);
+    }
+
+    public StatusForXmlRpc getStatus() {
+        return status;
+    }
+
+}
+
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/GetAllVmRuntimeStatsVDSCommand.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/GetAllVmRuntimeStatsVDSCommand.java
new file mode 100644
index 0000000..5d17ff0
--- /dev/null
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/GetAllVmRuntimeStatsVDSCommand.java
@@ -0,0 +1,170 @@
+package org.ovirt.engine.core.vdsbroker.vdsbroker;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.ovirt.engine.core.common.businessentities.VmDynamic;
+import org.ovirt.engine.core.common.businessentities.VmStatistics;
+import 
org.ovirt.engine.core.common.vdscommands.VdsIdAndVdsVDSCommandParametersBase;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.vdsbroker.vdsbroker.entities.VmInternalData;
+
+/**
+ * Command for retrieving vm stats from VDSM that uses data optimization.
+ *
+ * TODO:
+ *  - device stats every ~5 mins, not in each iteration
+ *  - write test to check if all retrieved data is correctly set
+ */
+public class GetAllVmRuntimeStatsVDSCommand<P extends 
VdsIdAndVdsVDSCommandParametersBase> extends VdsBrokerCommand<P> {
+
+    public enum Hash {
+        VM_STATUS("vmStatus"),
+        VM_CONF_INFO("vmConfInfo"),
+        DEVICE_STATS("deviceStats"),
+        VM_GUEST_DETAILS("vmGuestDetails");
+
+        private final String text;
+
+        private Hash(final String val) {
+            text = val;
+        }
+
+        public String toString() {
+            return text;
+        }
+
+        // needed because the hashes names is allvmstats struct doesn't 
correspond to vdsm verbs
+        public String toStatsHashName() {
+            switch (this) {
+                case VM_STATUS:
+                    return "status";
+                case VM_CONF_INFO:
+                    return "info";
+                case VM_GUEST_DETAILS:
+                    return "guestDetails";
+                default:
+                    return null;
+            }
+        }
+    }
+
+    // todo static field should be moved into a holder class
+    private static AllVmRuntimeStats allVmRuntimeStats;
+    // map that contains all properties for given vm. vmId -> prop -> name
+    private static Map<String, Map<String, String>> allVmStats = new 
HashMap<>();
+    // map of vmIds to update for given hash. hash -> [vmIds]
+    private Map<Hash, List<String>> hashesToUpdate = new HashMap<>();
+    // old hash values for given vm to determine which hashes to update. vmId 
-> hash -> hashValue
+    private static Map<String, Map<Hash, String>> oldHashValues = new 
HashMap<>();
+
+    public GetAllVmRuntimeStatsVDSCommand(P parameters) {
+        super(parameters, parameters.getVds());
+    }
+
+    @Override
+    protected void ExecuteVdsBrokerCommand() {
+        allVmRuntimeStats = getBroker().getAllVmRuntimeStats();
+
+        ProceedProxyReturnValue();
+
+        initHashes();
+        updateMainStatsAndSetHashes();
+        updateSubStats();
+        setReturnValue(buildVmData());
+    }
+
+    private void initHashes() {
+        for (Hash hash : Hash.values()) {
+            hashesToUpdate.put(hash, new ArrayList<String>());
+        }
+    }
+
+    /**
+     * This method goes through the values got via getAllVmRuntimeStats and 
puts them into allVmStats for all vms.
+     * For all vms it also compares retrieved hashes and if they differ from 
their last value, it updates the
+     * hashesToUpdate collection.
+     */
+    private void updateMainStatsAndSetHashes() {
+        for (String vmId : allVmRuntimeStats.getAllRuntimeStats().keySet()) {
+            allVmStats.put(vmId, (Map) 
allVmRuntimeStats.getAllRuntimeStatsForVm(vmId));
+            allVmStats.remove("status");
+
+            if (oldHashValues.get(vmId) == null) {
+                oldHashValues.put(vmId, new HashMap<Hash, String>());
+            }
+
+            for (Hash hash : Hash.values()) {
+               if (isHashDifferentForVm(hash, 
allVmRuntimeStats.getHashesForVm(vmId).get(hash.toStatsHashName()), vmId)) {
+                   logUpgrade(vmId, hash.toString());
+                   hashesToUpdate.get(hash).add(vmId);
+                   oldHashValues.get(vmId).put(hash, 
allVmRuntimeStats.getHashesForVm(vmId).get(hash.toStatsHashName()));
+               }
+            }
+        }
+    }
+
+    /**
+     * This method updates all "substats" (that correspond to hashes).
+     */
+    private void updateSubStats() {
+        for (Hash hash : hashesToUpdate.keySet()) {
+            InnerVmRuntimeStats innerVmRuntimeStats = 
getBroker().getInnerVmRuntimeStats(hash, hashesToUpdate.get(hash));
+            if (innerVmRuntimeStats.getInnerVmStats() == null) {
+                continue;
+            }
+            for (String vmId : innerVmRuntimeStats.getInnerVmStats().keySet()) 
{
+                
allVmStats.get(vmId).putAll(innerVmRuntimeStats.getInnerStatsForVm(vmId));
+            }
+        }
+    }
+
+    /**
+     * This method builds VmInternalData objects for each vm based on 
allVmStats collection.
+     */
+    private Map<Guid, VmInternalData> buildVmData() {
+        Map<Guid, VmInternalData> returnVMs = new HashMap<>();
+
+        for (String vmId : allVmStats.keySet()) {
+            VmDynamic vmDynamic = new ExtendedVmDynamic(getVds());
+            vmDynamic.setId(new Guid(vmId));
+            VdsBrokerObjectsBuilder.updateVMDynamicData(vmDynamic, (Map) 
allVmStats.get(vmId));
+
+            VmStatistics vmStatistics = new VmStatistics();
+            vmStatistics.setId(new Guid(vmId));
+            VdsBrokerObjectsBuilder.updateVMStatisticsData(vmStatistics, (Map) 
allVmStats.get(vmId));
+
+            VmInternalData vmInternalData = new VmInternalData(vmDynamic, 
vmStatistics,
+                    
VdsBrokerObjectsBuilder.buildVmGuestAgentInterfacesData(vmDynamic.getId(), 
(Map) allVmStats.get(vmId)));
+
+            returnVMs.put(new Guid(vmId), vmInternalData);
+        }
+
+        return returnVMs;
+    }
+
+    private void logUpgrade(String vmId, String hashName) {
+         log.info(new StringBuilder().append("Must upgrade hash 
").append(hashName).append(" for vm ").append(vmId).toString());
+    }
+
+    private boolean isHashDifferentForVm(Hash hash, String hashValue, String 
vmId) {
+        return hashValue == null || oldHashValues == null || 
oldHashValues.get(vmId) == null || 
hashValue.equals(oldHashValues.get(vmId).get(hash));
+    }
+
+    @Override
+    protected boolean getIsPrintReturnValue() {
+        return false;
+    }
+
+    @Override
+    protected StatusForXmlRpc getReturnStatus() {
+        return allVmRuntimeStats.getStatus();
+    }
+
+    @Override
+    protected Object getReturnValueFromBroker() {
+        return allVmRuntimeStats.getAllRuntimeStats();
+    }
+
+}
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java
index 873e82b..731c2ba 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java
@@ -1,5 +1,6 @@
 package org.ovirt.engine.core.vdsbroker.vdsbroker;
 
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Future;
 import java.util.concurrent.FutureTask;
@@ -50,6 +51,10 @@
 
     VMInfoListReturnForXmlRpc getAllVmStats();
 
+    AllVmRuntimeStats getAllVmRuntimeStats();
+
+    InnerVmRuntimeStats 
getInnerVmRuntimeStats(GetAllVmRuntimeStatsVDSCommand.Hash statHash, 
List<String> vmIds);
+
     StatusOnlyReturnForXmlRpc migrate(Map<String, String> migrationInfo);
 
     StatusOnlyReturnForXmlRpc migrateStatus(String vmId);
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/InnerVmRuntimeStats.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/InnerVmRuntimeStats.java
new file mode 100644
index 0000000..f024085
--- /dev/null
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/InnerVmRuntimeStats.java
@@ -0,0 +1,28 @@
+package org.ovirt.engine.core.vdsbroker.vdsbroker;
+
+import java.io.Serializable;
+import java.util.Map;
+
+public class InnerVmRuntimeStats implements Serializable{
+    private static final String STATUS = "status";
+
+    private StatusForXmlRpc status;
+    private Map<String, Map<String, String>> infoMap; // id -> prop -> val
+
+    public InnerVmRuntimeStats(Map<String, Object> innerMap, String statName) {
+        status = new StatusForXmlRpc((Map<String, Object>) 
innerMap.get(STATUS));
+        infoMap = (Map<String, Map<String, String>>) innerMap.get(statName);
+    }
+
+    public StatusForXmlRpc getStatus() {
+        return status;
+    }
+
+    public Map<String, Map<String, String>> getInnerVmStats() {
+        return infoMap;
+    }
+
+    public Map<String, String> getInnerStatsForVm(String vmId) {
+        return infoMap.get(vmId);
+    }
+}
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java
index fac9e68..ed47d71 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java
@@ -889,7 +889,7 @@
         }
     }
 
-    private static VMStatus convertToVmStatus(String statusName) {
+    public static VMStatus convertToVmStatus(String statusName) {
         VMStatus status = VMStatus.Unassigned;
         if ("Running".equals(statusName) || "Unknown".equals(statusName)) {
             status = VMStatus.Up;
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java
index 9c18928..1f8c058 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java
@@ -36,6 +36,12 @@
 
     public Map<String, Object> getAllVmStats();
 
+    public Map<String, Object> getAllVmRuntimeStats();
+    public Map<String, Object> getVmStatus(String[] vmIds);
+    public Map<String, Object> getVmConfInfo(String[] vmIds);
+    public Map<String, Object> getAllVmDeviceStats();
+    public Map<String, Object> getVmGuestDetails(String[] vmIds);
+
     public Map<String, Object> migrate(Map<String, String> migrationInfo);
 
     public Map<String, Object> migrateStatus(String vmId);
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java
index 024005d..96787c9 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java
@@ -1,10 +1,10 @@
 package org.ovirt.engine.core.vdsbroker.vdsbroker;
 
 import java.lang.reflect.UndeclaredThrowableException;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Future;
 import java.util.concurrent.FutureTask;
-
 import org.apache.commons.httpclient.HttpClient;
 import org.ovirt.engine.core.compat.Guid;
 import 
org.ovirt.engine.core.vdsbroker.gluster.GlusterHookContentInfoReturnForXmlRpc;
@@ -18,6 +18,9 @@
 import org.ovirt.engine.core.vdsbroker.irsbroker.IsoListReturnForXmlRpc;
 import org.ovirt.engine.core.vdsbroker.irsbroker.OneUuidReturnForXmlRpc;
 import org.ovirt.engine.core.vdsbroker.xmlrpc.XmlRpcRunTimeException;
+
+
+import static 
org.ovirt.engine.core.vdsbroker.vdsbroker.GetAllVmRuntimeStatsVDSCommand.Hash;
 
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class VdsServerWrapper implements IVdsServer {
@@ -213,6 +216,53 @@
     }
 
     @Override
+    public AllVmRuntimeStats getAllVmRuntimeStats() {
+        try {
+            Map<String, Object> xmlRpcReturnValue = 
vdsServer.getAllVmRuntimeStats();
+            AllVmRuntimeStats wrapper = new 
AllVmRuntimeStats(xmlRpcReturnValue);
+            return wrapper;
+        } catch (UndeclaredThrowableException ute) {
+            throw new XmlRpcRunTimeException(ute);
+        }
+    }
+
+    @Override
+    public InnerVmRuntimeStats getInnerVmRuntimeStats(Hash statHash, 
List<String> vmIds) {
+        try {
+            Map<String, Object> xmlRpcReturnValue = null;
+
+            switch (statHash) {
+                case VM_STATUS:
+                    xmlRpcReturnValue = vdsServer.getVmStatus(toArray(vmIds));
+                    break;
+                case VM_CONF_INFO:
+                    xmlRpcReturnValue = 
vdsServer.getVmConfInfo(toArray(vmIds));
+                    break;
+                case DEVICE_STATS:
+                    xmlRpcReturnValue = vdsServer.getAllVmDeviceStats();
+                    break;
+                case VM_GUEST_DETAILS:
+                    xmlRpcReturnValue = 
vdsServer.getVmGuestDetails(toArray(vmIds));
+                    break;
+            }
+            InnerVmRuntimeStats wrapper = new 
InnerVmRuntimeStats(xmlRpcReturnValue, statHash.toString());
+            return wrapper;
+        } catch (UndeclaredThrowableException ute) {
+            throw new XmlRpcRunTimeException(ute);
+        }
+    }
+
+    private String[] toArray(List<String> vmIds) {
+        String[] array = new String[vmIds.size()];
+
+        for (int i = 0; i < array.length; i++) {
+            array[i] = vmIds.get(i);
+        }
+
+        return array;
+    }
+
+    @Override
     public StatusOnlyReturnForXmlRpc migrate(Map<String, String> 
migrationInfo) {
         try {
             Map<String, Object> xmlRpcReturnValue = 
vdsServer.migrate(migrationInfo);


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

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

Reply via email to