You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by bu...@apache.org on 2019/07/29 21:33:31 UTC

svn commit: r1863971 - in /uima/uima-ducc/trunk: uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/ uima-ducc-orchestrator/src/main/java/org/apache/uima/ducc/orchestrator/ uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/

Author: burn
Date: Mon Jul 29 21:33:30 2019
New Revision: 1863971

URL: http://svn.apache.org/viewvc?rev=1863971&view=rev
Log:
UIMA-6099 Move all scheduling_class checks from CLI to OR & SM

Modified:
    uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobSubmit.java
    uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationSubmit.java
    uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationSubmit.java
    uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java
    uima/uima-ducc/trunk/uima-ducc-orchestrator/src/main/java/org/apache/uima/ducc/orchestrator/Validate.java
    uima/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java
    uima/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java

Modified: uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobSubmit.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobSubmit.java?rev=1863971&r1=1863970&r2=1863971&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobSubmit.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobSubmit.java Mon Jul 29 21:33:30 2019
@@ -29,8 +29,6 @@ import java.util.Properties;
 
 import org.apache.uima.ducc.cli.aio.AllInOneLauncher;
 import org.apache.uima.ducc.common.exception.DuccRuntimeException;
-import org.apache.uima.ducc.common.utils.DuccSchedulerClasses;
-import org.apache.uima.ducc.common.utils.IllegalConfigurationException;
 import org.apache.uima.ducc.common.utils.Utils;
 import org.apache.uima.ducc.transport.event.IDuccContext.DuccContext;
 import org.apache.uima.ducc.transport.event.SubmitJobDuccEvent;
@@ -229,37 +227,8 @@ public class DuccJobSubmit
 			
 		}
     }
-    /*
-     * If preemptable change to a non-preemptable scheduling class.
-     * If none provided use the default fixed class
-     */
-    protected void transform_scheduling_class(CliBase base, Properties props)
-            throws Exception
-    {
-    	 String scheduling_class = null;
-         String user_scheduling_class = null;
-         String pname = UiOption.SchedulingClass.pname();
-        try {
-            DuccSchedulerClasses duccSchedulerClasses = DuccSchedulerClasses.getInstance();
-            if (props.containsKey(pname)) {
-                user_scheduling_class = props.getProperty(pname);
-                if (duccSchedulerClasses.isPreemptable(user_scheduling_class)) {
-                    scheduling_class = duccSchedulerClasses.getDebugClassSpecificName(user_scheduling_class);
-                }
-            } else {
-                scheduling_class = duccSchedulerClasses.getDebugClassDefaultName();
-            }
-        } catch (Exception e) {
-            throw new IllegalConfigurationException("Error in DUCC configuration files - see administrator", e);
-        }
-         if (scheduling_class != null) {
-              props.setProperty(pname, scheduling_class);
-              String text = pname+"="+scheduling_class+" -- was "+user_scheduling_class;
-              base.message(text);
-         }
-    }
 
-    private void check_descriptor_options() {
+  private void check_descriptor_options() {
 		boolean isDDjob = jobRequestProperties.containsKey(UiOption.ProcessDD.pname());
 		boolean isPPjob = jobRequestProperties.containsKey(UiOption.ProcessDescriptorCM.pname())
 				|| jobRequestProperties.containsKey(UiOption.ProcessDescriptorAE.pname())
@@ -305,8 +274,7 @@ public class DuccJobSubmit
                 props.setProperty(UiOption.ProcessDeploymentsMax.pname(), "1");
                 props.setProperty(UiOption.ProcessFailuresLimit.pname(), "1");
 
-                // Alter scheduling class?
-                transform_scheduling_class(this, props);
+                // Scheduling class now checked in OR's Validate
             }
 
             do_debug = UiOption.DriverDebug.pname();

Modified: uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationSubmit.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationSubmit.java?rev=1863971&r1=1863970&r2=1863971&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationSubmit.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationSubmit.java Mon Jul 29 21:33:30 2019
@@ -22,8 +22,6 @@ import java.util.ArrayList;
 import java.util.Map.Entry;
 import java.util.Properties;
 
-import org.apache.uima.ducc.common.utils.DuccSchedulerClasses;
-import org.apache.uima.ducc.common.utils.IllegalConfigurationException;
 import org.apache.uima.ducc.transport.event.IDuccContext.DuccContext;
 import org.apache.uima.ducc.transport.event.SubmitServiceDuccEvent;
 import org.apache.uima.ducc.transport.event.SubmitServiceReplyDuccEvent;
@@ -154,25 +152,6 @@ public class DuccManagedReservationSubmi
      */
     public boolean execute() throws Exception
     {
-        // If the specified scheduling class is pre-emptable, change to a fixed one if possible
-        String pname = UiOption.SchedulingClass.pname();
-        String scheduling_class = serviceRequestProperties.getProperty(pname);
-        if (scheduling_class != null) {
-            try {
-                DuccSchedulerClasses duccSchedulerClasses = DuccSchedulerClasses.getInstance();
-                if (duccSchedulerClasses.isPreemptable(scheduling_class)) {
-                    String np_scheduling_class = duccSchedulerClasses.getDebugClassSpecificName(scheduling_class);
-                    if (np_scheduling_class != null) {
-                        serviceRequestProperties.setProperty(pname, np_scheduling_class);
-                        String msg = "Changed the scheduling_class from " + scheduling_class + " to the non-preemptable " + np_scheduling_class;
-                        message(msg);
-                    }
-                }
-            } catch (Exception e) {
-                throw new IllegalConfigurationException("Error in DUCC configuration files - see administrator", e);
-            }
-        }
-
         // Could omit this if not a java process
         check_heap_size(UiOption.ProcessExecutableArgs.pname());
 

Modified: uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationSubmit.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationSubmit.java?rev=1863971&r1=1863970&r2=1863971&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationSubmit.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationSubmit.java Mon Jul 29 21:33:30 2019
@@ -19,11 +19,8 @@
 package org.apache.uima.ducc.cli;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Properties;
 
-import org.apache.uima.ducc.common.utils.DuccSchedulerClasses;
-import org.apache.uima.ducc.common.utils.IllegalConfigurationException;
 import org.apache.uima.ducc.transport.event.IDuccContext.DuccContext;
 import org.apache.uima.ducc.transport.event.SubmitReservationDuccEvent;
 import org.apache.uima.ducc.transport.event.SubmitReservationReplyDuccEvent;
@@ -101,19 +98,8 @@ public class DuccReservationSubmit
      */
 	public boolean execute() throws Exception
     {		
-        String pname = UiOption.SchedulingClass.pname();
-        String scheduling_class = requestProperties.getProperty(pname);
-        if (scheduling_class != null) {
-            String[] reserveClasses;
-            try {
-                reserveClasses = DuccSchedulerClasses.getInstance().getReserveClasses();
-            } catch (Exception e) {
-                throw new IllegalConfigurationException("Error in DUCC configuration files - see administrator", e);
-            }
-            if (!Arrays.asList(reserveClasses).contains(scheduling_class)) {
-                throw new IllegalArgumentException("Invalid value for scheduling_class - must be one of the reserve classes");
-            }
-        }
+	      // Scheduling class is now checked in OR
+	  
         SubmitReservationDuccEvent      ev    = new SubmitReservationDuccEvent(requestProperties, CliVersion.getVersion());
         SubmitReservationReplyDuccEvent reply = null;
         

Modified: uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java?rev=1863971&r1=1863970&r2=1863971&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java Mon Jul 29 21:33:30 2019
@@ -24,8 +24,6 @@ import java.util.List;
 import org.apache.uima.ducc.common.Pair;
 import org.apache.uima.ducc.common.utils.DuccProperties;
 import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
-import org.apache.uima.ducc.common.utils.DuccSchedulerClasses;
-import org.apache.uima.ducc.common.utils.IllegalConfigurationException;
 import org.apache.uima.ducc.transport.event.ServiceDisableEvent;
 import org.apache.uima.ducc.transport.event.ServiceEnableEvent;
 import org.apache.uima.ducc.transport.event.ServiceIgnoreEvent;
@@ -443,29 +441,10 @@ public class DuccServiceApi
 
             check_heap_size(UiOption.ProcessExecutableArgs.pname());
 
-        } else {
+         } else {
             throw new IllegalArgumentException("Invalid service endpoint: " + endpoint);
         }
 
-        // Check if falsely using a fair-share class; set the default if missing
-        String scheduling_class = cli_props.getProperty(UiOption.SchedulingClass.pname());
-        boolean isPreemptableClass = false;
-        try {
-            DuccSchedulerClasses duccSchedulerClasses = DuccSchedulerClasses.getInstance();
-            if (scheduling_class != null) {
-                isPreemptableClass = duccSchedulerClasses.isPreemptable(scheduling_class);
-            } else {
-                cli_props.setProperty(UiOption.SchedulingClass.pname(), duccSchedulerClasses.getDebugClassDefaultName());
-            }
-        } catch (IllegalArgumentException e) {
-          throw e;    // Unknown scheduling class
-        } catch (Exception e) {
-            throw new IllegalConfigurationException("Error in DUCC configuration files - see administrator", e);
-        }
-        if (isPreemptableClass) {
-            throw new IllegalArgumentException("Invalid pre-emptable scheduling class: " + scheduling_class);
-        }
-
         // work out stuff I'm dependent upon
         if ( !check_service_dependencies(endpoint) ) {
             throw new IllegalArgumentException("Invalid service dependencies");

Modified: uima/uima-ducc/trunk/uima-ducc-orchestrator/src/main/java/org/apache/uima/ducc/orchestrator/Validate.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-orchestrator/src/main/java/org/apache/uima/ducc/orchestrator/Validate.java?rev=1863971&r1=1863970&r2=1863971&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-orchestrator/src/main/java/org/apache/uima/ducc/orchestrator/Validate.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-orchestrator/src/main/java/org/apache/uima/ducc/orchestrator/Validate.java Mon Jul 29 21:33:30 2019
@@ -19,10 +19,10 @@
 package org.apache.uima.ducc.orchestrator;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Properties;
 
 import org.apache.uima.ducc.common.utils.DuccLogger;
-import org.apache.uima.ducc.common.utils.DuccProperties;
 import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
 import org.apache.uima.ducc.common.utils.DuccSchedulerClasses;
 import org.apache.uima.ducc.orchestrator.authentication.DuccWebAdministrators;
@@ -38,7 +38,7 @@ import org.apache.uima.ducc.transport.ev
 import org.apache.uima.ducc.transport.event.cli.JobRequestProperties;
 import org.apache.uima.ducc.transport.event.cli.JobSpecificationProperties;
 import org.apache.uima.ducc.transport.event.cli.ReservationRequestProperties;
-import org.apache.uima.ducc.transport.event.cli.ServiceRequestProperties;
+import org.apache.uima.ducc.transport.event.cli.SpecificationProperties;
 import org.apache.uima.ducc.transport.event.common.DuccWorkReservation;
 import org.apache.uima.ducc.transport.event.common.IDuccSchedulingInfo;
 
@@ -111,34 +111,17 @@ public class Validate {
 			return false;
 		}	
 		JobRequestProperties properties = (JobRequestProperties) duccEvent.getProperties();
-		String key;
-		String value;
 		//
 		retVal = integer(retVal,
 				properties,
 				JobSpecificationProperties.key_process_pipeline_count,
 				IDuccSchedulingInfo.defaultThreadsPerProcess,
 				IDuccSchedulingInfo.minThreadsPerProcess);
-		// scheduling class
-		key = JobRequestProperties.key_scheduling_class;
-		value = (String) properties.get(key);
-		if(value == null) {
-			String reason = createReason("invalid", key, value);
-			addError(properties,reason);
-			retVal = false;
-		}
-		// Check if a valid class name
-    DuccSchedulerClasses duccSchedulerClasses = DuccSchedulerClasses.getInstance();
-    DuccProperties props = null;
-    try {
-      props = duccSchedulerClasses.getClasses().get(value);
-    } catch (Exception e) {
-    }
-    if (props == null) {
-      String reason = createReason("unknown", key, value);
-      addError(properties,reason);
-      retVal = false;
-    }
+		
+		// check scheduling class - change to a fixed class if debugging
+    boolean fixit = properties.containsKey(JobSpecificationProperties.key_process_debug);
+		retVal = validate_scheduling_class(retVal, properties, fixit);
+		
 		return retVal;
 	}
 	
@@ -158,32 +141,37 @@ public class Validate {
 	}
 		
 	public static boolean request(SubmitReservationDuccEvent duccEvent) {
-		boolean retVal = true;
 		if (!validate_cli_version(duccEvent)) {
 			return false;
 		}	
 		ReservationRequestProperties properties = (ReservationRequestProperties) duccEvent.getProperties();
-		String key;
-		String value;
-		// memory size
-		key = ReservationRequestProperties.key_memory_size;
+		// Check memory size
+		String key = ReservationRequestProperties.key_memory_size;
 		String memorySize = (String) properties.get(key);
 		MemorySpecification memorySpecification = new MemorySpecification(memorySize);
-		value = memorySpecification.getSize();
-		if(value == null) {
-			String reason = createReason("invalid", key, value);
-			addError(properties,reason);
-			retVal = false;
-		}
-		// scheduling class
-		key = ReservationRequestProperties.key_scheduling_class;
-		value = (String) properties.get(key);
+		String value = memorySpecification.getSize();
 		if(value == null) {
 			String reason = createReason("invalid", key, value);
 			addError(properties,reason);
-			retVal = false;
+			return false;
 		}
-		return retVal;
+		
+		// Check if class is valid
+    try {
+        String[] reserveClasses = DuccSchedulerClasses.getInstance().getReserveClasses();
+        key = SpecificationProperties.key_scheduling_class;
+        String schedulingClass = properties.getProperty(key);
+        if (!Arrays.asList(reserveClasses).contains(schedulingClass)) {
+          String reason = createReason("invalid as not one of the reserve classes", key, schedulingClass);
+          addError(properties,reason);
+          return false;
+        }
+    } catch (Exception e) {
+      addError(properties, e.toString());
+      return false;
+    }
+		
+    return true;
 	}
 	
 	public static boolean request(CancelReservationDuccEvent duccEvent, DuccWorkReservation duccWorkReservation) {
@@ -219,25 +207,18 @@ public class Validate {
 		boolean retVal = true;
 		if (!validate_cli_version(duccEvent)) {
 			return false;
-		}		
+		}
+		//TODO - why is this the same as the job request ?
 		JobRequestProperties properties = (JobRequestProperties) duccEvent.getProperties();
-		String key;
-		String value;
-		//
+
 		retVal = integer(retVal,
 				properties,
 				JobSpecificationProperties.key_process_pipeline_count,
 				IDuccSchedulingInfo.defaultThreadsPerProcess,
 				IDuccSchedulingInfo.minThreadsPerProcess);
-		// scheduling class
-		key = ServiceRequestProperties.key_scheduling_class;
-		value = (String) properties.get(key);
-		if(value == null) {
-			String reason = createReason("invalid", key, value);
-			addError(properties,reason);
-			retVal = false;
-		}
-		return retVal;
+		
+    // check scheduling class
+    return validate_scheduling_class(retVal, properties, true);
 	}
 	
 	public static boolean request(CancelServiceDuccEvent duccEvent) {
@@ -258,4 +239,51 @@ public class Validate {
 		logger.warn("validate_cli_request", null, reason);
 		return false;
 	}
+	
+	// Scheduling class must be specified and valid
+	// Change a preemptable class to fixed if an AP or service
+	private static boolean validate_scheduling_class(boolean retVal, SpecificationProperties properties, boolean fixit) {
+	  if (!retVal) {
+	    return false;
+	  }
+	  String key = SpecificationProperties.key_scheduling_class;
+    String schedulingClass = properties.getProperty(key);
+    if (schedulingClass == null) {  // Should never happen as default value set earlier by OrchestratorHelper
+      String reason = createReason("invalid", key, schedulingClass);
+      addError(properties,reason);
+      return false;
+    }
+    
+    // Check if a valid class name
+    DuccSchedulerClasses duccSchedulerClasses = DuccSchedulerClasses.getInstance();
+    boolean isPreemptable;
+    try {
+      isPreemptable = duccSchedulerClasses.isPreemptable(schedulingClass);
+    } catch (IllegalArgumentException e) {   // Must be an unknown class
+      String reason = createReason("unknown", key, schedulingClass);
+      addError(properties,reason);
+      return false;
+    } catch (Exception e) {
+      addError(properties, e.toString());   // Invalid class configuration
+      return false;
+    }
+    
+    // Check if must be changed
+    if (isPreemptable && fixit) {
+      String fixedClass = null;
+      try {
+        fixedClass = duccSchedulerClasses.getDebugClassSpecificName(schedulingClass);
+      } catch (Exception e) {
+      }
+      if (fixedClass == null) {
+        addError(properties, "Invalid class configuration - all classes must have a debug (fixed) entry");
+        return false;
+      }
+      properties.setProperty(key, fixedClass);
+      String reason = createReason("changed preemptable class to", key, fixedClass);
+      addWarning(properties,reason);
+    }
+    
+    return true;
+	}
 }

Modified: uima/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java?rev=1863971&r1=1863970&r2=1863971&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java Mon Jul 29 21:33:30 2019
@@ -1089,7 +1089,7 @@ public class ServiceHandler
     {
     	String methodName = "register";
 
-        String error = null;
+        String error;
         boolean must_deregister = false;
 
         String url = meta.getProperty("endpoint");
@@ -1114,6 +1114,7 @@ public class ServiceHandler
         } catch ( Exception e ) {
             error = ("Internal error; unable to store service descriptor. " + url);
             logger.error(methodName, id, e);
+            return ServiceManagerComponent.makeResponse(false, error, url, id.getFriendly());
         }
 
 
@@ -1128,12 +1129,11 @@ public class ServiceHandler
             //                 }
         }
 
-        if ( error == null ) {
-            serviceStateHandler.registerService(id.getFriendly(), url, sset);
-            return ServiceManagerComponent.makeResponse(true, "Registered", url, id.getFriendly());
-        } else {
-            return ServiceManagerComponent.makeResponse(false, error, url, id.getFriendly());
-        }
+        serviceStateHandler.registerService(id.getFriendly(), url, sset);
+        
+        // Include warning of class change if any
+        String msg = "Registered" + sset.getWarning();
+        return ServiceManagerComponent.makeResponse(true, msg, url, id.getFriendly());
     }
 
     synchronized ServiceReplyEvent modify(ServiceModifyEvent ev)

Modified: uima/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java?rev=1863971&r1=1863970&r2=1863971&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java Mon Jul 29 21:33:30 2019
@@ -43,6 +43,7 @@ import org.apache.uima.ducc.common.TcpSt
 import org.apache.uima.ducc.common.persistence.services.IStateServices;
 import org.apache.uima.ducc.common.utils.DuccLogger;
 import org.apache.uima.ducc.common.utils.DuccProperties;
+import org.apache.uima.ducc.common.utils.DuccSchedulerClasses;
 import org.apache.uima.ducc.common.utils.SystemPropertyResolver;
 import org.apache.uima.ducc.common.utils.id.DuccId;
 import org.apache.uima.ducc.transport.event.common.DuccWorkJob;
@@ -173,6 +174,8 @@ public class ServiceSet
     //  Swapped these 2 values  UIMA-5244
     String archive_key = IStateServices.SvcMetaProps.is_archived.columnName();
     String archive_flag  = "true";
+    
+    private String warning = "";  // May hold class-change msg
 
     //
     // Constructor for a registered service
@@ -185,6 +188,9 @@ public class ServiceSet
         this.meta_props = meta;
         this.id = id;
 
+        // Check for valid scheduling class here (was in the CLI)
+        validateSchedulingClass(props);
+        
         this.service_state = ServiceState.Stopped;
         this.linger_time = props.getLongProperty(UiOption.ServiceLinger.pname(), linger_time);
         this.key = meta.getProperty(IStateServices.SvcMetaProps.endpoint.pname());
@@ -260,6 +266,10 @@ public class ServiceSet
     	return key;
     }
     
+    String getWarning() {
+      return warning;
+    }
+    
     // UIMA-4258
     // Get potentially pending instances from meta and stash them away for a bit
     // Used in hot-start to remap instance ids to ducc ids
@@ -314,6 +324,34 @@ public class ServiceSet
 
     }
 
+    // Check if a valid class name & if must be changed to a fixed one
+    private void validateSchedulingClass(DuccProperties properties) {
+      DuccSchedulerClasses duccSchedulerClasses = DuccSchedulerClasses.getInstance();
+      String key = UiOption.SchedulingClass.pname();
+      String schedulingClass = properties.getProperty(key);
+      try {
+        if (schedulingClass == null) {
+          properties.setProperty(key, duccSchedulerClasses.getDebugClassDefaultName());
+          return;
+        }
+        //if (!duccSchedulerClasses.getClasses().containsKey(schedulingClass)) {
+        //  throw new IllegalArgumentException("Unknown scheduling_class: " + schedulingClass);
+        //}
+        if (duccSchedulerClasses.isPreemptable(schedulingClass)) {
+          String fixedClass = duccSchedulerClasses.getDebugClassSpecificName(schedulingClass);
+          if (fixedClass == null) {
+            throw new IllegalArgumentException("Invalid class configuration - all classes must have a debug (fixed) entry");
+          }
+          properties.setProperty(key, fixedClass);
+          warning = " (changed preemptable " + key + " to " + fixedClass + ")";
+        }
+      } catch (IllegalArgumentException e) {
+        throw e;
+      } catch (Exception e) {
+        throw new IllegalArgumentException(e);
+      }
+    }
+
     synchronized Long[] getImplementors()
     {
         return implementors.keySet().toArray(new Long[implementors.size()]);