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