Noam Slomianko has uploaded a new change for review.

Change subject: engine: Integrate External Scheduler in to normal workflow
......................................................................

engine: Integrate External Scheduler in to normal workflow

SchedulingManager now starts a thread to call discover and update the db,
when the thread finishes he tells SchedulingManager to update his internal 
state.

Added the calls to the ExternalSchedulerBroker in the normal scheduling
workflow where appropriate.

Change-Id: Ib6788979a64fdaebb4afab5ba7ff7d6a023a5aab
Signed-off-by: Noam Slomianko <[email protected]>
---
D 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBroker.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/SchedulingManager.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBroker.java
R 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBrokerImpl.java
R 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryResult.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryThread.java
R 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryUnit.java
R 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerFactory.java
R 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulingManager.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/SchedulingManagerTest.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/scheduling/PolicyUnit.java
A packaging/dbscripts/upgrade/03_03_0680_add_enabled_column_to_policy_unit.sql
12 files changed, 369 insertions(+), 115 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/54/17654/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
deleted file mode 100644
index 97fc455..0000000
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBroker.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.ovirt.engine.core.bll.scheduling;
-
-import java.util.List;
-
-import org.ovirt.engine.core.common.utils.Pair;
-import org.ovirt.engine.core.compat.Guid;
-
-public interface ExternalSchedulerBroker {
-    ExternalSchedulerDiscoveryResult 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);
-
-    Pair<Guid, List<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/SchedulingManager.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/SchedulingManager.java
index 35f0894..445b7b9 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/SchedulingManager.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/SchedulingManager.java
@@ -13,6 +13,9 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 
+import 
org.ovirt.engine.core.bll.scheduling.external.ExternalSchedulerDiscoveryResult;
+import 
org.ovirt.engine.core.bll.scheduling.external.ExternalSchedulerDiscoveryThread;
+import org.ovirt.engine.core.bll.scheduling.external.ExternalSchedulerFactory;
 import org.ovirt.engine.core.common.businessentities.BusinessEntity;
 import org.ovirt.engine.core.common.businessentities.MigrationSupport;
 import org.ovirt.engine.core.common.businessentities.VDS;
@@ -62,7 +65,7 @@
     /**
      * <policy unit id, policy unit> map
      */
-    private final ConcurrentHashMap<Guid, PolicyUnitImpl> policyUnits;
+    private ConcurrentHashMap<Guid, PolicyUnitImpl> policyUnits;
 
     private final ConcurrentHashMap<Guid, Object> clusterLockMap = new 
ConcurrentHashMap<Guid, Object>();
 
@@ -79,6 +82,15 @@
     private void init() {
         loadPolicyUnits();
         loadClusterPolicies();
+        ExternalSchedulerDiscoveryThread discoveryThread = new 
ExternalSchedulerDiscoveryThread();
+        discoveryThread.run();
+    }
+
+    public void reloadPolicyUnits() {
+        synchronized (policyUnits) {
+            policyUnits = new ConcurrentHashMap<Guid, PolicyUnitImpl>();
+            loadPolicyUnits();
+        }
     }
 
     public List<ClusterPolicy> getClusterPolicies() {
@@ -115,7 +127,9 @@
     }
 
     public Map<Guid, PolicyUnitImpl> getPolicyUnitsMap() {
-        return policyUnits;
+        synchronized (policyUnits) {
+            return policyUnits;
+        }
     }
 
     protected void loadClusterPolicies() {
@@ -175,11 +189,6 @@
                             messages,
                             memoryChecker);
 
-            // filter the hosts through external filters as last step in 
filtering
-            vdsList =
-                    runExternalFilters(vdsList, Collections.singletonList(vm),
-                            new HashMap<String, Object>(), messages);
-
             if (vdsList == null || vdsList.size() == 0) {
                 return null;
             }
@@ -233,11 +242,6 @@
                         messages,
                         noWaitingMemoryChecker);
 
-        // after running the internal filters, run the external filters
-        vdsList =
-                runExternalFilters(vdsList, Collections.singletonList(vm), new 
HashMap<String, Object>(),
-                        messages);
-
         if (vdsList == null || vdsList.size() == 0) {
             return false;
         }
@@ -266,10 +270,6 @@
                         messages,
                         memoryChecker);
 
-        // check with the external filters
-        destVdsList =
-                runExternalFilters(vdsList, Collections.singletonList(vm), new 
HashMap<String, Object>(), messages);
-
         return destVdsList != null && destVdsList.size() == 1;
     }
 
@@ -279,37 +279,6 @@
             ids.add(entity.getId());
         }
         return ids;
-    }
-
-    protected List<VDS> runExternalFilters(List<VDS> vdsList,
-            List<VM> vmList,
-            Map<String, Object> parameters,
-            List<String> messages) {
-        List<Guid> filteredVdsIds =
-                runExternalFiltersOnIds(getEntityIds(vdsList), 
getEntityIds(vmList), parameters, messages);
-        List<VDS> filteredVds = new ArrayList<>();
-        for (VDS host : vdsList) {
-            if (filteredVdsIds.contains(host.getId())) {
-                filteredVds.add(host);
-            }
-        }
-        return filteredVds;
-    }
-
-    protected List<Guid> runExternalFiltersOnIds(List<Guid> vdsIds,
-            List<Guid> vmIds,
-            Map<String, Object> parameters,
-            List<String> messages) {
-        if (Config.GetValue(ConfigValues.ExternalSchedulerEnabled)) {
-            return getExternalSchedulingManager().runExternalFilters(vdsIds, 
vmIds, parameters, messages);
-        } else {
-            //if the external scheduler is disabled, just return the vds list 
unfiltered
-            return vdsIds;
-        }
-    }
-
-    private ExternalSchedulingManager getExternalSchedulingManager() {
-        return new ExternalSchedulingManager();
     }
 
     protected Map<String, Object> createClusterPolicyParameters(VDSGroup 
cluster, VM vm) {
@@ -341,18 +310,82 @@
             Map<String, Object> parameters,
             Map<Guid, Integer> filterPositionMap,
             List<String> messages, VdsFreeMemoryChecker memoryChecker) {
+        ArrayList<PolicyUnitImpl> internalFilters = new 
ArrayList<PolicyUnitImpl>();
+        ArrayList<PolicyUnitImpl> externalFilters = new 
ArrayList<PolicyUnitImpl>();
+        sortFilters(filters, filterPositionMap);
         if (filters != null) {
-            sortFilters(filters, filterPositionMap);
             for (Guid filter : filters) {
+                PolicyUnitImpl filterPolicyUnit = policyUnits.get(filter);
+                if (filterPolicyUnit.isInternal()){
+                    internalFilters.add(filterPolicyUnit);
+                } else {
+                    if (filterPolicyUnit.isEnabled()) {
+                        externalFilters.add(filterPolicyUnit);
+                    }
+                }
+            }
+        }
+        
+        hostList =
+                runInternalFilters(internalFilters, hostList, parameters, 
filterPositionMap, messages, memoryChecker);
+        
+        if (Config.GetValue(ConfigValues.ExternalSchedulerEnabled)){
+            hostList = runExternalFilters(externalFilters, hostList, 
parameters, messages);
+        }
+        
+        return hostList;
+    }
+
+    private List<VDS> runInternalFilters(ArrayList<PolicyUnitImpl> filters,
+            List<VDS> hostList,
+            Map<String, Object> parameters,
+            Map<Guid, Integer> filterPositionMap,
+            List<String> messages, VdsFreeMemoryChecker memoryChecker) {
+        if (filters != null) {
+            for (PolicyUnitImpl filterPolicyUnit : filters) {
                 if (hostList == null || hostList.isEmpty()) {
                     break;
                 }
-                PolicyUnitImpl filterPolicyUnit = policyUnits.get(filter);
                 filterPolicyUnit.setMemoryChecker(memoryChecker);
                 hostList = filterPolicyUnit.filter(hostList, parameters, 
messages);
             }
         }
         return hostList;
+    }
+
+    private List<VDS> runExternalFilters(ArrayList<PolicyUnitImpl> filters,
+            List<VDS> hostList,
+            Map<String, Object> parameters,
+            List<String> messages) {
+        List<Guid> filteredIDs = null;
+        if (filters != null) {
+            VM vm = (VM) parameters.get(PolicyUnitImpl.VM);
+            List<String> filterNames = new ArrayList<String>();
+            for (PolicyUnitImpl filter : filters) {
+                filterNames.add(filter.getName());
+            }
+            List<Guid> hostIDs = new ArrayList<Guid>();
+            for (VDS host : hostList) {
+                hostIDs.add(host.getId());
+            }
+            filteredIDs =
+                    
ExternalSchedulerFactory.getInstance().runFilters(filterNames, hostIDs, 
vm.getId(), parameters);
+        }
+
+        return intersectHosts(hostList, filteredIDs);
+    }
+    
+    private List<VDS> intersectHosts(List<VDS> hosts, List<Guid> IDs) {
+        if (IDs == null) {
+            return hosts;
+        }
+        List<VDS> retList = new ArrayList<VDS>();
+        for (VDS vds : hosts) {
+            if (IDs.contains(vds.getId())) {
+                retList.add(vds);
+            }
+        }
+        return retList;
     }
 
     private void sortFilters(ArrayList<Guid> filters, final Map<Guid, Integer> 
filterPositionMap) {
@@ -379,17 +412,26 @@
     protected Guid runFunctions(ArrayList<Pair<Guid, Integer>> functions,
             List<VDS> hostList,
             Map<String, Object> parameters) {
-        Map<Guid, Integer> hostCostTable = new HashMap<Guid, Integer>();
+        ArrayList<Pair<PolicyUnitImpl, Integer>> internalScoreFunctions =
+                new ArrayList<Pair<PolicyUnitImpl, Integer>>();
+        ArrayList<Pair<PolicyUnitImpl, Integer>> externalScoreFunctions =
+                new ArrayList<Pair<PolicyUnitImpl, Integer>>();
+        
         for (Pair<Guid, Integer> pair : functions) {
-            List<Pair<Guid, Integer>> scoreResult = 
policyUnits.get(pair.getFirst()).score(hostList, parameters);
-            for (Pair<Guid, Integer> result : scoreResult) {
-                Guid hostId = result.getFirst();
-                if (hostCostTable.get(hostId) == null) {
-                    hostCostTable.put(hostId, 0);
+            PolicyUnitImpl currentPolicy = policyUnits.get(pair.getFirst());
+            if(currentPolicy.isInternal()){
+                internalScoreFunctions.add(new Pair<PolicyUnitImpl, 
Integer>(currentPolicy, pair.getSecond()));
+            } else {
+                if (currentPolicy.isEnabled()) {
+                    externalScoreFunctions.add(new Pair<PolicyUnitImpl, 
Integer>(currentPolicy, pair.getSecond()));
                 }
-                hostCostTable.put(hostId,
-                        hostCostTable.get(hostId) + pair.getSecond() * 
result.getSecond());
             }
+        }
+
+        Map<Guid, Integer> hostCostTable = 
runInternalFunctions(internalScoreFunctions, hostList, parameters);
+
+        if (Config.GetValue(ConfigValues.ExternalSchedulerEnabled)) {
+            runExternalFunctions(externalScoreFunctions, hostList, parameters, 
hostCostTable);
         }
         Entry<Guid, Integer> bestHostEntry = null;
         for (Entry<Guid, Integer> entry : hostCostTable.entrySet()) {
@@ -401,6 +443,57 @@
             return null;
         }
         return bestHostEntry.getKey();
+    }
+
+    private Map<Guid, Integer> 
runInternalFunctions(ArrayList<Pair<PolicyUnitImpl, Integer>> functions,
+            List<VDS> hostList,
+            Map<String, Object> parameters) {
+        Map<Guid, Integer> hostCostTable = new HashMap<Guid, Integer>();
+        for (Pair<PolicyUnitImpl, Integer> pair : functions) {
+            List<Pair<Guid, Integer>> scoreResult = 
pair.getFirst().score(hostList, parameters);
+            for (Pair<Guid, Integer> result : scoreResult) {
+                Guid hostId = result.getFirst();
+                if (hostCostTable.get(hostId) == null) {
+                    hostCostTable.put(hostId, 0);
+                }
+                hostCostTable.put(hostId,
+                        hostCostTable.get(hostId) + pair.getSecond() * 
result.getSecond());
+            }
+        }
+        return hostCostTable;
+    }
+
+    private void runExternalFunctions(ArrayList<Pair<PolicyUnitImpl, Integer>> 
functions,
+            List<VDS> hostList,
+            Map<String, Object> parameters,
+            Map<Guid, Integer> hostCostTable) {
+        List<Pair<String, Integer>> scoreNameAndWeight = new 
ArrayList<Pair<String, Integer>>();
+        for (Pair<PolicyUnitImpl, Integer> pair : functions) {
+            scoreNameAndWeight.add(new Pair<String, 
Integer>(pair.getFirst().getName(), pair.getSecond()));
+        }
+
+        List<Guid> hostIDs = new ArrayList<Guid>();
+        for (VDS vds : hostList) {
+            hostIDs.add(vds.getId());
+        }
+        VM vm = (VM) parameters.get(PolicyUnitImpl.VM);
+        List<Pair<Guid, Integer>> externalScores =
+                
ExternalSchedulerFactory.getInstance().runScores(scoreNameAndWeight,
+                        hostIDs,
+                        vm.getId(),
+                        parameters);
+        sumScoreResults(hostCostTable, externalScores);
+    }
+
+    private void sumScoreResults(Map<Guid, Integer> hostCostTable, 
List<Pair<Guid, Integer>> externalScores) {
+        for (Pair<Guid, Integer> pair : externalScores) {
+            Guid hostId = pair.getFirst();
+            if (hostCostTable.get(hostId) == null) {
+                hostCostTable.put(hostId, 0);
+            }
+            hostCostTable.put(hostId,
+                    hostCostTable.get(hostId) + pair.getSecond());
+        }
     }
 
     public Map<String, String> getCustomPropertiesRegexMap(ClusterPolicy 
clusterPolicy) {
@@ -479,16 +572,40 @@
         for (VDSGroup cluster : clusters) {
             ClusterPolicy policy = policyMap.get(cluster.getClusterPolicyId());
             PolicyUnitImpl policyUnit = policyUnits.get(policy.getBalance());
-            List<VDS> hosts = getVdsDAO()
-                    .getAllOfTypes(new VDSType[] { VDSType.VDS, 
VDSType.oVirtNode });
-            Pair<List<Guid>, Guid> pair = policyUnit.balance(cluster,
-                    hosts,
-                    cluster.getClusterPolicyProperties(),
-                    new ArrayList<String>());
-            if (pair != null && pair.getSecond() != null) {
-                migrationHandler.migrateVM((ArrayList<Guid>) pair.getFirst(), 
pair.getSecond());
+            Pair<List<Guid>, Guid> balanceResult = null;
+            if (policyUnit.isInternal()){
+                balanceResult = internalRunBalance(policyUnit, cluster);
+            } else if (Config.GetValue(ConfigValues.ExternalSchedulerEnabled)) 
{
+                if (policyUnit.isEnabled()) {
+                    balanceResult = externalRunBalance(policyUnit, cluster);
+                }
+            }
+            
+            if (balanceResult != null && balanceResult.getSecond() != null) {
+                migrationHandler.migrateVM((ArrayList<Guid>) 
balanceResult.getFirst(), balanceResult.getSecond());
             }
         }
     }
 
+    private Pair<List<Guid>, Guid> internalRunBalance(PolicyUnitImpl 
policyUnit, VDSGroup cluster) {
+        List<VDS> hosts = getVdsDAO()
+                .getAllOfTypes(new VDSType[] { VDSType.VDS, VDSType.oVirtNode 
});
+        return policyUnit.balance(cluster,
+                hosts,
+                cluster.getClusterPolicyProperties(),
+                new ArrayList<String>());
+        
+    }
+    
+    private Pair<List<Guid>, Guid> externalRunBalance(PolicyUnitImpl 
policyUnit, VDSGroup cluster){
+        List<VDS> hosts = getVdsDAO()
+                .getAllOfTypes(new VDSType[] { VDSType.VDS, VDSType.oVirtNode 
});
+        List<Guid> hostIDs = new ArrayList<Guid>();
+        for (VDS vds : hosts) {
+            hostIDs.add(vds.getId());
+        }
+        return ExternalSchedulerFactory.getInstance()
+                .runBalance(policyUnit.getName(), hostIDs, 
cluster.getClusterPolicyProperties());
+    }
+
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBroker.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBroker.java
new file mode 100644
index 0000000..246b4f5
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBroker.java
@@ -0,0 +1,21 @@
+package org.ovirt.engine.core.bll.scheduling.external;
+
+import java.util.List;
+import java.util.Map;
+
+import org.ovirt.engine.core.common.utils.Pair;
+import org.ovirt.engine.core.compat.Guid;
+
+public interface ExternalSchedulerBroker {
+    ExternalSchedulerDiscoveryResult runDiscover();
+
+    List<Guid> runFilters(List<String> filterNames, List<Guid> hostIDs, Guid 
vmID, Map<String, Object> propertiesMap);
+
+    List<Pair<Guid, Integer>> runScores(List<Pair<String, Integer>> 
scoreNameAndWeight,
+            List<Guid> hostIDs,
+            Guid vmID,
+            Map<String, Object> propertiesMap);
+
+    Pair<List<Guid>, Guid> runBalance(String balanceName, List<Guid> hostIDs, 
Map<String, 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/external/ExternalSchedulerBrokerImpl.java
similarity index 78%
rename from 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerBrokerImpl.java
rename to 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBrokerImpl.java
index 78cf7b4..23ad9c6 100644
--- 
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/external/ExternalSchedulerBrokerImpl.java
@@ -1,15 +1,15 @@
-package org.ovirt.engine.core.bll.scheduling;
+package org.ovirt.engine.core.bll.scheduling.external;
 
 import java.io.IOException;
+import java.net.MalformedURLException;
 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.config.Config;
 import org.ovirt.engine.core.common.config.ConfigValues;
 import org.ovirt.engine.core.common.utils.Pair;
@@ -28,27 +28,25 @@
 
     private static Log log = 
LogFactory.getLog(ExternalSchedulerBrokerImpl.class);
 
-    private XmlRpcClient rpcClient = null;
+    private XmlRpcClientConfigImpl config = null;
 
     public ExternalSchedulerBrokerImpl() {
         String extSchedUrl = 
Config.GetValue(ConfigValues.ExternalSchedulerServiceURL);
-        XmlRpcClientConfigImpl config = new 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);
+        } catch (MalformedURLException e) {
+            log.error("External scheduler got bad url", e);
         }
     }
 
     @Override
     public ExternalSchedulerDiscoveryResult runDiscover() {
         try {
-            Object result = rpcClient.execute(DISCOVER, EMPTY);
+            XmlRpcClient client = new XmlRpcClient();
+            client.setConfig(config);
+            Object result = client.execute(DISCOVER, EMPTY);
             return parseDiscoverResults(result);
 
         } catch (XmlRpcException e) {
@@ -70,10 +68,15 @@
 
 
     @Override
-    public List<Guid> runFilters(List<String> filterNames, List<Guid> hostIDs, 
Guid vmID, String propertiesMap) {
+    public List<Guid> runFilters(List<String> filterNames,
+            List<Guid> hostIDs,
+            Guid vmID,
+            Map<String, Object> propertiesMap) {
 
         try {
-            Object result = rpcClient.execute(FILTER, 
createFilterArgs(filterNames, hostIDs, vmID, propertiesMap));
+            XmlRpcClient client = new XmlRpcClient();
+            client.setConfig(config);
+            Object result = client.execute(FILTER, 
createFilterArgs(filterNames, hostIDs, vmID, propertiesMap));
             return parseFilterResults(result);
 
         } catch (XmlRpcException e) {
@@ -85,7 +88,10 @@
         }
     }
 
-    private Object[] createFilterArgs(List<String> filterNames, List<Guid> 
hostIDs, Guid vmID, String propertiesMap) {
+    private Object[] createFilterArgs(List<String> filterNames,
+            List<Guid> hostIDs,
+            Guid vmID,
+            Map<String, Object> propertiesMap) {
         Object[] sentObject = new Object[4];
         // filters name
         sentObject[0] = filterNames;
@@ -115,9 +121,11 @@
     public List<Pair<Guid, Integer>> runScores(List<Pair<String, Integer>> 
scoreNameAndWeight,
             List<Guid> hostIDs,
             Guid vmID,
-            String propertiesMap) {
+            Map<String, Object> propertiesMap) {
         try {
-            Object result = rpcClient.execute(SCORE, 
createScoreArgs(scoreNameAndWeight, hostIDs, vmID, propertiesMap));
+            XmlRpcClient client = new XmlRpcClient();
+            client.setConfig(config);
+            Object result = client.execute(SCORE, 
createScoreArgs(scoreNameAndWeight, hostIDs, vmID, propertiesMap));
             return parseScoreResults(result);
 
         } catch (XmlRpcException e) {
@@ -132,7 +140,7 @@
     private Object[] createScoreArgs(List<Pair<String, Integer>> 
scoreNameAndWeight,
             List<Guid> hostIDs,
             Guid vmID,
-            String propertiesMap) {
+            Map<String, Object> propertiesMap) {
         Object[] sentObject = new Object[4];
 
         Object[] pairs = new Object[scoreNameAndWeight.size()];
@@ -175,11 +183,13 @@
     }
 
     @Override
-    public Pair<Guid, List<Guid>> runBalance(String balanceName, List<Guid> 
hostIDs, String propertiesMap) {
+    public Pair<List<Guid>, Guid> runBalance(String balanceName, List<Guid> 
hostIDs, Map<String, String> propertiesMap) {
         // TODO Auto-generated method stub
         try {
+            XmlRpcClient client = new XmlRpcClient();
+            client.setConfig(config);
             Object result =
-                    rpcClient.execute(BALANCE, createBalanceArgs(balanceName, 
hostIDs, propertiesMap));
+                    client.execute(BALANCE, createBalanceArgs(balanceName, 
hostIDs, propertiesMap));
             return parseBalanceResults(result);
 
         } catch (XmlRpcException e) {
@@ -191,7 +201,7 @@
         }
     }
 
-    private Object[] createBalanceArgs(String balanceName, List<Guid> hostIDs, 
String propertiesMap) {
+    private Object[] createBalanceArgs(String balanceName, List<Guid> hostIDs, 
Map<String, String> propertiesMap) {
         Object[] sentObject = new Object[3];
         // balance name
         sentObject[0] = balanceName;
@@ -203,7 +213,7 @@
         return sentObject;
     }
 
-    private Pair<Guid, List<Guid>> parseBalanceResults(Object result) {
+    private Pair<List<Guid>, Guid> parseBalanceResults(Object result) {
         if (result == null || !(result instanceof Object[])) {
             log.error("External scheduler error, malformed balance results");
             return null;
@@ -214,9 +224,9 @@
         for (Object hostID : (Object[]) castedResult[1]) {
             hostIDs.add(new Guid(hostID.toString()));
         }
-        Pair<Guid, List<Guid>> retValue = new Pair<Guid, List<Guid>>();
-        retValue.setFirst(new Guid(castedResult[0].toString()));
-        retValue.setSecond(hostIDs);
+        Pair<List<Guid>, Guid> retValue = new Pair<List<Guid>, Guid>();
+        retValue.setFirst(hostIDs);
+        retValue.setSecond(new Guid(castedResult[0].toString()));
 
         return retValue;
     }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerDiscoveryResult.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryResult.java
similarity index 98%
rename from 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerDiscoveryResult.java
rename to 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryResult.java
index aa653d4..108b7f6 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerDiscoveryResult.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryResult.java
@@ -1,4 +1,4 @@
-package org.ovirt.engine.core.bll.scheduling;
+package org.ovirt.engine.core.bll.scheduling.external;
 
 import java.util.HashMap;
 import java.util.LinkedList;
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryThread.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryThread.java
new file mode 100644
index 0000000..78f13d9
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryThread.java
@@ -0,0 +1,109 @@
+package org.ovirt.engine.core.bll.scheduling.external;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.ovirt.engine.core.bll.scheduling.SchedulingManager;
+import org.ovirt.engine.core.common.scheduling.PolicyUnit;
+import org.ovirt.engine.core.common.scheduling.PolicyUnitType;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.utils.customprop.SimpleCustomPropertiesUtil;
+
+public class ExternalSchedulerDiscoveryThread extends Thread {
+
+    @Override
+    public void run() {
+        ExternalSchedulerDiscoveryResult discoveryResult = 
ExternalSchedulerFactory.getInstance().runDiscover();
+        if (discoveryResult != null) {
+            updateDB(discoveryResult);
+        }
+    }
+
+    private void updateDB(ExternalSchedulerDiscoveryResult discoveryResult) {
+        List<PolicyUnit> allPolicyUnits = 
DbFacade.getInstance().getPolicyUnitDao().getAll();
+        List<PolicyUnit> foundInBoth = new LinkedList<PolicyUnit>();
+        for (ExternalSchedulerDiscoveryUnit unit : 
discoveryResult.getFilters()) {
+            PolicyUnit found = compareToDB(allPolicyUnits, unit, 
PolicyUnitType.Filter);
+            if (found != null) {
+                foundInBoth.add(found);
+            }
+        }
+        for (ExternalSchedulerDiscoveryUnit unit : 
discoveryResult.getScores()) {
+            PolicyUnit found = compareToDB(allPolicyUnits, unit, 
PolicyUnitType.Weight);
+            if (found != null) {
+                foundInBoth.add(found);
+            }
+        }
+        for (ExternalSchedulerDiscoveryUnit unit : 
discoveryResult.getBalance()) {
+            PolicyUnit found = compareToDB(allPolicyUnits, unit, 
PolicyUnitType.LoadBalancing);
+            if (found != null) {
+                foundInBoth.add(found);
+            }
+        }
+
+
+        allPolicyUnits.removeAll(foundInBoth);
+        // found in the db but not found in discovery, mark as such
+        markExternalPoliciesAsDisabled(allPolicyUnits);
+
+        SchedulingManager.getInstance().reloadPolicyUnits();
+    }
+
+    private void markExternalPoliciesAsDisabled(List<PolicyUnit> units) {
+        for (PolicyUnit policyUnit : units) {
+            if (!policyUnit.isInternal()) {
+                policyUnit.setEnabled(false);
+                DbFacade.getInstance().getPolicyUnitDao().update(policyUnit);
+            }
+        }
+    }
+
+    private PolicyUnit compareToDB(List<PolicyUnit> dbEnteries,
+            ExternalSchedulerDiscoveryUnit discoveryUnit,
+            PolicyUnitType type) {
+        for (PolicyUnit policyUnit : dbEnteries) {
+            if (policyUnit.isInternal()) {
+                continue;
+            }
+
+            if (policyUnit.getPolicyUnitType() != type) {
+                continue;
+            }
+
+            if (!policyUnit.getName().equals(discoveryUnit.getName())) {
+                continue;
+            }
+
+            if 
(!policyUnit.getParameterRegExMap().equals(SimpleCustomPropertiesUtil.getInstance()
+                    .convertProperties(discoveryUnit.getRegex()))) {
+                sendToDb(discoveryUnit, true, type);
+            }
+
+            // TODO: when policy unit description is merged, compare it as well
+
+            return policyUnit;
+
+        }
+        sendToDb(discoveryUnit, false, type);
+        return null;
+    }
+
+    private void sendToDb(ExternalSchedulerDiscoveryUnit discovery, boolean 
isUpdate, PolicyUnitType type) {
+        PolicyUnit policy = createFromDiscoveryUnit(discovery, type);
+        if (isUpdate) {
+            DbFacade.getInstance().getPolicyUnitDao().update(policy);
+        } else {
+            DbFacade.getInstance().getPolicyUnitDao().save(policy);
+        }
+    }
+
+    private PolicyUnit createFromDiscoveryUnit(ExternalSchedulerDiscoveryUnit 
discoveryUnit, PolicyUnitType type) {
+        PolicyUnit policy = new PolicyUnit();
+        policy.setName(discoveryUnit.getName());
+        policy.setPolicyUnitType(type);
+        policy.setParameterRegExMap(SimpleCustomPropertiesUtil.getInstance()
+                .convertProperties(discoveryUnit.getRegex()));
+        // TODO: when policy unit description is merged, set it
+        return policy;
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerDiscoveryUnit.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryUnit.java
similarity index 89%
rename from 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerDiscoveryUnit.java
rename to 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryUnit.java
index aa4eaa0..8fcaa3b 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerDiscoveryUnit.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerDiscoveryUnit.java
@@ -1,4 +1,4 @@
-package org.ovirt.engine.core.bll.scheduling;
+package org.ovirt.engine.core.bll.scheduling.external;
 
 public class ExternalSchedulerDiscoveryUnit{
     private String name;
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/external/ExternalSchedulerFactory.java
similarity index 80%
rename from 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulerFactory.java
rename to 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerFactory.java
index 45f79cc..182cde2 100644
--- 
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/external/ExternalSchedulerFactory.java
@@ -1,4 +1,4 @@
-package org.ovirt.engine.core.bll.scheduling;
+package org.ovirt.engine.core.bll.scheduling.external;
 
 public class ExternalSchedulerFactory {
     private final static ExternalSchedulerBrokerImpl instance = new 
ExternalSchedulerBrokerImpl();
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulingManager.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulingManager.java
similarity index 97%
rename from 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulingManager.java
rename to 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulingManager.java
index 77813c7..a64239e 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/ExternalSchedulingManager.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulingManager.java
@@ -1,4 +1,4 @@
-package org.ovirt.engine.core.bll.scheduling;
+package org.ovirt.engine.core.bll.scheduling.external;
 
 import java.io.IOException;
 import java.net.URL;
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/SchedulingManagerTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/SchedulingManagerTest.java
index 6ac1239..e4face4 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/SchedulingManagerTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/scheduling/SchedulingManagerTest.java
@@ -6,6 +6,7 @@
 import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.Mockito;
+import org.ovirt.engine.core.bll.scheduling.external.ExternalSchedulingManager;
 import org.ovirt.engine.core.common.businessentities.BusinessEntity;
 import org.ovirt.engine.core.common.businessentities.VDSGroup;
 import org.ovirt.engine.core.common.businessentities.VM;
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/scheduling/PolicyUnit.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/scheduling/PolicyUnit.java
index f3d8ca8..ec2a824 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/scheduling/PolicyUnit.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/scheduling/PolicyUnit.java
@@ -33,6 +33,10 @@
      * policy unit acceptable custom parameters; format <parameterName, regex>
      */
     private Map<String, String> parameterRegExMap;
+    /**
+     * If not internal, is it currently reachable
+     */
+    private boolean enabled = true;
 
     @Override
     public Object getQueryableId() {
@@ -81,6 +85,14 @@
         this.parameterRegExMap = parameterRegExMap;
     }
 
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;
@@ -88,6 +100,7 @@
         result = prime * result + ((policyUnitType == null) ? 0 : 
policyUnitType.hashCode());
         result = prime * result + ((id == null) ? 0 : id.hashCode());
         result = prime * result + (internal ? 1231 : 1237);
+        result = prime * result + (enabled ? 1231 : 1237);
         result = prime * result + ((name == null) ? 0 : name.hashCode());
         result = prime * result + ((parameterRegExMap == null) ? 0 : 
parameterRegExMap.hashCode());
         return result;
@@ -121,7 +134,9 @@
             return false;
         if (policyUnitType != other.policyUnitType)
             return false;
+        if (enabled != other.enabled) {
+            return false;
+        }
         return true;
     }
-
 }
diff --git 
a/packaging/dbscripts/upgrade/03_03_0680_add_enabled_column_to_policy_unit.sql 
b/packaging/dbscripts/upgrade/03_03_0680_add_enabled_column_to_policy_unit.sql
new file mode 100644
index 0000000..faf31fe
--- /dev/null
+++ 
b/packaging/dbscripts/upgrade/03_03_0680_add_enabled_column_to_policy_unit.sql
@@ -0,0 +1 @@
+SELECT fn_db_add_column('policy_units', 'enabled', 'boolean');


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

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

Reply via email to