You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2014/10/22 11:45:15 UTC
[03/11] git commit: CAMEL-7834 Add camel-docker component
CAMEL-7834 Add camel-docker component
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/d96dbf8d
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/d96dbf8d
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/d96dbf8d
Branch: refs/heads/master
Commit: d96dbf8dc3125a12bfc1a8be0bd941e28e05ddea
Parents: 1c4dc30
Author: Andrew Block <an...@gmail.com>
Authored: Tue Oct 21 23:11:09 2014 -0500
Committer: Willem Jiang <wi...@gmail.com>
Committed: Wed Oct 22 15:41:27 2014 +0800
----------------------------------------------------------------------
components/camel-docker/README.md | 108 ++
components/camel-docker/pom.xml | 89 ++
.../component/docker/DockerClientFactory.java | 95 ++
.../component/docker/DockerClientProfile.java | 166 +++
.../camel/component/docker/DockerComponent.java | 72 +
.../component/docker/DockerConfiguration.java | 70 +
.../camel/component/docker/DockerConstants.java | 164 ++
.../camel/component/docker/DockerEndpoint.java | 87 ++
.../camel/component/docker/DockerHelper.java | 242 +++
.../camel/component/docker/DockerOperation.java | 233 +++
.../docker/consumer/DockerEventsConsumer.java | 148 ++
.../docker/exception/DockerException.java | 34 +
.../docker/producer/DockerProducer.java | 1411 ++++++++++++++++++
.../services/org/apache/camel/component/docker | 1 +
.../docker/DockerClientProfileTest.java | 60 +
.../docker/DockerConfigurationTest.java | 66 +
.../component/docker/DockerHelperTest.java | 34 +
.../component/docker/RemoveImageCmdUriTest.java | 81 +
.../headers/AttachContainerCmdHeaderTest.java | 78 +
.../docker/headers/AuthCmdHeaderTest.java | 87 ++
.../docker/headers/BaseDockerHeaderTest.java | 125 ++
.../docker/headers/BuildImageCmdHeaderTest.java | 100 ++
.../headers/CopyFileContainerCmdHeaderTest.java | 67 +
.../headers/CreateContainerCmdHeaderTest.java | 68 +
.../headers/CreateImageCmdHeaderTest.java | 64 +
.../headers/DiffContainerCmdHeaderTest.java | 61 +
.../docker/headers/InfoCmdHeaderTest.java | 57 +
.../headers/InspectContainerCmdHeaderTest.java | 62 +
.../headers/InspectImageCmdHeaderTest.java | 64 +
.../headers/KillContainerCmdHeaderTest.java | 65 +
.../headers/ListContainersCmdHeaderTest.java | 71 +
.../docker/headers/ListImagesCmdHeaderTest.java | 67 +
.../headers/LogContainerCmdHeaderTest.java | 79 +
.../headers/PauseContainerCmdHeaderTest.java | 62 +
.../docker/headers/PingCmdHeaderTest.java | 57 +
.../docker/headers/PullImageCmdHeaderTest.java | 68 +
.../docker/headers/PushImageCmdHeaderTest.java | 86 ++
.../headers/RemoveContainerCmdHeaderTest.java | 70 +
.../headers/RemoveImageCmdHeaderTest.java | 70 +
.../headers/RestartContainerCmdHeaderTest.java | 65 +
.../headers/SearchImagesCmdHeaderTest.java | 62 +
.../headers/StopContainerCmdHeaderTest.java | 65 +
.../docker/headers/TagImageCmdHeaderTest.java | 70 +
.../headers/TopContainerCmdHeaderTest.java | 65 +
.../headers/UnpauseContainerCmdHeaderTest.java | 62 +
.../docker/headers/VersionCmdHeaderTest.java | 57 +
.../headers/WaitContainerCmdHeaderTest.java | 62 +
.../docker/it/DockerProducerTestIT.java | 55 +
.../src/test/resources/log4j.properties | 14 +
components/pom.xml | 1 +
50 files changed, 5267 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/README.md
----------------------------------------------------------------------
diff --git a/components/camel-docker/README.md b/components/camel-docker/README.md
new file mode 100644
index 0000000..6bda03b
--- /dev/null
+++ b/components/camel-docker/README.md
@@ -0,0 +1,108 @@
+Docker Camel Component
+=======================
+
+Camel component for communicating with Docker.
+
+## Docker Remote API
+
+The Docker Camel component leverages the [docker-java](https://github.com/docker-java/docker-java) via the [Docker Remote API](https://docs.docker.com/reference/api/docker_remote_api/)
+
+## URI Format
+
+ docker://[operation]?[options]
+
+## Header Strategy
+
+All URI option can be passed as Header properties. Values found in a message header take precedence over URI parameters. A header property takes the form of a URI option prefixed with *CamelDocker* as shown below
+
+| URI Option | Header Property |
+| ------------- | ---------------- |
+|containerId|CamelDockerContainerId |
+
+## General Options
+
+The following parameters can be used with any invocation of the component
+
+The following options are required
+
+| Option | Header | Description | Default Value |
+|-----------|-----------|-----------------|-------------------|
+| host | CamelDockerHost | Docker host | localhost |
+| port | CamelDockerPort | Docker port | 5000 |
+
+The following are additional optional parameters
+
+| Option | Header | Description | Default Value |
+|-----------|-----------|-----------------|-------------------|
+| username | CamelDockerUserName | User name to authenticate with | |
+| password | CamelDockerPassword | Password to authenticate with | |
+| email | CamelDockerEmail | Email address associated with the user | |
+| secure | CamelDockerSecure | Use HTTPS communication | false |
+| requestTimeout | CamelDockerRequestTimeout | Request timeout for response (in seconds) | 30 |
+
+
+## Consumer Operations
+
+| Operation | Options | Description | Produces |
+| ------------- | ---------------- | ------------- | ---------------- |
+|events| initialRange | Monitor Docker events (Streaming) | Event |
+
+## Producer Operations
+
+The following producer operations are available
+
+### Misc
+| Operation | Options | Description | Returns |
+| ------------- | ---------------- | ------------- | ---------------- |
+| auth | | Check auth configuration | |
+| info | | System wide information | Info |
+| ping | | Ping the Docker server | |
+| version | | Show the docker version information | Version |
+
+
+### Images
+
+| Operation | Options | Description | Body Content | Returns |
+| ------------- | ---------------- | ------------- | ---------------- | ---------------- |
+| image/list | filter, showAll | List images | | List<Image> |
+| image/create | **repository** | Create an image | InputStream |CreateImageResponse |
+| image/build | noCache, quiet, remove, tag | Build an image from Dockerfile via stdin | InputStream or File | InputStream |
+| image/pull | **repository**, registry, tag | Pull an image from the registry | |InputStream |
+| image/push | **name** | Push an image on the registry | InputStream |
+| image/search | **term** | Search for images | | List<SearchItem> |
+| image/remove | **imageId**, force, noPrune | Remove an image | | |
+| image/tag | **imageId**, **repository**, **tag**, **force** | Tag an image into a repository | | |
+| image/inspect | **imageId** | Inspect an image | | InspectImageResponse |
+
+### Containers
+
+| Operation | Options | Description | Body Content |
+| ------------- | ---------------- | ------------- | ---------------- |
+| container/list | showSize, showAll, before, since, limit, List containers | initialRange | List<Container> |
+| container/create | **imageId**, name, exposedPorts, workingDir, disableNetwork, hostname, user, tty, stdInOpen, stdInOnce, memoryLimit, memorySwap, cpuShares, attachStdIn, attachStdOut, attachStdErr, env, cmd, dns, image, volumes, volumesFrom | Create a container | CreateContainerResponse |
+| container/start | **containerId**, binds, links, lxcConf, portBindings, privileged, publishAllPorts, dns, dnsSearch, volumesFrom, networkMode, devices, restartPolicy, capAdd, capDrop | Start a container | |
+| container/inspect | **containerId** | Inspect a container | InspectContainerResponse |
+| container/wait | **containerId** | Wait a container | Integer
+| container/log | **containerId**, stdOut, stdErr, timestamps, followStream, tailAll, tail | Get container logs | InputStream |
+| container/attach | **containerId**, stdOut, stdErr, timestamps, logs, followStream | Attach to a container | InputStream |
+| container/stop | **containerId**, timeout | Stop a container | |
+| container/restart | **containerId**, timeout | Restart a container | |
+| container/diff | **containerId** | Inspect changes on a container | ChangeLog |
+| container/kill | **containerId**, signal, | Kill a container | |
+| container/top | **containerId**, psArgs | List processes running in a container | TopContainerResponse |
+| container/pause | **containerId** | Pause a container | |
+| container/unpause | **containerId** | Unpause a container | |
+| container/commit | **containerId**, repository, message, tag, attachStdIn, attachStdOut, attachStdErr, cmd, disableNetwork, pause, env, exposedPorts, hostname, memory, memorySwap, openStdIn, portSpecs, stdInOnce, tty, user, volumes, hostname | Create a new image from a container's changes | String |
+| container/copyfile | **containerId**, **resource**, hostPath | Copy files or folders from a container | InputStream |
+| container/remove | **containerId**, force, removeVolumes | Remove a container | |
+
+
+## Examples
+
+The following example consumes events from Docker
+
+ docker://events?host=192.168.59.103&port=2375
+
+The following example queries Docker for system wide information
+
+ docker://info?host=192.168.59.103&port=2375
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-docker/pom.xml b/components/camel-docker/pom.xml
new file mode 100644
index 0000000..2a5f8b0
--- /dev/null
+++ b/components/camel-docker/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>components</artifactId>
+ <version>2.15-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-docker</artifactId>
+ <packaging>bundle</packaging>
+ <name>Camel :: Docker</name>
+ <description>Camel Docker Support</description>
+
+
+ <properties>
+ <camel.osgi.export.pkg>org.apache.camel.component.docker.*</camel.osgi.export.pkg>
+ <camel.osgi.export.service>org.apache.camel.spi.ComponentResolver;component=docker</camel.osgi.export.service>
+ <docker.java.version>0.10.2</docker.java.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core</artifactId>
+ </dependency>
+
+ <!-- Docker -->
+ <dependency>
+ <groupId>com.github.docker-java</groupId>
+ <artifactId>docker-java</artifactId>
+ <version>${docker.java.version}</version>
+ </dependency>
+
+ <!-- logging -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- testing -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <version>${powermock-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito</artifactId>
+ <version>${powermock-version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerClientFactory.java
----------------------------------------------------------------------
diff --git a/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerClientFactory.java b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerClientFactory.java
new file mode 100644
index 0000000..d38e7b9
--- /dev/null
+++ b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerClientFactory.java
@@ -0,0 +1,95 @@
+/**
+ * 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.camel.component.docker;
+
+import com.github.dockerjava.api.DockerClient;
+import com.github.dockerjava.core.DockerClientBuilder;
+import com.github.dockerjava.core.DockerClientConfig;
+import org.apache.camel.Message;
+import org.apache.camel.component.docker.exception.DockerException;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * Methods for communicating with Docker
+ */
+public class DockerClientFactory {
+
+
+ /**
+ * Produces a {@link DockerClient} to communicate with Docker
+ *
+ * @param dockerConfiguration
+ * @param message the Camel message
+ * @return a DockerClient
+ * @throws DockerException
+ */
+ public static DockerClient getDockerClient(DockerConfiguration dockerConfiguration, Message message) throws DockerException {
+
+ ObjectHelper.notNull(dockerConfiguration, "dockerConfiguration");
+
+ Integer port = null;
+ String host = null;
+ DockerClient client = null;
+
+
+ port = DockerHelper.getProperty(DockerConstants.DOCKER_PORT, dockerConfiguration, message, Integer.class);
+ host = DockerHelper.getProperty(DockerConstants.DOCKER_HOST, dockerConfiguration, message, String.class);
+
+ int uriPort = port != null ? port : dockerConfiguration.getDefaultPort();
+ String uriHost = host != null ? host : dockerConfiguration.getDefaultHost();
+
+ String username = DockerHelper.getProperty(DockerConstants.DOCKER_USERNAME, dockerConfiguration, message, String.class);
+ String password = DockerHelper.getProperty(DockerConstants.DOCKER_PASSWORD, dockerConfiguration, message, String.class);
+ String email = DockerHelper.getProperty(DockerConstants.DOCKER_EMAIL, dockerConfiguration, message, String.class);
+ Integer requestTimeout = DockerHelper.getProperty(DockerConstants.DOCKER_API_REQUEST_TIMEOUT, dockerConfiguration, message, Integer.class);
+ String serverAddress = DockerHelper.getProperty(DockerConstants.DOCKER_SERVER_ADDRESS, dockerConfiguration, message, String.class);
+ Boolean secure = DockerHelper.getProperty(DockerConstants.DOCKER_SECURE, dockerConfiguration, message, Boolean.class);
+
+
+ DockerClientProfile clientProfile = new DockerClientProfile();
+ clientProfile.setHost(uriHost);
+ clientProfile.setPort(uriPort);
+ clientProfile.setEmail(email);
+ clientProfile.setUsername(username);
+ clientProfile.setPassword(password);
+ clientProfile.setRequestTimeout(requestTimeout);
+ clientProfile.setServerAddress(serverAddress);
+
+ if(secure != null && secure) {
+ clientProfile.setSecure(secure);
+ }
+
+ client = dockerConfiguration.getClient(clientProfile);
+
+ if(client != null) {
+ return client;
+ }
+
+ DockerClientConfig.DockerClientConfigBuilder configBuilder = new DockerClientConfig.DockerClientConfigBuilder()
+ .withUsername(username)
+ .withPassword(password)
+ .withEmail(email)
+ .withReadTimeout(requestTimeout)
+ .withUri(clientProfile.toUrl());
+
+ DockerClientConfig config = configBuilder.build();
+
+ return DockerClientBuilder.getInstance(config).build();
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerClientProfile.java
----------------------------------------------------------------------
diff --git a/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerClientProfile.java b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerClientProfile.java
new file mode 100644
index 0000000..1f5b9ff
--- /dev/null
+++ b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerClientProfile.java
@@ -0,0 +1,166 @@
+/**
+ * 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.camel.component.docker;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.camel.component.docker.exception.DockerException;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * The elements representing a client initiating a connection to Docker
+ */
+public class DockerClientProfile {
+
+ private String host;
+ private Integer port;
+ private String username;
+ private String password;
+ private String email;
+ private String serverAddress;
+ private Integer requestTimeout;
+ private boolean secure;
+
+ public String getHost() {
+ return host;
+ }
+ public void setHost(String host) {
+ this.host = host;
+ }
+ public Integer getPort() {
+ return port;
+ }
+ public void setPort(Integer port) {
+ this.port = port;
+ }
+ public String getUsername() {
+ return username;
+ }
+ public void setUsername(String username) {
+ this.username = username;
+ }
+ public String getPassword() {
+ return password;
+ }
+ public void setPassword(String password) {
+ this.password = password;
+ }
+ public String getEmail() {
+ return email;
+ }
+ public void setEmail(String email) {
+ this.email = email;
+ }
+ public String getServerAddress() {
+ return serverAddress;
+ }
+ public void setServerAddress(String serverAddress) {
+ this.serverAddress = serverAddress;
+ }
+
+ public Integer getRequestTimeout() {
+ return requestTimeout;
+ }
+ public void setRequestTimeout(Integer requestTimeout) {
+ this.requestTimeout = requestTimeout;
+ }
+ public boolean isSecure() {
+ return secure;
+ }
+ public void setSecure(boolean secure) {
+ this.secure = secure;
+ }
+ public String toUrl() throws DockerException {
+ ObjectHelper.notNull(this.host, "host");
+ ObjectHelper.notNull(this.port, "port");
+
+ URL uri;
+ String secure = this.secure ? "https" : "http";
+ try {
+ uri = new URL(secure, this.host, this.port, "");
+ } catch (MalformedURLException e) {
+ throw new DockerException(e);
+ }
+
+ return uri.toString();
+
+ }
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((email == null) ? 0 : email.hashCode());
+ result = prime * result + ((host == null) ? 0 : host.hashCode());
+ result = prime * result + ((password == null) ? 0 : password.hashCode());
+ result = prime * result + ((port == null) ? 0 : port.hashCode());
+ result = prime * result + ((requestTimeout == null) ? 0 : requestTimeout.hashCode());
+ result = prime * result + (secure ? 1231 : 1237);
+ result = prime * result + ((serverAddress == null) ? 0 : serverAddress.hashCode());
+ result = prime * result + ((username == null) ? 0 : username.hashCode());
+ return result;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ DockerClientProfile other = (DockerClientProfile)obj;
+ if (email == null) {
+ if (other.email != null)
+ return false;
+ } else if (!email.equals(other.email))
+ return false;
+ if (host == null) {
+ if (other.host != null)
+ return false;
+ } else if (!host.equals(other.host))
+ return false;
+ if (password == null) {
+ if (other.password != null)
+ return false;
+ } else if (!password.equals(other.password))
+ return false;
+ if (port == null) {
+ if (other.port != null)
+ return false;
+ } else if (!port.equals(other.port))
+ return false;
+ if (requestTimeout == null) {
+ if (other.requestTimeout != null)
+ return false;
+ } else if (!requestTimeout.equals(other.requestTimeout))
+ return false;
+ if (secure != other.secure)
+ return false;
+ if (serverAddress == null) {
+ if (other.serverAddress != null)
+ return false;
+ } else if (!serverAddress.equals(other.serverAddress))
+ return false;
+ if (username == null) {
+ if (other.username != null)
+ return false;
+ } else if (!username.equals(other.username))
+ return false;
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerComponent.java b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerComponent.java
new file mode 100644
index 0000000..b53492b
--- /dev/null
+++ b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerComponent.java
@@ -0,0 +1,72 @@
+/**
+ * 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.camel.component.docker;
+
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.component.docker.exception.DockerException;
+import org.apache.camel.impl.DefaultComponent;
+
+/**
+ * Represents the component that manages {@link DockerEndpoint}.
+ */
+public class DockerComponent extends DefaultComponent {
+
+ private DockerConfiguration configuration;
+
+ public DockerComponent() {
+
+ }
+
+ public DockerComponent(DockerConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+
+ DockerConfiguration configuration = getConfiguration();
+
+ String normalizedRemaining = remaining.replaceAll("/", "");
+
+ DockerOperation operation = DockerOperation.getDockerOperation(normalizedRemaining);
+
+ if(operation == null) {
+ throw new DockerException(remaining + " is not a valid operation");
+ }
+
+ configuration.setOperation(operation);
+
+ // Validate URI Parameters
+ DockerHelper.validateParameters(operation, parameters);
+
+ Endpoint endpoint = new DockerEndpoint(uri, this, configuration);
+ setProperties(configuration, parameters);
+ configuration.setParameters(parameters);
+
+ return endpoint;
+ }
+
+ protected DockerConfiguration getConfiguration() {
+ if(configuration == null) {
+ configuration = new DockerConfiguration();
+ }
+
+ return configuration;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerConfiguration.java b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerConfiguration.java
new file mode 100644
index 0000000..5175552
--- /dev/null
+++ b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerConfiguration.java
@@ -0,0 +1,70 @@
+/**
+ * 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.camel.component.docker;
+
+import com.github.dockerjava.api.DockerClient;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.component.docker.exception.DockerException;
+
+public class DockerConfiguration {
+
+
+ private Map<String, Object> parameters = new HashMap<String, Object>();
+ private Map<DockerClientProfile, DockerClient> clients = new HashMap<DockerClientProfile, DockerClient>();
+
+ private static final String DEFAULT_DOCKER_HOST = "localhost";
+ private static final int DEFAULT_DOCKER_PORT = 5000;
+
+ private DockerOperation operation;
+
+ public void setClient(DockerClientProfile clientProfile, DockerClient client) {
+ clients.put(clientProfile, client);
+ }
+
+ public Map<String, Object> getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(Map<String, Object> parameters) {
+ this.parameters = parameters;
+ }
+
+ public DockerOperation getOperation() {
+ return operation;
+ }
+
+ public void setOperation(DockerOperation operation) {
+ this.operation = operation;
+ }
+
+ public String getDefaultHost() {
+ return DEFAULT_DOCKER_HOST;
+ }
+
+ public Integer getDefaultPort() {
+ return DEFAULT_DOCKER_PORT;
+ }
+
+ public DockerClient getClient(DockerClientProfile clientProfile) throws DockerException {
+ return clients.get(clientProfile);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerConstants.java b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerConstants.java
new file mode 100644
index 0000000..4e40d1f
--- /dev/null
+++ b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerConstants.java
@@ -0,0 +1,164 @@
+/**
+ * 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.camel.component.docker;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Docker Component constants
+ */
+public class DockerConstants {
+
+ public static final String DOCKER_PREFIX = "CamelDocker";
+
+ public static final Map<String,Class<?>> DOCKER_DEFAULT_PARAMETERS = new HashMap<String,Class<?>>();
+
+
+ /** Connectivity **/
+ public static final String DOCKER_HOST = "CamelDockerHost";
+ public static final String DOCKER_PORT = "CamelDockerPort";
+ public static final String DOCKER_SECURE = "CamelDockerSecure";
+ public static final String DOCKER_API_REQUEST_TIMEOUT = "CamelDockerRequestTimeout";
+
+
+ /** List Images **/
+ public static final String DOCKER_FILTER = "CamelDockerFilter";
+ public static final String DOCKER_SHOW_ALL = "CamelDockerShowAll";
+
+ /** Common **/
+ public static final String DOCKER_CONTAINER_ID = "CamelDockerContainerId";
+ public static final String DOCKER_IMAGE_ID = "CamelDockerImageId";
+
+ /** Auth **/
+ public static final String DOCKER_USERNAME = "CamelDockerUsername";
+ public static final String DOCKER_PASSWORD = "CamelDockerPassword";
+ public static final String DOCKER_EMAIL = "CamelDockerEmail";
+ public static final String DOCKER_SERVER_ADDRESS = "CamelDockerServerAddress";
+
+ /** Pull **/
+ public static final String DOCKER_REPOSITORY = "CamelDockerRepository";
+ public static final String DOCKER_TAG = "CamelDockerTag";
+ public static final String DOCKER_REGISTRY = "CamelDockerRegistry";
+
+ /** Push **/
+ public static final String DOCKER_NAME = "CamelDockerName";
+
+ /** Search **/
+ public static final String DOCKER_TERM = "CamelDockerTerm";
+
+ /** Remove **/
+ public static final String DOCKER_FORCE = "CamelDockerForce";
+ public static final String DOCKER_NO_PRUNE = "CamelDockerNoPrune";
+
+ /** Events **/
+ public static final String DOCKER_INITIAL_RANGE = "CamelDockerInitialRange";
+
+ /** List Container **/
+ public static final String DOCKER_LIMIT = "CamelDockerLimit";
+ public static final String DOCKER_SHOW_SIZE = "CamelDockerShowSize";
+ public static final String DOCKER_SINCE = "CamelDockerSince";
+ public static final String DOCKER_BEFORE = "CamelDockerBefore";
+
+
+ /** Remove Container **/
+ public static final String DOCKER_REMOVE_VOLUMES = "CamelDockerRemoveVolumes";
+
+ /** Attach Container **/
+ public static final String DOCKER_FOLLOW_STREAM = "CamelDockerFollowStream";
+ public static final String DOCKER_STD_OUT = "CamelDockerStdOut";
+ public static final String DOCKER_STD_ERR = "CamelDockerStdErr";
+ public static final String DOCKER_TIMESTAMPS = "CamelDockerTimestamps";
+ public static final String DOCKER_LOGS = "CamelDockerLogs";
+
+ /** Logs **/
+ public static final String DOCKER_TAIL = "CamelDockerTail";
+ public static final String DOCKER_TAIL_ALL = "CamelDockerTailAll";
+
+ /** Copy **/
+ public static final String DOCKER_RESOURCE = "CamelDockerResource";
+ public static final String DOCKER_HOST_PATH = "CamelDockerHostPath";
+
+ /** Stop Container **/
+ public static final String DOCKER_TIMEOUT = "CamelDockerTimeout";
+
+ /** Kill Container **/
+ public static final String DOCKER_SIGNAL = "CamelDockerSignal";
+
+ /** Top Container **/
+ public static final String DOCKER_PS_ARGS = "CamelDockerPsArgs";
+
+ /** Build Image **/
+ public static final String DOCKER_NO_CACHE = "CamelDockerNoCache";
+ public static final String DOCKER_QUIET = "CamelDockerQuiet";
+ public static final String DOCKER_REMOVE = "CamelDockerRemove";
+
+ /** Commit **/
+ public static final String DOCKER_COMMENT = "CamelDockerComment";
+ public static final String DOCKER_MESSAGE = "CamelDockerMessage";
+ public static final String DOCKER_AUTHOR = "CamelDockerAuthor";
+ public static final String DOCKER_ATTACH_STD_ERR = "CamelDockerAttachStdErr";
+ public static final String DOCKER_ATTACH_STD_IN = "CamelDockerAttachStdIn";
+ public static final String DOCKER_ATTACH_STD_OUT = "CamelDockerAttachStdOut";
+ public static final String DOCKER_CMD = "CamelDockerCmd";
+ public static final String DOCKER_DISABLE_NETWORK = "CamelDockerDisableNetwork";
+ public static final String DOCKER_ENV = "CamelDockerEnv";
+ public static final String DOCKER_PAUSE = "CamelDockerPause";
+ public static final String DOCKER_EXPOSED_PORTS = "CamelDockerExposedPorts";
+ public static final String DOCKER_HOSTNAME = "CamelDockerHostname";
+ public static final String DOCKER_MEMORY = "CamelDockerMemory";
+ public static final String DOCKER_MEMORY_SWAP = "CamelDockerMemorySwap";
+ public static final String DOCKER_OPEN_STD_IN = "CamelDockerOpenStdIn";
+ public static final String DOCKER_PORT_SPECS = "CamelDockerPortSpecs";
+ public static final String DOCKER_STD_IN_ONCE = "CamelDockerStdInOnce";
+ public static final String DOCKER_TTY = "CamelDockerTty";
+ public static final String DOCKER_USER = "CamelDockerUser";
+ public static final String DOCKER_VOLUMES = "CamelDockerVolumes";
+ public static final String DOCKER_WORKING_DIR = "CamelDockerWorkingDir";
+
+ /** Create Container **/
+ public static final String DOCKER_MEMORY_LIMIT = "CamelDockerMemoryLimit";
+ public static final String DOCKER_CPU_SHARES = "CamelDockerCpuShares";
+ public static final String DOCKER_DNS = "CamelDockerDns";
+ public static final String DOCKER_IMAGE = "CamelDockerImage";
+ public static final String DOCKER_STD_IN_OPEN = "CamelDockerStdInOpen";
+ public static final String DOCKER_VOLUMES_FROM = "CamelDockerVolumesFrom";
+
+ /** Start Container **/
+ public static final String DOCKER_BINDS = "CamelDockerBinds";
+ public static final String DOCKER_LINKS = "CamelDockerLinks";
+ public static final String DOCKER_LXC_CONF = "CamelDockerLxcConf";
+ public static final String DOCKER_PUBLISH_ALL_PORTS = "CamelDockerPublishAllPorts";
+ public static final String DOCKER_PORT_BINDINGS = "CamelDockerPortBindings";
+ public static final String DOCKER_PRIVILEGED = "CamelDockerDnsSearch";
+ public static final String DOCKER_DNS_SEARCH = "CamelDockerDnsSearch";
+ public static final String DOCKER_NETWORK_MODE = "CamelNetworkMode";
+ public static final String DOCKER_DEVICES = "CamelDockeDevices";
+ public static final String DOCKER_RESTART_POLICY = "CamelDockerRestartPolicy";
+ public static final String DOCKER_CAP_ADD = "CamelDockerCapAdd";
+ public static final String DOCKER_CAP_DROP = "CamelDockerCapDrop";
+
+ static {
+ DOCKER_DEFAULT_PARAMETERS.put(DOCKER_HOST, String.class);
+ DOCKER_DEFAULT_PARAMETERS.put(DOCKER_PORT, Integer.class);
+ DOCKER_DEFAULT_PARAMETERS.put(DOCKER_USERNAME, String.class);
+ DOCKER_DEFAULT_PARAMETERS.put(DOCKER_PASSWORD, String.class);
+ DOCKER_DEFAULT_PARAMETERS.put(DOCKER_EMAIL, String.class);
+ DOCKER_DEFAULT_PARAMETERS.put(DOCKER_SERVER_ADDRESS, String.class);
+ DOCKER_DEFAULT_PARAMETERS.put(DOCKER_SECURE, Boolean.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerEndpoint.java b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerEndpoint.java
new file mode 100644
index 0000000..bac1316
--- /dev/null
+++ b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerEndpoint.java
@@ -0,0 +1,87 @@
+/**
+ * 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.camel.component.docker;
+
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.component.docker.consumer.DockerEventsConsumer;
+import org.apache.camel.component.docker.exception.DockerException;
+import org.apache.camel.component.docker.producer.DockerProducer;
+import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.spi.UriEndpoint;
+
+/**
+ * Represents a Docker endpoint.
+ */
+@UriEndpoint(scheme = "docker", consumerClass = DockerEventsConsumer.class)
+public class DockerEndpoint extends DefaultEndpoint {
+
+ private DockerConfiguration configuration;
+
+ public DockerEndpoint() {
+ }
+
+ public DockerEndpoint(String uri, DockerComponent component, DockerConfiguration configuration) {
+ super(uri, component);
+ this.configuration = configuration;
+ }
+
+ public DockerEndpoint(String endpointUri) {
+ super(endpointUri);
+ }
+
+ public Producer createProducer() throws Exception {
+ DockerOperation operation = configuration.getOperation();
+
+ if(operation != null && operation.canProduce()) {
+ return new DockerProducer(this);
+ }
+ else {
+ throw new DockerException(operation + " is not a valid producer operation");
+ }
+ }
+
+ public Consumer createConsumer(Processor processor) throws Exception {
+
+ DockerOperation operation = configuration.getOperation();
+
+ switch (operation) {
+ case EVENTS:
+ return new DockerEventsConsumer(this, processor);
+ default:
+ throw new DockerException(operation + " is not a valid consumer operation");
+ }
+
+ }
+
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public DockerConfiguration getConfiguration() {
+ return configuration;
+ }
+
+ @Override
+ public boolean isLenientProperties() {
+ return true;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerHelper.java b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerHelper.java
new file mode 100644
index 0000000..efca4f9
--- /dev/null
+++ b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerHelper.java
@@ -0,0 +1,242 @@
+/**
+ * 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.camel.component.docker;
+
+import com.github.dockerjava.api.DockerClientException;
+import com.github.dockerjava.api.model.AuthConfig;
+
+import java.lang.reflect.Array;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.Message;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.commons.lang.BooleanUtils;
+
+/**
+ * Utility methods for Docker Component
+ */
+public class DockerHelper {
+
+ private static final String STRING_DELIMITER = ";";
+
+ /**
+ * Validates the URI parameters for a given {@link DockerOperation}
+ *
+ * @param dockerOperation
+ * @param parameters
+ */
+ public static void validateParameters(DockerOperation dockerOperation, Map<String,Object> parameters) {
+ Map<String,Class<?>> validParamMap = new HashMap<String,Class<?>>();
+ validParamMap.putAll(DockerConstants.DOCKER_DEFAULT_PARAMETERS);
+ validParamMap.putAll(dockerOperation.getParameters());
+
+ for(String key : parameters.keySet()) {
+
+ String transformedKey = DockerHelper.transformToHeaderName(key);
+
+ // Validate URI parameter name
+ if(!validParamMap.containsKey(transformedKey)) {
+ throw new DockerClientException(key + " is not a valid URI parameter");
+ }
+
+
+ try {
+ Class<?> parameterClass = validParamMap.get(transformedKey);
+ Object parameterValue = parameters.get(key);
+
+ if(parameterClass == null || parameterValue == null) {
+ throw new DockerClientException("Failed to validate parameter type for property " + key);
+ }
+
+ if(Integer.class == parameterClass) {
+ Integer.parseInt((String)parameterValue);
+ }
+ else if(Boolean.class == parameterClass) {
+ BooleanUtils.toBooleanObject((String)parameterValue, "true", "false", "null");
+ }
+
+
+ }
+ catch(Exception e) {
+ throw new DockerClientException("Failed to validate parameter type for property " + key);
+ }
+ }
+
+ }
+
+ /**
+ * Transforms a Docker Component header value to its' analogous URI parameter
+ * @param name
+ * @return
+ */
+ public static String transformFromHeaderName(String name) {
+ ObjectHelper.notEmpty(name, "name");
+
+ StringBuilder formattedName = new StringBuilder();
+
+ String nameSubstring = name.substring(DockerConstants.DOCKER_PREFIX.length());
+
+ if(nameSubstring.length() > 0) {
+ formattedName.append(nameSubstring.substring(0,1).toLowerCase());
+ formattedName.append(nameSubstring.substring(1));
+ }
+
+ return formattedName.toString();
+ }
+
+ /**
+ * Transforms a Docker Component URI parameter to its' analogous header value
+ * @param name
+ * @return
+ */
+ public static String transformToHeaderName(String name) {
+ ObjectHelper.notEmpty(name, "name");
+
+ StringBuilder formattedName = new StringBuilder(DockerConstants.DOCKER_PREFIX);
+
+
+ if(name.length() > 0) {
+ formattedName.append(name.substring(0,1).toUpperCase());
+ formattedName.append(name.substring(1));
+ }
+
+ return formattedName.toString();
+ }
+
+ /**
+ * Attempts to locate a given property name within a URI parameter or the message header.
+ * A found value in a message header takes precedence over a URI parameter.
+ *
+ * @param name
+ * @param configuration
+ * @param message
+ * @param clazz
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T getProperty(String name, DockerConfiguration configuration, Message message, Class<T> clazz) {
+ // First attempt to locate property from Message Header, then fallback to Endpoint property
+
+ if(message != null) {
+ T headerProperty = message.getHeader(name, clazz);
+
+ if(headerProperty != null) {
+ return headerProperty;
+ }
+ }
+
+ Object prop = configuration.getParameters().get(transformFromHeaderName(name));
+
+ if(prop != null) {
+
+ if(prop.getClass().isAssignableFrom(clazz)) {
+ return (T) prop;
+ }
+ else if(Integer.class == clazz) {
+ return (T) Integer.valueOf((String)prop);
+ }
+ else if(Boolean.class == clazz) {
+ return (T)BooleanUtils.toBooleanObject((String)prop, "true", "false", "null");
+ }
+ }
+
+ return null;
+
+
+ }
+
+ /**
+ * Attempts to locate a given property which is an array by name within a URI parameter or the message header.
+ * A found value in a message header takes precedence over a URI parameter.
+ *
+ * @param name
+ * @param message
+ * @param clazz
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T[] getArrayProperty(String name, Message message, Class<T> clazz) {
+
+ if(message != null) {
+ Object header = message.getHeader(name);
+
+ if(header != null) {
+ if(header.getClass().isAssignableFrom(clazz)) {
+
+ T[] headerArray = (T[])Array.newInstance(clazz, 1);
+ headerArray[0] = (T) header;
+ return headerArray;
+
+ }
+
+ if(header.getClass().isArray()) {
+ if(header.getClass().getDeclaringClass().isAssignableFrom(clazz)) {
+ return (T[])header;
+ }
+ }
+ }
+
+ }
+
+ return null;
+
+ }
+
+ public static AuthConfig getAuthConfig(DockerConfiguration configuration, Message message) {
+ String username = getProperty(DockerConstants.DOCKER_USERNAME, configuration, message, String.class);
+ String password = getProperty(DockerConstants.DOCKER_PASSWORD, configuration, message, String.class);
+
+ ObjectHelper.notNull(username, "username");
+ ObjectHelper.notNull(password, "password");
+
+ String email = getProperty(DockerConstants.DOCKER_EMAIL, configuration, message, String.class);
+ String serverAddress = getProperty(DockerConstants.DOCKER_SERVER_ADDRESS, configuration, message, String.class);
+
+
+ AuthConfig authConfig = new AuthConfig();
+ authConfig.setUsername(username);
+ authConfig.setPassword(password);
+ authConfig.setEmail(email);
+ authConfig.setServerAddress(serverAddress);
+
+ return authConfig;
+ }
+
+ public static String[] parseDelimitedStringHeader(String headerName, Message message) {
+
+
+ Object header = message.getHeader(headerName);
+
+ if(header != null) {
+
+ if(header instanceof String) {
+ return ((String) header).split(STRING_DELIMITER);
+ }
+
+ if(header instanceof String[]) {
+ return((String[]) header);
+ }
+ }
+
+
+ return null;
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerOperation.java
----------------------------------------------------------------------
diff --git a/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerOperation.java b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerOperation.java
new file mode 100644
index 0000000..e02c311
--- /dev/null
+++ b/components/camel-docker/src/main/java/org/apache/camel/component/docker/DockerOperation.java
@@ -0,0 +1,233 @@
+/**
+ * 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.camel.component.docker;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Operations the Docker Component supports
+ */
+public enum DockerOperation {
+
+ EVENTS("events",false,true,
+ DockerConstants.DOCKER_INITIAL_RANGE, Long.class),
+ AUTH("auth",false,true,
+ DockerConstants.DOCKER_USERNAME, String.class,
+ DockerConstants.DOCKER_PASSWORD, String.class,
+ DockerConstants.DOCKER_EMAIL, String.class,
+ DockerConstants.DOCKER_SERVER_ADDRESS, String.class),
+ INFO("info",false,true),
+ PING("ping",false,true),
+ VERSION("version",false,true),
+ LIST_IMAGES("imagelist",false,true,
+ DockerConstants.DOCKER_FILTER, String.class,
+ DockerConstants.DOCKER_SHOW_ALL, Boolean.class),
+ PULL_IMAGE("imagepull",false,true,
+ DockerConstants.DOCKER_REGISTRY, String.class,
+ DockerConstants.DOCKER_TAG, String.class,
+ DockerConstants.DOCKER_REPOSITORY, String.class),
+ PUSH_IMAGE("imagepush",false,true,
+ DockerConstants.DOCKER_NAME, String.class,
+ DockerConstants.DOCKER_USERNAME, String.class,
+ DockerConstants.DOCKER_PASSWORD, String.class,
+ DockerConstants.DOCKER_EMAIL, String.class,
+ DockerConstants.DOCKER_SERVER_ADDRESS, String.class),
+ CREATE_IMAGE("imagecreate",false,true,
+ DockerConstants.DOCKER_REPOSITORY, String.class),
+ SEARCH_IMAGES("imagesearch",false,true,
+ DockerConstants.DOCKER_TERM, String.class),
+ REMOVE_IMAGE("imageremove",false,true,
+ DockerConstants.DOCKER_IMAGE_ID, String.class,
+ DockerConstants.DOCKER_FORCE, Boolean.class,
+ DockerConstants.DOCKER_NO_PRUNE, String.class),
+ INSPECT_IMAGE("imageinspect",false,true,
+ DockerConstants.DOCKER_IMAGE_ID, String.class,
+ DockerConstants.DOCKER_NO_PRUNE, Boolean.class,
+ DockerConstants.DOCKER_FORCE, Boolean.class),
+ LIST_CONTAINERS("containerlist",false,true,
+ DockerConstants.DOCKER_LIMIT, String.class,
+ DockerConstants.DOCKER_SHOW_ALL, Boolean.class,
+ DockerConstants.DOCKER_SHOW_SIZE, Boolean.class,
+ DockerConstants.DOCKER_BEFORE, String.class,
+ DockerConstants.DOCKER_SINCE, String.class),
+ WAIT_CONTAINER("containerwait",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class),
+ INSPECT_CONTAINER("inspectcontainer",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class),
+ REMOVE_CONTAINER("removecontainer",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class,
+ DockerConstants.DOCKER_FORCE, Boolean.class,
+ DockerConstants.DOCKER_REMOVE_VOLUMES, Boolean.class),
+ ATTACH_CONTAINER("containerattach",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class,
+ DockerConstants.DOCKER_FOLLOW_STREAM, Boolean.class,
+ DockerConstants.DOCKER_TIMESTAMPS, Boolean.class,
+ DockerConstants.DOCKER_STD_OUT, Boolean.class,
+ DockerConstants.DOCKER_STD_ERR, Boolean.class,
+ DockerConstants.DOCKER_LOGS, Boolean.class),
+ LOG_CONTAINER("containerlog",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class,
+ DockerConstants.DOCKER_FOLLOW_STREAM, Boolean.class,
+ DockerConstants.DOCKER_TIMESTAMPS, Boolean.class,
+ DockerConstants.DOCKER_STD_OUT, Boolean.class,
+ DockerConstants.DOCKER_STD_ERR, Boolean.class,
+ DockerConstants.DOCKER_TAIL, Integer.class,
+ DockerConstants.DOCKER_TAIL_ALL, Boolean.class),
+ CONTAINER_COPY_FILE("containercopyfile",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class,
+ DockerConstants.DOCKER_RESOURCE, String.class,
+ DockerConstants.DOCKER_HOST_PATH, String.class),
+ DIFF_CONTAINER("containerdiff",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class),
+ STOP_CONTAINER("containerstop",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class,
+ DockerConstants.DOCKER_TIMEOUT, Integer.class),
+ KILL_CONTAINER("containerkill",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class,
+ DockerConstants.DOCKER_SIGNAL, String.class),
+ RESTART_CONTAINER("containerrestart",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class,
+ DockerConstants.DOCKER_TIMEOUT, Integer.class),
+ TOP_CONTAINER("containertop",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class,
+ DockerConstants.DOCKER_TIMEOUT, Integer.class),
+ TAG_IMAGE("imagetag",false,true,
+ DockerConstants.DOCKER_IMAGE_ID, String.class,
+ DockerConstants.DOCKER_REPOSITORY, String.class,
+ DockerConstants.DOCKER_FORCE, Boolean.class),
+ PAUSE_CONTAINER("containerpause",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class),
+ UNPAUSE_CONTAINER("containerunpause",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class),
+ BUILD_IMAGE("imagebuild",false,true,
+ DockerConstants.DOCKER_NO_CACHE, Boolean.class,
+ DockerConstants.DOCKER_REMOVE, Boolean.class,
+ DockerConstants.DOCKER_QUIET, Boolean.class),
+ COMMIT_CONTAINER("containercommit",false,true,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class,
+ DockerConstants.DOCKER_REPOSITORY, String.class,
+ DockerConstants.DOCKER_TAG, String.class,
+ DockerConstants.DOCKER_MESSAGE, String.class,
+ DockerConstants.DOCKER_AUTHOR, String.class,
+ DockerConstants.DOCKER_ATTACH_STD_ERR, Boolean.class,
+ DockerConstants.DOCKER_ATTACH_STD_IN, Boolean.class,
+ DockerConstants.DOCKER_ATTACH_STD_OUT, Boolean.class,
+ DockerConstants.DOCKER_PAUSE, Boolean.class,
+ DockerConstants.DOCKER_ENV, String.class,
+ DockerConstants.DOCKER_HOSTNAME, String.class,
+ DockerConstants.DOCKER_MEMORY, Integer.class,
+ DockerConstants.DOCKER_MEMORY_SWAP, Integer.class,
+ DockerConstants.DOCKER_OPEN_STD_IN, Boolean.class,
+ DockerConstants.DOCKER_PORT_SPECS, String.class,
+ DockerConstants.DOCKER_STD_IN_ONCE, Boolean.class,
+ DockerConstants.DOCKER_TTY, Boolean.class,
+ DockerConstants.DOCKER_WORKING_DIR, String.class),
+ CREATE_CONTAINER("containercreate",false,true,
+ DockerConstants.DOCKER_IMAGE_ID, String.class,
+ DockerConstants.DOCKER_NAME, String.class,
+ DockerConstants.DOCKER_WORKING_DIR, String.class,
+ DockerConstants.DOCKER_DISABLE_NETWORK, Boolean.class,
+ DockerConstants.DOCKER_HOSTNAME, String.class,
+ DockerConstants.DOCKER_PORT_SPECS, String.class,
+ DockerConstants.DOCKER_USER, String.class,
+ DockerConstants.DOCKER_TTY, Boolean.class,
+ DockerConstants.DOCKER_STD_IN_OPEN, Boolean.class,
+ DockerConstants.DOCKER_STD_IN_ONCE, Boolean.class,
+ DockerConstants.DOCKER_MEMORY_LIMIT, Long.class,
+ DockerConstants.DOCKER_MEMORY_SWAP, Long.class,
+ DockerConstants.DOCKER_CPU_SHARES, Integer.class,
+ DockerConstants.DOCKER_ATTACH_STD_IN, Boolean.class,
+ DockerConstants.DOCKER_ATTACH_STD_OUT, Boolean.class,
+ DockerConstants.DOCKER_ATTACH_STD_ERR, Boolean.class,
+ DockerConstants.DOCKER_ENV, String.class,
+ DockerConstants.DOCKER_CMD, String.class,
+ DockerConstants.DOCKER_DNS, String.class,
+ DockerConstants.DOCKER_IMAGE, String.class,
+ DockerConstants.DOCKER_VOLUMES_FROM, String.class),
+ START_CONTAINER("containerstart",false,true,
+ DockerConstants.DOCKER_PUBLISH_ALL_PORTS, Boolean.class,
+ DockerConstants.DOCKER_PRIVILEGED, Boolean.class,
+ DockerConstants.DOCKER_DNS, String.class,
+ DockerConstants.DOCKER_DNS_SEARCH, String.class,
+ DockerConstants.DOCKER_CONTAINER_ID, String.class,
+ DockerConstants.DOCKER_VOLUMES_FROM, String.class,
+ DockerConstants.DOCKER_NETWORK_MODE, String.class,
+ DockerConstants.DOCKER_CAP_ADD, String.class,
+ DockerConstants.DOCKER_CAP_DROP, String.class);
+
+
+ private String text;
+ private boolean canConsume, canProduce;
+ private Map<String, Class<?>> parameters;
+
+
+ private DockerOperation(String text, boolean canConsume, boolean canProduce, Object... params) {
+
+ this.text = text;
+ this.canConsume = canConsume;
+ this.canProduce = canProduce;
+
+ parameters = new HashMap<String,Class<?>>();
+
+ if(params.length > 0) {
+
+ if(params.length % 2 != 0) {
+ throw new IllegalArgumentException("Invalid parameter list, "
+ + "must be of the form 'String name1, Class class1, String name2, Class class2...");
+ }
+
+ int nParameters = params.length / 2;
+
+ for(int i = 0; i < nParameters; i++) {
+ parameters.put((String) params[i * 2], (Class<?>) params[i * 2 + 1]);
+ }
+
+
+ }
+
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+
+ public boolean canConsume() {
+ return canConsume;
+ }
+
+ public boolean canProduce() {
+ return canProduce;
+ }
+
+ public Map<String,Class<?>> getParameters() {
+ return parameters;
+ }
+
+ public static DockerOperation getDockerOperation(String name) {
+ for(DockerOperation dockerOperation : DockerOperation.values()) {
+ if(dockerOperation.toString().equals(name)) {
+ return dockerOperation;
+ }
+ }
+
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/src/main/java/org/apache/camel/component/docker/consumer/DockerEventsConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-docker/src/main/java/org/apache/camel/component/docker/consumer/DockerEventsConsumer.java b/components/camel-docker/src/main/java/org/apache/camel/component/docker/consumer/DockerEventsConsumer.java
new file mode 100644
index 0000000..787cb7c
--- /dev/null
+++ b/components/camel-docker/src/main/java/org/apache/camel/component/docker/consumer/DockerEventsConsumer.java
@@ -0,0 +1,148 @@
+/**
+ * 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.camel.component.docker.consumer;
+
+import com.github.dockerjava.api.command.EventCallback;
+import com.github.dockerjava.api.command.EventsCmd;
+import com.github.dockerjava.api.model.Event;
+
+import java.util.Date;
+import java.util.concurrent.ExecutorService;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.component.docker.DockerClientFactory;
+import org.apache.camel.component.docker.DockerConstants;
+import org.apache.camel.component.docker.DockerEndpoint;
+import org.apache.camel.component.docker.DockerHelper;
+import org.apache.camel.impl.DefaultConsumer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Docker Consumer for streaming events
+ */
+public class DockerEventsConsumer extends DefaultConsumer implements EventCallback {
+
+ private transient static final Logger LOGGER = LoggerFactory.getLogger(DockerEventsConsumer.class);
+
+ private DockerEndpoint endpoint;
+
+ private EventsCmd eventsCmd;
+
+ private ExecutorService eventsExecutorService;
+
+ public DockerEventsConsumer(DockerEndpoint endpoint, Processor processor) throws Exception {
+ super(endpoint, processor);
+ this.endpoint = endpoint;
+
+ }
+
+ @Override
+ public DockerEndpoint getEndpoint() {
+ return (DockerEndpoint)super.getEndpoint();
+ }
+
+
+ /**
+ * Determine the point in time to begin streaming events
+ */
+ private long processInitialEvent() {
+
+ long currentTime = new Date().getTime();
+
+ Long initialRange = DockerHelper.getProperty(DockerConstants.DOCKER_INITIAL_RANGE, endpoint.getConfiguration(), null, Long.class);
+
+ if (initialRange != null) {
+ currentTime = currentTime - initialRange;
+ }
+
+ return currentTime;
+
+
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+
+ eventsCmd = DockerClientFactory.getDockerClient(endpoint.getConfiguration(), null).eventsCmd(this);
+
+ eventsCmd.withSince(String.valueOf(processInitialEvent()));
+ eventsExecutorService = eventsCmd.exec();
+
+ super.doStart();
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+
+ if(eventsExecutorService != null && !eventsExecutorService.isTerminated()) {
+ LOGGER.trace("Stopping Docker events Executor Service");
+
+ eventsExecutorService.shutdown();
+ }
+
+ super.doStop();
+ }
+
+
+ @Override
+ public void onEvent(Event event) {
+
+ LOGGER.debug("Received Docker Event: " + event);
+
+ final Exchange exchange = getEndpoint().createExchange();
+ Message message = exchange.getIn();
+ message.setBody(event);
+
+ try {
+ LOGGER.trace("Processing exchange [{}]...", exchange);
+ getAsyncProcessor().process(exchange, new AsyncCallback() {
+ @Override
+ public void done(boolean doneSync) {
+ LOGGER.trace("Done processing exchange [{}]...", exchange);
+ }
+ });
+ } catch (Exception e) {
+ exchange.setException(e);
+ }
+ if (exchange.getException() != null) {
+ getExceptionHandler().handleException("Error processing exchange", exchange, exchange.getException());
+ }
+
+ }
+
+ @Override
+ public void onException(Throwable throwable) {
+ LOGGER.error("Error Consuming from Docker Events: {}", throwable.getMessage());
+
+ }
+
+ @Override
+ public void onCompletion(int numEvents) {
+
+ LOGGER.debug("Docker events connection completed. Events processed : {}", numEvents);
+
+ eventsCmd.withSince(null);
+
+ LOGGER.debug("Reestablishing connection with Docker");
+ eventsCmd.exec();
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d96dbf8d/components/camel-docker/src/main/java/org/apache/camel/component/docker/exception/DockerException.java
----------------------------------------------------------------------
diff --git a/components/camel-docker/src/main/java/org/apache/camel/component/docker/exception/DockerException.java b/components/camel-docker/src/main/java/org/apache/camel/component/docker/exception/DockerException.java
new file mode 100644
index 0000000..77ce343
--- /dev/null
+++ b/components/camel-docker/src/main/java/org/apache/camel/component/docker/exception/DockerException.java
@@ -0,0 +1,34 @@
+/**
+ * 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.camel.component.docker.exception;
+
+/**
+ * Errors occurring during the processing of the Docker component
+ */
+public class DockerException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public DockerException(String message) {
+ super(message);
+ }
+
+ public DockerException(Throwable throwable) {
+ super(throwable);
+ }
+
+}