git.net

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [camel] 01/03: Added a Camel connector for R3's Corda blockchain platform using corda-rpc module


I should have fixed the kit now.

--
Andrea Cosentino 
----------------------------------
Apache Camel PMC Chair
Apache Karaf Committer
Apache Servicemix PMC Member
Email: ancosen1985@xxxxxxxxx
Twitter: @oscerd2
Github: oscerd






On Tuesday, November 27, 2018, 11:36:17 AM GMT+1, bibryam@xxxxxxxxxx <bibryam@xxxxxxxxxx> wrote: 





This is an automated email from the ASF dual-hosted git repository.

bibryam pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 8a1dcfbb04c2dc0d8fe352ae5ac2d14fee859d5a
Author: Bilgin Ibryam <bibryam@xxxxxxxxx>
AuthorDate: Tue Nov 27 10:16:58 2018 +0000

    Added a Camel connector for R3's Corda blockchain platform using corda-rpc module
---
apache-camel/src/main/descriptors/common-bin.xml  |  2 +
bom/camel-bom/pom.xml                              |  10 +
components/camel-corda/.gitignore                  |  6 +
components/camel-corda/README.md                  |  3 +
components/camel-corda/pom.xml                    |  84 ++++
.../camel-corda/src/main/docs/corda-component.adoc | 141 ++++++
.../camel/component/corda/CordaComponent.java      |  54 +++
.../camel/component/corda/CordaConfiguration.java  | 168 +++++++
.../camel/component/corda/CordaConstants.java      |  69 +++
.../camel/component/corda/CordaConsumer.java      | 267 +++++++++++
.../camel/component/corda/CordaEndpoint.java      | 101 +++++
.../camel/component/corda/CordaProducer.java      | 240 ++++++++++
.../src/main/resources/META-INF/LICENSE.txt        | 203 +++++++++
.../src/main/resources/META-INF/NOTICE.txt        |  11 +
.../services/org/apache/camel/component/corda      |  18 +
.../apache/camel/component/corda/CamelFlow.java    |  32 ++
.../corda/CordaConsumerNetworkMapFeedTest.java    |  49 ++
.../CordaConsumerStartTrackedFlowDynamicTest.java  |  54 +++
.../corda/CordaConsumerStateMachineFeedTest.java  |  49 ++
.../component/corda/CordaConsumerTestSupport.java  |  62 +++
.../corda/CordaConsumerTransactionMapFeedTest.java |  49 ++
.../CordaConsumerVaultTrackByCriteriaTest.java    |  51 +++
.../corda/CordaConsumerVaultTrackByTest.java      |  53 +++
...ordaConsumerVaultTrackByWithPagingSpecTest.java |  52 +++
.../CordaConsumerVaultTrackByWithSortingTest.java  |  52 +++
.../corda/CordaConsumerVaultTrackTest.java        |  49 ++
.../camel/component/corda/CordaProducerTest.java  | 498 +++++++++++++++++++++
.../camel/component/corda/CordaTestSupport.java    |  74 +++
.../component/corda/IntegrationWhiteList.java      |  35 ++
...corda.core.serialization.SerializationWhitelist |  1 +
.../src/test/resources/log4j2.properties          |  34 ++
.../org.mockito.plugins.MockMaker                  |  1 +
components/pom.xml                                |  1 +
components/readme.adoc                            |  5 +-
docs/user-manual/en/SUMMARY.md                    |  1 +
parent/pom.xml                                    |  25 ++
.../karaf/features/src/main/resources/features.xml |  5 +
.../components-starter/camel-corda-starter/pom.xml |  65 +++
.../CordaComponentAutoConfiguration.java          | 128 ++++++
.../springboot/CordaComponentConfiguration.java    | 182 ++++++++
.../src/main/resources/META-INF/LICENSE.txt        | 203 +++++++++
.../src/main/resources/META-INF/NOTICE.txt        |  11 +
.../additional-spring-configuration-metadata.json  |  10 +
.../src/main/resources/META-INF/spring.factories  |  19 +
.../src/main/resources/META-INF/spring.provides    |  17 +
platforms/spring-boot/components-starter/pom.xml  |  1 +
.../camel-spring-boot-dependencies/pom.xml        |  24 +
47 files changed, 3268 insertions(+), 1 deletion(-)

diff --git a/apache-camel/src/main/descriptors/common-bin.xml b/apache-camel/src/main/descriptors/common-bin.xml
index 22c929a..10fe745 100644
--- a/apache-camel/src/main/descriptors/common-bin.xml
+++ b/apache-camel/src/main/descriptors/common-bin.xml
@@ -68,6 +68,7 @@
        <include>org.apache.camel:camel-connector</include>
        <include>org.apache.camel:camel-consul</include>
        <include>org.apache.camel:camel-context</include>
+        <include>org.apache.camel:camel-corda</include>
        <include>org.apache.camel:camel-couchdb</include>
        <include>org.apache.camel:camel-couchbase</include>
        <include>org.apache.camel:camel-crypto</include>
@@ -394,6 +395,7 @@
        <include>org.apache.camel:camel-cometd-starter</include>
        <include>org.apache.camel:camel-consul-starter</include>
        <include>org.apache.camel:camel-context-starter</include>
+        <include>org.apache.camel:camel-corda-starter</include>
        <include>org.apache.camel:camel-core-starter</include>
        <include>org.apache.camel:camel-couchdb-starter</include>
        <include>org.apache.camel:camel-couchbase-starter</include>
diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index fc9cacf..f63ca96 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -492,6 +492,16 @@
        <version>${project.version}</version>
      </dependency>
      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-corda</artifactId>
+          <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-corda-starter</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core</artifactId>
        <version>${project.version}</version>
diff --git a/components/camel-corda/.gitignore b/components/camel-corda/.gitignore
new file mode 100644
index 0000000..f1ea348
--- /dev/null
+++ b/components/camel-corda/.gitignore
@@ -0,0 +1,6 @@
+**/.DS_Store
+.DS_Store
+target
+.idea
+*.iml
+*.log
diff --git a/components/camel-corda/README.md b/components/camel-corda/README.md
new file mode 100644
index 0000000..1431dd2
--- /dev/null
+++ b/components/camel-corda/README.md
@@ -0,0 +1,3 @@
+# camel-corda
+
+[Apache Camel](http://camel.apache.org/) connector for R's [Corda](https://www.corda.net/) blockchain platform using corda-rpc library. 
diff --git a/components/camel-corda/pom.xml b/components/camel-corda/pom.xml
new file mode 100644
index 0000000..b7969a0
--- /dev/null
+++ b/components/camel-corda/pom.xml
@@ -0,0 +1,84 @@
+<?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.23.0-SNAPSHOT</version>
+      </parent>
+
+      <artifactId>camel-corda</artifactId>
+      <packaging>jar</packaging>
+
+      <name>Camel :: Corda</name>
+      <description>Camel Corda which is based on corda-rpc support</description>
+
+    <properties>
+        <camel.osgi.export.pkg>org.apache.camel.component.corda.*</camel.osgi.export.pkg>
+        <camel.osgi.export.service>org.apache.camel.spi.ComponentResolver;component=corda</camel.osgi.export.service>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.corda</groupId>
+            <artifactId>corda-rpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- for testing -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/components/camel-corda/src/main/docs/corda-component.adoc b/components/camel-corda/src/main/docs/corda-component.adoc
new file mode 100644
index 0000000..eb454ae
--- /dev/null
+++ b/components/camel-corda/src/main/docs/corda-component.adoc
@@ -0,0 +1,141 @@
+[[corda-component]]
+== corda Component
+
+*Available as of Camel version 2.23*
+
+*Available as of Camel version 2.23*
+
+
+The *Corda* blockchain component uses the https://www.corda.net/[corda] rpc client
+
+Maven users will need to add the following dependency to their `pom.xml`
+for this component:
+
+[source,xml]
+------------------------------------------------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-corda</artifactId>
+    <version>x.x.x</version>
+    <!-- use the same version as your Camel core version -->
+</dependency>
+------------------------------------------------------------
+
+=== URI Format
+
+[source,text]
+----
+corda://<host:port>[?options]
+----
+
+=== Corda Options
+
+
+// component options: START
+The corda component supports 2 options, which are listed below.
+
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *configuration* (common) | Default configuration |  | CordaConfiguration
+| *resolveProperty Placeholders* (advanced) | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | boolean
+|===
+// component options: END
+
+
+// endpoint options: START
+The corda endpoint is configured using URI syntax:
+
+----
+corda:url
+----
+
+with the following path and query parameters:
+
+==== Path Parameters (1 parameters):
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *configuration* | *Required* URL to the corda node |  | CordaConfiguration
+|===
+
+
+==== Query Parameters (4 parameters):
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
+| *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
+| *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. |  | ExchangePattern
+| *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
+|===
+// endpoint options: END
+// spring-boot-auto-configure options: START
+=== Spring Boot Auto-Configuration
+
+
+The component supports 14 options, which are listed below.
+
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *camel.component.corda.configuration.arguments* |  |  | Object[]
+| *camel.component.corda.configuration.contract-state-class* |  |  | Class
+| *camel.component.corda.configuration.flow-loci-class* |  |  | Class
+| *camel.component.corda.configuration.host* |  |  | String
+| *camel.component.corda.configuration.operation* |  |  | String
+| *camel.component.corda.configuration.page-specification* |  |  | PageSpecification
+| *camel.component.corda.configuration.password* |  |  | String
+| *camel.component.corda.configuration.port* |  |  | Integer
+| *camel.component.corda.configuration.process-snapshot* |  |  | Boolean
+| *camel.component.corda.configuration.query-criteria* |  |  | QueryCriteria
+| *camel.component.corda.configuration.sort* |  |  | Sort
+| *camel.component.corda.configuration.username* |  |  | String
+| *camel.component.corda.enabled* | Enable corda component | true | Boolean
+| *camel.component.corda.resolve-property-placeholders* | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | Boolean
+|===
+// spring-boot-auto-configure options: END
+
+
+
+You can append query options to the URI in the following format,
+?options=value&option2=value&...
+
+
+### Message Headers
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Header |Description
+
+|`All URI options` |All URI options can also be set as exchange headers.
+
+|=======================================================================
+
+
+
+### Samples
+
+Subscribe for new vault state changes:
+
+[source,java]
+---------------------------------------------------------------------------------------------
+from("corda://localhost:10006?username=user1&password=test?operation=VAULT_TRACK&contractStateClass=#contractStateClass")
+    .to("jms:queue:vault");
+---------------------------------------------------------------------------------------------
+
+Read the node information:
+
+[source,java]
+--------------------------------------------------------
+from("direct:start")
+    .to("corda://localhost:10006?username=user1&password=test?operation=NODE_INFO");
+--------------------------------------------------------
diff --git a/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaComponent.java b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaComponent.java
new file mode 100644
index 0000000..04cf6d5
--- /dev/null
+++ b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaComponent.java
@@ -0,0 +1,54 @@
+/**
+ * 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.corda;
+
+import java.util.Map;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.DefaultComponent;
+import org.apache.camel.spi.Metadata;
+
+/**
+ * Represents the component that manages {@link CordaComponent}.
+ */
+public class CordaComponent extends DefaultComponent {
+
+    @Metadata(description = "Default configuration")
+    private CordaConfiguration configuration;
+
+    public CordaComponent() {
+    }
+
+    public CordaComponent(CamelContext camelContext) {
+        super(camelContext);
+    }
+
+    public CordaConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(CordaConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    protected Endpoint createEndpoint(String uri, final String remaining, final Map<String, Object> parameters) throws Exception {
+        CordaConfiguration conf =  configuration != null ? configuration.copy() : new CordaConfiguration();
+        setProperties(conf, parameters);
+        return new CordaEndpoint(uri, remaining, this, conf);
+    }
+
+}
diff --git a/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaConfiguration.java b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaConfiguration.java
new file mode 100644
index 0000000..4d932ba
--- /dev/null
+++ b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaConfiguration.java
@@ -0,0 +1,168 @@
+/**
+ * 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.corda;
+
+import net.corda.core.contracts.ContractState;
+import net.corda.core.flows.FlowLogic;
+import net.corda.core.node.services.vault.PageSpecification;
+import net.corda.core.node.services.vault.QueryCriteria;
+import net.corda.core.node.services.vault.Sort;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+
+@UriParams
+public class CordaConfiguration implements Cloneable {
+    @UriParam
+    @Metadata(required = "true")
+    private String operation;
+
+    @UriParam
+    @Metadata(required = "true", secret = true)
+    private String username;
+
+    @UriParam
+    @Metadata(required = "true", secret = true)
+    private String password;
+
+    @Metadata(required = "true")
+    private String host;
+
+    @Metadata(required = "true")
+    private int port;
+
+    @Metadata(required = "false", defaultValue = "true")
+    private boolean processSnapshot = true;
+
+    private Class<FlowLogic<?>> flowLociClass;
+
+    private Object [] arguments;
+
+    private Class<ContractState> contractStateClass;
+
+    private QueryCriteria queryCriteria;
+
+    private PageSpecification pageSpecification;
+
+    private Sort sort;
+
+    public String getOperation() {
+        return operation;
+    }
+
+    public void setOperation(String operation) {
+        this.operation = operation;
+    }
+
+    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 getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public boolean isProcessSnapshot() {
+        return processSnapshot;
+    }
+
+    public void setProcessSnapshot(boolean processSnapshot) {
+        this.processSnapshot = processSnapshot;
+    }
+
+    public Class<FlowLogic<?>> getFlowLociClass() {
+        return flowLociClass;
+    }
+
+    public void setFlowLociClass(Class<FlowLogic<?>> flowLociClass) {
+        this.flowLociClass = flowLociClass;
+    }
+
+    public Object[] getArguments() {
+        return arguments;
+    }
+
+    public void setArguments(Object[] arguments) {
+        this.arguments = arguments;
+    }
+
+    public Class<ContractState> getContractStateClass() {
+        return contractStateClass;
+    }
+
+    public void setContractStateClass(Class<ContractState> contractStateClass) {
+        this.contractStateClass = contractStateClass;
+    }
+
+    public QueryCriteria getQueryCriteria() {
+        return queryCriteria;
+    }
+
+    public void setQueryCriteria(QueryCriteria queryCriteria) {
+        this.queryCriteria = queryCriteria;
+    }
+
+    public PageSpecification getPageSpecification() {
+        return pageSpecification;
+    }
+
+    public void setPageSpecification(PageSpecification pageSpecification) {
+        this.pageSpecification = pageSpecification;
+    }
+
+    public Sort getSort() {
+        return sort;
+    }
+
+    public void setSort(Sort sort) {
+        this.sort = sort;
+    }
+
+    public CordaConfiguration copy() {
+        try {
+            return (CordaConfiguration)super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeCamelException(e);
+        }
+    }
+
+}
diff --git a/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaConstants.java b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaConstants.java
new file mode 100644
index 0000000..f7c29be
--- /dev/null
+++ b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaConstants.java
@@ -0,0 +1,69 @@
+/**
+ * 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.corda;
+
+public interface CordaConstants {
+    String OPERATION = "OPERATION";
+    String NODE_INFO = "NODE_INFO";
+    String CURRENT_NODE_TIME = "CURRENT_NODE_TIME";
+    String GET_PROTOCOL_VERSION = "GET_PROTOCOL_VERSION";
+    String NETWORK_MAP_SNAPSHOT = "NETWORK_MAP_SNAPSHOT";
+    String REGISTERED_FLOWS = "REGISTERED_FLOWS";
+    String CLEAR_NETWORK_MAP_CACHE = "CLEAR_NETWORK_MAP_CACHE";
+    String IS_FLOWS_DRAINING_MODE_ENABLED = "IS_FLOWS_DRAINING_MODE_ENABLED";
+    String ADD_VAULT_TRANSACTION_NOTE = "ADD_VAULT_TRANSACTION_NOTE";
+    String NOTARY_IDENTITIES = "NOTARY_IDENTITIES";
+    String SET_FLOWS_DRAINING_MODE_ENABLED = "SET_FLOWS_DRAINING_MODE_ENABLED";
+    String GET_VAULT_TRANSACTION_NOTES = "GET_VAULT_TRANSACTION_NOTES";
+    String UPLOAD_ATTACHMENT = "UPLOAD_ATTACHMENT";
+    String ATTACHMENT_EXISTS = "ATTACHMENT_EXISTS";
+    String OPEN_ATTACHMENT = "OPEN_ATTACHMENT";
+    String QUERY_ATTACHMENTS = "QUERY_ATTACHMENTS";
+    String NODE_INFO_FROM_PARTY = "NODE_INFO_FROM_PARTY";
+    String NOTARY_PARTY_FROM_X500_NAME = "NOTARY_PARTY_FROM_X500_NAME";
+    String PARTIES_FROM_NAME = "PARTIES_FROM_NAME";
+    String PARTIES_FROM_KEY = "PARTIES_FROM_KEY";
+    String START_FLOW_DYNAMIC = "START_FLOW_DYNAMIC";
+    String STATE_MACHINE_SNAPSHOT = "STATE_MACHINE_SNAPSHOT";
+    String STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_SNAPSHOT = "STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_SNAPSHOT";
+    String WELL_KNOWN_PARTY_FROM_X500_NAME = "WELL_KNOWN_PARTY_FROM_X500_NAME";
+    String WELL_KNOWN_PARTY_FROM_ANONYMOUS = "WELL_KNOWN_PARTY_FROM_ANONYMOUS";
+    String VAULT_QUERY = "VAULT_QUERY";
+    String VAULT_QUERY_BY = "VAULT_QUERY_BY";
+    String VAULT_QUERY_BY_CRITERIA = "VAULT_QUERY_BY_CRITERIA";
+    String VAULT_QUERY_BY_WITH_PAGING_SPEC = "VAULT_QUERY_BY_WITH_PAGING_SPEC";
+    String VAULT_QUERY_BY_WITH_SORTING = "VAULT_QUERY_BY_WITH_SORTING";
+
+    String VAULT_TRACK = "VAULT_TRACK";
+    String VAULT_TRACK_BY = "VAULT_TRACK_BY";
+    String VAULT_TRACK_BY_CRITERIA = "VAULT_TRACK_BY_CRITERIA";
+    String VAULT_TRACK_BY_WITH_PAGING_SPEC = "VAULT_TRACK_BY_WITH_PAGING_SPEC";
+    String VAULT_TRACK_BY_WITH_SORTING = "VAULT_TRACK_BY_WITH_SORTING";
+    String STATE_MACHINE_FEED = "STATE_MACHINE_FEED";
+    String NETWORK_MAP_FEED = "NETWORK_MAP_FEED";
+    String STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_FEED = "STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_FEED";
+    String START_TRACKED_FLOW_DYNAMIC = "START_TRACKED_FLOW_DYNAMIC";
+
+    String ATTACHMENT_QUERY_CRITERIA = "ATTACHMENT_QUERY_CRITERIA";
+    String SORT = "SORT";
+    String EXACT_MATCH = "EXACT_MATCH";
+    String ARGUMENTS = "ARGUMENTS";
+    String DRAINING_MODE = "DRAINING_MODE";
+    String SECURE_HASH = "SECURE_HASH";
+    String QUERY_CRITERIA = "QUERY_CRITERIA";
+    String PAGE_SPECIFICATION = "PAGE_SPECIFICATION";
+}
diff --git a/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaConsumer.java b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaConsumer.java
new file mode 100644
index 0000000..3c1f617
--- /dev/null
+++ b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaConsumer.java
@@ -0,0 +1,267 @@
+/**
+ * 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.corda;
+
+import java.util.List;
+import net.corda.core.contracts.ContractState;
+import net.corda.core.messaging.CordaRPCOps;
+import net.corda.core.messaging.DataFeed;
+import net.corda.core.messaging.FlowProgressHandle;
+import net.corda.core.messaging.StateMachineInfo;
+import net.corda.core.messaging.StateMachineTransactionMapping;
+import net.corda.core.messaging.StateMachineUpdate;
+import net.corda.core.node.NodeInfo;
+import net.corda.core.node.services.NetworkMapCache;
+import net.corda.core.node.services.Vault;
+import net.corda.core.node.services.vault.PageSpecification;
+import net.corda.core.node.services.vault.QueryCriteria;
+import net.corda.core.node.services.vault.Sort;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.impl.DefaultConsumer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import rx.Observable;
+import rx.Subscription;
+
+import static org.apache.camel.component.corda.CordaConstants.NETWORK_MAP_FEED;
+import static org.apache.camel.component.corda.CordaConstants.START_TRACKED_FLOW_DYNAMIC;
+import static org.apache.camel.component.corda.CordaConstants.STATE_MACHINE_FEED;
+import static org.apache.camel.component.corda.CordaConstants.STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_FEED;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY_CRITERIA;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY_WITH_PAGING_SPEC;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY_WITH_SORTING;
+
+/**
+ * The corda consumer.
+ */
+public class CordaConsumer extends DefaultConsumer {
+    private static final Logger LOG = LoggerFactory.getLogger(CordaConsumer.class);
+    private final CordaConfiguration configuration;
+    private CordaRPCOps cordaRPCOps;
+    private Subscription subscription;
+
+    public CordaConsumer(CordaEndpoint endpoint, Processor processor, CordaConfiguration configuration, CordaRPCOps cordaRPCOps) {
+        super(endpoint, processor);
+        this.configuration = configuration;
+        this.cordaRPCOps = cordaRPCOps;
+    }
+
+    @Override
+    public CordaEndpoint getEndpoint() {
+        return (CordaEndpoint) super.getEndpoint();
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        Exchange exchange = this.getEndpoint().createExchange();
+        Class<ContractState> contractStateClass = configuration.getContractStateClass();
+        QueryCriteria criteria = configuration.getQueryCriteria();
+        PageSpecification pageSpec = configuration.getPageSpecification();
+        Sort sorting = configuration.getSort();
+
+        DataFeed<Vault.Page<ContractState>, Vault.Update<ContractState>> pageUpdateDataFeed = null;
+        switch (configuration.getOperation()) {
+
+        case VAULT_TRACK:
+            LOG.debug("subscribing for operation: " + VAULT_TRACK);
+            pageUpdateDataFeed = cordaRPCOps.vaultTrack(contractStateClass);
+            processSnapshot(exchange, pageUpdateDataFeed.getSnapshot());
+            subscription = pageUpdateDataFeed.getUpdates().subscribe(
+                x -> processContractStateUpdate(x),
+                t -> processError(t, CordaConstants.VAULT_TRACK),
+                () -> processDone(CordaConstants.VAULT_TRACK)
+            );
+            break;
+
+        case VAULT_TRACK_BY:
+            LOG.debug("subscribing for operation: " + VAULT_TRACK_BY);
+            pageUpdateDataFeed = cordaRPCOps.vaultTrackBy(criteria, pageSpec, sorting, contractStateClass);
+            processSnapshot(exchange, pageUpdateDataFeed.getSnapshot());
+            subscription = pageUpdateDataFeed.getUpdates().subscribe(
+                x -> processContractStateUpdate(x),
+                t -> processError(t, CordaConstants.VAULT_TRACK_BY),
+                () -> processDone(CordaConstants.VAULT_TRACK_BY)
+            );
+            break;
+
+        case VAULT_TRACK_BY_CRITERIA:
+            LOG.debug("subscribing for operation: " + VAULT_TRACK_BY_CRITERIA);
+            pageUpdateDataFeed = cordaRPCOps.vaultTrackByCriteria(contractStateClass, criteria);
+            processSnapshot(exchange, pageUpdateDataFeed.getSnapshot());
+            subscription = pageUpdateDataFeed.getUpdates().subscribe(
+                x -> processContractStateUpdate(x),
+                t -> processError(t, CordaConstants.VAULT_TRACK_BY_CRITERIA),
+                () -> processDone(CordaConstants.VAULT_TRACK_BY_CRITERIA)
+            );
+            break;
+
+        case VAULT_TRACK_BY_WITH_PAGING_SPEC:
+            LOG.debug("subscribing for operation: " + VAULT_TRACK_BY_WITH_PAGING_SPEC);
+            pageUpdateDataFeed = cordaRPCOps.vaultTrackByWithPagingSpec(contractStateClass, criteria, pageSpec);
+            processSnapshot(exchange, pageUpdateDataFeed.getSnapshot());
+            subscription = pageUpdateDataFeed.getUpdates().subscribe(
+                x -> processContractStateUpdate(x),
+                t -> processError(t, CordaConstants.VAULT_TRACK_BY_WITH_PAGING_SPEC),
+                () -> processDone(CordaConstants.VAULT_TRACK_BY_WITH_PAGING_SPEC)
+            );
+            break;
+
+        case VAULT_TRACK_BY_WITH_SORTING:
+            LOG.debug("subscribing for operation: " + VAULT_TRACK_BY_WITH_SORTING);
+            pageUpdateDataFeed = cordaRPCOps.vaultTrackByWithSorting(contractStateClass, criteria, sorting);
+            processSnapshot(exchange, pageUpdateDataFeed.getSnapshot());
+            subscription = pageUpdateDataFeed.getUpdates().subscribe(
+                x -> processContractStateUpdate(x),
+                t -> processError(t, CordaConstants.VAULT_TRACK_BY_WITH_SORTING),
+                () -> processDone(CordaConstants.VAULT_TRACK_BY_WITH_SORTING)
+            );
+            break;
+
+        case STATE_MACHINE_FEED:
+            LOG.debug("subscribing for operation: " + STATE_MACHINE_FEED);
+            DataFeed<List<StateMachineInfo>, StateMachineUpdate> stateFeed = cordaRPCOps.stateMachinesFeed();
+            processSnapshot(exchange, stateFeed.getSnapshot());
+            subscription = stateFeed.getUpdates().subscribe(
+                x -> processStateMachineUpdate(x),
+                t -> processError(t, CordaConstants.STATE_MACHINE_FEED),
+                () -> processDone(CordaConstants.STATE_MACHINE_FEED)
+            );
+            break;
+
+        case NETWORK_MAP_FEED:
+            LOG.debug("subscribing for operation: " + NETWORK_MAP_FEED);
+
+            DataFeed<List<NodeInfo>, NetworkMapCache.MapChange> networkMapFeed = cordaRPCOps.networkMapFeed();
+            processSnapshot(exchange, networkMapFeed.getSnapshot());
+            subscription = networkMapFeed.getUpdates().subscribe(
+                x -> proceedNetworkMapFeed(x),
+                t -> processError(t, CordaConstants.NETWORK_MAP_FEED),
+                () -> processDone(CordaConstants.NETWORK_MAP_FEED)
+            );
+            break;
+
+        case STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_FEED:
+            LOG.debug("subscribing for operation: " + STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_FEED);
+
+            DataFeed<List<StateMachineTransactionMapping>, StateMachineTransactionMapping> transactionFeed = cordaRPCOps.stateMachineRecordedTransactionMappingFeed();
+            processSnapshot(exchange, transactionFeed.getSnapshot());
+            subscription = transactionFeed.getUpdates().subscribe(
+                x -> processTransactionMappingFeed(x),
+                t -> processError(t, CordaConstants.STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_FEED),
+                () -> processDone(CordaConstants.STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_FEED)
+            );
+            break;
+
+        case START_TRACKED_FLOW_DYNAMIC:
+            LOG.debug("subscribing for operation: " + START_TRACKED_FLOW_DYNAMIC);
+
+            FlowProgressHandle<Object> objectFlowProgressHandle = cordaRPCOps.startTrackedFlowDynamic(configuration.getFlowLociClass(), configuration.getArguments());
+            Object result = objectFlowProgressHandle.getReturnValue().get();
+            Observable<String> progress = objectFlowProgressHandle.getProgress();
+            processSnapshot(exchange, result);
+            subscription = progress.subscribe(
+                x -> processFlowProcess(x),
+                t -> processError(t, CordaConstants.START_TRACKED_FLOW_DYNAMIC),
+                () -> processDone(CordaConstants.START_TRACKED_FLOW_DYNAMIC)
+            );
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unsupported operation " + configuration.getOperation());
+        }
+
+        LOG.info("Subscribed: {}", this.configuration);
+    }
+
+    private void processSnapshot(Exchange exchange, Object page) {
+        if (configuration.isProcessSnapshot()) {
+            try {
+                exchange.getIn().setBody(page);
+                getProcessor().process(exchange);
+            } catch (Exception e) {
+                LOG.error("Error processing snapshot", e);
+            }
+        }
+    }
+
+    private void processFlowProcess(String x) {
+        LOG.debug("processFlowProcess {}", x);
+        Exchange exchange = this.getEndpoint().createExchange();
+        exchange.getIn().setBody(x);
+        processEvent(exchange);
+    }
+
+    private void processTransactionMappingFeed(StateMachineTransactionMapping x) {
+        LOG.debug("processTransactionMappingFeed {}", x);
+        Exchange exchange = this.getEndpoint().createExchange();
+        exchange.getIn().setBody(x);
+        processEvent(exchange);
+    }
+
+    private void proceedNetworkMapFeed(NetworkMapCache.MapChange x) {
+        LOG.debug("proceedNetworkMapFeed {}", x);
+        Exchange exchange = this.getEndpoint().createExchange();
+        exchange.getIn().setBody(x);
+        processEvent(exchange);
+    }
+
+    private void processStateMachineUpdate(StateMachineUpdate x) {
+        LOG.debug("processStateMachineUpdate {}", x);
+        Exchange exchange = this.getEndpoint().createExchange();
+        exchange.getIn().setBody(x);
+        processEvent(exchange);
+    }
+
+    private void processContractStateUpdate(Vault.Update<ContractState> x) {
+        LOG.debug("processContractStateUpdate {}", x);
+        Exchange exchange = this.getEndpoint().createExchange();
+        exchange.getIn().setBody(x);
+        processEvent(exchange);
+    }
+
+    private void processError(Throwable throwable, String operation) {
+        LOG.debug("processError for operation: " + operation + " " + throwable);
+        Exchange exchange = this.getEndpoint().createExchange();
+        exchange.setException(throwable);
+        processEvent(exchange);
+    }
+
+    public void processEvent(Exchange exchange) {
+        LOG.debug("processEvent {}", exchange);
+        try {
+            getProcessor().process(exchange);
+        } catch (Exception e) {
+            LOG.error("Error processing event ", e);
+        }
+    }
+
+    private void processDone(String operation) {
+        LOG.debug("processDone for operation: {}", operation);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        if (subscription != null) {
+            subscription.unsubscribe();
+        }
+        super.doStop();
+    }
+}
diff --git a/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaEndpoint.java b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaEndpoint.java
new file mode 100644
index 0000000..4ba221a
--- /dev/null
+++ b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaEndpoint.java
@@ -0,0 +1,101 @@
+/**
+ * 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.corda;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import net.corda.client.rpc.CordaRPCClient;
+import net.corda.client.rpc.CordaRPCConnection;
+import net.corda.core.messaging.CordaRPCOps;
+import net.corda.core.utilities.NetworkHostAndPort;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriPath;
+
+/**
+ * The corda component uses the corda-rpc to interact with corda nodes.
+ */
+@UriEndpoint(firstVersion = "2.23.0", scheme = "corda", title = "corda", syntax = "corda:url", consumerClass = CordaConsumer.class, label = "corda,blockchain")
+public class CordaEndpoint extends DefaultEndpoint {
+
+    @UriPath(description = "URL to the corda node")
+    @Metadata(required = "true")
+    private CordaConfiguration configuration;
+    private CordaRPCConnection rpcConnection;
+    private CordaRPCOps proxy;
+
+    public CordaEndpoint(String uri, String remaining, CordaComponent component, CordaConfiguration configuration) {
+        super(uri, component);
+        this.configuration = configuration;
+
+        try {
+            URI nodeURI = new URI(uri);
+            configuration.setHost(nodeURI.getHost());
+            configuration.setPort(nodeURI.getPort());
+
+            if (nodeURI.getUserInfo() != null) {
+                String[] creds = nodeURI.getUserInfo().split(":");
+                if (configuration.getUsername() == null) {
+                    configuration.setUsername(creds[0]);
+                }
+                if (configuration.getPassword() == null) {
+                    configuration.setPassword(creds.length > 1 ? creds[1] : "");
+                }
+            }
+        } catch (URISyntaxException e) {
+            throw new IllegalArgumentException("Invalid URI: " + remaining, e);
+        }
+    }
+
+    @Override
+    public Producer createProducer() throws Exception {
+        return new CordaProducer(this, configuration, proxy);
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) throws Exception {
+        CordaConsumer consumer = new CordaConsumer(this, processor, configuration, proxy);
+        configureConsumer(consumer);
+        return consumer;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        NetworkHostAndPort rpcAddress = new NetworkHostAndPort(configuration.getHost(), configuration.getPort());
+        CordaRPCClient rpcClient = new CordaRPCClient(rpcAddress);
+        rpcConnection = rpcClient.start(this.configuration.getUsername(), this.configuration.getPassword());
+        proxy = rpcConnection.getProxy();
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        if (rpcConnection != null) {
+            rpcConnection.notifyServerAndClose();
+        }
+        super.doStop();
+    }
+
+    public boolean isSingleton() {
+        return true;
+    }
+
+}
diff --git a/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaProducer.java b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaProducer.java
new file mode 100644
index 0000000..ea9fe7b
--- /dev/null
+++ b/components/camel-corda/src/main/java/org/apache/camel/component/corda/CordaProducer.java
@@ -0,0 +1,240 @@
+/**
+ * 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.corda;
+
+import java.io.InputStream;
+import java.security.PublicKey;
+import net.corda.core.contracts.ContractState;
+import net.corda.core.crypto.SecureHash;
+import net.corda.core.flows.FlowLogic;
+import net.corda.core.identity.AbstractParty;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.core.messaging.CordaRPCOps;
+import net.corda.core.node.services.vault.AttachmentQueryCriteria;
+import net.corda.core.node.services.vault.AttachmentSort;
+import net.corda.core.node.services.vault.PageSpecification;
+import net.corda.core.node.services.vault.QueryCriteria;
+import net.corda.core.node.services.vault.Sort;
+import org.apache.camel.InvokeOnHeader;
+import org.apache.camel.Message;
+import org.apache.camel.impl.HeaderSelectorProducer;
+
+import static org.apache.camel.component.corda.CordaConstants.ARGUMENTS;
+import static org.apache.camel.component.corda.CordaConstants.ATTACHMENT_QUERY_CRITERIA;
+import static org.apache.camel.component.corda.CordaConstants.DRAINING_MODE;
+import static org.apache.camel.component.corda.CordaConstants.EXACT_MATCH;
+import static org.apache.camel.component.corda.CordaConstants.PAGE_SPECIFICATION;
+import static org.apache.camel.component.corda.CordaConstants.QUERY_CRITERIA;
+import static org.apache.camel.component.corda.CordaConstants.SECURE_HASH;
+import static org.apache.camel.component.corda.CordaConstants.SORT;
+
+/**
+ * The corda producer.
+ */
+
+public class CordaProducer extends HeaderSelectorProducer {
+    private CordaConfiguration configuration;
+    private CordaRPCOps cordaRPCOps;
+
+    public CordaProducer(CordaEndpoint endpoint, final CordaConfiguration configuration, CordaRPCOps cordaRPCOps) {
+        super(endpoint, CordaConstants.OPERATION, () -> configuration.getOperation(), false);
+        this.configuration = configuration;
+        this.cordaRPCOps = cordaRPCOps;
+    }
+
+    @Override
+    public CordaEndpoint getEndpoint() {
+        return (CordaEndpoint) super.getEndpoint();
+    }
+
+    @InvokeOnHeader(CordaConstants.CURRENT_NODE_TIME)
+    void currentNodeTime(Message message) throws Exception {
+        message.setBody(cordaRPCOps.currentNodeTime());
+    }
+
+    @InvokeOnHeader(CordaConstants.GET_PROTOCOL_VERSION)
+    void getProtocolVersion(Message message) throws Exception {
+        message.setBody(cordaRPCOps.getProtocolVersion());
+    }
+
+    @InvokeOnHeader(CordaConstants.NETWORK_MAP_SNAPSHOT)
+    void networkMapSnapshot(Message message) throws Exception {
+        message.setBody(cordaRPCOps.networkMapSnapshot());
+    }
+
+    @InvokeOnHeader(CordaConstants.STATE_MACHINE_SNAPSHOT)
+    void stateMachinesSnapshot(Message message) throws Exception {
+        message.setBody(cordaRPCOps.stateMachinesSnapshot());
+    }
+
+    @InvokeOnHeader(CordaConstants.STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_SNAPSHOT)
+    void stateMachineRecordedTransactionMappingSnapshot(Message message) throws Exception {
+        message.setBody(cordaRPCOps.stateMachineRecordedTransactionMappingSnapshot());
+    }
+
+    @InvokeOnHeader(CordaConstants.REGISTERED_FLOWS)
+    void registeredFlows(Message message) throws Exception {
+        message.setBody(cordaRPCOps.registeredFlows());
+    }
+
+    @InvokeOnHeader(CordaConstants.CLEAR_NETWORK_MAP_CACHE)
+    void clearNetworkMapCache(Message message) throws Exception {
+        cordaRPCOps.clearNetworkMapCache();
+    }
+
+    @InvokeOnHeader(CordaConstants.IS_FLOWS_DRAINING_MODE_ENABLED)
+    void isFlowsDrainingModeEnabled(Message message) throws Exception {
+        message.setBody(cordaRPCOps.isFlowsDrainingModeEnabled());
+    }
+
+    @InvokeOnHeader(CordaConstants.SET_FLOWS_DRAINING_MODE_ENABLED)
+    void setFlowsDrainingModeEnabled(Message message) throws Exception {
+        Boolean mode = message.getHeader(DRAINING_MODE, Boolean.class);
+        cordaRPCOps.setFlowsDrainingModeEnabled(mode);
+    }
+
+    @InvokeOnHeader(CordaConstants.NOTARY_IDENTITIES)
+    void notaryIdentities(Message message) throws Exception {
+        message.setBody(cordaRPCOps.notaryIdentities());
+    }
+
+    @InvokeOnHeader(CordaConstants.NODE_INFO)
+    void nodeInfo(Message message) throws Exception {
+        message.setBody(cordaRPCOps.nodeInfo());
+    }
+
+    @InvokeOnHeader(CordaConstants.ADD_VAULT_TRANSACTION_NOTE)
+    void addVaultTransactionNote(Message message) throws Exception {
+        SecureHash secureHash = message.getHeader(SECURE_HASH, SecureHash.class);
+        String note = message.getBody(String.class);
+        cordaRPCOps.addVaultTransactionNote(secureHash, note);
+    }
+
+    @InvokeOnHeader(CordaConstants.GET_VAULT_TRANSACTION_NOTES)
+    void getVaultTransactionNotes(Message message) throws Exception {
+        SecureHash secureHash = message.getHeader(SECURE_HASH, SecureHash.class);
+        message.setBody(cordaRPCOps.getVaultTransactionNotes(secureHash));
+    }
+
+    @InvokeOnHeader(CordaConstants.UPLOAD_ATTACHMENT)
+    void uploadAttachment(Message message) throws Exception {
+        InputStream inputStream = message.getBody(InputStream.class);
+        SecureHash secureHash = cordaRPCOps.uploadAttachment(inputStream);
+        message.setHeader(SECURE_HASH, secureHash);
+    }
+
+    @InvokeOnHeader(CordaConstants.ATTACHMENT_EXISTS)
+    void attachmentExists(Message message) throws Exception {
+        SecureHash secureHash = message.getHeader(SECURE_HASH, SecureHash.class);
+        message.setBody(cordaRPCOps.attachmentExists(secureHash));
+    }
+
+    @InvokeOnHeader(CordaConstants.OPEN_ATTACHMENT)
+    void openAttachment(Message message) throws Exception {
+        SecureHash secureHash = message.getHeader(SECURE_HASH, SecureHash.class);
+        message.setBody(cordaRPCOps.openAttachment(secureHash));
+    }
+
+    @InvokeOnHeader(CordaConstants.QUERY_ATTACHMENTS)
+    void queryAttachments(Message message) throws Exception {
+        AttachmentQueryCriteria queryCriteria = message.getHeader(ATTACHMENT_QUERY_CRITERIA, AttachmentQueryCriteria.class);
+        AttachmentSort attachmentSort = message.getHeader(SORT, AttachmentSort.class);
+        message.setBody(cordaRPCOps.queryAttachments(queryCriteria, attachmentSort));
+    }
+
+    @InvokeOnHeader(CordaConstants.NODE_INFO_FROM_PARTY)
+    void nodeInfoFromParty(Message message) throws Exception {
+        AbstractParty party = message.getBody(AbstractParty.class);
+        message.setBody(cordaRPCOps.nodeInfoFromParty(party));
+    }
+
+    @InvokeOnHeader(CordaConstants.NOTARY_PARTY_FROM_X500_NAME)
+    void notaryPartyFromX500Name(Message message) throws Exception {
+        CordaX500Name x500Name = message.getBody(CordaX500Name.class);
+        message.setBody(cordaRPCOps.notaryPartyFromX500Name(x500Name));
+    }
+
+    @InvokeOnHeader(CordaConstants.PARTIES_FROM_NAME)
+    void partiesFromName(Message message) throws Exception {
+        String query = message.getBody(String.class);
+        Boolean exactMatch = message.getHeader(EXACT_MATCH, Boolean.class);
+        message.setBody(cordaRPCOps.partiesFromName(query, exactMatch));
+    }
+
+    @InvokeOnHeader(CordaConstants.PARTIES_FROM_KEY)
+    void partyFromKey(Message message) throws Exception {
+        PublicKey key = message.getBody(PublicKey.class);
+        message.setBody(cordaRPCOps.partyFromKey(key));
+    }
+
+    @InvokeOnHeader(CordaConstants.WELL_KNOWN_PARTY_FROM_X500_NAME)
+    void wellKnownPartyFromX500Name(Message message) throws Exception {
+        CordaX500Name x500Name = message.getBody(CordaX500Name.class);
+        message.setBody(cordaRPCOps.wellKnownPartyFromX500Name(x500Name));
+    }
+
+    @InvokeOnHeader(CordaConstants.WELL_KNOWN_PARTY_FROM_ANONYMOUS)
+    void wellKnownPartyFromAnonymous(Message message) throws Exception {
+        AbstractParty party = message.getBody(AbstractParty.class);
+        message.setBody(cordaRPCOps.wellKnownPartyFromAnonymous(party));
+    }
+
+    @InvokeOnHeader(CordaConstants.START_FLOW_DYNAMIC)
+    void startFlowDynamic(Message message) throws Exception {
+        Object [] args = message.getHeader(ARGUMENTS, Object [].class);
+        Class<FlowLogic<?>> aClass = message.getBody(Class.class);
+        message.setBody(cordaRPCOps.startFlowDynamic(aClass, args).getReturnValue().get());
+    }
+
+    @InvokeOnHeader(CordaConstants.VAULT_QUERY)
+    void vaultQuery(Message message) throws Exception {
+        Class<ContractState> contractStateClass = (Class<ContractState>) message.getBody(Class.class);
+        message.setBody(cordaRPCOps.vaultQuery(contractStateClass));
+    }
+
+    @InvokeOnHeader(CordaConstants.VAULT_QUERY_BY)
+    void vaultQueryBy(Message message) throws Exception {
+        Class<ContractState> contractStateClass = (Class<ContractState>) message.getBody(Class.class);
+        QueryCriteria criteria = message.getHeader(QUERY_CRITERIA, QueryCriteria.class);
+        PageSpecification pageSpec = message.getHeader(PAGE_SPECIFICATION, PageSpecification.class);
+        Sort sorting = message.getHeader(SORT, Sort.class);
+        message.setBody(cordaRPCOps.vaultQueryBy(criteria, pageSpec, sorting, contractStateClass));
+    }
+
+    @InvokeOnHeader(CordaConstants.VAULT_QUERY_BY_CRITERIA)
+    void vaultQueryByCriteria(Message message) throws Exception {
+        Class<ContractState> contractStateClass = (Class<ContractState>) message.getBody(Class.class);
+        QueryCriteria criteria = message.getHeader(QUERY_CRITERIA, QueryCriteria.class);
+        message.setBody(cordaRPCOps.vaultQueryByCriteria(criteria, contractStateClass));
+    }
+
+    @InvokeOnHeader(CordaConstants.VAULT_QUERY_BY_WITH_PAGING_SPEC)
+    void vaultQueryByWithPagingSpec(Message message) throws Exception {
+        Class<ContractState> contractStateClass = (Class<ContractState>) message.getBody(Class.class);
+        QueryCriteria criteria = message.getHeader(QUERY_CRITERIA, QueryCriteria.class);
+        PageSpecification pageSpec = message.getHeader(PAGE_SPECIFICATION, PageSpecification.class);
+        message.setBody(cordaRPCOps.vaultQueryByWithPagingSpec(contractStateClass, criteria, pageSpec));
+    }
+
+    @InvokeOnHeader(CordaConstants.VAULT_QUERY_BY_WITH_SORTING)
+    void vaultQueryByWithSorting(Message message) throws Exception {
+        Class<ContractState> contractStateClass = (Class<ContractState>) message.getBody(Class.class);
+        QueryCriteria criteria = message.getHeader(QUERY_CRITERIA, QueryCriteria.class);
+        Sort sorting = message.getHeader(SORT, Sort.class);
+        message.setBody(cordaRPCOps.vaultQueryByWithSorting(contractStateClass, criteria, sorting));
+    }
+}
diff --git a/components/camel-corda/src/main/resources/META-INF/LICENSE.txt b/components/camel-corda/src/main/resources/META-INF/LICENSE.txt
new file mode 100755
index 0000000..6b0b127
--- /dev/null
+++ b/components/camel-corda/src/main/resources/META-INF/LICENSE.txt
@@ -0,0 +1,203 @@
+
+                                Apache License
+                          Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+  1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+  2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+  3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+  4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+  5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+  6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+  7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+  8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+  9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+  END OF TERMS AND CONDITIONS
+
+  APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+  Copyright [yyyy] [name of copyright owner]
+
+  Licensed 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.
+
diff --git a/components/camel-corda/src/main/resources/META-INF/NOTICE.txt b/components/camel-corda/src/main/resources/META-INF/NOTICE.txt
new file mode 100755
index 0000000..2e215bf
--- /dev/null
+++ b/components/camel-corda/src/main/resources/META-INF/NOTICE.txt
@@ -0,0 +1,11 @@
+  =========================================================================
+  ==  NOTICE file corresponding to the section 4 d of                    ==
+  ==  the Apache License, Version 2.0,                                  ==
+  ==  in this case for the Apache Camel distribution.                    ==
+  =========================================================================
+
+  This product includes software developed by
+  The Apache Software Foundation (http://www.apache.org/).
+
+  Please read the different LICENSE files present in the licenses directory of
+  this distribution.
diff --git a/components/camel-corda/src/main/resources/META-INF/services/org/apache/camel/component/corda b/components/camel-corda/src/main/resources/META-INF/services/org/apache/camel/component/corda
new file mode 100755
index 0000000..b7423d9
--- /dev/null
+++ b/components/camel-corda/src/main/resources/META-INF/services/org/apache/camel/component/corda
@@ -0,0 +1,18 @@
+#
+# 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.corda.CordaComponent
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CamelFlow.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CamelFlow.java
new file mode 100644
index 0000000..fc3a001
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CamelFlow.java
@@ -0,0 +1,32 @@
+/**
+ * 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.corda;
+
+import net.corda.core.flows.FlowLogic;
+
+public class CamelFlow extends FlowLogic<String> {
+    private String in;
+
+    public CamelFlow(String in) {
+        this.in = in;
+    }
+
+    @Override
+    public String call() {
+        return in + " world!";
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerNetworkMapFeedTest.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerNetworkMapFeedTest.java
new file mode 100644
index 0000000..a08c90a
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerNetworkMapFeedTest.java
@@ -0,0 +1,49 @@
+/**
+ * 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.corda;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.camel.component.corda.CordaConstants.NETWORK_MAP_FEED;
+import static org.apache.camel.component.corda.CordaConstants.OPERATION;
+import static org.apache.camel.component.corda.CordaConstants.STATE_MACHINE_FEED;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaConsumerNetworkMapFeedTest extends CordaConsumerTestSupport {
+
+    @Test
+    public void networkMapFeedTest() throws Exception {
+        mockResult.expectedMinimumMessageCount(1);
+        mockError.expectedMessageCount(0);
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                errorHandler(deadLetterChannel("mock:error"));
+
+                from(getUrl() + "&" + OPERATION.toLowerCase() + "=" + NETWORK_MAP_FEED)
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerStartTrackedFlowDynamicTest.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerStartTrackedFlowDynamicTest.java
new file mode 100644
index 0000000..96a0182
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerStartTrackedFlowDynamicTest.java
@@ -0,0 +1,54 @@
+/**
+ * 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.corda;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.camel.component.corda.CordaConstants.OPERATION;
+import static org.apache.camel.component.corda.CordaConstants.START_TRACKED_FLOW_DYNAMIC;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaConsumerStartTrackedFlowDynamicTest extends CordaConsumerTestSupport {
+
+
+    @Test
+    public void startTrackedFlowDynamicTest() throws Exception {
+        //Expects CamelFlow is deployed on the node
+        mockResult.expectedMinimumMessageCount(1);
+        mockError.expectedMessageCount(0);
+        MockEndpoint.assertIsSatisfied(context);
+        assertEquals("Hello world!", mockResult.getExchanges().get(0).getIn().getBody());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                errorHandler(deadLetterChannel("mock:error"));
+
+                from(getUrl() + "&" + OPERATION.toLowerCase() + "=" + START_TRACKED_FLOW_DYNAMIC
+                    + "&flowLociClass=#flowLociClass"
+                    + "&arguments=#arguments")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerStateMachineFeedTest.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerStateMachineFeedTest.java
new file mode 100644
index 0000000..eefc988
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerStateMachineFeedTest.java
@@ -0,0 +1,49 @@
+/**
+ * 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.corda;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.camel.component.corda.CordaConstants.OPERATION;
+import static org.apache.camel.component.corda.CordaConstants.STATE_MACHINE_FEED;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaConsumerStateMachineFeedTest extends CordaConsumerTestSupport {
+
+    @Test
+    public void stateMachineFeedTest() throws Exception {
+        mockResult.expectedMinimumMessageCount(1);
+        mockError.expectedMessageCount(0);
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                errorHandler(deadLetterChannel("mock:error"));
+
+                from(getUrl() + "&" + OPERATION.toLowerCase() + "=" + STATE_MACHINE_FEED)
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerTestSupport.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerTestSupport.java
new file mode 100644
index 0000000..c27dd12
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerTestSupport.java
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.corda;
+
+import com.google.common.collect.ImmutableSet;
+import net.corda.core.contracts.OwnableState;
+import net.corda.core.flows.FlowLogic;
+import net.corda.core.node.services.Vault;
+import net.corda.core.node.services.vault.PageSpecification;
+import net.corda.core.node.services.vault.QueryCriteria;
+import net.corda.core.node.services.vault.Sort;
+import net.corda.core.node.services.vault.SortAttribute;
+import org.apache.camel.impl.JndiRegistry;
+import org.junit.Ignore;
+
+import static net.corda.core.node.services.vault.QueryCriteriaUtils.DEFAULT_PAGE_NUM;
+import static net.corda.core.node.services.vault.QueryCriteriaUtils.MAX_PAGE_SIZE;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaConsumerTestSupport extends CordaTestSupport {
+
+    @Override
+    public boolean isUseAdviceWith() {
+        return false;
+    }
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry registry = super.createRegistry();
+
+        String [] args = new String[] {"Hello"};
+        Class<FlowLogic<String>> flowLociClass = (Class<FlowLogic<String>>) Class.forName("org.apache.camel.component.corda.CamelFlow");
+
+        QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria(Vault.StateStatus.CONSUMED);
+        PageSpecification pageSpec = new PageSpecification(DEFAULT_PAGE_NUM, MAX_PAGE_SIZE);
+        Sort.SortColumn sortByUid = new Sort.SortColumn(new SortAttribute.Standard(Sort.LinearStateAttribute.UUID), Sort.Direction.DESC);
+        Sort sort = new Sort(ImmutableSet.of(sortByUid));
+
+        registry.bind("contractStateClass", OwnableState.class);
+        registry.bind("queryCriteria", criteria);
+        registry.bind("pageSpecification", pageSpec);
+        registry.bind("sort", sort);
+        registry.bind("flowLociClass", flowLociClass);
+        registry.bind("arguments", args);
+        return registry;
+    }
+
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerTransactionMapFeedTest.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerTransactionMapFeedTest.java
new file mode 100644
index 0000000..2e6c300
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerTransactionMapFeedTest.java
@@ -0,0 +1,49 @@
+/**
+ * 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.corda;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.camel.component.corda.CordaConstants.NETWORK_MAP_FEED;
+import static org.apache.camel.component.corda.CordaConstants.OPERATION;
+import static org.apache.camel.component.corda.CordaConstants.STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_FEED;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaConsumerTransactionMapFeedTest extends CordaConsumerTestSupport {
+
+    @Test
+    public void transactionMapFeedTest() throws Exception {
+        mockResult.expectedMinimumMessageCount(1);
+        mockError.expectedMessageCount(0);
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                errorHandler(deadLetterChannel("mock:error"));
+
+                from(getUrl() + "&" + OPERATION.toLowerCase() + "=" + STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_FEED)
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByCriteriaTest.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByCriteriaTest.java
new file mode 100644
index 0000000..d7048f0
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByCriteriaTest.java
@@ -0,0 +1,51 @@
+/**
+ * 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.corda;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.camel.component.corda.CordaConstants.OPERATION;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY_CRITERIA;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaConsumerVaultTrackByCriteriaTest extends CordaConsumerTestSupport {
+
+    @Test
+    public void vaultTrackByCriteriaTest() throws Exception {
+        mockResult.expectedMinimumMessageCount(1);
+        mockError.expectedMessageCount(0);
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                errorHandler(deadLetterChannel("mock:error"));
+
+                from(getUrl() + "&" + OPERATION.toLowerCase() + "=" + VAULT_TRACK_BY_CRITERIA
+                        + "&contractStateClass=#contractStateClass"
+                        + "&queryCriteria=#queryCriteria")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByTest.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByTest.java
new file mode 100644
index 0000000..cbef3be
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByTest.java
@@ -0,0 +1,53 @@
+/**
+ * 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.corda;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.camel.component.corda.CordaConstants.OPERATION;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaConsumerVaultTrackByTest extends CordaConsumerTestSupport {
+
+    @Test
+    public void vaultTrackByTest() throws Exception {
+        mockResult.expectedMinimumMessageCount(1);
+        mockError.expectedMessageCount(0);
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                errorHandler(deadLetterChannel("mock:error"));
+
+                from(getUrl() + "&" + OPERATION.toLowerCase() + "=" + VAULT_TRACK_BY
+                        + "&contractStateClass=#contractStateClass"
+                        + "&queryCriteria=#queryCriteria"
+                        + "&pageSpecification=#pageSpecification"
+                        + "&sort=#sort")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByWithPagingSpecTest.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByWithPagingSpecTest.java
new file mode 100644
index 0000000..b2fefac
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByWithPagingSpecTest.java
@@ -0,0 +1,52 @@
+/**
+ * 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.corda;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.camel.component.corda.CordaConstants.OPERATION;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY_WITH_PAGING_SPEC;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaConsumerVaultTrackByWithPagingSpecTest extends CordaConsumerTestSupport {
+
+    @Test
+    public void vaultTrackByWithPagingSpecTest() throws Exception {
+        mockResult.expectedMinimumMessageCount(1);
+        mockError.expectedMessageCount(0);
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                errorHandler(deadLetterChannel("mock:error"));
+
+                from(getUrl() + "&" + OPERATION.toLowerCase() + "=" + VAULT_TRACK_BY_WITH_PAGING_SPEC
+                        + "&contractStateClass=#contractStateClass"
+                        + "&queryCriteria=#queryCriteria"
+                        + "&pageSpecification=#pageSpecification")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByWithSortingTest.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByWithSortingTest.java
new file mode 100644
index 0000000..4835ee0
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackByWithSortingTest.java
@@ -0,0 +1,52 @@
+/**
+ * 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.corda;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.camel.component.corda.CordaConstants.OPERATION;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK_BY_WITH_SORTING;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaConsumerVaultTrackByWithSortingTest extends CordaConsumerTestSupport {
+
+    @Test
+    public void vaultTrackByWithSortingTest() throws Exception {
+        mockResult.expectedMinimumMessageCount(1);
+        mockError.expectedMessageCount(0);
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                errorHandler(deadLetterChannel("mock:error"));
+
+                from(getUrl() + "&" + OPERATION.toLowerCase() + "=" + VAULT_TRACK_BY_WITH_SORTING
+                        + "&contractStateClass=#contractStateClass"
+                        + "&queryCriteria=#queryCriteria"
+                        + "&sort=#sort")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackTest.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackTest.java
new file mode 100644
index 0000000..b5ffa43
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaConsumerVaultTrackTest.java
@@ -0,0 +1,49 @@
+/**
+ * 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.corda;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.camel.component.corda.CordaConstants.OPERATION;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_TRACK;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaConsumerVaultTrackTest extends CordaConsumerTestSupport {
+
+    @Test
+    public void vaultTrackTest() throws Exception {
+        mockResult.expectedMinimumMessageCount(1);
+        mockError.expectedMessageCount(0);
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                errorHandler(deadLetterChannel("mock:error"));
+
+                from(getUrl() + "&" + OPERATION.toLowerCase() + "=" + VAULT_TRACK
+                        + "&contractStateClass=#contractStateClass")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaProducerTest.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaProducerTest.java
new file mode 100644
index 0000000..c76a663
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaProducerTest.java
@@ -0,0 +1,498 @@
+/**
+ * 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.corda;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import com.google.common.collect.ImmutableSet;
+import net.corda.core.contracts.OwnableState;
+import net.corda.core.crypto.SecureHash;
+import net.corda.core.flows.FlowLogic;
+import net.corda.core.identity.AbstractParty;
+import net.corda.core.identity.AnonymousParty;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.core.identity.Party;
+import net.corda.core.node.services.Vault;
+import net.corda.core.node.services.vault.AttachmentQueryCriteria;
+import net.corda.core.node.services.vault.AttachmentSort;
+import net.corda.core.node.services.vault.ColumnPredicate;
+import net.corda.core.node.services.vault.EqualityComparisonOperator;
+import net.corda.core.node.services.vault.PageSpecification;
+import net.corda.core.node.services.vault.QueryCriteria;
+import net.corda.core.node.services.vault.Sort;
+import net.corda.core.node.services.vault.SortAttribute;
+import org.apache.camel.Exchange;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static net.corda.core.node.services.vault.QueryCriteriaUtils.DEFAULT_PAGE_NUM;
+import static net.corda.core.node.services.vault.QueryCriteriaUtils.MAX_PAGE_SIZE;
+import static org.apache.camel.component.corda.CordaConstants.ADD_VAULT_TRANSACTION_NOTE;
+import static org.apache.camel.component.corda.CordaConstants.ARGUMENTS;
+import static org.apache.camel.component.corda.CordaConstants.ATTACHMENT_EXISTS;
+import static org.apache.camel.component.corda.CordaConstants.ATTACHMENT_QUERY_CRITERIA;
+import static org.apache.camel.component.corda.CordaConstants.CLEAR_NETWORK_MAP_CACHE;
+import static org.apache.camel.component.corda.CordaConstants.CURRENT_NODE_TIME;
+import static org.apache.camel.component.corda.CordaConstants.DRAINING_MODE;
+import static org.apache.camel.component.corda.CordaConstants.EXACT_MATCH;
+import static org.apache.camel.component.corda.CordaConstants.GET_PROTOCOL_VERSION;
+import static org.apache.camel.component.corda.CordaConstants.GET_VAULT_TRANSACTION_NOTES;
+import static org.apache.camel.component.corda.CordaConstants.IS_FLOWS_DRAINING_MODE_ENABLED;
+import static org.apache.camel.component.corda.CordaConstants.NETWORK_MAP_SNAPSHOT;
+import static org.apache.camel.component.corda.CordaConstants.NODE_INFO;
+import static org.apache.camel.component.corda.CordaConstants.NODE_INFO_FROM_PARTY;
+import static org.apache.camel.component.corda.CordaConstants.NOTARY_IDENTITIES;
+import static org.apache.camel.component.corda.CordaConstants.NOTARY_PARTY_FROM_X500_NAME;
+import static org.apache.camel.component.corda.CordaConstants.OPEN_ATTACHMENT;
+import static org.apache.camel.component.corda.CordaConstants.OPERATION;
+import static org.apache.camel.component.corda.CordaConstants.PAGE_SPECIFICATION;
+import static org.apache.camel.component.corda.CordaConstants.PARTIES_FROM_KEY;
+import static org.apache.camel.component.corda.CordaConstants.PARTIES_FROM_NAME;
+import static org.apache.camel.component.corda.CordaConstants.QUERY_ATTACHMENTS;
+import static org.apache.camel.component.corda.CordaConstants.QUERY_CRITERIA;
+import static org.apache.camel.component.corda.CordaConstants.REGISTERED_FLOWS;
+import static org.apache.camel.component.corda.CordaConstants.SECURE_HASH;
+import static org.apache.camel.component.corda.CordaConstants.SET_FLOWS_DRAINING_MODE_ENABLED;
+import static org.apache.camel.component.corda.CordaConstants.SORT;
+import static org.apache.camel.component.corda.CordaConstants.START_FLOW_DYNAMIC;
+import static org.apache.camel.component.corda.CordaConstants.STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_SNAPSHOT;
+import static org.apache.camel.component.corda.CordaConstants.STATE_MACHINE_SNAPSHOT;
+import static org.apache.camel.component.corda.CordaConstants.UPLOAD_ATTACHMENT;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_QUERY;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_QUERY_BY;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_QUERY_BY_CRITERIA;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_QUERY_BY_WITH_PAGING_SPEC;
+import static org.apache.camel.component.corda.CordaConstants.VAULT_QUERY_BY_WITH_SORTING;
+import static org.apache.camel.component.corda.CordaConstants.WELL_KNOWN_PARTY_FROM_ANONYMOUS;
+import static org.apache.camel.component.corda.CordaConstants.WELL_KNOWN_PARTY_FROM_X500_NAME;
+
+@Ignore("This integration test requires a locally running corda node such cordapp-template-java")
+public class CordaProducerTest extends CordaTestSupport {
+    private static final SecureHash.SHA256 TEST_SHA_256 = SecureHash.parse("6D1687C143DF792A011A1E80670A4E4E0C25D0D87A39514409B1ABFC2043581F");
+
+    @Produce(uri = "direct:start")
+    protected ProducerTemplate template;
+
+    @Override
+    public boolean isUseAdviceWith() {
+        return false;
+    }
+
+    @Test
+    public void currentNodeTimeTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, CURRENT_NODE_TIME);
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void getProtocolVersionTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, GET_PROTOCOL_VERSION);
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void networkMapSnapshotTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, NETWORK_MAP_SNAPSHOT);
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void stateMachinesSnapshotTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, STATE_MACHINE_SNAPSHOT);
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void stateMachineRecordedTransactionMappingSnapshotTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, STATE_MACHINE_RECORDED_TRANSACTION_MAPPING_SNAPSHOT);
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void registeredFlowsTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, REGISTERED_FLOWS);
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void clearNetworkMapCacheTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, CLEAR_NETWORK_MAP_CACHE);
+        template.send(exchange);
+        Object body = exchange.getException();
+        assertNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void isFlowsDrainingModeEnabledTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, IS_FLOWS_DRAINING_MODE_ENABLED);
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void setFlowsDrainingModeEnabledTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, SET_FLOWS_DRAINING_MODE_ENABLED);
+        exchange.getIn().setHeader(DRAINING_MODE, false);
+        template.send(exchange);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void notaryIdentitiesTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, NOTARY_IDENTITIES);
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void nodeInfoTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, NODE_INFO);
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void addVaultTransactionNoteTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader("Some note", OPERATION, ADD_VAULT_TRANSACTION_NOTE);
+
+        exchange.getIn().setHeader(SECURE_HASH, TEST_SHA_256);
+        template.send(exchange);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void getVaultTransactionNotesTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, GET_VAULT_TRANSACTION_NOTES);
+
+        exchange.getIn().setHeader(SECURE_HASH, TEST_SHA_256);
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void uploadAttachmentTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, UPLOAD_ATTACHMENT);
+        exchange.getIn().setBody(zipIt("HELLO" + System.nanoTime(), "test1.txt"));
+        template.send(exchange);
+
+        Object body = exchange.getIn().getHeader(SECURE_HASH);
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void attachmentExistsTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, ATTACHMENT_EXISTS);
+        exchange.getIn().setHeader(SECURE_HASH, TEST_SHA_256);
+
+        template.send(exchange);
+
+        Boolean body = exchange.getIn().getBody(Boolean.class);
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void openAttachmentTest() throws Exception {
+        //Setup node with attachment
+        Exchange uploadExchange = createExchangeWithBodyAndHeader(null, OPERATION, UPLOAD_ATTACHMENT);
+        uploadExchange.getIn().setBody(zipIt("HELLO" + System.nanoTime(), "test2.txt"));
+        template.send(uploadExchange);
+
+        Object hash = uploadExchange.getIn().getHeader(SECURE_HASH);
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, OPEN_ATTACHMENT);
+        exchange.getIn().setHeader(SECURE_HASH, hash);
+
+        template.send(exchange);
+
+        InputStream body = exchange.getIn().getBody(InputStream.class);
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void queryAttachmentsTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, QUERY_ATTACHMENTS);
+        AttachmentQueryCriteria.AttachmentsQueryCriteria queryCriteria =
+                new AttachmentQueryCriteria.AttachmentsQueryCriteria(
+                        new ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, "Daredevil"));
+        AttachmentSort attachmentSort = null;
+
+        exchange.getIn().setHeader(ATTACHMENT_QUERY_CRITERIA, queryCriteria);
+        exchange.getIn().setHeader(SORT, attachmentSort);
+
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void nodeInfoFromPartyTest() throws Exception {
+        //Expects IntegrationWhiteList is deployed on the node
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, NODE_INFO_FROM_PARTY);
+        PublicKey pub = generatePublicKey();
+        CordaX500Name cordaX500Name1 = new CordaX500Name("PartyA", "London", "GB");
+        Party party = new Party(cordaX500Name1, pub);
+        exchange.getIn().setBody(party);
+
+        template.send(exchange);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void notaryPartyFromX500NameTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, NOTARY_PARTY_FROM_X500_NAME);
+        CordaX500Name cordaX500Name = new CordaX500Name("Notary", "London", "GB");
+        exchange.getIn().setBody(cordaX500Name);
+
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void partiesFromNameTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader("A", OPERATION, PARTIES_FROM_NAME);
+        exchange.getIn().setHeader(EXACT_MATCH, false);
+
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void partyFromKeyTest() throws Exception {
+        //Expects IntegrationWhiteList is deployed on the node
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, PARTIES_FROM_KEY);
+        PublicKey pub = generatePublicKey();
+        exchange.getIn().setBody(pub);
+
+        template.send(exchange);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void wellKnownPartyFromX500NameTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, WELL_KNOWN_PARTY_FROM_X500_NAME);
+        CordaX500Name cordaX500Name1 = new CordaX500Name("PartyA", "London", "GB");
+        exchange.getIn().setBody(cordaX500Name1);
+
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void wellKnownPartyFromAnonymousTest() throws Exception {
+        //Expects IntegrationWhiteList is deployed on the node
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, WELL_KNOWN_PARTY_FROM_ANONYMOUS);
+        PublicKey pub = generatePublicKey();
+
+        AbstractParty party = new AnonymousParty(pub);
+        exchange.getIn().setBody(party);
+
+        template.send(exchange);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void startFlowDynamicTest() throws Exception {
+        //Expects CamelFlow is deployed on the node
+        Exchange exchange = createExchangeWithBodyAndHeader(null, OPERATION, START_FLOW_DYNAMIC);
+        String [] args = new String[] {"Hello"};
+        Class<FlowLogic<String>> aClass = (Class<FlowLogic<String>>) Class.forName("org.apache.camel.component.corda.CamelFlow");
+        exchange.getIn().setBody(aClass);
+        exchange.getIn().setHeader(ARGUMENTS, args);
+
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        assertEquals("Hello world!", body.toString());
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void vaultQueryTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(OwnableState.class, OPERATION, VAULT_QUERY);
+
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void vaultQueryByTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(OwnableState.class, OPERATION, VAULT_QUERY_BY);
+        QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria(Vault.StateStatus.CONSUMED);
+        PageSpecification pageSpec = new PageSpecification(DEFAULT_PAGE_NUM, MAX_PAGE_SIZE);
+        Sort.SortColumn sortByUid = new Sort.SortColumn(new SortAttribute.Standard(Sort.LinearStateAttribute.UUID), Sort.Direction.DESC);
+        Sort sorting = new Sort(ImmutableSet.of(sortByUid));
+        exchange.getIn().setHeader(QUERY_CRITERIA, criteria);
+        exchange.getIn().setHeader(PAGE_SPECIFICATION, pageSpec);
+        exchange.getIn().setHeader(SORT, sorting);
+
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void vaultQueryByCriteriaTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(OwnableState.class, OPERATION, VAULT_QUERY_BY_CRITERIA);
+        QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria(Vault.StateStatus.CONSUMED);
+        exchange.getIn().setHeader(QUERY_CRITERIA, criteria);
+
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void vaultQueryByWithPagingSpecTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(OwnableState.class, OPERATION, VAULT_QUERY_BY_WITH_PAGING_SPEC);
+        QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria(Vault.StateStatus.CONSUMED);
+        PageSpecification pageSpec = new PageSpecification(DEFAULT_PAGE_NUM, MAX_PAGE_SIZE);
+        exchange.getIn().setHeader(QUERY_CRITERIA, criteria);
+        exchange.getIn().setHeader(PAGE_SPECIFICATION, pageSpec);
+
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    @Test
+    public void vaultQueryByWithSortingTest() throws Exception {
+        Exchange exchange = createExchangeWithBodyAndHeader(OwnableState.class, OPERATION, VAULT_QUERY_BY_WITH_SORTING);
+        QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria(Vault.StateStatus.CONSUMED);
+        Sort.SortColumn sortByUid = new Sort.SortColumn(new SortAttribute.Standard(Sort.LinearStateAttribute.UUID), Sort.Direction.DESC);
+        Sort sorting = new Sort(ImmutableSet.of(sortByUid));
+        exchange.getIn().setHeader(QUERY_CRITERIA, criteria);
+        exchange.getIn().setHeader(SORT, sorting);
+
+        template.send(exchange);
+        Object body = exchange.getIn().getBody();
+        assertNotNull(body);
+        Object exception = exchange.getException();
+        assertNull(exception);
+    }
+
+    private ByteArrayInputStream zipIt(String in, String name) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            ZipOutputStream zos = new ZipOutputStream(baos);
+            ZipEntry entry = new ZipEntry(name);
+            zos.putNextEntry(entry);
+            zos.write(in.getBytes());
+            zos.closeEntry();
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        }
+
+        return new ByteArrayInputStream(baos.toByteArray());
+    }
+
+    private PublicKey generatePublicKey() throws NoSuchAlgorithmException {
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+        kpg.initialize(2048);
+        KeyPair kp = kpg.generateKeyPair();
+        return kp.getPublic();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:start")
+                        .to(getUrl());
+            }
+        };
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaTestSupport.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaTestSupport.java
new file mode 100755
index 0000000..7586e3f
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/CordaTestSupport.java
@@ -0,0 +1,74 @@
+/**
+ * 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.corda;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultExchange;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.mockito.MockitoAnnotations;
+
+public class CordaTestSupport extends CamelTestSupport {
+
+    @EndpointInject(uri = "mock:result")
+    protected MockEndpoint mockResult;
+
+    @EndpointInject(uri = "mock:error")
+    protected MockEndpoint mockError;
+
+    @Override
+    public boolean isUseAdviceWith() {
+        return true;
+    }
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry registry = super.createRegistry();
+        return registry;
+    }
+
+    protected String getUrl() {
+        return "corda://localhost:10006?username=user1&password=test";
+    }
+
+    protected Exchange createExchangeWithBodyAndHeader(Object body, String key, Object value) {
+        DefaultExchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(body);
+        exchange.getIn().setHeader(key, value);
+        return exchange;
+    }
+
+    @BeforeClass
+    public static void startServer() throws Exception {
+    }
+
+    @AfterClass
+    public static void stopServer() throws Exception {
+    }
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        super.setUp();
+    }
+}
diff --git a/components/camel-corda/src/test/java/org/apache/camel/component/corda/IntegrationWhiteList.java b/components/camel-corda/src/test/java/org/apache/camel/component/corda/IntegrationWhiteList.java
new file mode 100644
index 0000000..cdee285
--- /dev/null
+++ b/components/camel-corda/src/test/java/org/apache/camel/component/corda/IntegrationWhiteList.java
@@ -0,0 +1,35 @@
+/**
+ * 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.corda;
+
+import java.util.ArrayList;
+import java.util.List;
+import net.corda.core.serialization.SerializationWhitelist;
+
+public class IntegrationWhiteList implements SerializationWhitelist {
+
+    @Override
+    public List<Class<?>> getWhitelist() {
+        List list = new ArrayList();
+//        list.add(RSAPublicKeyImpl.class);
+//        list.add(AlgorithmId.class);
+//        list.add(ObjectIdentifier.class);
+//        list.add(BitArray.class);
+//        list.add(BigInteger.class);
+        return list;
+    }
+}
diff --git a/components/camel-corda/src/test/resources/META-INF/services/net.corda.core.serialization.SerializationWhitelist b/components/camel-corda/src/test/resources/META-INF/services/net.corda.core.serialization.SerializationWhitelist
new file mode 100644
index 0000000..8c42a02
--- /dev/null
+++ b/components/camel-corda/src/test/resources/META-INF/services/net.corda.core.serialization.SerializationWhitelist
@@ -0,0 +1 @@
+org.apache.camel.component.corda.IntegrationWhiteList
diff --git a/components/camel-corda/src/test/resources/log4j2.properties b/components/camel-corda/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..952c0fb
--- /dev/null
+++ b/components/camel-corda/src/test/resources/log4j2.properties
@@ -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.
+## ---------------------------------------------------------------------------
+rootLogger.level = DEBUG
+rootLogger.appenderRef.file.ref = file
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-corda-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+#rootLogger.org.fabric=DEBUG
+#rootLogger.org.apache.http=DEBUG
+
+
diff --git a/components/camel-corda/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/components/camel-corda/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 0000000..ca6ee9c
--- /dev/null
+++ b/components/camel-corda/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1 @@
+mock-maker-inline
\ No newline at end of file
diff --git a/components/pom.xml b/components/pom.xml
index e77582a..fc8e6c9 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -108,6 +108,7 @@
    <module>camel-cometd</module>
    <module>camel-consul</module>
    <module>camel-context</module>
+    <module>camel-corda</module>
    <module>camel-couchbase</module>
    <module>camel-couchdb</module>
    <module>camel-crypto</module>
diff --git a/components/readme.adoc b/components/readme.adoc
index e6460b5..17c953b 100644
--- a/components/readme.adoc
+++ b/components/readme.adoc
@@ -2,7 +2,7 @@ Components
^^^^^^^^^^

// components: START
-Number of Components: 306 in 207 JAR artifacts (22 deprecated)
+Number of Components: 307 in 208 JAR artifacts (22 deprecated)

[width="100%",cols="4,1,5",options="header"]
|===
@@ -179,6 +179,9 @@ Number of Components: 306 in 207 JAR artifacts (22 deprecated)
| link:../camel-core/src/main/docs/controlbus-component.adoc[Control Bus] (camel-core) +
`controlbus:command:language` | 2.11 | The controlbus component provides easy management of Camel applications based on the Control Bus EIP pattern.

+| link:camel-corda/src/main/docs/corda-component.adoc[corda] (camel-corda) +
+`corda:url` | 2.23 | The corda component uses the corda-rpc to interact with corda nodes.
+
| link:camel-couchbase/src/main/docs/couchbase-component.adoc[Couchbase] (camel-couchbase) +
`couchbase:protocol:hostname:port` | 2.19 | Represents a Couchbase endpoint that can query Views with a Poll strategy and/or produce various type of operations.

diff --git a/docs/user-manual/en/SUMMARY.md b/docs/user-manual/en/SUMMARY.md
index 7a0c3ef..fb911d2 100644
--- a/docs/user-manual/en/SUMMARY.md
+++ b/docs/user-manual/en/SUMMARY.md
@@ -220,6 +220,7 @@
    * [CoAP](coap-component.adoc)
    * [CometD](cometd-component.adoc)
    * [Consul](consul-component.adoc)
+    * [Corda](corda-component.adoc)
    * [Couchbase](couchbase-component.adoc)
    * [CouchDB](couchdb-component.adoc)
    * [Crypto (JCE)](crypto-component.adoc)
diff --git a/parent/pom.xml b/parent/pom.xml
index 9dcf516..1a39043 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -165,6 +165,7 @@
    <consul-client-version>1.2.5</consul-client-version>
    <consul-client-bundle-version>1.2.5_1</consul-client-bundle-version>
    <cobertura-maven-plugin-version>2.7</cobertura-maven-plugin-version>
+    <corda-version>3.3-corda</corda-version>
    <couchbase-client-version>1.4.13</couchbase-client-version>
    <couchbase-client-bundle-version>1.4.13_1</couchbase-client-bundle-version>
    <curator-version>2.12.0</curator-version>
@@ -1030,6 +1031,25 @@
        <version>${project.version}</version>
      </dependency>
      <dependency>
+        <groupId>net.corda</groupId>
+        <artifactId>corda-rpc</artifactId>
+        <version>${corda-version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>co.paralleluniverse</groupId>
+            <artifactId>quasar-core</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-core</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.hibernate.javax.persistence</groupId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core-xml</artifactId>
        <version>${project.version}</version>
@@ -2596,6 +2616,11 @@
      </dependency>
      <dependency>
        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-corda-starter</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core-starter</artifactId>
        <version>${project.version}</version>
      </dependency>
diff --git a/platforms/karaf/features/src/main/resources/features.xml b/platforms/karaf/features/src/main/resources/features.xml
index cd6fe58..43d3c4a 100644
--- a/platforms/karaf/features/src/main/resources/features.xml
+++ b/platforms/karaf/features/src/main/resources/features.xml
@@ -426,6 +426,11 @@
    <feature version='${project.version}'>camel-core</feature>
    <bundle>mvn:org.apache.camel/camel-context/${project.version}</bundle>
  </feature>
+  <feature name='camel-corda' version='${project.version}' resolver='(obr)' start-level='50'>
+    <feature version='${project.version}'>camel-core</feature>
+    <bundle dependency='true'>wrap:net.corda/corda-rpc/${corda-version}</bundle>
+    <bundle>mvn:org.apache.camel/camel-corda/${project.version}</bundle>
+  </feature>
  <feature name='camel-couchdb' version='${project.version}' resolver='(obr)' start-level='50'>
    <feature version='${project.version}'>camel-core</feature>
    <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.lightcouch/${lightcouch-bundle-version}</bundle>
diff --git a/platforms/spring-boot/components-starter/camel-corda-starter/pom.xml b/platforms/spring-boot/components-starter/camel-corda-starter/pom.xml
new file mode 100644
index 0000000..e1636b2
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-corda-starter/pom.xml
@@ -0,0 +1,65 @@
+<?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-starter</artifactId>
+    <version>2.23.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>camel-corda-starter</artifactId>
+  <packaging>jar</packaging>
+  <name>Spring-Boot Starter :: Camel :: Corda</name>
+  <description>Spring-Boot Starter for Camel Corda which is based on corda-rpc support</description>
+  <dependencies>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter</artifactId>
+      <version>${spring-boot-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-corda</artifactId>
+      <version>${project.version}</version>
+      <!--START OF GENERATED CODE-->
+      <exclusions>
+        <exclusion>
+          <groupId>commons-logging</groupId>
+          <artifactId>commons-logging</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.apache.logging.log4j</groupId>
+          <artifactId>log4j-core</artifactId>
+        </exclusion>
+      </exclusions>
+      <!--END OF GENERATED CODE-->
+    </dependency>
+    <!--START OF GENERATED CODE-->
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-core-starter</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-spring-boot-starter</artifactId>
+    </dependency>
+    <!--END OF GENERATED CODE-->
+  </dependencies>
+</project>
diff --git a/platforms/spring-boot/components-starter/camel-corda-starter/src/main/java/org/apache/camel/component/corda/springboot/CordaComponentAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/java/org/apache/camel/component/corda/springboot/CordaComponentAutoConfiguration.java
new file mode 100644
index 0000000..a3ed689
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/java/org/apache/camel/component/corda/springboot/CordaComponentAutoConfiguration.java
@@ -0,0 +1,128 @@
+/**
+ * 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.corda.springboot;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Generated;
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.corda.CordaComponent;
+import org.apache.camel.spi.ComponentCustomizer;
+import org.apache.camel.spi.HasId;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.spring.boot.ComponentConfigurationProperties;
+import org.apache.camel.spring.boot.util.CamelPropertiesHelper;
+import org.apache.camel.spring.boot.util.ConditionalOnCamelContextAndAutoConfigurationBeans;
+import org.apache.camel.spring.boot.util.GroupCondition;
+import org.apache.camel.spring.boot.util.HierarchicalPropertiesEvaluator;
+import org.apache.camel.util.IntrospectionSupport;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+
+/**
+ * Generated by camel-package-maven-plugin - do not edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.SpringBootAutoConfigurationMojo")
+@Configuration
+@Conditional({ConditionalOnCamelContextAndAutoConfigurationBeans.class,
+        CordaComponentAutoConfiguration.GroupConditions.class})
+@AutoConfigureAfter(CamelAutoConfiguration.class)
+@EnableConfigurationProperties({ComponentConfigurationProperties.class,
+        CordaComponentConfiguration.class})
+public class CordaComponentAutoConfiguration {
+
+    private static final Logger LOGGER = LoggerFactory
+            .getLogger(CordaComponentAutoConfiguration.class);
+    @Autowired
+    private ApplicationContext applicationContext;
+    @Autowired
+    private CamelContext camelContext;
+    @Autowired
+    private CordaComponentConfiguration configuration;
+    @Autowired(required = false)
+    private List<ComponentCustomizer<CordaComponent>> customizers;
+
+    static class GroupConditions extends GroupCondition {
+        public GroupConditions() {
+            super("camel.component", "camel.component.corda");
+        }
+    }
+
+    @Lazy
+    @Bean(name = "corda-component")
+    @ConditionalOnMissingBean(CordaComponent.class)
+    public CordaComponent configureCordaComponent() throws Exception {
+        CordaComponent component = new CordaComponent();
+        component.setCamelContext(camelContext);
+        Map<String, Object> parameters = new HashMap<>();
+        IntrospectionSupport.getProperties(configuration, parameters, null,
+                false);
+        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
+            Object value = entry.getValue();
+            Class<?> paramClass = value.getClass();
+            if (paramClass.getName().endsWith("NestedConfiguration")) {
+                Class nestedClass = null;
+                try {
+                    nestedClass = (Class) paramClass.getDeclaredField(
+                            "CAMEL_NESTED_CLASS").get(null);
+                    HashMap<String, Object> nestedParameters = new HashMap<>();
+                    IntrospectionSupport.getProperties(value, nestedParameters,
+                            null, false);
+                    Object nestedProperty = nestedClass.newInstance();
+                    CamelPropertiesHelper.setCamelProperties(camelContext,
+                            nestedProperty, nestedParameters, false);
+                    entry.setValue(nestedProperty);
+                } catch (NoSuchFieldException e) {
+                }
+            }
+        }
+        CamelPropertiesHelper.setCamelProperties(camelContext, component,
+                parameters, false);
+        if (ObjectHelper.isNotEmpty(customizers)) {
+            for (ComponentCustomizer<CordaComponent> customizer : customizers) {
+                boolean useCustomizer = (customizer instanceof HasId)
+                        ? HierarchicalPropertiesEvaluator.evaluate(
+                                applicationContext.getEnvironment(),
+                                "camel.component.customizer",
+                                "camel.component.corda.customizer",
+                                ((HasId) customizer).getId())
+                        : HierarchicalPropertiesEvaluator.evaluate(
+                                applicationContext.getEnvironment(),
+                                "camel.component.customizer",
+                                "camel.component.corda.customizer");
+                if (useCustomizer) {
+                    LOGGER.debug("Configure component {}, with customizer {}",
+                            component, customizer);
+                    customizer.customize(component);
+                }
+            }
+        }
+        return component;
+    }
+}
\ No newline at end of file
diff --git a/platforms/spring-boot/components-starter/camel-corda-starter/src/main/java/org/apache/camel/component/corda/springboot/CordaComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/java/org/apache/camel/component/corda/springboot/CordaComponentConfiguration.java
new file mode 100644
index 0000000..75e0b4d
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/java/org/apache/camel/component/corda/springboot/CordaComponentConfiguration.java
@@ -0,0 +1,182 @@
+/**
+ * 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.corda.springboot;
+
+import javax.annotation.Generated;
+import net.corda.core.node.services.vault.PageSpecification;
+import net.corda.core.node.services.vault.QueryCriteria;
+import net.corda.core.node.services.vault.Sort;
+import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * The corda component uses the corda-rpc to interact with corda nodes.
+ * 
+ * Generated by camel-package-maven-plugin - do not edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.SpringBootAutoConfigurationMojo")
+@ConfigurationProperties(prefix = "camel.component.corda")
+public class CordaComponentConfiguration
+        extends
+            ComponentConfigurationPropertiesCommon {
+
+    /**
+    * Whether to enable auto configuration of the corda component. This is
+    * enabled by default.
+    */
+    private Boolean enabled;
+    /**
+    * Default configuration
+    */
+    private CordaConfigurationNestedConfiguration configuration;
+    /**
+    * Whether the component should resolve property placeholders on itself when
+    * starting. Only properties which are of String type can use property
+    * placeholders.
+    */
+    private Boolean resolvePropertyPlaceholders = true;
+
+    public CordaConfigurationNestedConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(
+            CordaConfigurationNestedConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    public Boolean getResolvePropertyPlaceholders() {
+        return resolvePropertyPlaceholders;
+    }
+
+    public void setResolvePropertyPlaceholders(
+            Boolean resolvePropertyPlaceholders) {
+        this.resolvePropertyPlaceholders = resolvePropertyPlaceholders;
+    }
+
+    public static class CordaConfigurationNestedConfiguration {
+        public static final Class CAMEL_NESTED_CLASS = org.apache.camel.component.corda.CordaConfiguration.class;
+        private String operation;
+        private String username;
+        private String password;
+        private String host;
+        private Integer port;
+        private Boolean processSnapshot;
+        private Class flowLociClass;
+        private Object[] arguments;
+        private Class contractStateClass;
+        private QueryCriteria queryCriteria;
+        private PageSpecification pageSpecification;
+        private Sort sort;
+
+        public String getOperation() {
+            return operation;
+        }
+
+        public void setOperation(String operation) {
+            this.operation = operation;
+        }
+
+        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 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 Boolean getProcessSnapshot() {
+            return processSnapshot;
+        }
+
+        public void setProcessSnapshot(Boolean processSnapshot) {
+            this.processSnapshot = processSnapshot;
+        }
+
+        public Class getFlowLociClass() {
+            return flowLociClass;
+        }
+
+        public void setFlowLociClass(Class flowLociClass) {
+            this.flowLociClass = flowLociClass;
+        }
+
+        public Object[] getArguments() {
+            return arguments;
+        }
+
+        public void setArguments(Object[] arguments) {
+            this.arguments = arguments;
+        }
+
+        public Class getContractStateClass() {
+            return contractStateClass;
+        }
+
+        public void setContractStateClass(Class contractStateClass) {
+            this.contractStateClass = contractStateClass;
+        }
+
+        public QueryCriteria getQueryCriteria() {
+            return queryCriteria;
+        }
+
+        public void setQueryCriteria(QueryCriteria queryCriteria) {
+            this.queryCriteria = queryCriteria;
+        }
+
+        public PageSpecification getPageSpecification() {
+            return pageSpecification;
+        }
+
+        public void setPageSpecification(PageSpecification pageSpecification) {
+            this.pageSpecification = pageSpecification;
+        }
+
+        public Sort getSort() {
+            return sort;
+        }
+
+        public void setSort(Sort sort) {
+            this.sort = sort;
+        }
+    }
+}
\ No newline at end of file
diff --git a/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/LICENSE.txt b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/LICENSE.txt
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/LICENSE.txt
@@ -0,0 +1,203 @@
+
+                                Apache License
+                          Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+  1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+  2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+  3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+  4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+  5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+  6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+  7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+  8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+  9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+  END OF TERMS AND CONDITIONS
+
+  APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+  Copyright [yyyy] [name of copyright owner]
+
+  Licensed 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.
+
diff --git a/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/NOTICE.txt b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/NOTICE.txt
new file mode 100644
index 0000000..2e215bf
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/NOTICE.txt
@@ -0,0 +1,11 @@
+  =========================================================================
+  ==  NOTICE file corresponding to the section 4 d of                    ==
+  ==  the Apache License, Version 2.0,                                  ==
+  ==  in this case for the Apache Camel distribution.                    ==
+  =========================================================================
+
+  This product includes software developed by
+  The Apache Software Foundation (http://www.apache.org/).
+
+  Please read the different LICENSE files present in the licenses directory of
+  this distribution.
diff --git a/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
new file mode 100644
index 0000000..fbaf6a3
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -0,0 +1,10 @@
+{
+  "properties": [
+    {
+      "defaultValue": true,
+      "name": "camel.component.corda.enabled",
+      "description": "Enable corda component",
+      "type": "java.lang.Boolean"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/spring.factories b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..a79cfd8
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,19 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.apache.camel.component.corda.springboot.CordaComponentAutoConfiguration
diff --git a/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/spring.provides b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/spring.provides
new file mode 100644
index 0000000..30c7acd
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-corda-starter/src/main/resources/META-INF/spring.provides
@@ -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.
+## ---------------------------------------------------------------------------
+provides: camel-corda
diff --git a/platforms/spring-boot/components-starter/pom.xml b/platforms/spring-boot/components-starter/pom.xml
index 8e8db9a..79f84bf 100644
--- a/platforms/spring-boot/components-starter/pom.xml
+++ b/platforms/spring-boot/components-starter/pom.xml
@@ -139,6 +139,7 @@
    <module>camel-cometd-starter</module>
    <module>camel-consul-starter</module>
    <module>camel-context-starter</module>
+    <module>camel-corda-starter</module>
    <module>camel-core-starter</module>
    <module>camel-couchbase-starter</module>
    <module>camel-couchdb-starter</module>
diff --git a/platforms/spring-boot/spring-boot-dm/camel-spring-boot-dependencies/pom.xml b/platforms/spring-boot/spring-boot-dm/camel-spring-boot-dependencies/pom.xml
index 4af8855..9e7e339 100644
--- a/platforms/spring-boot/spring-boot-dm/camel-spring-boot-dependencies/pom.xml
+++ b/platforms/spring-boot/spring-boot-dm/camel-spring-boot-dependencies/pom.xml
@@ -187,6 +187,25 @@
        <version>1.2.17</version>
      </dependency>
      <dependency>
+        <groupId>net.corda</groupId>
+        <artifactId>corda-rpc</artifactId>
+        <version>3.3-corda</version>
+        <exclusions>
+          <exclusion>
+            <groupId>co.paralleluniverse</groupId>
+            <artifactId>quasar-core</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-core</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.hibernate.javax.persistence</groupId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
        <groupId>net.sf.saxon</groupId>
        <artifactId>Saxon-HE</artifactId>
        <version>9.8.0-14</version>
@@ -699,6 +718,11 @@
      </dependency>
      <dependency>
        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-corda-starter</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core</artifactId>
        <version>${project.version}</version>
      </dependency>