Noam Slomianko has uploaded a new change for review.

Change subject: engine : Add external scheduler integretion [WIP]
......................................................................

engine : Add external scheduler integretion [WIP]

Created ExternalSchedulerBroker interface and the corrisponding factory
and implamantation.

Still need to integrate in to the SchedulerManager flows

Change-Id: Ia81d47591c1a1bd885deea8f811b8381c1b30118
Signed-off-by: Noam Slomianko <nslom...@redhat.com>
---
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBroker.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBrokerImpl.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerFactory.java
3 files changed, 266 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/36/17536/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBroker.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBroker.java
new file mode 100644
index 0000000..f91fc43
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBroker.java
@@ -0,0 +1,21 @@
+package org.ovirt.engine.core.bll.scheduling;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.ovirt.engine.core.common.utils.Pair;
+import org.ovirt.engine.core.compat.Guid;
+
+public interface ExternalSchedulerBroker {
+    HashMap<String, List<String>> runDiscover();
+
+    List<Guid> runFilters(List<String> filterNames, List<Guid> hostIDs, Guid 
vmID, String propertiesMap);
+
+    List<Pair<Guid, Integer>> runScores(List<Pair<String, Integer>> 
scoreNameAndWeight,
+            List<Guid> hostIDs,
+            Guid vmID,
+            String propertiesMap);
+
+    Guid runBalance(String balanceName, List<Guid> hostIDs, String 
propertiesMap);
+
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBrokerImpl.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBrokerImpl.java
new file mode 100644
index 0000000..d25656e
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBrokerImpl.java
@@ -0,0 +1,232 @@
+package org.ovirt.engine.core.bll.scheduling;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.xmlrpc.client.XmlRpcClient;
+import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
+import org.ovirt.engine.core.bll.adbroker.LdapBrokerBase;
+import org.ovirt.engine.core.common.businessentities.VDS;
+import org.ovirt.engine.core.common.config.Config;
+import org.ovirt.engine.core.common.config.ConfigValues;
+import org.ovirt.engine.core.common.errors.VdcBllMessages;
+import org.ovirt.engine.core.common.utils.Pair;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+public class ExternalSchedulerBrokerImpl implements ExternalSchedulerBroker {
+
+    private static String DISCOVER = "discover";
+    private static String FILTER = "runFilters";
+    private static String SCORE = "runCostFunctions";
+    private static String BALANCE = "runLoadBalancing";
+
+    private static Object[] EMPTY = new Object[] {};
+
+    private static Log log = LogFactory.getLog(LdapBrokerBase.class);
+
+    private XmlRpcClient rpcClient = null;
+
+    public ExternalSchedulerBrokerImpl() {
+        String extSchedUrl = 
Config.GetValue(ConfigValues.ExternalSchedulerServiceURL);
+        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
+        config.setConnectionTimeout((Integer) 
Config.GetValue(ConfigValues.ExternalSchedulerConnectionTimeout));
+        try {
+            config.setServerURL(new URL(extSchedUrl));
+            XmlRpcClient client = new XmlRpcClient();
+            client.setConfig(config);
+            rpcClient = client;
+
+        } catch (IOException e) {
+            log.error("Could not communicate with the external scheduler at " 
+ extSchedUrl, e);
+        }
+    }
+
+    @Override
+    public HashMap<String, List<String>> runDiscover() {
+        try {
+            Object result = rpcClient.execute(DISCOVER, EMPTY);
+            return parseDiscoverResults(result);
+
+        } catch (XmlRpcException e) {
+            log.error("Could not communicate with the external scheduler while 
discovering" + e);
+            // TODO: decision is needed what to do here:
+            // - return all vds without filtering?
+            // - return empty vds list?
+            return null;
+        }
+    }
+
+    private HashMap<String, List<String>> parseDiscoverResults(Object result) {
+        if (result == null || !(result instanceof HashMap)) {
+            log.error("External scheduler error, malformed discover results");
+            return null;
+        }
+        HashMap<String, Object[]> castedResult = (HashMap<String, Object[]>) 
result;
+        // Its a list of host IDs
+        HashMap<String, List<String>> retValue = new HashMap<String, 
List<String>>();
+        for (String key : castedResult.keySet()) {
+            List<String> values = new LinkedList<String>();
+            for (Object o : castedResult.get(key)) {
+                values.add((String) o);
+            }
+            retValue.put(key, values);
+        }
+        return retValue;
+    }
+
+
+    @Override
+    public List<Guid> runFilters(List<String> filterNames, List<Guid> hostIDs, 
Guid vmID, String propertiesMap) {
+
+        try {
+            Object result = rpcClient.execute(FILTER, 
createFilterArgs(filterNames, hostIDs, vmID, propertiesMap));
+            return parseFilterResults(result);
+
+        } catch (XmlRpcException e) {
+            log.error("Could not communicate with the external scheduler while 
filtering " + e);
+            // TODO: decision is needed what to do here:
+            // - return all vds without filtering?
+            // - return empty vds list?
+            return null;
+        }
+    }
+
+    private Object[] createFilterArgs(List<String> filterNames, List<Guid> 
hostIDs, Guid vmID, String propertiesMap) {
+        Object[] sentObject = new Object[4];
+        // filters name
+        sentObject[0] = filterNames;
+        // hosts xml
+        sentObject[1] = hostIDs.toArray();
+        // vm xml
+        sentObject[2] = vmID;
+        // additional args
+        sentObject[3] = propertiesMap;
+        return sentObject;
+    }
+
+    private List<Guid> parseFilterResults(Object result) {
+        if (result == null || !(result instanceof Object[])) {
+            log.error("External scheduler error, malformed filter results");
+            return null;
+        }
+        // Its a list of host IDs
+        List<Guid> retValue = new LinkedList<Guid>();
+        for (Object hostID : (Object[]) result) {
+            retValue.add(new Guid(hostID.toString()));
+        }
+        return retValue;
+    }
+
+    @Override
+    public List<Pair<Guid, Integer>> runScores(List<Pair<String, Integer>> 
scoreNameAndWeight,
+            List<Guid> hostIDs,
+            Guid vmID,
+            String propertiesMap) {
+        try {
+            Object result = rpcClient.execute(SCORE, 
createScoreArgs(scoreNameAndWeight, hostIDs, vmID, propertiesMap));
+            return parseScoreResults(result);
+
+        } catch (XmlRpcException e) {
+            log.error("Could not communicate with the external scheduler while 
running score functions " + e);
+            // TODO: decision is needed what to do here:
+            // - return all vds without filtering?
+            // - return empty vds list?
+            return null;
+        }
+    }
+
+    private Object[] createScoreArgs(List<Pair<String, Integer>> 
scoreNameAndWeight,
+            List<Guid> hostIDs,
+            Guid vmID,
+            String propertiesMap) {
+        Object[] sentObject = new Object[4];
+
+        Object[] pairs = new Object[scoreNameAndWeight.size()];
+
+        for (int i = 0; i < pairs.length; i++) {
+            pairs[i] = new Object[] { scoreNameAndWeight.get(i).getFirst(), 
scoreNameAndWeight.get(i).getSecond() };
+        }
+        // score name + weight pairs
+        sentObject[0] = pairs;
+        // hosts xml
+        sentObject[1] = hostIDs.toArray();
+        // vm xml
+        sentObject[2] = vmID;
+        // additional args
+        sentObject[3] = propertiesMap;
+
+        return sentObject;
+    }
+
+    private List<Pair<Guid, Integer>> parseScoreResults(Object result) {
+        if (result == null || !(result instanceof Object[])) {
+            log.error("External scheduler error, malformed score results");
+            return null;
+        }
+        List<Pair<Guid, Integer>> retValue = new LinkedList<Pair<Guid, 
Integer>>();
+        // Its a list of (hostID,score) pairs
+        for (Object hostsIDAndScore : (Object[]) result) {
+            if (!(hostsIDAndScore instanceof Object[]) || ((Object[]) 
hostsIDAndScore).length != 2) {
+                // some kind of error
+                log.error("External scheduler error, malformed score results");
+                return null;
+            }
+            Object[] castedHostsIDAndScore = (Object[]) hostsIDAndScore;
+            Pair<Guid, Integer> pair = new Pair<Guid, Integer>();
+            pair.setFirst(new Guid(castedHostsIDAndScore[0].toString()));
+            pair.setSecond((Integer) castedHostsIDAndScore[1]);
+            retValue.add(pair);
+        }
+        return retValue;
+    }
+
+    @Override
+    public Guid runBalance(String balanceName, List<Guid> hostIDs, String 
propertiesMap) {
+        // TODO Auto-generated method stub
+        try {
+            Object result =
+                    rpcClient.execute(BALANCE, createBalanceArgs(balanceName, 
hostIDs, propertiesMap));
+            return parseBalanceResults(result);
+
+        } catch (XmlRpcException e) {
+            log.error("Could not communicate with the external scheduler while 
balancing " + e);
+            // TODO: decision is needed what to do here:
+            // - return all vds without filtering?
+            // - return empty vds list?
+            return null;
+        }
+    }
+
+    private Object[] createBalanceArgs(String balanceName, List<Guid> hostIDs, 
String propertiesMap) {
+        Object[] sentObject = new Object[3];
+        // balance name
+        sentObject[0] = balanceName;
+        // hosts xml
+        sentObject[1] = hostIDs.toArray();
+        // additional args
+        sentObject[2] = propertiesMap;
+
+        return sentObject;
+    }
+
+    private Guid parseBalanceResults(Object result) {
+        if (result == null || !(result instanceof Object[])) {
+            log.error("External scheduler error, malformed balance results");
+            return null;
+        }
+        Object[] castedResult = (Object[]) result;
+        if (castedResult.length != 1) {
+            // is it an error to get more then one vm to balance?
+            log.error("External scheduler error, malformed balance results");
+            return null;
+        }
+        return new Guid(castedResult[0].toString());
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerFactory.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerFactory.java
new file mode 100644
index 0000000..f8431ec
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerFactory.java
@@ -0,0 +1,13 @@
+package org.ovirt.engine.core.bll.scheduling;
+
+public class ExternalSchedulerFactory {
+    private static ExternalSchedulerBrokerImpl instance;
+
+    static {
+        instance = new ExternalSchedulerBrokerImpl();
+    }
+
+    public static ExternalSchedulerBroker getInstance() {
+        return instance;
+    }
+}


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

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

Reply via email to