You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by ch...@apache.org on 2014/04/10 22:07:01 UTC

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

Author: challngr
Date: Thu Apr 10 20:07:00 2014
New Revision: 1586457

URL: http://svn.apache.org/r1586457
Log:
UIMA-3726 Dynamic modification of service registration.

Modified:
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceSubmit.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java?rev=1586457&r1=1586456&r2=1586457&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java Thu Apr 10 20:07:00 2014
@@ -76,6 +76,7 @@ public abstract class CliBase
     protected ArrayList<String> messages = new ArrayList<String>();
 
     protected boolean debug;
+    private   boolean load_defaults = true;
 
     protected ConsoleListener  console_listener = null;
     protected boolean suppress_console_log;
@@ -84,7 +85,7 @@ public abstract class CliBase
     protected IDuccCallback consoleCb = null;
 
     protected MonitorListener monitor_listener = null;
-
+    
     CountDownLatch waiter = null;
 
     protected Properties userSpecifiedProperties;
@@ -101,6 +102,11 @@ public abstract class CliBase
      */
     public abstract boolean execute() throws Exception;
 
+    protected void inhibitDefaults()
+    {
+        this.load_defaults = false;
+    }
+
     /*
      * Get log directory or employ default log directory if not specified
      */
@@ -325,11 +331,14 @@ public abstract class CliBase
         suppress_console_log = cli_props.containsKey(UiOption.SuppressConsoleLog.pname());
         
         // Apply defaults for and fixup the environment if needed
-        setDefaults(uiOpts, suppress_console_log);
+        //   -- unless default loading is inhibited, as it must be for modify operations
+        if ( load_defaults ) {
+            setDefaults(uiOpts, suppress_console_log);
+        }
         
         cli_props.setProperty(UiOption.SubmitPid.pname(), ManagementFactory.getRuntimeMXBean().getName());
 
-        if ( getLogDirectory() == null ) {
+        if ( load_defaults && (getLogDirectory() == null) ) {
             throw new IllegalArgumentException("Cannot access log directory.");
         }
         setWorkingDirectory();

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java?rev=1586457&r1=1586456&r2=1586457&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java Thu Apr 10 20:07:00 2014
@@ -56,7 +56,6 @@ public class DuccServiceApi 
         UiOption.Description,
         UiOption.SchedulingClass,
         UiOption.LogDirectory,
-        UiOption.SuppressConsoleLog,
         UiOption.WorkingDirectory,
         UiOption.Jvm,
         UiOption.ProcessJvmArgs,
@@ -158,7 +157,12 @@ public class DuccServiceApi 
         int i = 0;
         for ( ; i < registration_options.length; i++ ) {
             UiOption o = registration_options[i];
+
+            if ( o == UiOption.ProcessDD ) continue;                     // disallowed for modify
+            if ( o == UiOption.ServiceRequestEndpoint) continue;         // disallowed for modify
+
             if ( o == UiOption.Register ) o = UiOption.Modify;
+
             modify_options[i] = o;
         }
         modify_options[i++] = UiOption.Activate;
@@ -245,24 +249,45 @@ public class DuccServiceApi 
     }
 
     /**
-     * Attempt a fast-fail if a bad debug port is specified.
+     * Attempt a fast-fail if a bad debug port is specified.  Fill in the host if not supplied.
      */
-    private void enrichPropertiesForDebug()
+    private void enrichPropertiesForDebug(UiOption verb)
     {
+
         String debug_port = cli_props.getProperty(UiOption.ProcessDebug.pname());
-        if ( debug_port == null ) return; 
-        
+        String debug_host = host_address;
+        if ( debug_port == null )       return; 
+
+        if ( debug_port.equals("off") ) {
+            switch (verb ) {
+                case Register:
+                    System.out.println("Note: 'process_debug = off' removed; 'off' is valid only for --modify");
+                    cli_props.remove(UiOption.ProcessDebug.pname());     // 'off' invalid for registration
+                    return;
+                case Modify:
+                    return;
+            }
+        }
+
+        if ( debug_port.contains(":") ) {
+            String[] parts = debug_port.split(":");
+            if ( parts.length != 2 ) {
+                throw new IllegalArgumentException("Error: " + 
+                                                   UiOption.ProcessDebug.pname() + 
+                                                   " process_debug must be a single numeric port, or else of the form 'host:port'");
+            }
+
+            debug_host = parts[0];
+            debug_port = parts[1];
+        }
+
         try {
-            int port = Integer.parseInt(debug_port);
+			Integer.parseInt(debug_port);
         } catch ( NumberFormatException e ) {
             throw new IllegalArgumentException("Invalid debug port specified, not numeric: " + debug_port);
         }
 
-        String debug_host = cli_props.getProperty(UiOption.ProcessDebugHost.pname());
-        if ( debug_host == null ) {
-            cli_props.put(UiOption.ProcessDebugHost.pname(), host_address);
-        }
-
+        cli_props.setProperty(UiOption.ProcessDebug.pname(), debug_host + ":" + debug_port);
     }
 
     String extractEndpoint(String jvmargs)
@@ -335,7 +360,7 @@ public class DuccServiceApi 
                                                    + "\n                  extracted: " + inferred_endpoint );
             }
 
-            enrichPropertiesForDebug();
+            enrichPropertiesForDebug(UiOption.Register);
             
         } else if (endpoint.startsWith(ServiceType.Custom.decode())) {
 
@@ -490,6 +515,36 @@ public class DuccServiceApi 
     {
         DuccProperties dp = new DuccProperties();
 
+        inhibitDefaults();
+        init (this.getClass().getName(), modify_options, args, null, dp, callback, "sm");
+
+        enrichPropertiesForDebug(UiOption.Modify);
+
+        Pair<Integer, String> id = getId(UiOption.Modify);
+        String user = dp.getProperty(UiOption.User.pname());
+        byte[] auth_block = (byte[]) dp.get(UiOption.Signature.pname());
+
+        ServiceModifyEvent ev = new ServiceModifyEvent(user, id.first(), id.second(), dp, auth_block);        
+
+        try {
+            return (IServiceReply) dispatcher.dispatchAndWaitForDuccReply(ev);
+        } finally {
+            dispatcher.close();
+        }
+    }
+
+    /**
+     * The service 'modify' command is used to change various aspects of a registered service
+     * without the need to reregister it.
+     *
+     * @param args String array of arguments as described in the <a href="/doc/duccbook.html#DUCC_CLI_SERVICES">DUCC CLI reference.</a>
+     * @return {@link IServiceReply IServiceReply} object with modify status.
+     */
+    public IServiceReply modifyX(String[] args)
+        throws Exception
+    {
+        DuccProperties dp = new DuccProperties();
+
         init (this.getClass().getName(), modify_options, args, null, dp, callback, "sm");
 
         Pair<Integer, String> id = getId(UiOption.Modify);

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceSubmit.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceSubmit.java?rev=1586457&r1=1586456&r2=1586457&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceSubmit.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceSubmit.java Thu Apr 10 20:07:00 2014
@@ -59,7 +59,6 @@ public class DuccServiceSubmit 
         UiOption.ProcessInitializationTimeMax,
 
         UiOption.ProcessDebug,
-        UiOption.ProcessDebugHost,
 
         UiOption.InstanceFailureLimit,
         UiOption.ClasspathOrder,
@@ -109,10 +108,6 @@ public class DuccServiceSubmit 
     {
         init (this.getClass().getName(), opts, props, requestProperties, null);
     }
-
-    private void set_debug_parms(Properties props, int port)
-    {
-    }
     
     protected void enrich_parameters_for_debug(Properties props)
         throws Exception
@@ -124,16 +119,25 @@ public class DuccServiceSubmit 
             // we allow both jd and jp to debug, but the ports have to differ
             String do_debug = UiOption.ProcessDebug.pname();
             if ( props.containsKey(do_debug) ) {
-                String port_s = props.getProperty(do_debug);
-                if ( port_s == null ) {
+                String deb = props.getProperty(do_debug);
+                if ( deb == null ) {
                     throw new IllegalArgumentException("Missing port for " + do_debug);
                 }
-                debug_port = Integer.parseInt(port_s);
-                debug_host = props.getProperty(UiOption.ProcessDebugHost.pname());
-                if ( debug_host == null ) {
-                    throw new IllegalArgumentException("Debug is requested but process_debug_host is missing");
+
+                if ( deb.equals("off") ) {
+                    System.out.println("Note: Ignoring process_debug = off");
+                    return;
                 }
 
+                String[] parts = deb.split(":");
+                if ( parts.length != 2 ) {
+                    System.out.println("Warning: process_debug must be of the form host: port.  Found '" + deb + "'.  Ignoring debug.");
+                    return;
+                }
+
+                debug_host = parts[0];
+                debug_port = Integer.parseInt(parts[1]);
+
                 String debug_jvmargs = "-Xdebug -Xrunjdwp:transport=dt_socket,address=" + debug_host + ":" + debug_port;
                 String jvmargs = props.getProperty(UiOption.ProcessJvmArgs.pname());
                 if (jvmargs == null) {

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java?rev=1586457&r1=1586456&r2=1586457&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java Thu Apr 10 20:07:00 2014
@@ -399,14 +399,6 @@ public interface IUiOptions
             public String label()       { return "ProcessDebug"; }
         },            
 
-        ProcessDebugHost {              // inserted by service registration so we can remember where to call home
-            public String pname()       { return "process_debug_host"; }
-            public String argname()     { return "debugger-host-name"; }
-            public String description() { return "Nodename where java debugger is listening for connection.  Only valid for services."; }
-            public String example()     { return "gallifrey"; }
-            public String label()       { return "ProcessDebugHost"; }
-        },            
-
         ProcessDescriptorAE { 
             public String pname()       { return JobSpecificationProperties.key_process_descriptor_AE; }
             public String description() { return "Process Analysis Enginefor aggregate."; }

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java?rev=1586457&r1=1586456&r2=1586457&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java Thu Apr 10 20:07:00 2014
@@ -28,7 +28,6 @@ import java.util.Set;
 
 import org.apache.uima.ducc.cli.DuccServiceApi;
 import org.apache.uima.ducc.cli.IUiOptions.UiOption;
-import org.apache.uima.ducc.common.Pair;
 import org.apache.uima.ducc.common.utils.DuccLogger;
 import org.apache.uima.ducc.common.utils.DuccProperties;
 import org.apache.uima.ducc.common.utils.id.DuccId;
@@ -873,11 +872,13 @@ public class ServiceHandler
         return new ServiceReplyEvent(true, "Modifying", sset.getKey(), sset.getId().getFriendly());
     }
 
+    boolean dirty_meta_props = false;
+    boolean dirty_job_props = false;
+    boolean restart_pinger = false;
+    boolean restart_service = false;
 
-    Pair<Boolean, Boolean> modifyRegistration(ServiceSet sset, UiOption option, String value)
+    void modifyRegistration(ServiceSet sset, UiOption option, String value)
     {
-        boolean restart_pinger = false;
-        boolean restart_service = false;
 
         int     intval = 0;
         boolean boolval = false;
@@ -888,11 +889,13 @@ public class ServiceHandler
             case Instances:
                 intval = Integer.parseInt(value);                
                 sset.updateRegisteredInstances(intval);
+                dirty_meta_props = true;
                 break;
 
             case Autostart:
                 boolval = Boolean.parseBoolean(value);
                 sset.setAutostart(boolval);
+                dirty_meta_props = true;
                 break;
 
             // For the moment, these all update the registration but don't change internal 
@@ -911,12 +914,30 @@ public class ServiceHandler
             case ClasspathOrder:
             case ServiceDependency:
             case ServiceRequestEndpoint:
-            case ServiceLinger:
             case ProcessInitializationTimeMax:
+            case WorkingDirectory:
+                sset.setJobProperty(option.pname(), value);
+                dirty_job_props = true;
+                break;
+
             case InstanceInitFailureLimit:
+                sset.updateInitFailureLimit(value);
                 sset.setJobProperty(option.pname(), value);
+                dirty_job_props = true;
                 break;
-                
+
+            case ServiceLinger:
+                sset.updateLinger(value);
+                sset.setJobProperty(option.pname(), value);
+                dirty_job_props = true;
+                break;
+
+            case ProcessDebug:
+                // Note this guy updates the props differently based on the value
+                sset.updateDebug(value);      // value may be numeric, or "off" 
+                dirty_job_props = true;
+                break;
+
             case ServicePingArguments:
             case ServicePingClasspath:
             case ServicePingJvmArgs:
@@ -927,11 +948,10 @@ public class ServiceHandler
             case InstanceFailureLimit:
                 sset.setJobProperty(option.pname(), value);
                 restart_pinger = true;
+                dirty_job_props = true;
                 break;
 
         }
-
-        return new Pair<Boolean, Boolean>(restart_pinger, restart_service);
     }
 
     //void doModify(long id, String url, int instances, Trinary autostart, boolean activate)
@@ -944,14 +964,18 @@ public class ServiceHandler
         ServiceSet sset = serviceStateHandler.getServiceForApi(id, url);
 
         DuccProperties mods  = sme.getProperties();
-        boolean restart_pinger = false;
-        boolean restart_service = false;
-
+        restart_pinger = false;
+        restart_service = false;
         Set<String> keys = mods.stringPropertyNames();        
 
         for (String kk : keys ) {
             UiOption k = optionMap.get(kk);
 
+            if ( k == null ) {
+            	logger.debug(methodName, sset.getId(), "Bypass property", kk);
+            	continue;
+            }
+            
             switch ( k ) {
                 case Help:
                 case Debug:
@@ -964,19 +988,31 @@ public class ServiceHandler
             }
 
             String v = (String) mods.get(kk);
-            Pair<Boolean, Boolean> update = null;           
             try {
-                update = modifyRegistration(sset, k, v);
+            	modifyRegistration(sset, k, v);
             } catch ( Throwable t ) {
                 logger.error(methodName, sset.getId(), "Modify", kk, "to", v, "Failed:", t);
                 continue;
             }
 
-            restart_service |= update.first();
-            restart_pinger  |= update.second();
-
             logger.info(methodName, sset.getId(), "Modify", kk, "to", v, "restart_service[" + restart_service + "]", "restart_pinger[" + restart_pinger + "]");
         }
+        
+        if ( dirty_job_props ) {
+            sset.saveServiceProperties();
+            dirty_job_props = false;
+        }
+        if ( dirty_meta_props ) {
+            sset.saveMetaProperties();
+            dirty_meta_props = false;
+        }
+
+        if ( restart_pinger ) {
+            sset.restartPinger();
+            restart_pinger = false;
+        }
+
+        // restart_service - not yet
     }
 
     //void doModify(long id, String url, int instances, Trinary autostart, boolean activate)
@@ -1039,7 +1075,7 @@ public class ServiceHandler
              (pingJvmArgs   != null) ||
              (pingTimeout   != null) ||
              (pingDolog     != null) ) {
-            sset.restartPinger(pingClass, pingArguments, pingClasspath, pingJvmArgs, pingTimeout, pingDolog);
+            // sset.restartPinger(pingClass, pingArguments, pingClasspath, pingJvmArgs, pingTimeout, pingDolog);
         }
 
     }

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java?rev=1586457&r1=1586456&r2=1586457&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java Thu Apr 10 20:07:00 2014
@@ -523,17 +523,10 @@ public class ServiceSet
         }
     }
 
-    synchronized void restartPinger(String pingClass, String pingArguments, String pingClasspath, String pingJvmArgs, String pingTimeout, String pingDolog)
+    synchronized void restartPinger()
     {
-        String methodName = "restartPinger";
-        logger.info(methodName, id, "Modify pinger:", pingClass, pingArguments, pingClasspath, pingJvmArgs, pingTimeout, pingDolog);
-
         stopPingThread(); 
         resetRuntimeErrors();
-        // to Implemnt: 
-        //   Replace non-null properties in the registration progerties file, save the props, then stop and restart the pinger.
-        //   May only have to stop the pinger, and state machine will restart it for us.
-        //   TODO: Deal with pingOnly, if it turns out to be a special case.
     }
 
     /**
@@ -731,7 +724,6 @@ public class ServiceSet
     {
         meta_props.setProperty("instances", Integer.toString(n));
         registered_instances = n;
-        saveMetaProperties();
     }
 
     /**
@@ -740,8 +732,6 @@ public class ServiceSet
      */
     synchronized void updateInstances(int n, boolean update)
     {
-    	String methodName = "setNInstances";
-
         if ( n >= 0 ) {
      
             instances = n;
@@ -760,6 +750,38 @@ public class ServiceSet
         }
     }
 
+    synchronized void updateDebug(String val)
+    {
+        if ( val.equals("off") ) {
+            job_props.remove(UiOption.ProcessDebug.pname());
+            this.process_debug = false;
+        } else {
+            job_props.put(UiOption.ProcessDebug.pname(), val);
+            this.process_debug = true;
+        }
+    }
+
+    synchronized void updateLinger(String val)
+    {
+    	String methodName = "updateLinger";
+        try {
+            this.linger_time = Long.parseLong(val);
+        } catch( NumberFormatException e ) {
+            logger.error(methodName, id, "Cannot update linger, not numeric:", val);
+        }
+    }
+
+    synchronized void updateInitFailureLimit(String val)
+    {
+    	String methodName = "updateInitFailureLimit";
+        try {
+            this.init_failure_max = Integer.parseInt(val);
+        } catch( NumberFormatException e ) {
+            logger.error(methodName, id, "Cannot update init failure max, not numeric:", val);
+        }
+    }
+
+
     synchronized void persistReferences()
     {
         if ( references.size() == 0 ) {