You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by he...@apache.org on 2015/05/27 22:37:49 UTC

camel git commit: [CAMEL-8808] Created Grape component.

Repository: camel
Updated Branches:
  refs/heads/master c936be321 -> 520295b22


[CAMEL-8808] Created Grape component.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/520295b2
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/520295b2
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/520295b2

Branch: refs/heads/master
Commit: 520295b22b03058c5b4149ad7cd5b99c4af9aef3
Parents: c936be3
Author: Henryk Konsek <he...@gmail.com>
Authored: Wed May 27 22:37:39 2015 +0200
Committer: Henryk Konsek <he...@gmail.com>
Committed: Wed May 27 22:37:39 2015 +0200

----------------------------------------------------------------------
 components/camel-grape/pom.xml                  | 114 +++++++++++++++++++
 .../grape/FilePatchesRepository.groovy          |  60 ++++++++++
 .../camel/component/grape/GrapeCommand.groovy   |  25 ++++
 .../camel/component/grape/GrapeComponent.groovy |  38 +++++++
 .../camel/component/grape/GrapeConstants.groovy |  23 ++++
 .../camel/component/grape/GrapeEndpoint.groovy  |  70 ++++++++++++
 .../camel/component/grape/GrapeProducer.groovy  |  68 +++++++++++
 .../component/grape/MavenCoordinates.groovy     |  50 ++++++++
 .../component/grape/PatchesRepository.groovy    |  27 +++++
 .../services/org/apache/camel/component/grape   |  17 +++
 .../component/grape/GrapeComponentTest.groovy   | 100 ++++++++++++++++
 components/pom.xml                              |   1 +
 parent/pom.xml                                  |   8 +-
 13 files changed, 598 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-grape/pom.xml b/components/camel-grape/pom.xml
new file mode 100644
index 0000000..9197371
--- /dev/null
+++ b/components/camel-grape/pom.xml
@@ -0,0 +1,114 @@
+<?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.16-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>camel-grape</artifactId>
+	<name>Camel :: Grape</name>
+	<description>Camel Component for Grape</description>
+
+	<properties>
+		<groovy-eclipse-batch.version>2.3.7-01</groovy-eclipse-batch.version>
+		<groovy-eclipse-compiler.version>2.9.1-01</groovy-eclipse-compiler.version>
+		<plexus-compiler-api.version>2.4</plexus-compiler-api.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>${commons-io-version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+			<version>${commons-lang3-version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.camel</groupId>
+			<artifactId>camel-core</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.ivy</groupId>
+			<artifactId>ivy</artifactId>
+			<version>${ivy-version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.codehaus.groovy</groupId>
+			<artifactId>groovy</artifactId>
+			<version>${groovy-version}</version>
+		</dependency>
+
+		<!-- Testing -->
+		<dependency>
+			<groupId>org.apache.camel</groupId>
+			<artifactId>camel-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+        <dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-classic</artifactId>
+			<scope>test</scope>
+			<version>${logback-version}</version>
+		</dependency>
+    </dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<dependencies>
+					<dependency>
+						<groupId>org.codehaus.groovy</groupId>
+						<artifactId>groovy-eclipse-batch</artifactId>
+						<version>${groovy-eclipse-batch.version}</version>
+					</dependency>
+					<dependency>
+						<groupId>org.codehaus.groovy</groupId>
+						<artifactId>groovy-eclipse-compiler</artifactId>
+						<version>${groovy-eclipse-compiler.version}</version>
+					</dependency>
+					<dependency>
+						<groupId>org.codehaus.plexus</groupId>
+						<artifactId>plexus-compiler-api</artifactId>
+						<version>${plexus-compiler-api.version}</version>
+					</dependency>
+				</dependencies>
+				<configuration>
+					<compilerId>groovy-eclipse-compiler</compilerId>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.groovy</groupId>
+				<artifactId>groovy-eclipse-compiler</artifactId>
+				<version>${groovy-eclipse-compiler.version}</version>
+				<extensions>true</extensions>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/FilePatchesRepository.groovy
----------------------------------------------------------------------
diff --git a/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/FilePatchesRepository.groovy b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/FilePatchesRepository.groovy
new file mode 100644
index 0000000..2689453
--- /dev/null
+++ b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/FilePatchesRepository.groovy
@@ -0,0 +1,60 @@
+/**
+ * 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.grape
+
+import org.apache.commons.lang3.SystemUtils
+
+import java.nio.file.Paths
+
+import static org.apache.commons.io.FileUtils.writeStringToFile
+import static org.apache.commons.io.IOUtils.readLines
+
+class FilePatchesRepository implements PatchesRepository {
+
+    private final File repository
+
+    FilePatchesRepository() {
+        this(Paths.get(SystemUtils.userHome.absolutePath, ".camel-iot-labs", "patches").toFile())
+    }
+
+    FilePatchesRepository(File repository) {
+        if(!repository.exists()) {
+            if(repository.getParentFile() != null) {
+                repository.getParentFile().mkdirs()
+            }
+            repository.createNewFile()
+        }
+        this.repository = repository
+    }
+
+    @Override
+    void install(String coordinates) {
+        writeStringToFile(repository, coordinates + "\n", true);
+    }
+
+    @Override
+    List<String> listPatches() {
+        readLines(new FileReader(repository))
+    }
+
+    @Override
+    void clear() {
+        repository.delete()
+        repository.createNewFile()
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeCommand.groovy
----------------------------------------------------------------------
diff --git a/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeCommand.groovy b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeCommand.groovy
new file mode 100644
index 0000000..901b992
--- /dev/null
+++ b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeCommand.groovy
@@ -0,0 +1,25 @@
+/**
+ * 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.grape
+
+enum GrapeCommand {
+
+    grab,
+    listPatches,
+    clearPatches
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeComponent.groovy
----------------------------------------------------------------------
diff --git a/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeComponent.groovy b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeComponent.groovy
new file mode 100644
index 0000000..a3d8d7b
--- /dev/null
+++ b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeComponent.groovy
@@ -0,0 +1,38 @@
+/**
+ * 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.grape
+
+import org.apache.camel.impl.DefaultComponent
+
+class GrapeComponent extends DefaultComponent {
+
+    PatchesRepository patchesRepository = new FilePatchesRepository()
+
+    @Override
+    protected GrapeEndpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) {
+        new GrapeEndpoint(uri, remaining, this)
+    }
+
+    PatchesRepository getPatchesRepository() {
+        return patchesRepository
+    }
+
+    void setPatchesRepository(PatchesRepository patchesRepository) {
+        this.patchesRepository = patchesRepository
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeConstants.groovy
----------------------------------------------------------------------
diff --git a/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeConstants.groovy b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeConstants.groovy
new file mode 100644
index 0000000..c778674
--- /dev/null
+++ b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeConstants.groovy
@@ -0,0 +1,23 @@
+/**
+ * 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.grape
+
+class GrapeConstants {
+
+    static final String GRAPE_COMMAND = 'CamelGrapeCommand'
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeEndpoint.groovy
----------------------------------------------------------------------
diff --git a/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeEndpoint.groovy b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeEndpoint.groovy
new file mode 100644
index 0000000..0053b54
--- /dev/null
+++ b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeEndpoint.groovy
@@ -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.grape
+
+import org.apache.camel.CamelContext
+import org.apache.camel.Consumer
+import org.apache.camel.Processor
+import org.apache.camel.Producer
+import org.apache.camel.impl.DefaultEndpoint
+
+import static groovy.grape.Grape.grab
+
+class GrapeEndpoint extends DefaultEndpoint {
+
+    private final String defaultCoordinates
+
+    GrapeEndpoint(String endpointUri, String defaultCoordinates, GrapeComponent component) {
+        super(endpointUri, component)
+        this.defaultCoordinates = defaultCoordinates
+    }
+
+    static def loadPatches(CamelContext camelContext) {
+        def classLoader = camelContext.applicationContextClassLoader
+        def patchesRepository = camelContext.getComponent('grape', GrapeComponent.class).patchesRepository
+        patchesRepository.listPatches().each {
+            def coordinates = MavenCoordinates.parseMavenCoordinates(it)
+            grab(classLoader: classLoader,
+                    group: coordinates.groupId, module: coordinates.artifactId, version: coordinates.version)
+        }
+    }
+
+    @Override
+    Producer createProducer() {
+        new GrapeProducer(this)
+    }
+
+    @Override
+    Consumer createConsumer(Processor processor) {
+        throw new UnsupportedOperationException('Grape component supports only the producer side of the route.')
+    }
+
+    @Override
+    boolean isSingleton() {
+        true
+    }
+
+    String getDefaultCoordinates() {
+        defaultCoordinates
+    }
+
+    @Override
+    GrapeComponent getComponent() {
+        super.getComponent() as GrapeComponent
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeProducer.groovy
----------------------------------------------------------------------
diff --git a/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeProducer.groovy b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeProducer.groovy
new file mode 100644
index 0000000..1e0f521
--- /dev/null
+++ b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/GrapeProducer.groovy
@@ -0,0 +1,68 @@
+/**
+ * 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.grape
+
+import groovy.grape.Grape
+import org.apache.camel.Exchange
+import org.apache.camel.impl.DefaultProducer
+
+import static GrapeCommand.clearPatches
+import static GrapeCommand.grab
+import static GrapeCommand.listPatches
+import static GrapeConstants.GRAPE_COMMAND
+
+class GrapeProducer extends DefaultProducer {
+
+    GrapeProducer(GrapeEndpoint endpoint) {
+        super(endpoint)
+    }
+
+    @Override
+    void process(Exchange exchange) {
+        def command = exchange.in.getHeader(GRAPE_COMMAND, grab, GrapeCommand.class)
+        switch(command) {
+            case grab:
+                def classLoader = exchange.context.applicationContextClassLoader
+                def rawCoordinates = exchange.in.getBody(String.class)
+                try {
+                    def coordinates = MavenCoordinates.parseMavenCoordinates(rawCoordinates)
+                    Grape.grab(classLoader: classLoader, group: coordinates.groupId, module: coordinates.artifactId, version: coordinates.version)
+                    endpoint.component.patchesRepository.install(rawCoordinates)
+                } catch (IllegalArgumentException ex) {
+                    def coordinates = MavenCoordinates.parseMavenCoordinates(getEndpoint().defaultCoordinates)
+                    Grape.grab(classLoader: classLoader, group: coordinates.groupId, module: coordinates.artifactId, version: coordinates.version)
+                    endpoint.component.patchesRepository.install(getEndpoint().defaultCoordinates)
+                }
+                break
+
+            case listPatches:
+                def patches = endpoint.component.patchesRepository.listPatches()
+                exchange.getIn().setBody(patches)
+                break
+
+            case clearPatches:
+                endpoint.component.patchesRepository.clear()
+                break
+        }
+    }
+
+    @Override
+    GrapeEndpoint getEndpoint() {
+        super.getEndpoint() as GrapeEndpoint
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/MavenCoordinates.groovy
----------------------------------------------------------------------
diff --git a/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/MavenCoordinates.groovy b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/MavenCoordinates.groovy
new file mode 100644
index 0000000..7959675
--- /dev/null
+++ b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/MavenCoordinates.groovy
@@ -0,0 +1,50 @@
+/**
+ * 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.grape
+
+import groovy.transform.Immutable
+
+@Immutable
+class MavenCoordinates {
+
+    private final String groupId
+
+    private final String artifactId
+
+    private final String version
+
+    static MavenCoordinates parseMavenCoordinates(String coordinates) {
+        def coordinatesParts = coordinates.split('/')
+        if(coordinatesParts.length != 3) {
+            throw new IllegalArgumentException("Invalid coordinates: ${coordinates}")
+        }
+        new MavenCoordinates(groupId: coordinatesParts[0], artifactId: coordinatesParts[1], version: coordinatesParts[2])
+    }
+
+    String getGroupId() {
+        return groupId
+    }
+
+    String getArtifactId() {
+        return artifactId
+    }
+
+    String getVersion() {
+        return version
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/PatchesRepository.groovy
----------------------------------------------------------------------
diff --git a/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/PatchesRepository.groovy b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/PatchesRepository.groovy
new file mode 100644
index 0000000..e5f9ce0
--- /dev/null
+++ b/components/camel-grape/src/main/groovy/org/apache/camel/component/grape/PatchesRepository.groovy
@@ -0,0 +1,27 @@
+/**
+ * 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.grape
+
+interface PatchesRepository {
+
+    void install(String coordinates);
+
+    List<String> listPatches();
+
+    void clear();
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/src/main/resources/META-INF/services/org/apache/camel/component/grape
----------------------------------------------------------------------
diff --git a/components/camel-grape/src/main/resources/META-INF/services/org/apache/camel/component/grape b/components/camel-grape/src/main/resources/META-INF/services/org/apache/camel/component/grape
new file mode 100644
index 0000000..747706a
--- /dev/null
+++ b/components/camel-grape/src/main/resources/META-INF/services/org/apache/camel/component/grape
@@ -0,0 +1,17 @@
+#
+# 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.
+
+class=org.apache.camel.component.grape.GrapeComponent
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/camel-grape/src/test/groovy/org/apache/camel/component/grape/GrapeComponentTest.groovy
----------------------------------------------------------------------
diff --git a/components/camel-grape/src/test/groovy/org/apache/camel/component/grape/GrapeComponentTest.groovy b/components/camel-grape/src/test/groovy/org/apache/camel/component/grape/GrapeComponentTest.groovy
new file mode 100644
index 0000000..15bbee6
--- /dev/null
+++ b/components/camel-grape/src/test/groovy/org/apache/camel/component/grape/GrapeComponentTest.groovy
@@ -0,0 +1,100 @@
+/**
+ * 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.grape
+
+import org.apache.camel.ServiceStatus
+import org.apache.camel.builder.RouteBuilder
+import org.apache.camel.component.grape.FilePatchesRepository
+import org.apache.camel.impl.DefaultCamelContext
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+
+import static org.apache.camel.component.grape.GrapeEndpoint.loadPatches
+import static org.apache.camel.ServiceStatus.Stopped
+
+class GrapeComponentTest extends Assert {
+
+    def pathesRepository = new FilePatchesRepository()
+
+    def camelContext = new DefaultCamelContext()
+
+    @Before
+    void before() {
+        camelContext.setApplicationContextClassLoader(new GroovyClassLoader())
+    }
+
+    @Test
+    void shouldLoadStreamComponent() {
+        pathesRepository.clear()
+        camelContext.start()
+        camelContext.createProducerTemplate().sendBody('grape:org.apache.camel/camel-stream/2.15.2', 'msg')
+        camelContext.createProducerTemplate().sendBody('stream:out', 'msg')
+    }
+
+    @Test
+    void shouldLoadStreamComponentViaBodyRequest() {
+        pathesRepository.clear()
+        camelContext.start()
+        camelContext.createProducerTemplate().sendBody('grape:grape', 'org.apache.camel/camel-stream/2.15.2')
+        camelContext.createProducerTemplate().sendBody('stream:out', 'msg')
+    }
+
+    @Test
+    void shouldLoadBeanAtRuntime() {
+        pathesRepository.clear()
+        camelContext.start()
+        camelContext.createProducerTemplate().sendBody('grape:grape', 'org.apache.camel/camel-stream/2.15.2')
+        def status = camelContext.createProducerTemplate().requestBody('bean:org.apache.camel.component.stream.StreamComponent?method=getStatus', null, ServiceStatus.class)
+        assertEquals(Stopped, status)
+    }
+
+    @Test
+    void shouldLoadPatchesAtStartup() {
+        // Given
+        pathesRepository.clear()
+        camelContext.start()
+        camelContext.createProducerTemplate().sendBody('grape:grape', 'org.apache.camel/camel-stream/2.15.2')
+        camelContext.stop()
+
+        camelContext = new DefaultCamelContext()
+        camelContext.setApplicationContextClassLoader(new GroovyClassLoader())
+        camelContext.addRoutes(new RouteBuilder() {
+            @Override
+            void configure() {
+                loadPatches(camelContext)
+            }
+        })
+
+        // When
+        camelContext.start()
+        def status = camelContext.createProducerTemplate().requestBody('bean:org.apache.camel.component.stream.StreamComponent?method=getStatus', null, ServiceStatus.class)
+
+        // Then
+        assertEquals(Stopped, status)
+    }
+
+    @Test
+    void shouldListPatches() {
+        pathesRepository.clear()
+        camelContext.start()
+        camelContext.createProducerTemplate().sendBody('grape:grape', 'org.apache.camel/camel-stream/2.15.2')
+        def patches = pathesRepository.listPatches()
+        assertEquals(['org.apache.camel/camel-stream/2.15.2'], patches)
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/components/pom.xml
----------------------------------------------------------------------
diff --git a/components/pom.xml b/components/pom.xml
index 368c5b3..e364395 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -108,6 +108,7 @@
     <module>camel-google-drive</module>
     <module>camel-google-mail</module>
     <module>camel-gora</module>
+    <module>camel-grape</module>
     <module>camel-gson</module>
     <module>camel-guava-eventbus</module>
     <module>camel-guice</module>

http://git-wip-us.apache.org/repos/asf/camel/blob/520295b2/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index da80edc..9abd2b1 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -122,9 +122,9 @@
     <commons-vfs2-version>2.0</commons-vfs2-version>
     <concurrentlinkedhashmap.version>1.4.2</concurrentlinkedhashmap.version>
     <cobertura-maven-plugin-version>2.7</cobertura-maven-plugin-version>
-    <cxf-version>3.0.5</cxf-version>
+    <cxf-version>3.0.4</cxf-version>
     <cxf-version-range>[2.7,4.0)</cxf-version-range>
-    <cxf-xjc-utils-version>3.0.3</cxf-xjc-utils-version>
+    <cxf-xjc-utils-version>3.0.2</cxf-xjc-utils-version>
     <deltaspike-version>1.3.0</deltaspike-version>
     <derby-version>10.11.1.1</derby-version>
     <disruptor-version>3.3.2</disruptor-version>
@@ -230,6 +230,7 @@
     <isorelax-bundle-version>20050913_4</isorelax-bundle-version>
     <isorelax-version>20090621</isorelax-version>
     <isorelax-jaxp-bridge-version>1.1</isorelax-jaxp-bridge-version>
+    <ivy-version>2.4.0</ivy-version>
     <jini-version>2.1</jini-version>
     <jackson-version>1.9.12</jackson-version>
     <jackson2-version>2.5.1</jackson2-version>
@@ -304,7 +305,7 @@
     <junit-version>4.11</junit-version>
     <jython-version>2.5.3</jython-version>
     <jzlib-version>1.1.3</jzlib-version>
-    <kafka-version>0.8.2.1</kafka-version>
+    <kafka-version>0.8.2.0</kafka-version>
     <kafka-bundle-version>0.8.2.0_1</kafka-bundle-version>
     <karaf-version>2.4.2</karaf-version>
     <karaf3-version>3.0.2</karaf3-version>
@@ -315,6 +316,7 @@
     <!-- virtual dependency only used by Eclipse m2e -->
     <lifecycle-mapping-version>1.0.0</lifecycle-mapping-version>
     <log4j-version>1.2.17</log4j-version>
+    <logback-version>1.1.2</logback-version>
     <lucene3-bundle-version>3.6.0_1</lucene3-bundle-version>
     <lucene3-version>3.6.0</lucene3-version>
     <lucene-bundle-version>4.10.3_1</lucene-bundle-version>