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 2015/03/03 22:10:24 UTC

svn commit: r1663792 - in /uima/sandbox/uima-ducc/trunk: src/main/resources/ uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ uima-ducc-web/src/main/java/org/apache/uima/ducc/ws...

Author: challngr
Date: Tue Mar  3 21:10:24 2015
New Revision: 1663792

URL: http://svn.apache.org/r1663792
Log:
UIMA-4258 Constant service instance ID in environment as DUCC_SERVICE_INSTANCE.

Modified:
    uima/sandbox/uima-ducc/trunk/src/main/resources/default.ducc.properties
    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/ServiceSet.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/OrchestratorStateDuccEvent.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/DuccDataHelper.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServiceInterpreter.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServicesHelper.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServicesRegistry.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAbstractHandler.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java

Modified: uima/sandbox/uima-ducc/trunk/src/main/resources/default.ducc.properties
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/src/main/resources/default.ducc.properties?rev=1663792&r1=1663791&r2=1663792&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/src/main/resources/default.ducc.properties (original)
+++ uima/sandbox/uima-ducc/trunk/src/main/resources/default.ducc.properties Tue Mar  3 21:10:24 2015
@@ -156,7 +156,7 @@ ducc.ws.jvm.args           = -Xmx2G -Dja
 
 # ========== CLI Configuration block ==========
 # These environment values are included on job/service/AP submissions
-ducc.environment.propagated = USER HOME LANG
+ducc.environment.propagated = USER HOME LANG DUCC_SERVICE_INSTANCE
 
 # No timeout on CLI requests
 ducc.cli.httpclient.sotimeout=0

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=1663792&r1=1663791&r2=1663792&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 Tue Mar  3 21:10:24 2015
@@ -41,6 +41,10 @@ class ServiceInstance
 
     long   numeric_id;                             // unique numeric ducc-assigned id
     long   share_id;                               // RM's share ID for this instance
+    int    instance_id = 0;                        // unique and constant ID assigned by SM to this instance
+                                                   // which allows services to know "which" instance they are
+                                                   // UIMA-4258
+
     String host;                                   // Where the instance is scheduled
 
     ServiceSet sset;                               // handle to the service definitiopn
@@ -63,6 +67,18 @@ class ServiceInstance
         this.host = "<unknown>";
     }
 
+    // UIMA-4258
+    public int getInstanceId()
+    {
+        return instance_id;
+    }
+
+    // UIMA-4258
+    public void setInstanceId(int id)
+    {
+        this.instance_id = id;
+    }
+
     public long getId() {
         return this.numeric_id;
     }
@@ -184,6 +200,7 @@ class ServiceInstance
         ProcessBuilder pb = new ProcessBuilder(args);
         Map<String, String> env = pb.environment();
         env.put("DUCC_HOME", System.getProperty("DUCC_HOME"));
+        env.put("DUCC_SERVICE_INSTANCE", Integer.toString(instance_id));  // UIMA-4258
 
         ArrayList<String> stdout_lines = new ArrayList<String>();
         ArrayList<String> stderr_lines = new ArrayList<String>();

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=1663792&r1=1663791&r2=1663792&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 Tue Mar  3 21:10:24 2015
@@ -29,11 +29,11 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Timer;
 import java.util.TimerTask;
+import java.util.TreeMap;
 
 import org.apache.uima.UIMAFramework;
 import org.apache.uima.ducc.cli.IUiOptions.UiOption;
@@ -74,7 +74,10 @@ public class ServiceSet
     // a unique-to SM key for implicit references.
 
     Map<Long, ServiceInstance> implementors = new HashMap<Long, ServiceInstance>();
-    List<ServiceInstance> pendingStarts = new LinkedList<ServiceInstance>();
+    TreeMap<Integer, Integer>  available_instance_ids = new TreeMap<Integer, Integer>();  // UIMA-4258
+    Map<Long, Integer>         pending_instances = new HashMap<Long, Integer>();          // For hot bounce, restore the instance ids UIMA-4258
+
+    // List<ServiceInstance> pendingStarts = new LinkedList<ServiceInstance>();           // UIMA-4258 not used anywhere
 
     // key is job/service id, value is same.  it's a map for fast existence check
     Map<DuccId, DuccId> references = new HashMap<DuccId, DuccId>();
@@ -242,6 +245,8 @@ public class ServiceSet
             meta_props.put("ping-only", "false");
             this.ping_only = false;
         }
+
+        savePendingInstanceIds();         // UIMA-4258
         // caller will save the meta props, **if** the rest of registration is ok.
 
         //UIMAFramework.getLogger(BaseUIMAAsynchronousEngineCommon_impl.class).setLevel(Level.OFF);
@@ -255,7 +260,22 @@ public class ServiceSet
         return id;
     }
 
-    protected void parseEndpoint(String ep)
+    // UIMA-4258
+    // Get potentially pending instances from meta and stash them away for a bit
+    // Used in hot-start to remap instance ids to ducc ids
+    void savePendingInstanceIds()
+    {
+        String ids = meta_props.getProperty(implementors_key);
+        if ( ids == null ) return;
+
+        String[] tmp = ids.split("\\s+");
+        for (String s : tmp) {
+            String[] id_inst = s.split("\\.");
+            pending_instances.put(Long.parseLong(id_inst[0]), Integer.parseInt(id_inst[1]));
+        }
+    }
+
+    void parseEndpoint(String ep)
     {
         if ( ep.startsWith(ServiceType.UimaAs.decode()) ) {
             int ndx = ep.indexOf(":");
@@ -446,6 +466,7 @@ public class ServiceSet
         si.setId(id.getFriendly());
         si.setStopped(false);
         si.setUser(this.user);
+        si.setInstanceId(pending_instances.get(id.getFriendly())); // UIMA-4258
 
         handler.addInstance(this, si);
         pendingImplementors.put(id.getFriendly(), si);
@@ -471,6 +492,7 @@ public class ServiceSet
         // must update history against stuff we used to have and don't any more
         //
         String old_impls = meta_props.getProperty(implementors_key);
+        logger.info("bootComplete", id, "IMPLS :", old_impls);
         if ( old_impls != null ) {
             Map<String, String> ip = new HashMap<String, String>();
             String[]   keys = old_impls.split("\\s+");
@@ -503,6 +525,24 @@ public class ServiceSet
             }
         }
 
+        // UIMA-4258 restore instance ID if this is a hot restart
+        if ( pending_instances.size() != 0 ) {
+            TreeMap<Integer, Integer> nst = new TreeMap<Integer, Integer>();
+            for (int i : pending_instances.values()) {
+                nst.put(i, i);
+            }
+            int ndx = 0;
+            while ( nst.size() > 0 ) {
+                if ( nst.containsKey(ndx) ) {
+                    nst.remove(ndx);
+                } else {
+                    available_instance_ids.put(ndx, ndx);
+                }
+                ndx++;
+            }
+        }
+        pending_instances = null;
+
         // on restart, if we think we were ref started when we crashed, but there are no
         // implementors, we can't actually be ref started, so clean that up.
         if ( isReferencedStart() && (countImplementors() == 0 ) ) {
@@ -804,12 +844,16 @@ public class ServiceSet
         if ( implementors.size() == 0 ) {
             meta_props.remove(implementors_key);
         } else {
-            StringBuffer sb = new StringBuffer();
+            StringBuffer sb_ducc_id = new StringBuffer();
             for ( Long l : implementors.keySet() ) {
-                sb.append(Long.toString(l));
-                sb.append(" ");
+                // UIMA-4258 Add instance id to ducc id when saving
+                ServiceInstance inst = implementors.get(l);
+                sb_ducc_id.append(Long.toString(l));
+                sb_ducc_id.append(".");
+                sb_ducc_id.append(Integer.toString(inst.getInstanceId()));
+                sb_ducc_id.append(" ");
             }
-            String s = sb.toString().trim();
+            String s = sb_ducc_id.toString().trim();
             meta_props.setProperty(implementors_key, s);
         }
 
@@ -1170,6 +1214,7 @@ public class ServiceSet
     	String methodName = "removeImplementor";
         logger.info(methodName, id, "Removing implementor", si.getId());
         implementors.remove(si.getId());
+        // Note, we don't save the instance id because this is only for ping-only services that have no instid
     }
 
     /**
@@ -1206,6 +1251,7 @@ public class ServiceSet
             
             logger.info(methodName, this.id, "Removing implementor", fid, "(", key, ") completion", jct);
             stoppedInstance = implementors.remove(fid);          // won't fail, was checked for on entry
+            conditionally_stash_instance_id(stoppedInstance.getInstanceId()); // UIMA-4258
             
             // TODO: put history into a better place
             String history = meta_props.getStringProperty(history_key, "");
@@ -1786,6 +1832,67 @@ public class ServiceSet
         log_text(logdir, buf.toString());
     }
 
+    /**
+     * See if there is an instance ID to reuse - if so, we need the lowest one.  
+     * If not, assign the next on in sequence.
+     *
+     * This maintains the property that all instances sequential from 0 to max are either 
+     * already assigned, or on the available_instance_ids tree.  Thus, if it's not on the tree,
+     * we can find the next one by taking the lenght of the implementors structure.
+     *
+     * The reason we need to remember this is because pingers are allowed to stop specific
+     * instances.  As well, specific instances may croak.  We always want to restart with the
+     * lowest available instance if we have to reuse ids.
+     */
+    synchronized int find_next_instance()
+    {
+        int ret = implementors.size();
+        if ( available_instance_ids.size() > 0 ) {
+            ret = available_instance_ids.firstKey();
+            available_instance_ids.remove(ret);
+        }
+        return ret;
+    }
+
+    /**
+     * Save the id for possible reuse.
+     *
+     * It's an error, albeit non-fatal, if the instance is already stashed.
+
+     * Note: this might be fatal for the instance, or the service, but it's not fatal for the SM
+     * so we simply note it in the log but not crash SM
+     * UIMA-4258
+     */
+    synchronized void stash_instance_id(int instid)
+    {
+    	String methodName = "stash_intance_id";
+        if ( available_instance_ids.containsKey(instid) ) {
+            try {
+                // put a scary marker in the log
+                throw new Exception("Duplicate instance id found: " + instid);
+            } catch (Exception e) {
+                logger.warn(methodName, id, e);
+            }
+            return;
+        }
+
+        available_instance_ids.put(instid, instid);
+    }
+
+    /**
+     * Save the id for possible reuse, if it hasn't already been saved.
+     * This is called when we see a state change that indicates a service has exited.  Usually we
+     * hope this is because it was stopped, in which case we already stashed the id.  But if it
+     * crashed it may not be stashed yet, so we do it here.
+     * UIMA-4258
+     */
+    synchronized void conditionally_stash_instance_id(int instid)
+    {
+        if ( available_instance_ids.containsKey(instid) ) {
+            return;
+        }
+        stash_instance_id(instid);        
+    }
 
     synchronized void start(int ninstances)
     {
@@ -1820,6 +1927,7 @@ public class ServiceSet
 
             for ( int i = 0; i < ninstances; i++ ) {
                 ServiceInstance si = new ServiceInstance(this);
+                si.setInstanceId(find_next_instance());
                 long instid = -1L;
                 logger.info(methodName, id, "Starting instance", i);
                 if ( (instid = si.start(props_filename, meta_props)) >= 0 ) {
@@ -1853,6 +1961,7 @@ public class ServiceSet
             logger.warn(methodName, id, "Can't find instance", iid, ", perhaps it's already gone.");
         } else {
             si.stop();
+            stash_instance_id(si.getInstanceId());         // UIMA-4258
             signal(si);
         }
     }
@@ -2013,6 +2122,7 @@ public class ServiceSet
 
         public void run() {
             si.stop();
+            stash_instance_id(si.getInstanceId());         // UIMA-4258
         }
     }
 

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/OrchestratorStateDuccEvent.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/OrchestratorStateDuccEvent.java?rev=1663792&r1=1663791&r2=1663792&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/OrchestratorStateDuccEvent.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/OrchestratorStateDuccEvent.java Tue Mar  3 21:10:24 2015
@@ -40,12 +40,12 @@ public class OrchestratorStateDuccEvent
 	
 	public void setWorkMap(DuccWorkMap value) {
 		this.workMap = value.deepCopy();
-		compress(this.workMap);
+		//compress(this.workMap);        // UIMA-4258, can't yet compress because of DUCC_SERVICE_INSTANCE
 	}
 	
 	public DuccWorkMap getWorkMap() {
 		DuccWorkMap value = this.workMap.deepCopy();
-		uncompress(value);
+		//uncompress(value);             // UIMA-4258, can't yet compress because of DUCC_SERVICE_INSTANCE
 		return value;
 	}
 	

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/DuccDataHelper.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/DuccDataHelper.java?rev=1663792&r1=1663791&r2=1663792&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/DuccDataHelper.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/DuccDataHelper.java Tue Mar  3 21:10:24 2015
@@ -71,72 +71,42 @@ public class DuccDataHelper {
 		}
 		return map;
 	}
-	
-	private String getServiceId(DuccId serviceId) {
-		String methodName = "getServiceId";
-		DuccId jobid = null;
-		duccLogger.trace(methodName, jobid, "enter");
-		String retVal = null;
-		ServicesRegistry servicesRegistry = ServicesRegistry.getInstance();
-		ServicesRegistryMap map = servicesRegistry.getMap();
-		for(Integer key : map.getDescendingKeySet()) {
-			ServicesRegistryMapPayload payload = map.get(key);
-			Properties meta = payload.meta;
-			String implementors = meta.getProperty(IServicesRegistry.implementors);
-			if(implementors != null) {
-				String[] implementorsArray = implementors.trim().split(" ");
-				for(String implementor : implementorsArray) {
-					if(implementor.trim().equals(""+serviceId.getFriendly()));
-					retVal = meta.getProperty(IServicesRegistry.numeric_id);
-					break;
-				}
-			}
-		}
-		duccLogger.trace(methodName, jobid, "exit");
-		return retVal;
-	}
-	
-	public TreeMap<String,ArrayList<String>> getServiceToServicesUsageMap() {
-		String methodName = "getServiceToServicesUsageMap";
-		DuccId jobid = null;
-		duccLogger.trace(methodName, jobid, "enter");
-		TreeMap<String,ArrayList<String>> map = new TreeMap<String,ArrayList<String>>();
-		DuccData duccData = DuccData.getInstance();
-		ConcurrentSkipListMap<JobInfo, JobInfo> jobs = duccData.getSortedServices();
-		for(JobInfo jobInfo : jobs.descendingKeySet()) {
-			DuccWorkJob service = jobInfo.getJob();
-			if(service.isOperational()) {
-				ServiceDeploymentType type = service.getServiceDeploymentType();
-				if(type != null) {
-					switch(type) {
-					case uima:
-					case custom:
-						DuccId duccId = service.getDuccId();
-						String serviceId = getServiceId(duccId);
-						if(serviceId != null) {
-							String[] dependencies = service.getServiceDependencies();
-							if(dependencies != null) {
-								for(String dependency : dependencies) {
-									if(!map.containsKey(dependency)) {
-										map.put(dependency, new ArrayList<String>());
-									}
-									ArrayList<String> serviceIds = map.get(dependency);
-									if(!serviceIds.contains(serviceId)) {
-										serviceIds.add(serviceId);
-									}
-								}
-							}
-						}
-						break;
-					default:
-						break;
-					}
-				}
-			}
-		}
-		duccLogger.trace(methodName, jobid, "exit");
-		return map;
-	}
+
+    // UIMA-4258 Common coe to parse meta.implementors	
+    public static String[] parseServiceIds(Properties meta)
+    {
+        String implementors = meta.getProperty(IServicesRegistry.implementors);
+        String[] ret = new String[0];
+        if(implementors != null) {
+            String[] tempArray = implementors.trim().split("\\s+");
+            ret = new String[tempArray.length];
+            int i = 0;
+            for (String s : tempArray) {
+                // Back compatibility for the shadow web servers, if no inst id then
+                // just return the 's'
+                if ( s.indexOf(".") > 0 ) {
+                    String[] id_inst = s.split("\\.");
+                    ret[i++] = id_inst[0].trim();
+                } else {
+                    ret[i++] = s;
+                }
+            }
+        }
+        return ret;
+    }
+
+    // UIMA-4258 return implementors in arraylist instead of strion[]
+    public static ArrayList<String> parseServiceIdsAsList(Properties meta)
+    {
+        String[] impls = parseServiceIds(meta);
+
+        ArrayList<String> ret = new ArrayList<String>();
+        for ( String s : impls ) {
+            ret.add(s);
+        }
+        return ret;
+    }
+
 	
 	public TreeMap<String,ArrayList<DuccId>> getServiceToReservationsUsageMap() {
 		TreeMap<String,ArrayList<DuccId>> map = new TreeMap<String,ArrayList<DuccId>>();

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServiceInterpreter.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServiceInterpreter.java?rev=1663792&r1=1663791&r2=1663792&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServiceInterpreter.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServiceInterpreter.java Tue Mar  3 21:10:24 2015
@@ -25,7 +25,7 @@ import org.apache.uima.ducc.common.utils
 import org.apache.uima.ducc.common.utils.DuccLoggerComponents;
 import org.apache.uima.ducc.common.utils.id.DuccId;
 import org.apache.uima.ducc.transport.event.sm.IService.ServiceState;
-import org.springframework.util.StringUtils;
+import org.apache.uima.ducc.ws.DuccDataHelper;
 
 public class ServiceInterpreter {
 	
@@ -70,18 +70,7 @@ public class ServiceInterpreter {
 		}
 		return retVal.trim();
 	}
-	
-	private static String[] getList(String string) {
-		String[] retVal = new String[0];
-		if(string != null) {
-			string = string.trim();
-			if(string.length() > 0) {
-				retVal = StringUtils.delimitedListToStringArray(string, " ");
-			}
-		}
-		return retVal;
-	}
-	
+		
 	private String placeholderPingerStatus = "";
 	
 	public String getPingerStatus() {
@@ -303,8 +292,8 @@ public class ServiceInterpreter {
 		String location = "getImplementors";
 		ArrayList<String> retVal = new ArrayList<String>();
 		try {
-			String value = getUninterpreted(meta, IServicesRegistry.implementors);
-			String[] implementors = getList(value);
+            // UIMA-4258, use common implementors parser
+            String[] implementors = DuccDataHelper.parseServiceIds(meta);
 			for(String implementor : implementors) {
 				retVal.add(implementor);
 			}

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServicesHelper.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServicesHelper.java?rev=1663792&r1=1663791&r2=1663792&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServicesHelper.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServicesHelper.java Tue Mar  3 21:10:24 2015
@@ -29,6 +29,7 @@ import org.apache.uima.ducc.transport.ev
 import org.apache.uima.ducc.transport.event.common.IDuccProcess;
 import org.apache.uima.ducc.transport.event.common.IDuccProcessMap;
 import org.apache.uima.ducc.ws.DuccData;
+import org.apache.uima.ducc.ws.DuccDataHelper;
 
 public class ServicesHelper {
 	
@@ -58,8 +59,8 @@ public class ServicesHelper {
 		ArrayList<String> retVal = new ArrayList<String>();
 		if(propertiesMeta != null) {
 			if(propertiesMeta.containsKey(IServicesRegistry.implementors)) {
-				String value = propertiesMeta.getProperty(IServicesRegistry.implementors);
-				String[] implementors = servicesRegistry.getList(value);
+                // UIMA-4258, use common implementors parser
+                String[] implementors = DuccDataHelper.parseServiceIds(propertiesMeta);
 				for(String implementor : implementors) {
 					retVal.add(implementor);
 				}

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServicesRegistry.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServicesRegistry.java?rev=1663792&r1=1663791&r2=1663792&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServicesRegistry.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/registry/ServicesRegistry.java Tue Mar  3 21:10:24 2015
@@ -30,6 +30,7 @@ import org.apache.uima.ducc.common.persi
 import org.apache.uima.ducc.common.utils.DuccLogger;
 import org.apache.uima.ducc.common.utils.DuccLoggerComponents;
 import org.apache.uima.ducc.common.utils.id.DuccId;
+import org.apache.uima.ducc.ws.DuccDataHelper;
 import org.apache.uima.ducc.ws.registry.sort.ServicesSortCache;
 import org.springframework.util.StringUtils;
 
@@ -203,8 +204,9 @@ public class ServicesRegistry {
 				ServicesRegistryMapPayload payload = map.get(key);
 				Properties meta = payload.meta;
 				if(meta != null) {
-					String implementors = meta.getProperty(IServicesRegistry.implementors);
-					String[] list = getList(implementors);
+                    // UIMA-4258, use common implementors parser
+                    String[] list = DuccDataHelper.parseServiceIds(meta);
+
 					for( String member : list ) {
 						if(member.equals(id+"")) {
 							if(meta.containsKey(IServicesRegistry.endpoint)) {

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAbstractHandler.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAbstractHandler.java?rev=1663792&r1=1663791&r2=1663792&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAbstractHandler.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAbstractHandler.java Tue Mar  3 21:10:24 2015
@@ -547,8 +547,8 @@ public abstract class DuccAbstractHandle
 		String deployments = "0";
 		if(propertiesMeta != null) {
 			if(propertiesMeta.containsKey(IServicesRegistry.implementors)) {
-				String value = propertiesMeta.getProperty(IServicesRegistry.implementors);
-				String[] implementors = servicesRegistry.getList(value);
+                // UIMA-4258, use common implementors parser
+                String[] implementors = DuccDataHelper.parseServiceIds(propertiesMeta);
 				deployments = ""+implementors.length;
 			}
 		}

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java?rev=1663792&r1=1663791&r2=1663792&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java Tue Mar  3 21:10:24 2015
@@ -2197,8 +2197,9 @@ public class DuccHandler extends DuccAbs
 			ServicesRegistryMapPayload payload = servicesRegistry.findService(name);
 			Properties properties;
 			properties = payload.meta;
-			
-			ArrayList<String> implementors = servicesRegistry.getArrayList(properties.getProperty(IServicesRegistry.implementors));
+
+            // UIMA-4258, use common implementors parser
+			ArrayList<String> implementors = DuccDataHelper.parseServiceIdsAsList(properties);
 			
 			DuccWorkJob service = null;
 			DuccWorkMap duccWorkMap = DuccData.getInstance().get();
@@ -2564,7 +2565,8 @@ public class DuccHandler extends DuccAbs
 			Properties properties;
 			properties = payload.meta;
 			
-			ArrayList<String> implementors = servicesRegistry.getArrayList(properties.getProperty(IServicesRegistry.implementors));
+            // UIMA-4258, use common implementors parser
+			ArrayList<String> implementors = DuccDataHelper.parseServiceIdsAsList(properties);
 			
 			DuccWorkMap duccWorkMap = DuccData.getInstance().get();
 			ArrayList<DuccWorkJob> servicesList = duccWorkMap.getServices(implementors);