Support for discovery of containers launched previously
diff --git a/containers-docker-local/pom.xml b/containers-docker-local/pom.xml
index ae7cada..4c67b7c 100644
--- a/containers-docker-local/pom.xml
+++ b/containers-docker-local/pom.xml
@@ -39,6 +39,12 @@
             <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>
+        
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.utils</artifactId>
+            <version>1.10.1-SNAPSHOT</version>
+        </dependency>
     </dependencies>
 </project>
 
diff --git a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerContainerFactory.java b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerContainerFactory.java
index a7c68d1..93b9464 100644
--- a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerContainerFactory.java
+++ b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerContainerFactory.java
@@ -25,9 +25,11 @@
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -37,12 +39,13 @@
 import org.apache.aries.containers.ContainerFactory;
 import org.apache.aries.containers.Service;
 import org.apache.aries.containers.ServiceConfig;
+import org.apache.felix.utils.json.JSONParser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class LocalDockerContainerFactory implements ContainerFactory {
     static final Logger LOG = LoggerFactory.getLogger(LocalDockerContainerFactory.class);
-    private static final String SERVICE_NAME = "service.name";
+    private static final String SERVICE_NAME = "org.apache.aries.containers.service.name";
 
     private static final String DOCKER_MACHINE_VM_NAME = System.getenv("DOCKER_MACHINE_NAME");
     private static final boolean CHECK_DOCKER_MACHINE = Stream
@@ -67,8 +70,6 @@
 
         if (docker == null)
             docker = new LocalDockerController();
-
-        // TODO discover any running docker containers.
     }
 
     @Override
@@ -79,9 +80,10 @@
         if (existingService != null)
             return existingService;
 
-        // TODO return discovered containers if it contains the requested one.
+        List<ContainerImpl> containers = discoverContainers(config);
+        if (containers.size() == 0)
+            containers = createContainers(config);
 
-        List<ContainerImpl> containers = createContainers(config);
         ServiceImpl svc = new ServiceImpl(config, this, containers);
         for (ContainerImpl c : containers) {
             c.setService(svc);
@@ -150,6 +152,54 @@
         }
     }
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private List<ContainerImpl> discoverContainers(ServiceConfig config) {
+        List<ContainerImpl> res = new ArrayList<>();
+        List<String> ids = docker.ps(SERVICE_NAME + "=" + config.getServiceName());
+        if (ids.size() == 0)
+            return Collections.emptyList();
+
+        String infoJSON = docker.inspect(ids.toArray(new String [] {}));
+        List<Object> data = new JSONParser(infoJSON).getParsedList();
+        for (Object d : data) {
+            if (!(d instanceof Map))
+                continue;
+
+            Map m = (Map) d;
+            Object ns = m.get("NetworkSettings");
+            Map<Integer, Integer> ports = new HashMap<>();
+            if (ns instanceof Map) {
+                Object pd = ((Map) ns).get("Ports");
+                if (pd instanceof Map) {
+                    Map pm = (Map) pd;
+                    for(Map.Entry entry : (Set<Map.Entry>) pm.entrySet()) {
+                        try {
+                            String key = entry.getKey().toString();
+                            int idx = key.indexOf('/');
+                            if (idx > 0)
+                                key = key.substring(0, idx);
+                            int containerPort = Integer.parseInt(key);
+                            int hostPort = -1;
+                            for (Object val : (List) entry.getValue()) {
+                                if (val instanceof Map) {
+                                    hostPort = Integer.parseInt(((Map) val).get("HostPort").toString());
+                                }
+                            }
+
+                            if (hostPort != -1) {
+                                ports.put(containerPort, hostPort);
+                            }
+                        } catch (Exception nfe) {
+                            // ignore parsing exceptions, try next one
+                        }
+                    }
+                }
+            }
+            res.add(new ContainerImpl(m.get("Id").toString(), LocalDockerContainerFactory.getContainerHost(), ports));
+        }
+        return res;
+    }
+
     private int getFreePort() throws IOException {
         try (ServerSocket ss = new ServerSocket(0)) {
             return ss.getLocalPort();
diff --git a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerController.java b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerController.java
index 2fecfa7..bb36d07 100644
--- a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerController.java
+++ b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerController.java
@@ -18,7 +18,7 @@
  */
 package org.apache.aries.containers.docker.local.impl;
 
-import java.io.LineNumberReader;
+import java.io.BufferedReader;
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.List;
@@ -48,18 +48,39 @@
         return new DockerContainerInfo(id, LocalDockerContainerFactory.getContainerHost());
     }
 
+    public List<String> ps(String labelFilter) {
+        String res = runCommand("docker", "ps", "-q", "-f", "label=" + labelFilter);
+
+        String[] sa = res.trim().split("\\s+");
+        List<String> sl = new ArrayList<>(sa.length);
+        for (String s : sa) {
+            s = s.trim();
+            if (s.length() > 0)
+                sl.add(s);
+        }
+        return sl;
+    }
+
+    public String inspect(String... ids) {
+        String[] command = new String[ids.length+2];
+        command[0] = "docker";
+        command[1] = "inspect";
+        System.arraycopy(ids, 0, command, 2, ids.length);
+        return runCommand(command);
+    }
+
     String runCommandExpectSingleID(String ... command) throws Exception {
-        String res = ProcessRunner.waitFor(ProcessRunner.run(command));
+        String res = runCommand(command);
         if (res != null) {
             res = res.trim();
             String lastLine = res;
-            try ( final LineNumberReader lnr = new LineNumberReader(new StringReader(res)) ) {
+            try (BufferedReader lnr = new BufferedReader(new StringReader(res))) {
                 String line;
-                while ( ( line = lnr.readLine()) != null ) {
+                while ((line = lnr.readLine()) != null) {
                     lastLine = line;
                 }
             }
-            if ( lastLine.indexOf(' ') != -1 ) {
+            if (lastLine.indexOf(' ') != -1 ) {
                  throw new Exception("Unable to execute docker command: " + res);
             }
             res = lastLine;
@@ -67,4 +88,8 @@
 
         return res;
     }
+
+    private String runCommand(String... command) {
+        return ProcessRunner.waitFor(ProcessRunner.run(command));
+    }
 }