aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject aries-containers git commit: Rename ContainerFactory to ServiceManager and add some Javadoc.
Date Fri, 26 May 2017 15:19:34 GMT
Repository: aries-containers
Updated Branches:
  refs/heads/master 5d0a7ed62 -> 56d7ed550


Rename ContainerFactory to ServiceManager and add some Javadoc.


Project: http://git-wip-us.apache.org/repos/asf/aries-containers/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-containers/commit/56d7ed55
Tree: http://git-wip-us.apache.org/repos/asf/aries-containers/tree/56d7ed55
Diff: http://git-wip-us.apache.org/repos/asf/aries-containers/diff/56d7ed55

Branch: refs/heads/master
Commit: 56d7ed55046cc1ff3014b7eaf771d401dd32a3ca
Parents: 5d0a7ed
Author: David Bosschaert <davidb@apache.org>
Authored: Fri May 26 16:19:11 2017 +0100
Committer: David Bosschaert <davidb@apache.org>
Committed: Fri May 26 16:19:11 2017 +0100

----------------------------------------------------------------------
 .../aries/containers/ContainerFactory.java      |  32 ---
 .../apache/aries/containers/ServiceManager.java |  62 +++++
 .../containers/docker/local/impl/Activator.java |   8 +-
 .../docker/local/impl/ContainerImpl.java        |   2 +-
 .../local/impl/LocalDockerContainerFactory.java | 247 -------------------
 .../local/impl/LocalDockerController.java       |   2 +-
 .../local/impl/LocalDockerServiceManager.java   | 247 +++++++++++++++++++
 .../docker/local/impl/ServiceImpl.java          |   6 +-
 .../impl/MarathonConfigManagedService.java      |  10 +-
 .../marathon/impl/MarathonContainerFactory.java | 151 ------------
 .../marathon/impl/MarathonServiceManager.java   | 151 ++++++++++++
 11 files changed, 474 insertions(+), 444 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-api/src/main/java/org/apache/aries/containers/ContainerFactory.java
----------------------------------------------------------------------
diff --git a/containers-api/src/main/java/org/apache/aries/containers/ContainerFactory.java
b/containers-api/src/main/java/org/apache/aries/containers/ContainerFactory.java
deleted file mode 100644
index d6f988b..0000000
--- a/containers-api/src/main/java/org/apache/aries/containers/ContainerFactory.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.aries.containers;
-
-import java.util.Set;
-
-import org.osgi.annotation.versioning.ProviderType;
-
-@ProviderType
-public interface ContainerFactory {
-    public static final String BINDING = "container.factory.binding";
-
-    Service getService(ServiceConfig config) throws Exception;
-
-    Set<String> listServices() throws Exception;
-}

http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-api/src/main/java/org/apache/aries/containers/ServiceManager.java
----------------------------------------------------------------------
diff --git a/containers-api/src/main/java/org/apache/aries/containers/ServiceManager.java
b/containers-api/src/main/java/org/apache/aries/containers/ServiceManager.java
new file mode 100644
index 0000000..8c86370
--- /dev/null
+++ b/containers-api/src/main/java/org/apache/aries/containers/ServiceManager.java
@@ -0,0 +1,62 @@
+/*
+ * 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.aries.containers;
+
+import java.util.Set;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+/** The service manager creates services and otherwise manages service.
+ * Multiple implementations of this inteface can co-exist binding to
+ * various back-end service containers. <p>
+ *
+ * To find a service manager for a specific binding select this service
+ * on the {@code container.factory.binding} service property.
+ */
+@ProviderType
+public interface ServiceManager {
+    /**
+     * Services should register this property to declare the back-end that
+     * they bind to. For example {@code marathon} or {@code docker.local}.
+     */
+    public static final String BINDING = "container.factory.binding";
+
+    /**
+     * Obtain a service for the specified configuration. If the service
+     * already exists it should be returned. Also if the service was created
+     * during previous runs of the manager it should be discovered and used.
+     * <p>
+     * Otherwise a new service should be created for the specified
+     * configuration. <p>
+     * Services can outlive the life cycle of the Service Manager.
+     *
+     * @param config The service configuration for the service.
+     * @return A {@link Service} instance representing this service.
+     * @throws Exception
+     */
+    Service getService(ServiceConfig config) throws Exception;
+
+    /**
+     * List available services by name.
+     * @return A set with the service names. If no services are found an empty
+     * set is returned.
+     * @throws Exception
+     */
+    Set<String> listServices() throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/Activator.java
----------------------------------------------------------------------
diff --git a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/Activator.java
b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/Activator.java
index a43c5a5..3b54050 100644
--- a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/Activator.java
+++ b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/Activator.java
@@ -21,7 +21,7 @@ package org.apache.aries.containers.docker.local.impl;
 import java.util.Dictionary;
 import java.util.Hashtable;
 
-import org.apache.aries.containers.ContainerFactory;
+import org.apache.aries.containers.ServiceManager;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 
@@ -29,9 +29,9 @@ public class Activator implements BundleActivator {
     @Override
     public void start(BundleContext context) throws Exception {
         Dictionary<String, Object> props = new Hashtable<>();
-        props.put(ContainerFactory.BINDING, "docker.local");
-        context.registerService(ContainerFactory.class,
-                new LocalDockerContainerFactory(), props);
+        props.put(ServiceManager.BINDING, "docker.local");
+        context.registerService(ServiceManager.class,
+                new LocalDockerServiceManager(), props);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/ContainerImpl.java
----------------------------------------------------------------------
diff --git a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/ContainerImpl.java
b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/ContainerImpl.java
index 6584ab6..2909f37 100644
--- a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/ContainerImpl.java
+++ b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/ContainerImpl.java
@@ -42,7 +42,7 @@ class ContainerImpl implements Container {
         try {
             service.killContainer(this);
         } catch (Exception e) {
-            LocalDockerContainerFactory.LOG.warn("Problem killing container {}", this, e);
+            LocalDockerServiceManager.LOG.warn("Problem killing container {}", this, e);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerContainerFactory.java
----------------------------------------------------------------------
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
deleted file mode 100644
index 673f664..0000000
--- a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerContainerFactory.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * 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.aries.containers.docker.local.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-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.regex.Pattern;
-import java.util.stream.Stream;
-
-import org.apache.aries.containers.Container;
-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 = "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
-            .of(System.getenv("PATH").split(Pattern.quote(File.pathSeparator)))
-            .map(Paths::get)
-            .anyMatch(path -> Files.exists(path.resolve("docker-machine")));
-
-    private static final boolean USE_DOCKER_MACHINE = (DOCKER_MACHINE_VM_NAME != null) &&
CHECK_DOCKER_MACHINE;
-    private static final String CONTAINER_HOST = USE_DOCKER_MACHINE
-            ? ProcessRunner.waitFor(ProcessRunner.run("docker-machine", "ip", DOCKER_MACHINE_VM_NAME))
-            : "localhost";
-
-
-    private volatile LocalDockerController docker;
-    private final ConcurrentMap<String, Service> services =
-            new ConcurrentHashMap<>();
-
-    public LocalDockerContainerFactory() {
-        if (docker == null)
-            docker = new LocalDockerController();
-    }
-
-    List<String> getDockerIDs(ServiceConfig config) {
-        return docker.ps(SERVICE_NAME + "=" + config.getServiceName());
-    }
-
-    @Override
-    public Service getService(ServiceConfig config) throws Exception {
-        Service existingService = services.get(config.getServiceName());
-        if (existingService != null)
-            return existingService;
-
-        List<ContainerImpl> containers = discoverContainers(config);
-        if (containers.size() == 0)
-            containers = createContainers(config);
-
-        ServiceImpl svc = new ServiceImpl(config, this, containers);
-        for (ContainerImpl c : containers) {
-            c.setService(svc);
-        }
-
-        services.put(config.getServiceName(), svc);
-
-        return svc;
-    }
-
-    private List<ContainerImpl> createContainers(ServiceConfig config) throws Exception
{
-        List<ContainerImpl> containers = new ArrayList<>();
-
-        for (int i=0; i<config.getRequestedInstances(); i++) {
-            containers.add(createDockerContainer(config));
-        }
-
-        return containers;
-    }
-
-    ContainerImpl createDockerContainer(ServiceConfig config) throws Exception {
-        List<String> command = new ArrayList<>();
-        command.add("-d");
-        command.add("-l");
-        command.add(SERVICE_NAME + "=" + config.getServiceName());
-
-        String ep = config.getEntryPoint();
-        if (ep != null) {
-            command.add("--entrypoint");
-            command.add(ep);
-        }
-
-        Map<Integer, Integer> ports = new HashMap<>();
-        for (Integer p : config.getContainerPorts()) {
-            command.add("-p");
-            int freePort = getFreePort();
-            command.add(freePort + ":" + p);
-            ports.put(p, freePort);
-
-        }
-
-        for(Map.Entry<String, String> entry : config.getEnvVars().entrySet()) {
-            command.add("-e");
-            command.add(entry.getKey() + '=' + entry.getValue());
-        }
-
-        command.add("--cpus");
-        command.add("" + config.getRequestedCpuUnits() + "");
-
-        command.add("-m");
-        command.add("" + ((int) config.getRequestedMemory()) + "m");
-
-        command.add(config.getContainerImage());
-        command.addAll(Arrays.asList(config.getCommandLine()));
-
-        DockerContainerInfo info = docker.run(command);
-
-        return new ContainerImpl(info.getID(), info.getIP(), ports);
-    }
-
-    public void destroyDockerContainer(String id, boolean remove) throws Exception {
-        if (remove) {
-            docker.remove(id);
-        } else {
-            docker.kill(id);
-        }
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    List<ContainerImpl> discoverContainers(ServiceConfig config) {
-        List<ContainerImpl> res = new ArrayList<>();
-        List<String> ids = getDockerIDs(config);
-        if (ids.size() == 0)
-            return Collections.emptyList();
-
-        String infoJSON = docker.inspect(ids);
-        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
-                        }
-                    }
-                }
-            }
-            // TODO check that the settings match!
-            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();
-        }
-    }
-
-    public static String getContainerHost() {
-        return CONTAINER_HOST;
-    }
-
-    @Override
-    @SuppressWarnings("rawtypes")
-    public Set<String> listServices() throws Exception {
-        Set<String> res = new HashSet<>();
-        List<String> ids = docker.ps(SERVICE_NAME);
-
-        for (Service svc : services.values()) {
-            res.add(svc.getConfiguration().getServiceName());
-            for (Container c : svc.listContainers()) {
-                ids.remove(c.getID());
-            }
-        }
-
-        String json = docker.inspect(ids);
-        for (Object data : new JSONParser(json).getParsedList()) {
-            // These are services that have been launched previously and are not internally
synced yet
-            if (!(data instanceof Map)) {
-                continue;
-            }
-
-            Object cd = ((Map) data).get("Config");
-            if (cd instanceof Map) {
-                Object ld = ((Map) cd).get("Labels");
-                if (ld instanceof Map) {
-                    Object serviceName = ((Map) ld).get(SERVICE_NAME);
-                    if (serviceName instanceof String) {
-                        res.add((String) serviceName);
-                    }
-                }
-            }
-        }
-
-        return res;
-    }
-}

http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerController.java
----------------------------------------------------------------------
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 6b0e8c7..cf3ede1 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
@@ -44,7 +44,7 @@ class LocalDockerController {
         execCmd.addAll(command);
 
         String id = runCommandExpectSingleID(execCmd.toArray(new String [] {}));
-        return new DockerContainerInfo(id, LocalDockerContainerFactory.getContainerHost());
+        return new DockerContainerInfo(id, LocalDockerServiceManager.getContainerHost());
     }
 
     public List<String> ps(String labelFilter) {

http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerServiceManager.java
----------------------------------------------------------------------
diff --git a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerServiceManager.java
b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerServiceManager.java
new file mode 100644
index 0000000..4639e25
--- /dev/null
+++ b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerServiceManager.java
@@ -0,0 +1,247 @@
+/*
+ * 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.aries.containers.docker.local.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+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.regex.Pattern;
+import java.util.stream.Stream;
+
+import org.apache.aries.containers.Container;
+import org.apache.aries.containers.ServiceManager;
+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 LocalDockerServiceManager implements ServiceManager {
+    static final Logger LOG = LoggerFactory.getLogger(LocalDockerServiceManager.class);
+    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
+            .of(System.getenv("PATH").split(Pattern.quote(File.pathSeparator)))
+            .map(Paths::get)
+            .anyMatch(path -> Files.exists(path.resolve("docker-machine")));
+
+    private static final boolean USE_DOCKER_MACHINE = (DOCKER_MACHINE_VM_NAME != null) &&
CHECK_DOCKER_MACHINE;
+    private static final String CONTAINER_HOST = USE_DOCKER_MACHINE
+            ? ProcessRunner.waitFor(ProcessRunner.run("docker-machine", "ip", DOCKER_MACHINE_VM_NAME))
+            : "localhost";
+
+
+    private volatile LocalDockerController docker;
+    private final ConcurrentMap<String, Service> services =
+            new ConcurrentHashMap<>();
+
+    public LocalDockerServiceManager() {
+        if (docker == null)
+            docker = new LocalDockerController();
+    }
+
+    List<String> getDockerIDs(ServiceConfig config) {
+        return docker.ps(SERVICE_NAME + "=" + config.getServiceName());
+    }
+
+    @Override
+    public Service getService(ServiceConfig config) throws Exception {
+        Service existingService = services.get(config.getServiceName());
+        if (existingService != null)
+            return existingService;
+
+        List<ContainerImpl> containers = discoverContainers(config);
+        if (containers.size() == 0)
+            containers = createContainers(config);
+
+        ServiceImpl svc = new ServiceImpl(config, this, containers);
+        for (ContainerImpl c : containers) {
+            c.setService(svc);
+        }
+
+        services.put(config.getServiceName(), svc);
+
+        return svc;
+    }
+
+    private List<ContainerImpl> createContainers(ServiceConfig config) throws Exception
{
+        List<ContainerImpl> containers = new ArrayList<>();
+
+        for (int i=0; i<config.getRequestedInstances(); i++) {
+            containers.add(createDockerContainer(config));
+        }
+
+        return containers;
+    }
+
+    ContainerImpl createDockerContainer(ServiceConfig config) throws Exception {
+        List<String> command = new ArrayList<>();
+        command.add("-d");
+        command.add("-l");
+        command.add(SERVICE_NAME + "=" + config.getServiceName());
+
+        String ep = config.getEntryPoint();
+        if (ep != null) {
+            command.add("--entrypoint");
+            command.add(ep);
+        }
+
+        Map<Integer, Integer> ports = new HashMap<>();
+        for (Integer p : config.getContainerPorts()) {
+            command.add("-p");
+            int freePort = getFreePort();
+            command.add(freePort + ":" + p);
+            ports.put(p, freePort);
+
+        }
+
+        for(Map.Entry<String, String> entry : config.getEnvVars().entrySet()) {
+            command.add("-e");
+            command.add(entry.getKey() + '=' + entry.getValue());
+        }
+
+        command.add("--cpus");
+        command.add("" + config.getRequestedCpuUnits() + "");
+
+        command.add("-m");
+        command.add("" + ((int) config.getRequestedMemory()) + "m");
+
+        command.add(config.getContainerImage());
+        command.addAll(Arrays.asList(config.getCommandLine()));
+
+        DockerContainerInfo info = docker.run(command);
+
+        return new ContainerImpl(info.getID(), info.getIP(), ports);
+    }
+
+    public void destroyDockerContainer(String id, boolean remove) throws Exception {
+        if (remove) {
+            docker.remove(id);
+        } else {
+            docker.kill(id);
+        }
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    List<ContainerImpl> discoverContainers(ServiceConfig config) {
+        List<ContainerImpl> res = new ArrayList<>();
+        List<String> ids = getDockerIDs(config);
+        if (ids.size() == 0)
+            return Collections.emptyList();
+
+        String infoJSON = docker.inspect(ids);
+        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
+                        }
+                    }
+                }
+            }
+            // TODO check that the settings match!
+            res.add(new ContainerImpl(m.get("Id").toString(), LocalDockerServiceManager.getContainerHost(),
ports));
+        }
+        return res;
+    }
+
+    private int getFreePort() throws IOException {
+        try (ServerSocket ss = new ServerSocket(0)) {
+            return ss.getLocalPort();
+        }
+    }
+
+    public static String getContainerHost() {
+        return CONTAINER_HOST;
+    }
+
+    @Override
+    @SuppressWarnings("rawtypes")
+    public Set<String> listServices() throws Exception {
+        Set<String> res = new HashSet<>();
+        List<String> ids = docker.ps(SERVICE_NAME);
+
+        for (Service svc : services.values()) {
+            res.add(svc.getConfiguration().getServiceName());
+            for (Container c : svc.listContainers()) {
+                ids.remove(c.getID());
+            }
+        }
+
+        String json = docker.inspect(ids);
+        for (Object data : new JSONParser(json).getParsedList()) {
+            // These are services that have been launched previously and are not internally
synced yet
+            if (!(data instanceof Map)) {
+                continue;
+            }
+
+            Object cd = ((Map) data).get("Config");
+            if (cd instanceof Map) {
+                Object ld = ((Map) cd).get("Labels");
+                if (ld instanceof Map) {
+                    Object serviceName = ((Map) ld).get(SERVICE_NAME);
+                    if (serviceName instanceof String) {
+                        res.add((String) serviceName);
+                    }
+                }
+            }
+        }
+
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/ServiceImpl.java
----------------------------------------------------------------------
diff --git a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/ServiceImpl.java
b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/ServiceImpl.java
index 2c594a5..94aba89 100644
--- a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/ServiceImpl.java
+++ b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/ServiceImpl.java
@@ -29,10 +29,10 @@ import org.apache.aries.containers.ServiceConfig;
 class ServiceImpl implements Service {
     private final ServiceConfig config;
     private final List<ContainerImpl> containers;
-    private final LocalDockerContainerFactory factory;
+    private final LocalDockerServiceManager factory;
 
     public ServiceImpl(ServiceConfig config,
-            LocalDockerContainerFactory factory,
+            LocalDockerServiceManager factory,
             List<ContainerImpl> containers) {
         this.config = config;
         this.factory = factory;
@@ -71,7 +71,7 @@ class ServiceImpl implements Service {
                 }
             }
         } catch (Exception e) {
-            LocalDockerContainerFactory.LOG.error("Problem changing instance count of service
{} to {}",
+            LocalDockerServiceManager.LOG.error("Problem changing instance count of service
{} to {}",
                     config.getServiceName(), count, e);
         }
     }

http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonConfigManagedService.java
----------------------------------------------------------------------
diff --git a/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonConfigManagedService.java
b/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonConfigManagedService.java
index 87c1baf..d4b8746 100644
--- a/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonConfigManagedService.java
+++ b/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonConfigManagedService.java
@@ -21,7 +21,7 @@ package org.apache.aries.containers.marathon.impl;
 import java.util.Dictionary;
 import java.util.Hashtable;
 
-import org.apache.aries.containers.ContainerFactory;
+import org.apache.aries.containers.ServiceManager;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.cm.ConfigurationException;
@@ -34,7 +34,7 @@ public class MarathonConfigManagedService implements ManagedService {
 
     private final BundleContext bundleContext;
     volatile String marathonURL;
-    volatile ServiceRegistration<ContainerFactory> reg;
+    volatile ServiceRegistration<ServiceManager> reg;
 
     MarathonConfigManagedService(BundleContext bc) {
         bundleContext = bc;
@@ -60,10 +60,10 @@ public class MarathonConfigManagedService implements ManagedService {
             reg.unregister();
 
         marathonURL = marURL;
-        ContainerFactory cf = new MarathonContainerFactory(marathonURL);
+        ServiceManager cf = new MarathonServiceManager(marathonURL);
 
         Dictionary<String, Object> props = new Hashtable<>();
-        props.put(ContainerFactory.BINDING, "marathon");
-        reg = bundleContext.registerService(ContainerFactory.class, cf, props);
+        props.put(ServiceManager.BINDING, "marathon");
+        reg = bundleContext.registerService(ServiceManager.class, cf, props);
     }
 }

http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonContainerFactory.java
----------------------------------------------------------------------
diff --git a/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonContainerFactory.java
b/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonContainerFactory.java
deleted file mode 100644
index e5c6b16..0000000
--- a/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonContainerFactory.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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.aries.containers.marathon.impl;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.aries.containers.ContainerFactory;
-import org.apache.aries.containers.Service;
-import org.apache.aries.containers.ServiceConfig;
-
-import mesosphere.dcos.client.DCOSClient;
-import mesosphere.dcos.client.model.DCOSAuthCredentials;
-import mesosphere.marathon.client.Marathon;
-import mesosphere.marathon.client.MarathonClient;
-import mesosphere.marathon.client.model.v2.App;
-import mesosphere.marathon.client.model.v2.Container;
-import mesosphere.marathon.client.model.v2.Docker;
-import mesosphere.marathon.client.model.v2.GetAppsResponse;
-import mesosphere.marathon.client.model.v2.Port;
-
-public class MarathonContainerFactory implements ContainerFactory {
-    private static final String SERVICE_NAME = "org.apache.aries.containers.service.name";
-
-    private final Marathon marathonClient;
-
-    public MarathonContainerFactory(String marathonURL) {
-        marathonClient = MarathonClient.getInstance(marathonURL);
-    }
-
-    public MarathonContainerFactory(String marathonURL, String dcosUser, String passToken,
boolean serviceAcct) {
-        DCOSAuthCredentials authCredentials;
-        if (serviceAcct) {
-            authCredentials = DCOSAuthCredentials.forServiceAccount(dcosUser, passToken);
-        } else {
-            authCredentials = DCOSAuthCredentials.forUserAccount(dcosUser, passToken);
-        }
-        marathonClient = DCOSClient.getInstance(marathonURL, authCredentials);
-    }
-
-    @Override
-    public Service getService(ServiceConfig config) throws Exception {
-        GetAppsResponse existing = marathonClient.getApps(
-                Collections.singletonMap("label", SERVICE_NAME + "==" + config.getServiceName()));
-        if (existing.getApps().size() > 0) {
-            return createServiceFromExistingApp(existing.getApps(), config);
-        }
-
-        App app = new App();
-        app.setId(config.getServiceName());
-        app.setCpus(config.getRequestedCpuUnits());
-        app.setMem(config.getRequestedMemory());
-        app.setInstances(config.getRequestedInstances());
-        app.setEnv(Collections.unmodifiableMap(config.getEnvVars()));
-
-        StringBuilder cmd = new StringBuilder();
-        if (config.getEntryPoint() != null) {
-            // TODO is this right?
-            cmd.append(config.getEntryPoint());
-        }
-
-        if (config.getCommandLine().length > 0) {
-            for (String c : config.getCommandLine()) {
-                if (cmd.length() > 0)
-                    cmd.append(' ');
-
-                if (c.contains(" "))
-                    c = "'" + c + "'";
-
-                cmd.append(c);
-            }
-        }
-        if (cmd.length() > 0)
-            app.setCmd(cmd.toString());
-
-        Docker docker = new Docker();
-        docker.setImage(config.getContainerImage());
-        docker.setNetwork("BRIDGE"); // TODO is this correct?
-        List<Port> ports = new ArrayList<>();
-        for (int p : config.getContainerPorts()) {
-            Port port = new Port();
-            port.setContainerPort(p);
-            ports.add(port);
-        }
-        docker.setPortMappings(ports);
-
-        Container container = new Container();
-        container.setType("DOCKER");
-        container.setDocker(docker);
-
-        app.setContainer(container);
-        app.addLabel(SERVICE_NAME, config.getServiceName());
-
-        App res = marathonClient.createApp(app);
-
-        return createServiceFromApp(res, config);
-    }
-
-    private Service createServiceFromExistingApp(List<App> apps, ServiceConfig config)
{
-        if (apps.size() != 1)
-            throw new IllegalStateException("More than one existing app found for service
" +
-                    config.getServiceName() + " " + apps);
-
-        return createServiceFromApp(apps.get(0), config);
-    }
-
-    private Service createServiceFromApp(App app, ServiceConfig cfg) {
-        // TODO make this check more thorough
-        if (!cfg.getServiceName().equals(app.getLabels().get(SERVICE_NAME)))
-            throw new IllegalStateException("Application and configuration don't match");
-
-        ServiceImpl svc = new ServiceImpl(marathonClient, app, cfg);
-        return svc;
-    }
-
-    @Override
-    public Set<String> listServices() throws Exception {
-        GetAppsResponse services = marathonClient.getApps(
-                Collections.singletonMap("label", SERVICE_NAME));
-
-        Set<String> serviceNames = new HashSet<>();
-        for (App app : services.getApps()) {
-            Map<String, String> labels = app.getLabels();
-            String name = labels.get(SERVICE_NAME);
-            if (name != null && name.length() > 0)
-                serviceNames.add(name);
-        }
-        return serviceNames;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/aries-containers/blob/56d7ed55/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonServiceManager.java
----------------------------------------------------------------------
diff --git a/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonServiceManager.java
b/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonServiceManager.java
new file mode 100644
index 0000000..f39ef61
--- /dev/null
+++ b/containers-marathon/src/main/java/org/apache/aries/containers/marathon/impl/MarathonServiceManager.java
@@ -0,0 +1,151 @@
+/*
+ * 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.aries.containers.marathon.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.aries.containers.ServiceManager;
+import org.apache.aries.containers.Service;
+import org.apache.aries.containers.ServiceConfig;
+
+import mesosphere.dcos.client.DCOSClient;
+import mesosphere.dcos.client.model.DCOSAuthCredentials;
+import mesosphere.marathon.client.Marathon;
+import mesosphere.marathon.client.MarathonClient;
+import mesosphere.marathon.client.model.v2.App;
+import mesosphere.marathon.client.model.v2.Container;
+import mesosphere.marathon.client.model.v2.Docker;
+import mesosphere.marathon.client.model.v2.GetAppsResponse;
+import mesosphere.marathon.client.model.v2.Port;
+
+public class MarathonServiceManager implements ServiceManager {
+    private static final String SERVICE_NAME = "org.apache.aries.containers.service.name";
+
+    private final Marathon marathonClient;
+
+    public MarathonServiceManager(String marathonURL) {
+        marathonClient = MarathonClient.getInstance(marathonURL);
+    }
+
+    public MarathonServiceManager(String marathonURL, String dcosUser, String passToken,
boolean serviceAcct) {
+        DCOSAuthCredentials authCredentials;
+        if (serviceAcct) {
+            authCredentials = DCOSAuthCredentials.forServiceAccount(dcosUser, passToken);
+        } else {
+            authCredentials = DCOSAuthCredentials.forUserAccount(dcosUser, passToken);
+        }
+        marathonClient = DCOSClient.getInstance(marathonURL, authCredentials);
+    }
+
+    @Override
+    public Service getService(ServiceConfig config) throws Exception {
+        GetAppsResponse existing = marathonClient.getApps(
+                Collections.singletonMap("label", SERVICE_NAME + "==" + config.getServiceName()));
+        if (existing.getApps().size() > 0) {
+            return createServiceFromExistingApp(existing.getApps(), config);
+        }
+
+        App app = new App();
+        app.setId(config.getServiceName());
+        app.setCpus(config.getRequestedCpuUnits());
+        app.setMem(config.getRequestedMemory());
+        app.setInstances(config.getRequestedInstances());
+        app.setEnv(Collections.unmodifiableMap(config.getEnvVars()));
+
+        StringBuilder cmd = new StringBuilder();
+        if (config.getEntryPoint() != null) {
+            // TODO is this right?
+            cmd.append(config.getEntryPoint());
+        }
+
+        if (config.getCommandLine().length > 0) {
+            for (String c : config.getCommandLine()) {
+                if (cmd.length() > 0)
+                    cmd.append(' ');
+
+                if (c.contains(" "))
+                    c = "'" + c + "'";
+
+                cmd.append(c);
+            }
+        }
+        if (cmd.length() > 0)
+            app.setCmd(cmd.toString());
+
+        Docker docker = new Docker();
+        docker.setImage(config.getContainerImage());
+        docker.setNetwork("BRIDGE"); // TODO is this correct?
+        List<Port> ports = new ArrayList<>();
+        for (int p : config.getContainerPorts()) {
+            Port port = new Port();
+            port.setContainerPort(p);
+            ports.add(port);
+        }
+        docker.setPortMappings(ports);
+
+        Container container = new Container();
+        container.setType("DOCKER");
+        container.setDocker(docker);
+
+        app.setContainer(container);
+        app.addLabel(SERVICE_NAME, config.getServiceName());
+
+        App res = marathonClient.createApp(app);
+
+        return createServiceFromApp(res, config);
+    }
+
+    private Service createServiceFromExistingApp(List<App> apps, ServiceConfig config)
{
+        if (apps.size() != 1)
+            throw new IllegalStateException("More than one existing app found for service
" +
+                    config.getServiceName() + " " + apps);
+
+        return createServiceFromApp(apps.get(0), config);
+    }
+
+    private Service createServiceFromApp(App app, ServiceConfig cfg) {
+        // TODO make this check more thorough
+        if (!cfg.getServiceName().equals(app.getLabels().get(SERVICE_NAME)))
+            throw new IllegalStateException("Application and configuration don't match");
+
+        ServiceImpl svc = new ServiceImpl(marathonClient, app, cfg);
+        return svc;
+    }
+
+    @Override
+    public Set<String> listServices() throws Exception {
+        GetAppsResponse services = marathonClient.getApps(
+                Collections.singletonMap("label", SERVICE_NAME));
+
+        Set<String> serviceNames = new HashSet<>();
+        for (App app : services.getApps()) {
+            Map<String, String> labels = app.getLabels();
+            String name = labels.get(SERVICE_NAME);
+            if (name != null && name.length() > 0)
+                serviceNames.add(name);
+        }
+        return serviceNames;
+    }
+
+}


Mime
View raw message