package org.ovirt.engine.core.bll.scheduling.policyunits;

import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.bll.CpuFlagsManagerHandler;
import org.ovirt.engine.core.bll.scheduling.PolicyUnitImpl;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.errors.VdcBllMessages;
import org.ovirt.engine.core.common.scheduling.PolicyUnit;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class CpuLevelFilterPolicyUnit extends PolicyUnitImpl {
    public CpuLevelFilterPolicyUnit(PolicyUnit policyUnit) {
        super(policyUnit);
    }

    @Override
    public List<VDS> filter(List<VDS> hosts, VM vm, Map<String, String> parameters, List<String> messages) {
        boolean filteredOutHosts = false;
        if (StringUtils.isNotEmpty(vm.getCpuName())) {
            List<VDS> hostsToRunOn = new ArrayList<VDS>();
            for (VDS host : hosts) {
                String hostCpuName = CpuFlagsManagerHandler.FindMaxServerCpuByFlags(host.getCpuFlags(), host.getVdsGroupCompatibilityVersion()).getCpuName();
                int compareResult = CpuFlagsManagerHandler.compareCpuLevels(vm.getCpuName(), hostCpuName, vm.getVdsGroupCompatibilityVersion());
                if (compareResult <= 0) {
                    hostsToRunOn.add(host);
                    log.debugFormat("Host {0} wasn't filtered out as it has a CPU level ({1}) which is higher or equal than the CPU level the VM was run with ({2})",
                            host.getName(),
                            hostCpuName,
                            vm.getCpuName());
                } else {
                    log.debugFormat("Host {0} was filtered out as it has a CPU level ({1}) which is lower than the CPU level the VM was run with ({2})",
                            host.getName(),
                            hostCpuName,
                            vm.getCpuName());
                    filteredOutHosts = true;
                }
            }

            if (filteredOutHosts) {
                messages.add(VdcBllMessages.ACTION_TYPE_FAILED_VDS_VM_CPU_LEVEL.toString());
            }

            return hostsToRunOn;
        } else {
            return hosts;
        }
    }
}

@@ -1149,24 +1149,87 @@
 tCpuName();%0A
+                if (StringUtils.isNotEmpty(hostCpuName)) %7B%0A    
             
@@ -1357,24 +1357,28 @@
 Version());%0A
+    
             
@@ -1423,24 +1423,28 @@
             
+    
 hostsToRunOn
@@ -1451,24 +1451,28 @@
 .add(host);%0A
+    
             
@@ -1645,32 +1645,36 @@
                 
+    
 host.getName(),%0A
@@ -1693,32 +1693,36 @@
                 
+    
 hostCpuName,%0A   
@@ -1738,32 +1738,36 @@
                 
+ 
+   
 vm.getCpuName())
@@ -1776,32 +1776,36 @@
                 
+    
 %7D else %7B%0A       
@@ -1789,32 +1789,36 @@
        %7D else %7B%0A
+    
                 
@@ -1974,32 +1974,36 @@
                 
+    
 host.getName(),%0A
@@ -2022,32 +2022,36 @@
                 
+ 
+   
 hostCpuName,%0A   
@@ -2039,32 +2039,36 @@
    hostCpuName,%0A
+    
                 
@@ -2117,16 +2117,20 @@
         
+    
 filtered
@@ -2146,16 +2146,38 @@
 = true;%0A
+                    %7D%0A
         

fix a possible null dereference in CpuLevelFilterPolicyUnit