Author: challngr
Date: Thu Aug 14 19:45:59 2014
New Revision: 1618030

URL: http://svn.apache.org/r1618030
Log:
UIMA-3988 SM cleanup "stop, start, disable, enable, observe, ignore" functions.

Added:
    
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceDisableEvent.java
    
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceEnableEvent.java
    
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceIgnoreEvent.java
    
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceObserveEvent.java
Modified:
    
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/IUiOptions.java
    
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ApiHandler.java
    
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/IServiceManager.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/ServiceInstance.java
    
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceManagerComponent.java
    
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java
    
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/event/ServiceManagerEventListener.java
    
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/IServiceDescription.java
    
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/ServiceDescription.java

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=1618030&r1=1618029&r2=1618030&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 Aug 14 19:45:59 2014
@@ -27,7 +27,11 @@ 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.transport.event.ServiceDisableEvent;
+import org.apache.uima.ducc.transport.event.ServiceEnableEvent;
+import org.apache.uima.ducc.transport.event.ServiceIgnoreEvent;
 import org.apache.uima.ducc.transport.event.ServiceModifyEvent;
+import org.apache.uima.ducc.transport.event.ServiceObserveEvent;
 import org.apache.uima.ducc.transport.event.ServiceQueryEvent;
 import org.apache.uima.ducc.transport.event.ServiceRegisterEvent;
 import org.apache.uima.ducc.transport.event.ServiceStartEvent;
@@ -120,6 +124,34 @@ public class DuccServiceApi 
         UiOption.RoleAdministrator,
     }; 
 
+    UiOption[] enable_options = {
+        UiOption.Help,
+        UiOption.Debug,
+        UiOption.Enable,
+        UiOption.RoleAdministrator,
+    }; 
+
+    UiOption[] disable_options = {
+        UiOption.Help,
+        UiOption.Debug,
+        UiOption.Disable,
+        UiOption.RoleAdministrator,
+    }; 
+
+    UiOption[] observe_options = {
+        UiOption.Help,
+        UiOption.Debug,
+        UiOption.Observe,
+        UiOption.RoleAdministrator,
+    }; 
+
+    UiOption[] ignore_options = {
+        UiOption.Help,
+        UiOption.Debug,
+        UiOption.Ignore,
+        UiOption.RoleAdministrator,
+    }; 
+
     // This gets generated from the registratoin_options.
     UiOption[] modify_options;
 
@@ -659,6 +691,90 @@ public class DuccServiceApi 
         }
     }
 
+    public IServiceReply observeReferences(String[] args)
+        throws Exception
+    {
+        DuccProperties dp = new DuccProperties();
+        init(this.getClass().getName(), observe_options, args, null, dp, 
callback, "sm");
+
+        Pair<Integer, String> id = getId(UiOption.Observe);
+        String user = dp.getProperty(UiOption.User.pname());
+        byte[] auth_block = (byte[]) dp.get(UiOption.Signature.pname());
+        boolean asAdministrator = 
dp.containsKey(UiOption.RoleAdministrator.pname());
+
+        ServiceObserveEvent ev = new ServiceObserveEvent(user, id.first(), 
id.second(), auth_block, CliVersion.getVersion());
+        ev.setAdministrative(asAdministrator);
+
+        try {
+            return (IServiceReply) dispatcher.dispatchAndWaitForDuccReply(ev);
+        } finally {
+            dispatcher.close();
+        }        
+    }
+
+    public IServiceReply ignoreReferences(String[] args)
+        throws Exception
+    {
+        DuccProperties dp = new DuccProperties();
+        init(this.getClass().getName(), ignore_options, args, null, dp, 
callback, "sm");
+
+        Pair<Integer, String> id = getId(UiOption.Ignore);
+        String user = dp.getProperty(UiOption.User.pname());
+        byte[] auth_block = (byte[]) dp.get(UiOption.Signature.pname());
+        boolean asAdministrator = 
dp.containsKey(UiOption.RoleAdministrator.pname());
+
+        ServiceIgnoreEvent ev = new ServiceIgnoreEvent(user, id.first(), 
id.second(), auth_block, CliVersion.getVersion());
+        ev.setAdministrative(asAdministrator);
+
+        try {
+            return (IServiceReply) dispatcher.dispatchAndWaitForDuccReply(ev);
+        } finally {
+            dispatcher.close();
+        }        
+    }
+
+    public IServiceReply enable(String[] args)
+        throws Exception
+    {
+        DuccProperties dp = new DuccProperties();
+        init(this.getClass().getName(), enable_options, args, null, dp, 
callback, "sm");
+
+        Pair<Integer, String> id = getId(UiOption.Enable);
+        String user = dp.getProperty(UiOption.User.pname());
+        byte[] auth_block = (byte[]) dp.get(UiOption.Signature.pname());
+        boolean asAdministrator = 
dp.containsKey(UiOption.RoleAdministrator.pname());
+
+        ServiceEnableEvent ev = new ServiceEnableEvent(user, id.first(), 
id.second(), auth_block, CliVersion.getVersion());
+        ev.setAdministrative(asAdministrator);
+
+        try {
+            return (IServiceReply) dispatcher.dispatchAndWaitForDuccReply(ev);
+        } finally {
+            dispatcher.close();
+        }        
+    }
+
+    public IServiceReply disable(String[] args)    
+        throws Exception
+    {
+        DuccProperties dp = new DuccProperties();
+        init(this.getClass().getName(), disable_options, args, null, dp, 
callback, "sm");
+
+        Pair<Integer, String> id = getId(UiOption.Disable);
+        String user = dp.getProperty(UiOption.User.pname());
+        byte[] auth_block = (byte[]) dp.get(UiOption.Signature.pname());
+        boolean asAdministrator = 
dp.containsKey(UiOption.RoleAdministrator.pname());
+
+        ServiceDisableEvent ev = new ServiceDisableEvent(user, id.first(), 
id.second(), auth_block, CliVersion.getVersion());
+        ev.setAdministrative(asAdministrator);
+
+        try {
+            return (IServiceReply) dispatcher.dispatchAndWaitForDuccReply(ev);
+        } finally {
+            dispatcher.close();
+        }        
+    }
+
     void help()
     {
         HelpFormatter formatter = new HelpFormatter();
@@ -708,6 +824,10 @@ public class DuccServiceApi 
            case Start:
            case Stop:
            case Modify:
+           case Disable:
+           case Enable:
+           case Ignore:
+           case Observe:
                System.out.println(msg);
                break;
            case Query:
@@ -762,6 +882,38 @@ public class DuccServiceApi 
         return format_reply(UiOption.Modify, reply);
     }
 
+    static boolean Enable(String[] args)
+        throws Exception
+    {
+        DuccServiceApi api = new DuccServiceApi(null);
+        IServiceReply reply = api.enable(args);
+        return format_reply(UiOption.Enable, reply);
+    }
+
+    static boolean Disable(String[] args)
+        throws Exception
+    {
+        DuccServiceApi api = new DuccServiceApi(null);
+        IServiceReply reply = api.disable(args);
+        return format_reply(UiOption.Disable, reply);
+    }
+
+    static boolean ObserveReferences(String[] args)
+        throws Exception
+    {
+        DuccServiceApi api = new DuccServiceApi(null);
+        IServiceReply reply = api.observeReferences(args);
+        return format_reply(UiOption.Observe, reply);
+    }
+
+    static boolean IgnoreReferences(String[] args)
+        throws Exception
+    {
+        DuccServiceApi api = new DuccServiceApi(null);
+        IServiceReply reply = api.ignoreReferences(args);
+        return format_reply(UiOption.Ignore, reply);
+    }
+
     static boolean Query(String[] args)
         throws Exception
     {
@@ -786,7 +938,11 @@ public class DuccServiceApi 
             UiOption.Start, 
             UiOption.Stop, 
             UiOption.Query, 
-            UiOption.Unregister
+            UiOption.Unregister,
+            UiOption.Observe,
+            UiOption.Ignore,
+            UiOption.Enable,
+            UiOption.Disable
         };        
         List<UiOption> check = new ArrayList<UiOption>();
         UiOption reply = UiOption.Help;
@@ -864,6 +1020,18 @@ public class DuccServiceApi 
                 case Stop:
                     rc = Stop(args);
                     break;
+                case Observe:
+                    rc = ObserveReferences(args);
+                    break;
+                case Ignore:
+                    rc = IgnoreReferences(args);
+                    break;
+                case Enable:
+                    rc = Enable(args);
+                    break;
+                case Disable:
+                    rc = Disable(args);
+                    break;
                 case Modify:
                     rc = Modify(args);
                     break;

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=1618030&r1=1618029&r2=1618030&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 Aug 14 19:45:59 2014
@@ -390,6 +390,38 @@ public interface IUiOptions
             public String label()       { return null; }
         },
 
+        Enable      { 
+            public String pname()       { return "enable"; } 
+            public String description() { return "Allow deployment starts for 
this service" ; } 
+            public String argname()     { return "service-id-or-endpoint" ; } 
+            public String example()     { return null; }
+            public String label()       { return null; }
+        },
+
+        Disable      { 
+            public String pname()       { return "disable"; } 
+            public String description() { return "Disable deployment starts 
for this service." ; }
+            public String argname()     { return "service-id-or-endpoint" ; } 
+            public String example()     { return null; }
+            public String label()       { return null; }
+        },
+
+        Observe      { 
+            public String pname()       { return "observe_references"; } 
+            public String description() { return "Enable reference-started 
control for a manually-started service." ; } 
+            public String argname()     { return "service-id-or-endpoint" ; } 
+            public String example()     { return null; }
+            public String label()       { return null; }
+        },
+
+        Ignore      { 
+            public String pname()       { return "ignore_references"; } 
+            public String description() { return "Disable reference-started 
control of service and revert to manual control." ; }
+            public String argname()     { return "service-id-or-endpoint" ; } 
+            public String example()     { return null; }
+            public String label()       { return null; }
+        },
+
         SubmitPid { 
             // generated
             public String pname()       { return 
JobRequestProperties.key_submitter_pid_at_host; }

Modified: 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ApiHandler.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ApiHandler.java?rev=1618030&r1=1618029&r2=1618030&view=diff
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ApiHandler.java
 (original)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ApiHandler.java
 Thu Aug 14 19:45:59 2014
@@ -19,6 +19,7 @@
 package org.apache.uima.ducc.sm;
 
 import org.apache.uima.ducc.cli.IUiOptions.UiOption;
+import org.apache.uima.ducc.transport.event.AServiceRequest;
 import org.apache.uima.ducc.transport.event.ServiceModifyEvent;
 import org.apache.uima.ducc.transport.event.ServiceStartEvent;
 import org.apache.uima.ducc.transport.event.ServiceStopEvent;
@@ -46,71 +47,54 @@ class ApiHandler
     String endpoint;
     int instances;
     Trinary autostart;
-    boolean update;
-    boolean activate;
 
-    ServiceModifyEvent modifyEvent;
+    AServiceRequest event;
 
     ApiHandler(ServiceUnregisterEvent event, ServiceHandler serviceHandler)
     {
         this.cmd = UiOption.Unregister;
-        this.friendly = event.getFriendly();
-        this.endpoint = event.getEndpoint();
+        this.event = event;
         this.serviceHandler = serviceHandler;
     }
 
     ApiHandler(ServiceStartEvent event, ServiceHandler serviceHandler)
     {
         this.cmd = UiOption.Start;
-        this.friendly = event.getFriendly();
-        this.endpoint = event.getEndpoint();
-        this.instances = event.getInstances();
-        this.update = event.getUpdate();
+        this.event = event;
         this.serviceHandler = serviceHandler;
     }
 
     ApiHandler(ServiceStopEvent event, ServiceHandler serviceHandler)
     {
         this.cmd = UiOption.Stop;
-        this.friendly = event.getFriendly();
-        this.endpoint = event.getEndpoint();
-        this.instances = event.getInstances();
-        this.update = event.getUpdate();
+        this.event = event;
         this.serviceHandler = serviceHandler;
     }
 
     ApiHandler(ServiceModifyEvent event, ServiceHandler serviceHandler)
     {
         this.cmd = UiOption.Modify;
-        this.modifyEvent = (ServiceModifyEvent) event;
+        this.event = event;
         this.serviceHandler = serviceHandler;
-
-        // this.friendly = event.getFriendly();
-        // this.endpoint = event.getEndpoint();
-        // this.instances = event.getInstances();
-        // this.autostart = event.getAutostart();
-        // this.activate = event.getActivate();
-        // this.serviceHandler = serviceHandler;
     }
 
     public void run()
     {
         switch ( cmd ) {
            case Start: 
-               serviceHandler.doStart(friendly, endpoint, instances, update);
+               serviceHandler.doStart((ServiceStartEvent) event);
                break;
 
            case Stop:
-               serviceHandler.doStop(friendly, endpoint, instances, update);
+               serviceHandler.doStop((ServiceStopEvent) event);
                break;
 
            case Unregister:
-               serviceHandler.doUnregister(friendly, endpoint);
+               serviceHandler.doUnregister((ServiceUnregisterEvent) event);
                break;
 
            case Modify:
-               // serviceHandler.doModify(friendly, endpoint, instances, 
autostart, activate);
-               serviceHandler.doModify(modifyEvent);
+               serviceHandler.doModify((ServiceModifyEvent) event);
                break;
         }
     }

Modified: 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/IServiceManager.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/IServiceManager.java?rev=1618030&r1=1618029&r2=1618030&view=diff
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/IServiceManager.java
 (original)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/IServiceManager.java
 Thu Aug 14 19:45:59 2014
@@ -20,7 +20,11 @@ package org.apache.uima.ducc.sm;
 
 import org.apache.uima.ducc.common.utils.id.DuccId;
 import org.apache.uima.ducc.transport.event.AServiceRequest;
+import org.apache.uima.ducc.transport.event.ServiceDisableEvent;
+import org.apache.uima.ducc.transport.event.ServiceEnableEvent;
+import org.apache.uima.ducc.transport.event.ServiceIgnoreEvent;
 import org.apache.uima.ducc.transport.event.ServiceModifyEvent;
+import org.apache.uima.ducc.transport.event.ServiceObserveEvent;
 import org.apache.uima.ducc.transport.event.ServiceQueryEvent;
 import org.apache.uima.ducc.transport.event.ServiceRegisterEvent;
 import org.apache.uima.ducc.transport.event.ServiceStartEvent;
@@ -48,6 +52,14 @@ public interface IServiceManager 
 
     public void stop(ServiceStopEvent ev);
 
+    public void enable(ServiceEnableEvent ev);
+
+    public void disable(ServiceDisableEvent ev);
+
+    public void observe(ServiceObserveEvent ev);
+
+    public void ignore(ServiceIgnoreEvent ev);
+
     public void query(ServiceQueryEvent ev);
 
     public void modify(ServiceModifyEvent ev);

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=1618030&r1=1618029&r2=1618030&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 Aug 14 19:45:59 2014
@@ -33,7 +33,11 @@ import org.apache.uima.ducc.common.utils
 import org.apache.uima.ducc.common.utils.DuccProperties;
 import org.apache.uima.ducc.common.utils.id.DuccId;
 import org.apache.uima.ducc.transport.event.AServiceRequest;
+import org.apache.uima.ducc.transport.event.ServiceDisableEvent;
+import org.apache.uima.ducc.transport.event.ServiceEnableEvent;
+import org.apache.uima.ducc.transport.event.ServiceIgnoreEvent;
 import org.apache.uima.ducc.transport.event.ServiceModifyEvent;
+import org.apache.uima.ducc.transport.event.ServiceObserveEvent;
 import org.apache.uima.ducc.transport.event.ServiceQueryEvent;
 import org.apache.uima.ducc.transport.event.ServiceQueryReplyEvent;
 import org.apache.uima.ducc.transport.event.ServiceReplyEvent;
@@ -688,7 +692,6 @@ public class ServiceHandler
 
         logger.info(methodName, sset.getId(), operation, "request from", 
userin, "not authorized.  Service owner:", userout);
         return false;
-
     }
 
     ServiceReplyEvent start(ServiceStartEvent ev)
@@ -706,9 +709,16 @@ public class ServiceHandler
             return new ServiceReplyEvent(false, "Owned by " + sset.getUser(),  
url, sset.getId().getFriendly());
         }
 
+
         int running    = sset.countImplementors();
         int instances  = ev.getInstances();
 
+        if ( (instances == -1) && !sset.enabled() ) {    // no args always 
enables
+            sset.enable();
+        } else if ( ! sset.enabled() ) {
+            return new ServiceReplyEvent(false, "Service is disabled, cannot 
start (" + sset.getDisableReason() + ")", url, sset.getId().getFriendly());
+        }
+
         if ( sset.isDebug() ) {
             if ( sset.countImplementors() > 0 ) {
                 return new ServiceReplyEvent(true, 
@@ -756,9 +766,13 @@ public class ServiceHandler
     // Start with some instances says: start exactly this many
     // If the --save option is included, also update the registration
     //
-    void doStart(long friendly, String epname, int instances, boolean update)
+    void doStart(ServiceStartEvent ev)
     {
        String methodName = "doStart";
+
+        long friendly = ev.getFriendly();
+        String epname = ev.getEndpoint();
+        int instances = ev.getInstances();
         ServiceSet sset = serviceStateHandler.getServiceForApi(friendly, 
epname);
 
         int running    = sset.countImplementors();
@@ -785,11 +799,13 @@ public class ServiceHandler
 
         sset.resetRuntimeErrors();
         sset.setStarted();                              // manual start 
overrides, if there's still a problem
-        sset.updateInstances(running + wanted, update); // pass in target 
instances
+        sset.updateInstances(running + wanted); // pass in target instances
     }
 
     ServiceReplyEvent stop(ServiceStopEvent ev)
     {
+        String methodName = "stop";
+
         long   id = ev.getFriendly();
         String url = ev.getEndpoint();
         ServiceSet sset = serviceStateHandler.getServiceForApi(id, url);
@@ -801,13 +817,26 @@ public class ServiceHandler
             return new ServiceReplyEvent(false, "Owned by " + sset.getUser(),  
url, sset.getId().getFriendly());
         }
 
-
         if ( sset.isStopped() ) {
             return new ServiceReplyEvent(false, "Already stopped", 
sset.getKey(), sset.getId().getFriendly());
         }
 
+        int running    = sset.countImplementors();
+        int instances  = ev.getInstances();
+        int tolose;
+        String msg;
+        // CLI/API prevents instances < -1
+        if ( instances == -1 ) {                             // figure out n 
to lose
+            tolose = running;
+            msg = "Stopping all deployments.";
+        } else {
+            tolose = Math.min(instances, running);
+            msg = "Stopping " + tolose + " deployments.";
+        }
+
+        logger.info(methodName, sset.getId(), msg);
         pendingRequests.add(new ApiHandler(ev, this));
-        return new ServiceReplyEvent(true, "Stopping", sset.getKey(), 
sset.getId().getFriendly());
+        return new ServiceReplyEvent(true, msg, sset.getKey(), 
sset.getId().getFriendly());
     }
 
     //
@@ -817,10 +846,14 @@ public class ServiceHandler
     // Otherwise we just stop the number asked for
     // If --save is insicated we update the registry
     //
-    void doStop(long id, String url, int instances, boolean update)
+    void doStop(ServiceStopEvent event)
+    //long id, String url, int instances)
     {
         //String methodName = "doStop";
 
+        int instances = event.getInstances();
+        long id = event.getFriendly();
+        String url = event.getEndpoint();
         ServiceSet sset = serviceStateHandler.getServiceForApi(id, url);
 
         int running    = sset.countImplementors();
@@ -828,12 +861,105 @@ public class ServiceHandler
         
         // CLI/API prevents instances < -1
         if ( instances == -1 ) {                             // figure out n 
to lose
-            tolose = running;
+            sset.disableAndStop("Disabled by stop from id " + event.getUser());
         } else {
             tolose = Math.min(instances, running);
+            sset.updateInstances(Math.max(0, running - tolose)); // pass in 
target intances running
+        }
+
+    }
+
+    ServiceReplyEvent disable(ServiceDisableEvent ev)
+    {
+        long   id = ev.getFriendly();
+        String url = ev.getEndpoint();
+        ServiceSet sset = serviceStateHandler.getServiceForApi(id, url);
+        if ( sset == null ) {
+            return new ServiceReplyEvent(false, "Unknown service", url, id);
+        }
+
+        if ( ! authorized("disable", sset, ev) ) {
+            return new ServiceReplyEvent(false, "Owned by " + sset.getUser(),  
url, sset.getId().getFriendly());
+        }
+
+        if ( !sset.enabled() ) {
+            return new ServiceReplyEvent(true, "Service is already disabled", 
sset.getKey(), sset.getId().getFriendly());
+        }
+
+        sset.disable("Disabled by owner or administrator " + ev.getUser());
+        sset.saveMetaProperties();
+        return new ServiceReplyEvent(true, "Disabled", sset.getKey(), 
sset.getId().getFriendly());
+    }
+
+    ServiceReplyEvent enable(ServiceEnableEvent ev)
+    {
+        long   id = ev.getFriendly();
+        String url = ev.getEndpoint();
+        ServiceSet sset = serviceStateHandler.getServiceForApi(id, url);
+        if ( sset == null ) {
+            return new ServiceReplyEvent(false, "Unknown service", url, id);
+        }
+
+        if ( ! authorized("enable", sset, ev) ) {
+            return new ServiceReplyEvent(false, "Owned by " + sset.getUser(),  
url, sset.getId().getFriendly());
+        }
+
+        if ( sset.enabled() ) {
+            return new ServiceReplyEvent(true, "Service is already enabled", 
sset.getKey(), sset.getId().getFriendly());
         }
 
-        sset.updateInstances(Math.max(0, running - tolose), update); // pass 
in target intances running
+        sset.enable();
+        sset.saveMetaProperties();
+        return new ServiceReplyEvent(true, "Enabled.", sset.getKey(), 
sset.getId().getFriendly());
+    }
+
+
+    ServiceReplyEvent ignore(ServiceIgnoreEvent ev)
+    {
+        long   id = ev.getFriendly();
+        String url = ev.getEndpoint();
+        ServiceSet sset = serviceStateHandler.getServiceForApi(id, url);
+        if ( sset == null ) {
+            return new ServiceReplyEvent(false, "Unknown service", url, id);
+        }
+
+        if ( ! authorized("ignore", sset, ev) ) {
+            return new ServiceReplyEvent(false, "Owned by " + sset.getUser(),  
url, sset.getId().getFriendly());
+        }
+
+        if ( sset.isAutostart() ) {
+            return new ServiceReplyEvent(false, "Service is autostarted, 
ignore-references not applied.", sset.getKey(), sset.getId().getFriendly());
+        }
+
+        if ( !sset.isReferencedStart() ) {
+            return new ServiceReplyEvent(true, "Service is already ignoring 
references", sset.getKey(), sset.getId().getFriendly());
+        }
+
+        
+        sset.ignoreReferences();
+        return new ServiceReplyEvent(true, "References now being ignored.", 
sset.getKey(), sset.getId().getFriendly());
+    }
+
+    ServiceReplyEvent observe(ServiceObserveEvent ev)
+    {
+        long   id = ev.getFriendly();
+        String url = ev.getEndpoint();
+        ServiceSet sset = serviceStateHandler.getServiceForApi(id, url);
+        if ( sset == null ) {
+            return new ServiceReplyEvent(false, "Unknown service", url, id);
+        }
+
+        if ( ! authorized("observe", sset, ev) ) {
+            return new ServiceReplyEvent(false, "Owned by " + sset.getUser(),  
url, sset.getId().getFriendly());
+        }
+
+        if ( sset.isAutostart() ) {
+            return new ServiceReplyEvent(false, "Must set autostart off before 
enabling reference-starts.", sset.getKey(), sset.getId().getFriendly());
+        }
+        
+        sset.enable();
+        sset.observeReferences();
+        return new ServiceReplyEvent(true, "Observing references.", 
sset.getKey(), sset.getId().getFriendly());
     }
 
     ServiceReplyEvent register(DuccId id, String props_filename, String 
meta_filename, DuccProperties props, DuccProperties meta)
@@ -1055,7 +1181,7 @@ public class ServiceHandler
 
     public ServiceReplyEvent unregister(ServiceUnregisterEvent ev)
     {
-        String methodName = "unregister";
+        //String methodName = "unregister";
         long id = ev.getFriendly();
         String url = ev.getEndpoint();
         ServiceSet sset = serviceStateHandler.getServiceForApi(id, url);
@@ -1081,23 +1207,25 @@ public class ServiceHandler
     //
     // Everything to do this must be vetted before it is called. Run in a new 
thread to not hold up the API.
     //
-    void doUnregister(long friendly, String url)
+    void doUnregister(ServiceUnregisterEvent ev)
     {
        String methodName = "doUnregister";
+        long friendly = ev.getFriendly();
+        String url = ev.getEndpoint();
+
         ServiceSet sset = serviceStateHandler.getUnregisteredService(friendly);
         if ( sset == null ) {
             logger.error(methodName, null, "Service", friendly, "(" + url + ") 
is not a known, unregistereed service. No action taken.");
             return;
         }
 
+        sset.disableAndStop("Disabled by unregister from id " + ev.getUser());
         if ( sset.isPingOnly() ) {
             logger.info(methodName, sset.getId(), "Unregister ping-only 
setvice:", friendly, url);
-            sset.stop();
             serviceStateHandler.removeService(sset);
             sset.deleteProperties();
         } else if ( sset.countImplementors() > 0 ) {
             logger.debug(methodName, sset.getId(), "Stopping implementors:", 
friendly, url);
-            sset.stop();             // will call removeServices once 
everything is stopped
         } else {
             logger.debug(methodName, sset.getId(), "Removing from map:", 
friendly, url);
             sset.clearQueue();       // will call removeServices if everything 
looks ok

Modified: 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceInstance.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceInstance.java?rev=1618030&r1=1618029&r2=1618030&view=diff
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceInstance.java
 (original)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceInstance.java
 Thu Aug 14 19:45:59 2014
@@ -208,8 +208,9 @@ class ServiceInstance
                        }
 
                } catch (Throwable t) {
-                       // TODO Auto-generated catch block
-            logger.error(methodName, null, t);
+            logger.error(methodName, sset.getId(), t);
+            sset.setErrorString(t.toString());
+            return -1;
                }
 
         for ( String s : stderr_lines ) {
@@ -251,6 +252,7 @@ class ServiceInstance
                     started = true;
                     logger.info(methodName, null, "Request to start service " 
+ sset.getId().toString() + " accepted as service instance ", numeric_id);
                 } catch ( NumberFormatException e ) {
+                    sset.setErrorString("Request to start service " + 
sset.getId().toString() + " failed, can't interpret submit response.: " + s);
                     logger.warn(methodName, null,  "Request to start service " 
+ sset.getId().toString() + " failed, can't interpret response.: " + s);
                 }
 
@@ -258,7 +260,7 @@ class ServiceInstance
         }
 
         if ( ! started ) {
-            logger.warn(methodName, null, "Request to start service " + 
sset.getId().toString() + " failed.");
+            logger.warn(methodName, sset.getId(), "Request to start service " 
+ sset.getId().toString() + " failed.");
             meta_props.put("submit-error", submit_buffer.toString());
             sset.log_errors(stdout_lines, stderr_lines);
         } else {

Modified: 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceManagerComponent.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceManagerComponent.java?rev=1618030&r1=1618029&r2=1618030&view=diff
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceManagerComponent.java
 (original)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceManagerComponent.java
 Thu Aug 14 19:45:59 2014
@@ -49,7 +49,11 @@ import org.apache.uima.ducc.common.utils
 import org.apache.uima.ducc.common.utils.id.DuccIdFactory;
 import org.apache.uima.ducc.transport.dispatcher.DuccEventDispatcher;
 import org.apache.uima.ducc.transport.event.AServiceRequest;
+import org.apache.uima.ducc.transport.event.ServiceDisableEvent;
+import org.apache.uima.ducc.transport.event.ServiceEnableEvent;
+import org.apache.uima.ducc.transport.event.ServiceIgnoreEvent;
 import org.apache.uima.ducc.transport.event.ServiceModifyEvent;
+import org.apache.uima.ducc.transport.event.ServiceObserveEvent;
 import org.apache.uima.ducc.transport.event.ServiceQueryEvent;
 import org.apache.uima.ducc.transport.event.ServiceQueryReplyEvent;
 import org.apache.uima.ducc.transport.event.ServiceRegisterEvent;
@@ -817,7 +821,7 @@ public class ServiceManagerComponent 
 
     public synchronized void start(ServiceStartEvent ev)
     {
-        String methodName = "startService";
+        String methodName = "start";
 
         if ( ! validate_user("Start", ev) ) return;   // necessary messages 
emitted in here
         if ( ! orchestratorAlive("Start", ev) ) return;
@@ -830,7 +834,7 @@ public class ServiceManagerComponent 
 
     public synchronized void stop(ServiceStopEvent ev)
     {
-        String methodName = "stopService";
+        String methodName = "stop";
 
         if ( ! validate_user("Stop", ev) ) return;   // necessary messages 
emitted in here
         if ( ! orchestratorAlive("Stop", ev) ) return;
@@ -841,6 +845,58 @@ public class ServiceManagerComponent 
         //ev.setReply(ServiceCode.OK, "Service not implemented.", 
"no-endpoint", null);
     }
 
+    public synchronized void enable(ServiceEnableEvent ev)
+    {
+        String methodName = "enable";
+
+        if ( ! validate_user("Enable", ev) ) return;   // necessary messages 
emitted in here
+        if ( ! orchestratorAlive("Enable", ev) ) return;
+
+        logger.info(methodName, null, "Enabling service", ev.toString());
+        ServiceReplyEvent reply = handler.enable(ev);
+        ev.setReply(reply);
+        //ev.setReply(ServiceCode.OK, "Service not implemented.", 
"no-endpoint", null);
+    }
+
+    public synchronized void disable(ServiceDisableEvent ev)
+    {
+        String methodName = "disable";
+
+        if ( ! validate_user("Disable", ev) ) return;   // necessary messages 
emitted in here
+        if ( ! orchestratorAlive("Disable", ev) ) return;
+
+        logger.info(methodName, null, "Disabling service", ev.toString());
+        ServiceReplyEvent reply = handler.disable(ev);
+        ev.setReply(reply);
+        //ev.setReply(ServiceCode.OK, "Service not implemented.", 
"no-endpoint", null);
+    }
+
+    public synchronized void observe(ServiceObserveEvent ev)
+    {
+        String methodName = "observe";
+
+        if ( ! validate_user("Observe", ev) ) return;   // necessary messages 
emitted in here
+        if ( ! orchestratorAlive("Observe", ev) ) return;
+
+        logger.info(methodName, null, "Observing references for service", 
ev.toString());
+        ServiceReplyEvent reply = handler.observe(ev);
+        ev.setReply(reply);
+        //ev.setReply(ServiceCode.OK, "Service not implemented.", 
"no-endpoint", null);
+    }
+
+    public synchronized void ignore(ServiceIgnoreEvent ev)
+    {
+        String methodName = "ignore";
+
+        if ( ! validate_user("Ignore", ev) ) return;   // necessary messages 
emitted in here
+        if ( ! orchestratorAlive("Ignore", ev) ) return;
+
+        logger.info(methodName, null, "Ignoring references for service", 
ev.toString());
+        ServiceReplyEvent reply = handler.ignore(ev);
+        ev.setReply(reply);
+        //ev.setReply(ServiceCode.OK, "Service not implemented.", 
"no-endpoint", null);
+    }
+
     public synchronized void query(ServiceQueryEvent ev)
     {
         String methodName = "query";

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=1618030&r1=1618029&r2=1618030&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 Aug 14 19:45:59 2014
@@ -26,6 +26,7 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.sql.Timestamp;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -105,7 +106,9 @@ public class ServiceSet
     // Automatically start at boot, and keep implementors alive
     boolean autostart = false;
     // We've been stopped, which is used to override autostart
-    boolean stopped   = false;
+    // boolean stopped   = false;     // TODO Must get rid of this entirely
+    boolean enabled   = true;
+
     // We've been started, so we know to enforce instance count even if not 
autostarted
     boolean started   = false;
     // Remember if was started by reference only so we can stop when refs die
@@ -193,9 +196,11 @@ public class ServiceSet
         this.registered_instances = this.instances;
         this.autostart = meta.getBooleanProperty("autostart", false);
         this.ping_only = meta.getBooleanProperty("ping-only", false);
-        this.stopped   = meta.getBooleanProperty("stopped", stopped);
+        this.enabled   = meta.getBooleanProperty("enabled", enabled);
         this.service_class = ServiceClass.Registered;
         this.init_failure_max = 
props.getIntProperty("instance_init_failures_limit", init_failure_max);
+        this.reference_start = meta.getBooleanProperty("reference", 
this.reference_start);
+
         
         
         if ( props.containsKey(UiOption.ProcessDebug.pname()) ) {
@@ -214,12 +219,13 @@ public class ServiceSet
         meta_props.remove("references");          // Will get refreshred in 
upcoming OR state messages
         meta_props.put("service-class", ""+service_class.decode());
         meta_props.put("service-type", ""+service_type.decode());
-        meta_props.put("stopped", ""+stopped);
+        meta_props.put("enabled", "" + enabled);         // may not have been 
there in the first place
         meta_props.put("service-state", ""+getState());
         meta_props.put("ping-active", "false");
         meta_props.put("service-alive",      "false");
         meta_props.put("service-healthy",    "false");
         meta_props.put("service-statistics", "N/A");
+        setReferenced(this.reference_start);
         meta_props.remove("submit-error");
 
         last_use = meta_props.getLongProperty("last-use", 0L);
@@ -454,7 +460,7 @@ public class ServiceSet
         // remove stuff that didn't come in.
         //
 
-        if ( isPingOnly() && ! stopped) {
+        if ( isPingOnly() && enabled() ) {
             start(1);   // nothing to recover but we need the pseudo service 
to run
             return;   
         }
@@ -503,28 +509,21 @@ public class ServiceSet
      *
      */
     synchronized void enforceAutostart()
-     {
-         String methodName = "enforceAutostart";
-         if ( ! autostart ) return;                           // not doing 
auto, nothing to do
-         if ( stopped     ) return;                           // doing auto, 
but we've been manually stopped
-         if ( init_failures >= init_failure_max ) return;     // too many init 
failures, no more enforcement
-         if ( ping_failures >= ping_failure_max ) return;     // ping-only 
-
-         // if ( (isPingOnly()) && (serviceMeta == null) ) {    // ping-only 
and monitor / pinger not alive
-         //     logger.info(methodName, id, "Autostarting 1 ping-only 
instance.");
-
-         //     start(1);                                       // ... then it 
needs to be started
-         //     return;
-         // }
-         
-         // could have more implementors than instances if some were started 
dynamically but the count not persisted
-         int needed = Math.max(0, instances - countImplementors());
-         if ( needed > 0 ) {
-             logger.info(methodName, id, "Autostarting", needed, "instance" + 
((needed > 1) ? "s" : ""), "already have", countImplementors());
-             start(needed);
-         }
+    {
+        String methodName = "enforceAutostart";
+        if ( ! autostart ) return;                           // not doing 
auto, nothing to do
+        if ( ! enabled() ) return;                           // doing auto, 
but we are disabled
+        if ( init_failures >= init_failure_max ) return;     // too many init 
failures, no more enforcement
+        if ( ping_failures >= ping_failure_max ) return;     // not pinging, 
let's not start more stuff
+        
+        // could have more implementors than instances if some were started 
dynamically but the count not persisted
+        int needed = Math.max(0, instances - countImplementors());
+        if ( needed > 0 ) {
+            logger.info(methodName, id, "Autostarting", needed, "instance" + 
((needed > 1) ? "s" : ""), "already have", countImplementors());
+            start(needed);
+        }
     }
-
+    
 
     boolean isUimaAs()
     {
@@ -582,7 +581,7 @@ public class ServiceSet
             // turning this on gives benefit of the doubt on failure management
             // by definition, an autostarted services is NOT reference started
             cancelLinger();
-            reference_start = false;
+            setReferenced(false);
             init_failures = 0;
             resetRuntimeErrors();
         }
@@ -601,8 +600,6 @@ public class ServiceSet
      */
     synchronized void setStarted()
     {
-        stopped = false;
-        reference_start = false;
         started = true;
         init_failures = 0;
     }
@@ -611,36 +608,77 @@ public class ServiceSet
      * Manual stop: override reference_start and manual start.
      *              remember 'stopped' so enforceAutostart doesn't restart
      */
-    synchronized void setStopped()
-    {
-        reference_start = false;
-        started = false;
-        stopped = true;
-    }
+    // synchronized void setStopped()
+    // {
+    //     started = false;
+    //     stopped = true;
+    // }
 
     /**
      * Start by reference: if autostarted or already manually started, don't 
change anything
      *                     else remember we're ref started and not stopped
      */
-    synchronized void setReferencedStart(boolean is_start)
-    {
-        if ( is_start ) {
-            if ( isAutostart() || isStarted() ) return;
-            this.stopped = false;
-            this.reference_start = true;
-            init_failures = 0;
-            resetRuntimeErrors();
-        } else {
-            this.reference_start = false;
-        }
-    }
+    // synchronized void xsetReferencedStart(boolean is_start)
+    // {
+    //     if ( is_start ) {
+    //         if ( isAutostart() || isStarted() ) return;
+    //         this.stopped = false;
+    //         this.reference_start = true;
+    //         init_failures = 0;
+    //         resetRuntimeErrors();
+    //     } else {
+    //         this.reference_start = false;
+    //     }
+    // }
 
     /**
-     * "Manually" stopped.
+     * Is the service stopped or about to stop?
      */
     synchronized boolean isStopped()
     {
-        return this.stopped;
+        switch ( service_state ) {
+            case Stopping:
+            case Stopped:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    synchronized void ignoreReferences()
+    {
+        setReferenced(false);
+        cancelLinger();
+    }
+
+    synchronized void observeReferences()
+    {
+        setReferenced(true);
+        if ( countReferences() == 0 ) {
+            lingeringStop();
+        }
+    }
+
+    synchronized void disable(String reason)
+    {
+        meta_props.put("disable-reason", reason);
+        this.enabled = false;
+    }
+
+    synchronized void enable()
+    {
+        meta_props.remove("disable-reason");
+        this.enabled = true;
+    }
+
+    synchronized boolean enabled()
+    {
+        return this.enabled;
+    }
+
+    synchronized String getDisableReason()
+    {
+        return meta_props.getStringProperty("disable-reason", "Unknown");
     }
 
     /**
@@ -708,7 +746,7 @@ public class ServiceSet
     private void saveProperties(DuccProperties props, File pfile, File 
pfile_tmp, String type)
     {
        
-       String methodName = "saveMetaProperties";
+       String methodName = "saveProperties";
         FileOutputStream fos = null;
         try {
             if ( (!pfile.exists()) || pfile.renameTo(pfile_tmp) ) {
@@ -767,7 +805,8 @@ public class ServiceSet
             meta_props.setProperty(implementors_key, s);
         }
 
-        meta_props.put("stopped", ""+stopped);
+        
+        meta_props.put("enabled", ""+enabled);
         meta_props.put("service-state", ""+ getState());
         meta_props.put("ping-active", "" + (serviceMeta != null));
         meta_props.put("service-alive",      "false");
@@ -819,22 +858,19 @@ public class ServiceSet
      * @param n      is the target number of instances we want running
      * @param update indicates whether tp match registration to the target
      */
-    synchronized void updateInstances(int n, boolean update)
+    synchronized void updateInstances(int n)
     {
         if ( n >= 0 ) {
      
             instances = n;
-            if ( update ) {
-                updateRegisteredInstances(n);
-            }
-
+            
             int running    = countImplementors();
             int diff       = n - running;
                 
             if ( diff > 0 ) {
                 start(diff);
             } else if ( diff < 0 ) {
-                stop(-diff);
+                stop(-diff); // TODO: no good, fix when changeTo is ready
             }
         }
     }
@@ -964,11 +1000,23 @@ public class ServiceSet
         }
     }
 
+    public void setErrorString(String s)
+    {
+        meta_props.put("submit-error", s);
+        saveMetaProperties();
+    }
+
     public String getErrorString()
     {
         return meta_props.getProperty("submit-error"); 
     }
 
+    void setReferenced(boolean r)
+    {
+        this.reference_start = r;
+        meta_props.put("reference", Boolean.toString(this.reference_start));
+    }
+
     public synchronized void reference(DuccId id)
     {
         String methodName = "reference";
@@ -983,23 +1031,27 @@ public class ServiceSet
         references.put(id, id);
         logger.info(methodName, this.id, " References job/service", id, 
"count[" + references.size() + "] implementors [" + implementors.size() + "]");
 
-        persistReferences();
-
+        boolean idle = true;
         for (ServiceInstance si : implementors.values() ) {     // see if 
anything is running
             logger.debug(methodName, this.id, "Implementor", si.getId(), 
"state:", si.getState());
-            if ( si.isRunning() ) return;                      // and if so, 
no need to start anything
+            if ( si.isRunning() ) {                             // and if so, 
no need to start anything
+                idle = false;
+                break;
+            }
         }
 
         // Nothing running, so we do referenced start.
-
-        if ( ! isStopped() ) {
+        if ( enabled() && idle ) {
             logger.info(methodName, this.id, "Reference starting new service 
instances.");
-            setReferencedStart(true);
+            init_failures = 0;
+            resetRuntimeErrors();
+            setReferenced(true);
             start(registered_instances);
         } else {
-            logger.info(methodName, this.id, "Not reference starting new 
service instances because service is stopped.");
+            logger.info(methodName, this.id, "Not reference starting new 
service instances because service is disabled.");
         }
 
+        persistReferences();
     }
 
     public synchronized void dereference(DuccId id)
@@ -1053,26 +1105,21 @@ public class ServiceSet
                     "references", countReferences()
                     );
 
-        while ( true ) {      
-            // Kids, don't try this at home! 
-            // All paths MUST lead to break or we loop forever - using 
while/break as goto mechanism
-            ping_failures = 0;   
-            
-            this.excessiveRunFailures = isExcessiveFailures;
-
-            // Note that nadditions could == ndeletions.  This is ok, because 
the monitor may want
-            // to 'reboot' an instance by killing a specific one and also 
starting up a new one.
-
-            if ( nadditions > 0) {
-                start(nadditions);
-            }
-            
-            for ( int i = 0; i < ndeletions; i++ ) {
-                stop(deletions[i]);
-            }
-
-            break;   // required break
+        ping_failures = 0;   
+        
+        this.excessiveRunFailures = isExcessiveFailures;
+        
+        // Note that nadditions could == ndeletions.  This is ok, because the 
monitor may want
+        // to 'reboot' an instance by killing a specific one and also starting 
up a new one.
+        
+        if ( nadditions > 0) {
+            start(nadditions);
+        }
+        
+        for ( int i = 0; i < ndeletions; i++ ) {
+            stop(deletions[i]);
         }
+        
         saveMetaProperties();
     }
 
@@ -1127,7 +1174,8 @@ public class ServiceSet
             logger.info(methodName, id, "Resetting init error counter from", 
init_failures, "to 0 on transition from", old_state, "to", state);
             init_failures = 0;
         }
-                
+
+        boolean save_meta = false;
         if ( canDeleteInstance(dwj) ) {
             // State Completed or Completing
             JobCompletionType jct = dwj.getCompletionType();
@@ -1140,9 +1188,9 @@ public class ServiceSet
             String history = meta_props.getStringProperty(history_key, "");
             history = history + " " + fid;
             meta_props.put(history_key, history);
-            saveMetaProperties();
+            save_meta = true;
 
-            logger.info(methodName, id, "Removing stopped instance",  inst_id, 
"from maps: state[", state, "] completion[", jct, "] isStopped", isStopped());
+            logger.info(methodName, id, "Removing stopped instance",  inst_id, 
"from maps: state[", state, "] completion[", jct, "] service-enabled", 
enabled());
 
             clearQueue();        // this won't do anything if it looks like 
the service is still active somehow
 
@@ -1176,15 +1224,19 @@ public class ServiceSet
                             break;
                     }
 
-                    if ( excessiveFailures() ) {
+                    if ( excessiveFailures() ) { 
+                        String disable_reason = null;
                         if ( excessiveRunFailures ) {
                             logger.warn(methodName, id, "Instance", inst_id, 
"Monitor signals excessive terminations. Not restarting.");
+                            disable_reason = "Excessive runtime errors";
                         } else {
                             logger.warn(methodName, id, "Instance", inst_id,
                                         "Excessive initialization failures. 
Total failures[" + init_failures + "]",
                                         "allowed [" + init_failure_max + "], 
not restarting.");
+                            disable_reason = "Excessive initialization errors";
                         }
-                        setAutostart(false);
+                        disable(disable_reason);
+                        save_meta = true;
                     } else {
                         logger.warn(methodName, id, "Instance", inst_id + ": 
Uunsolicited termination, not yet excessive.  Restarting instance.");
                         start(1);
@@ -1194,6 +1246,7 @@ public class ServiceSet
             }
         } 
 
+        if ( save_meta ) saveMetaProperties();
         inst.setState(state);            
         signal(inst);
     }
@@ -1250,14 +1303,6 @@ public class ServiceSet
             if ( serviceMeta.getServiceState().ordinality() <= 
response.ordinality() ) response = serviceMeta.getServiceState();
         }
 
-        // It can take a while for instance state to catch up with stopping, 
so we override it here if needed
-        if ( isStopped() ) {
-            if ( ServiceState.Stopping.ordinality() < response.ordinality() ) {
-                logger.info(methodName, id, "Adjust state to", 
ServiceState.Stopping, "from", response, "because of service stop.");
-                response = ServiceState.Stopping;
-            }
-        }
-
         return response;
     }
 
@@ -1301,6 +1346,7 @@ public class ServiceSet
                 stopPingThread();
                 break;
             case Stopped:
+                setReferenced(false);
                 stopPingThread();
                 break;
             default:
@@ -1755,7 +1801,7 @@ public class ServiceSet
                     signal(si);
                 } else {
                     logger.info(methodName, id, "Instance[", i, "] id ", 
instid, "Failed to start.");
-                    setAutostart(false);
+                    disable("Cannot submit service process");
                     signal(si);
                     break;
                 }
@@ -1792,29 +1838,41 @@ public class ServiceSet
 
         logger.info(methodName, id, "Stopping", count, "implementors");
 
-        if ( count >= implementors.size() ) {
-            stopPingThread();
-            setStopped();
+        Long[] keys = implementors.keySet().toArray(new 
Long[implementors.size()]);
+        Arrays.sort(keys);
+        for ( int i = 0, j = keys.length-1; i < count; i++, j-- ) {
+            Stopper s = new Stopper(implementors.get(keys[j]));
+            new Thread(s).start();
         }
+    }
 
-        for ( ServiceInstance si: implementors.values() ) {
-            if ( (count--) > 0 ) {
-                si.stop();
-                signal(si);
-            } else {
-                break;
-            }
-        }
+    synchronized void stopAll()
+    {
+        stop(implementors.size());
     }
 
     /**
-     * Stop everything
+     * Make the thing stop and not restart.
      */
-    synchronized void stop()
+    synchronized void disableAndStop(String reason)
     {
-        stop(implementors.size());
+        disable(reason);
+        stopAll();
     }
 
+    // /**
+    //  * Stop everything
+    //  */
+    // synchronized void stop()
+    // {
+    //     // TODO
+    //     // change state to Stopping and spawn stop threads for all 
implementors
+    //     for ( ServiceInstance si : implementors.values() ) {
+    //         Stopper s = new Stopper(si);
+    //         new Thread(s).start();
+    //     }
+    // }
+
     private class LingerTask
         extends TimerTask
     {
@@ -1833,7 +1891,8 @@ public class ServiceSet
             logger.debug(methodName, id, "Lingering stop completes.");
             // doesn't matter how its started i think, we have to set this 
flag off when we stop
             linger = null;
-            stop();
+            setReferenced(false);
+            stopAll();
         }
     }
 
@@ -1874,8 +1933,8 @@ public class ServiceSet
         sd.setBroker(broker);
         sd.setServiceState(getState());
         sd.setActive(serviceMeta != null);
-        sd.setStopped(stopped);
-        sd.setAutostart(autostart);
+        sd.setEnabled(enabled());
+        sd.setAutostart(isAutostart());
         sd.setLinger(linger_time);
         sd.setId(id);
         sd.setUser(user);

Modified: 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/event/ServiceManagerEventListener.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/event/ServiceManagerEventListener.java?rev=1618030&r1=1618029&r2=1618030&view=diff
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/event/ServiceManagerEventListener.java
 (original)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/event/ServiceManagerEventListener.java
 Thu Aug 14 19:45:59 2014
@@ -24,7 +24,11 @@ import org.apache.uima.ducc.sm.IServiceM
 import org.apache.uima.ducc.transport.dispatcher.DuccEventDispatcher;
 import 
org.apache.uima.ducc.transport.event.OrchestratorAbbreviatedStateDuccEvent;
 import org.apache.uima.ducc.transport.event.OrchestratorStateDuccEvent;
+import org.apache.uima.ducc.transport.event.ServiceDisableEvent;
+import org.apache.uima.ducc.transport.event.ServiceEnableEvent;
+import org.apache.uima.ducc.transport.event.ServiceIgnoreEvent;
 import org.apache.uima.ducc.transport.event.ServiceModifyEvent;
+import org.apache.uima.ducc.transport.event.ServiceObserveEvent;
 import org.apache.uima.ducc.transport.event.ServiceQueryEvent;
 import org.apache.uima.ducc.transport.event.ServiceRegisterEvent;
 import org.apache.uima.ducc.transport.event.ServiceReplyEvent;
@@ -133,6 +137,54 @@ public class ServiceManagerEventListener
        }
 
     // Incoming API requests
+       public void onServiceEnableEvent(@Body ServiceEnableEvent duccEvent) 
throws Exception 
+    {
+               String methodName = "onServiceEnableEvent";
+        try {
+            serviceManager.enable(duccEvent);
+        } catch ( Throwable t ) {
+            duccEvent.setReply(failureEvent());
+            logger.error(methodName, null, t);
+        }
+       }
+
+    // Incoming API requests
+       public void onServiceDisableEvent(@Body ServiceDisableEvent duccEvent) 
throws Exception 
+    {
+               String methodName = "onServiceDisableEvent";
+        try {
+            serviceManager.disable(duccEvent);
+        } catch ( Throwable t ) {
+            duccEvent.setReply(failureEvent());
+            logger.error(methodName, null, t);
+        }
+       }
+
+    // Incoming API requests
+       public void onServiceIgnoreEvent(@Body ServiceIgnoreEvent duccEvent) 
throws Exception 
+    {
+               String methodName = "onServiceIgnoreEvent";
+        try {
+            serviceManager.ignore(duccEvent);
+        } catch ( Throwable t ) {
+            duccEvent.setReply(failureEvent());
+            logger.error(methodName, null, t);
+        }
+       }
+
+    // Incoming API requests
+       public void onServiceObserveEvent(@Body ServiceObserveEvent duccEvent) 
throws Exception 
+    {
+               String methodName = "onServiceObserveEvent";
+        try {
+            serviceManager.observe(duccEvent);
+        } catch ( Throwable t ) {
+            duccEvent.setReply(failureEvent());
+            logger.error(methodName, null, t);
+        }
+       }
+
+    // Incoming API requests
        public void onServiceModifyEvent(@Body ServiceModifyEvent duccEvent) 
throws Exception 
     {
                String methodName = "onServiceModifyEvent";

Added: 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceDisableEvent.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceDisableEvent.java?rev=1618030&view=auto
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceDisableEvent.java
 (added)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceDisableEvent.java
 Thu Aug 14 19:45:59 2014
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.transport.event;
+
+
+@SuppressWarnings("serial")
+public class ServiceDisableEvent 
+    extends AServiceRequest
+{
+    private long friendly;
+    private String epname;
+
+       public ServiceDisableEvent(String user, long friendly, String epname, 
byte[] auth_block, int cli_version)
+    {
+               super(EventType.SERVICE_STOP, user, auth_block, cli_version);
+        this.friendly = friendly;
+        this.epname = epname;
+       }
+
+       public long getFriendly() {
+               return friendly;
+       }
+
+    public String getEndpoint()
+    {
+        return epname;
+    }
+
+       @Override
+       public String toString() {
+               return "ServiceDisableEvent [friendly=" + friendly + ", user=" 
+ user 
+                               + "]";
+       }
+       
+}

Added: 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceEnableEvent.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceEnableEvent.java?rev=1618030&view=auto
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceEnableEvent.java
 (added)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceEnableEvent.java
 Thu Aug 14 19:45:59 2014
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.transport.event;
+
+
+@SuppressWarnings("serial")
+public class ServiceEnableEvent 
+    extends AServiceRequest
+{
+    private long friendly;
+    private String epname;
+
+       public ServiceEnableEvent(String user, long friendly, String epname, 
byte[] auth_block, int cli_version)
+    {
+               super(EventType.SERVICE_STOP, user, auth_block, cli_version);
+        this.friendly = friendly;
+        this.epname = epname;
+       }
+
+       public long getFriendly() {
+               return friendly;
+       }
+
+    public String getEndpoint()
+    {
+        return epname;
+    }
+
+       @Override
+       public String toString() {
+               return "ServiceEnableEvent [friendly=" + friendly + ", user=" + 
user 
+                               + "]";
+       }
+       
+}

Added: 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceIgnoreEvent.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceIgnoreEvent.java?rev=1618030&view=auto
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceIgnoreEvent.java
 (added)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceIgnoreEvent.java
 Thu Aug 14 19:45:59 2014
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.transport.event;
+
+
+@SuppressWarnings("serial")
+public class ServiceIgnoreEvent 
+    extends AServiceRequest
+{
+    private long friendly;
+    private String epname;
+
+       public ServiceIgnoreEvent(String user, long friendly, String epname, 
byte[] auth_block, int cli_version)
+    {
+               super(EventType.SERVICE_STOP, user, auth_block, cli_version);
+        this.friendly = friendly;
+        this.epname = epname;
+       }
+
+       public long getFriendly() {
+               return friendly;
+       }
+
+    public String getEndpoint()
+    {
+        return epname;
+    }
+
+       @Override
+       public String toString() {
+               return "ServiceIgnoreEvent [friendly=" + friendly + ", user=" + 
user 
+                               + "]";
+       }
+       
+}

Added: 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceObserveEvent.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceObserveEvent.java?rev=1618030&view=auto
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceObserveEvent.java
 (added)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceObserveEvent.java
 Thu Aug 14 19:45:59 2014
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.transport.event;
+
+
+@SuppressWarnings("serial")
+public class ServiceObserveEvent 
+    extends AServiceRequest
+{
+    private long friendly;
+    private String epname;
+
+       public ServiceObserveEvent(String user, long friendly, String epname, 
byte[] auth_block, int cli_version)
+    {
+               super(EventType.SERVICE_STOP, user, auth_block, cli_version);
+        this.friendly = friendly;
+        this.epname = epname;
+       }
+
+       public long getFriendly() {
+               return friendly;
+       }
+
+    public String getEndpoint()
+    {
+        return epname;
+    }
+
+       @Override
+       public String toString() {
+               return "ServiceObserveEvent [friendly=" + friendly + ", user=" 
+ user
+                               + "]";
+       }
+       
+}

Modified: 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/IServiceDescription.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/IServiceDescription.java?rev=1618030&r1=1618029&r2=1618030&view=diff
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/IServiceDescription.java
 (original)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/IServiceDescription.java
 Thu Aug 14 19:45:59 2014
@@ -128,11 +128,11 @@ public interface IServiceDescription
      */
     public void setAutostart(boolean autostart);
 
-       public boolean isStopped();
+       public boolean isEnabled();
     /**
      * Internal to DUCC.
      */
-       public void setStopped(boolean stopped);
+       public void setEnabled(boolean enable);
 
        public IServiceStatistics getQstats();
     /**

Modified: 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/ServiceDescription.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/ServiceDescription.java?rev=1618030&r1=1618029&r2=1618030&view=diff
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/ServiceDescription.java
 (original)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/ServiceDescription.java
 Thu Aug 14 19:45:59 2014
@@ -64,8 +64,8 @@ public class ServiceDescription
     // current autorstart state
     private boolean autostart = true;
 
-    // manual stop?
-    private boolean stopped = false;
+    // enabled?
+    private boolean enabled = true;
 
     // for submitted service, the registered service id
     private ADuccId id;
@@ -194,12 +194,12 @@ public class ServiceDescription
                this.autostart = autostart;
        }
 
-       public boolean isStopped() {
-               return stopped;
+       public boolean isEnabled() {
+               return enabled;
        }
 
-       public void setStopped(boolean stopped) {
-               this.stopped = stopped;
+       public void setEnabled(boolean enabled) {
+               this.enabled = enabled;
        }
 
        public IServiceStatistics getQstats() {
@@ -329,8 +329,8 @@ public class ServiceDescription
         sb.append(autostart);
         sb.append("\n");
         
-        sb.append("   Manual Stop     : ");
-        sb.append(stopped);
+        sb.append("   Enabled         : ");
+        sb.append(enabled);
         sb.append("\n");
 
         sb.append("   Service Statistics: ");


Reply via email to