CAMEL-11332: Create a new camel-thrift data format

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

Branch: refs/heads/master
Commit: 362a8943f9a12ab4cf5b99dfebf4ac51a777f58f
Parents: 64e7388
Author: Dmitry Volodin <dmvo...@gmail.com>
Authored: Mon May 29 11:42:37 2017 +0300
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Fri Jun 2 12:58:50 2017 +0200

----------------------------------------------------------------------
 .../apache/camel/builder/DataFormatClause.java  |  29 +
 .../apache/camel/model/MarshalDefinition.java   |   2 +
 .../apache/camel/model/UnmarshalDefinition.java |   2 +
 .../model/dataformat/DataFormatsDefinition.java |   1 +
 .../model/dataformat/ThriftDataFormat.java      | 107 +++
 .../DataFormatTransformerDefinition.java        |   2 +
 .../apache/camel/model/dataformat/jaxb.index    |   1 +
 .../src/main/docs/protobuf-dataformat.adoc      |  22 +-
 .../ProtobufMarshalAndUnmarshalSpringTest.java  |  60 +-
 .../dataformat/protobuf/springDataFormat.xml    |  21 +-
 components/camel-thrift/ReadMe.md               |  30 +
 components/camel-thrift/pom.xml                 |  92 +++
 .../src/main/docs/thrift-dataformat.adoc        | 156 ++++
 .../dataformat/thrift/ThriftDataFormat.java     | 204 +++++
 .../src/main/resources/META-INF/LICENSE.txt     | 203 +++++
 .../src/main/resources/META-INF/NOTICE.txt      |  14 +
 .../services/org/apache/camel/dataformat/thrift |  18 +
 .../src/test/java/META-INF/MANIFEST.MF          |   3 +
 .../ThriftMarshalAndUnmarshalJsonTest.java      | 106 +++
 .../ThriftMarshalAndUnmarshalSpringTest.java    |  95 +++
 .../thrift/ThriftMarshalAndUnmarshalTest.java   | 108 +++
 .../dataformat/thrift/generated/Operation.java  |  55 ++
 .../camel/dataformat/thrift/generated/Work.java | 735 +++++++++++++++++++
 .../src/test/resources/log4j2.properties        |  28 +
 .../dataformat/thrift/springDataFormat.xml      |  57 ++
 .../camel-thrift/src/test/thrift/readme.txt     |   5 +
 .../src/test/thrift/tutorial-dataformat.thrift  |  84 +++
 components/pom.xml                              |   1 +
 .../src/main/resources/config.properties        |   0
 .../features/src/main/resources/features.xml    |   6 +
 .../camel-thrift-starter/pom.xml                |  61 ++
 .../ThriftDataFormatAutoConfiguration.java      | 129 ++++
 .../ThriftDataFormatConfiguration.java          |  76 ++
 .../src/main/resources/META-INF/LICENSE.txt     | 203 +++++
 .../src/main/resources/META-INF/NOTICE.txt      |  11 +
 .../main/resources/META-INF/spring.factories    |  19 +
 .../src/main/resources/META-INF/spring.provides |  17 +
 .../spring-boot/components-starter/pom.xml      |   1 +
 38 files changed, 2734 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java 
b/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java
index 0b18e91..ec719b8 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java
@@ -52,6 +52,7 @@ import org.apache.camel.model.dataformat.SoapJaxbDataFormat;
 import org.apache.camel.model.dataformat.StringDataFormat;
 import org.apache.camel.model.dataformat.SyslogDataFormat;
 import org.apache.camel.model.dataformat.TarFileDataFormat;
+import org.apache.camel.model.dataformat.ThriftDataFormat;
 import org.apache.camel.model.dataformat.TidyMarkupDataFormat;
 import org.apache.camel.model.dataformat.XMLBeansDataFormat;
 import org.apache.camel.model.dataformat.XMLSecurityDataFormat;
@@ -830,6 +831,34 @@ public class DataFormatClause<T extends 
ProcessorDefinition<?>> {
     public T syslog() {
         return dataFormat(new SyslogDataFormat());
     }
+    
+    /**
+     * Uses the Thrift data format
+     */
+    public T thrift() {
+        return dataFormat(new ThriftDataFormat());
+    }
+
+    public T thrift(Object defaultInstance) {
+        ThriftDataFormat dataFormat = new ThriftDataFormat();
+        dataFormat.setDefaultInstance(defaultInstance);
+        return dataFormat(dataFormat);
+    }
+    
+    public T thrift(Object defaultInstance, String contentTypeFormat) {
+        ThriftDataFormat dataFormat = new ThriftDataFormat();
+        dataFormat.setDefaultInstance(defaultInstance);
+        dataFormat.setContentTypeFormat(contentTypeFormat);
+        return dataFormat(dataFormat);
+    }
+
+    public T thrift(String instanceClassName) {
+        return dataFormat(new ThriftDataFormat(instanceClassName));
+    }
+    
+    public T thrift(String instanceClassName, String contentTypeFormat) {
+        return dataFormat(new ThriftDataFormat(instanceClassName, 
contentTypeFormat));
+    }
 
     /**
      * Return WellFormed HTML (an XML Document) either

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/camel-core/src/main/java/org/apache/camel/model/MarshalDefinition.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/model/MarshalDefinition.java 
b/camel-core/src/main/java/org/apache/camel/model/MarshalDefinition.java
index e149b7e..a2bddfc 100644
--- a/camel-core/src/main/java/org/apache/camel/model/MarshalDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/MarshalDefinition.java
@@ -49,6 +49,7 @@ import org.apache.camel.model.dataformat.SoapJaxbDataFormat;
 import org.apache.camel.model.dataformat.StringDataFormat;
 import org.apache.camel.model.dataformat.SyslogDataFormat;
 import org.apache.camel.model.dataformat.TarFileDataFormat;
+import org.apache.camel.model.dataformat.ThriftDataFormat;
 import org.apache.camel.model.dataformat.TidyMarkupDataFormat;
 import org.apache.camel.model.dataformat.UniVocityCsvDataFormat;
 import org.apache.camel.model.dataformat.UniVocityFixedWidthDataFormat;
@@ -105,6 +106,7 @@ public class MarshalDefinition extends 
NoOutputDefinition<MarshalDefinition> {
         @XmlElement(required = false, name = "string", type = 
StringDataFormat.class),
         @XmlElement(required = false, name = "syslog", type = 
SyslogDataFormat.class),
         @XmlElement(required = false, name = "tarfile", type = 
TarFileDataFormat.class),
+        @XmlElement(required = false, name = "thrift", type = 
ThriftDataFormat.class),
         @XmlElement(required = false, name = "tidyMarkup", type = 
TidyMarkupDataFormat.class),
         @XmlElement(required = false, name = "univocity-csv", type = 
UniVocityCsvDataFormat.class),
         @XmlElement(required = false, name = "univocity-fixed", type = 
UniVocityFixedWidthDataFormat.class),

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/camel-core/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/model/UnmarshalDefinition.java 
b/camel-core/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
index 34756f1..cd97c61 100644
--- a/camel-core/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/UnmarshalDefinition.java
@@ -49,6 +49,7 @@ import org.apache.camel.model.dataformat.SoapJaxbDataFormat;
 import org.apache.camel.model.dataformat.StringDataFormat;
 import org.apache.camel.model.dataformat.SyslogDataFormat;
 import org.apache.camel.model.dataformat.TarFileDataFormat;
+import org.apache.camel.model.dataformat.ThriftDataFormat;
 import org.apache.camel.model.dataformat.TidyMarkupDataFormat;
 import org.apache.camel.model.dataformat.UniVocityCsvDataFormat;
 import org.apache.camel.model.dataformat.UniVocityFixedWidthDataFormat;
@@ -105,6 +106,7 @@ public class UnmarshalDefinition extends 
NoOutputDefinition<UnmarshalDefinition>
         @XmlElement(required = false, name = "string", type = 
StringDataFormat.class),
         @XmlElement(required = false, name = "syslog", type = 
SyslogDataFormat.class),
         @XmlElement(required = false, name = "tarfile", type = 
TarFileDataFormat.class),
+        @XmlElement(required = false, name = "thrift", type = 
ThriftDataFormat.class),
         @XmlElement(required = false, name = "tidyMarkup", type = 
TidyMarkupDataFormat.class),
         @XmlElement(required = false, name = "univocity-csv", type = 
UniVocityCsvDataFormat.class),
         @XmlElement(required = false, name = "univocity-fixed", type = 
UniVocityFixedWidthDataFormat.class),

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/camel-core/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java
 
b/camel-core/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java
index 901130e..43133b0 100644
--- 
a/camel-core/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java
+++ 
b/camel-core/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java
@@ -68,6 +68,7 @@ public class DataFormatsDefinition {
         @XmlElement(required = false, name = "string", type = 
StringDataFormat.class),
         @XmlElement(required = false, name = "syslog", type = 
SyslogDataFormat.class),
         @XmlElement(required = false, name = "tarfile", type = 
TarFileDataFormat.class),
+        @XmlElement(required = false, name = "thrift", type = 
ThriftDataFormat.class),
         @XmlElement(required = false, name = "tidyMarkup", type = 
TidyMarkupDataFormat.class),
         @XmlElement(required = false, name = "univocity-csv", type = 
UniVocityCsvDataFormat.class),
         @XmlElement(required = false, name = "univocity-fixed", type = 
UniVocityFixedWidthDataFormat.class),

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/camel-core/src/main/java/org/apache/camel/model/dataformat/ThriftDataFormat.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/model/dataformat/ThriftDataFormat.java
 
b/camel-core/src/main/java/org/apache/camel/model/dataformat/ThriftDataFormat.java
new file mode 100644
index 0000000..242ca25
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/model/dataformat/ThriftDataFormat.java
@@ -0,0 +1,107 @@
+/**
+ * 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.model.dataformat;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.model.DataFormatDefinition;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.Metadata;
+
+/**
+ * Apache Thrift data format
+ *
+ * @version 
+ */
+@Metadata(firstVersion = "2.20.0", label = "dataformat,transformation", title 
= "Thrift")
+@XmlRootElement(name = "thrift")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ThriftDataFormat extends DataFormatDefinition {
+    @XmlAttribute
+    private String instanceClass;
+    @XmlAttribute @Metadata(enums = "binary,json,sjson", defaultValue = 
"binary")
+    private String contentTypeFormat;
+    @XmlTransient
+    private Object defaultInstance;
+    
+    public ThriftDataFormat() {
+        super("thrift");
+    }
+    
+    public ThriftDataFormat(String instanceClass) {
+        this();
+        setInstanceClass(instanceClass); 
+    }
+    
+    public ThriftDataFormat(String instanceClass, String contentTypeFormat) {
+        this();
+        setInstanceClass(instanceClass);
+        setContentTypeFormat(contentTypeFormat);
+    }
+
+    public String getInstanceClass() {
+        return instanceClass;
+    }
+
+    /**
+     * Name of class to use when unarmshalling
+     */
+    public void setInstanceClass(String instanceClass) {
+        this.instanceClass = instanceClass;
+    }
+    
+    /**
+     * Defines a content type format in which thrift message will be
+     * serialized/deserialized from(to) the Java been.
+     * The format can either be native or json for either native binary 
thrift, json or simple json fields representation.
+     * The default value is binary.
+     */
+    public void setContentTypeFormat(String contentTypeFormat) {
+        this.contentTypeFormat = contentTypeFormat;
+    }
+
+    public String getContentTypeFormat() {
+        return contentTypeFormat;
+    }
+
+    public Object getDefaultInstance() {
+        return defaultInstance;
+    }
+
+    public void setDefaultInstance(Object defaultInstance) {
+        this.defaultInstance = defaultInstance;
+    }
+
+    @Override
+    protected void configureDataFormat(DataFormat dataFormat, CamelContext 
camelContext) {
+        if (this.instanceClass != null) {
+            setProperty(camelContext, dataFormat, "instanceClass", 
instanceClass);
+        }
+        if (this.contentTypeFormat != null) {
+            setProperty(camelContext, dataFormat, "contentTypeFormat", 
contentTypeFormat);
+        }
+        if (this.defaultInstance != null) {
+            setProperty(camelContext, dataFormat, "defaultInstance", 
defaultInstance);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/camel-core/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java
 
b/camel-core/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java
index 97c3496..adda5df 100644
--- 
a/camel-core/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java
+++ 
b/camel-core/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java
@@ -54,6 +54,7 @@ import org.apache.camel.model.dataformat.SoapJaxbDataFormat;
 import org.apache.camel.model.dataformat.StringDataFormat;
 import org.apache.camel.model.dataformat.SyslogDataFormat;
 import org.apache.camel.model.dataformat.TarFileDataFormat;
+import org.apache.camel.model.dataformat.ThriftDataFormat;
 import org.apache.camel.model.dataformat.TidyMarkupDataFormat;
 import org.apache.camel.model.dataformat.UniVocityCsvDataFormat;
 import org.apache.camel.model.dataformat.UniVocityFixedWidthDataFormat;
@@ -113,6 +114,7 @@ public class DataFormatTransformerDefinition extends 
TransformerDefinition {
         @XmlElement(required = false, name = "string", type = 
StringDataFormat.class),
         @XmlElement(required = false, name = "syslog", type = 
SyslogDataFormat.class),
         @XmlElement(required = false, name = "tarfile", type = 
TarFileDataFormat.class),
+        @XmlElement(required = false, name = "thrift", type = 
ThriftDataFormat.class),
         @XmlElement(required = false, name = "tidyMarkup", type = 
TidyMarkupDataFormat.class),
         @XmlElement(required = false, name = "univocity-csv", type = 
UniVocityCsvDataFormat.class),
         @XmlElement(required = false, name = "univocity-fixed", type = 
UniVocityFixedWidthDataFormat.class),

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/camel-core/src/main/resources/org/apache/camel/model/dataformat/jaxb.index
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/resources/org/apache/camel/model/dataformat/jaxb.index 
b/camel-core/src/main/resources/org/apache/camel/model/dataformat/jaxb.index
index a8b348c..4fe9c7d 100644
--- a/camel-core/src/main/resources/org/apache/camel/model/dataformat/jaxb.index
+++ b/camel-core/src/main/resources/org/apache/camel/model/dataformat/jaxb.index
@@ -42,6 +42,7 @@ SoapJaxbDataFormat
 StringDataFormat
 SyslogDataFormat
 TarFileDataFormat
+ThriftDataFormat
 TidyMarkupDataFormat
 UniVocityCsvDataFormat
 UniVocityFixedWidthDataFormat

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-protobuf/src/main/docs/protobuf-dataformat.adoc
----------------------------------------------------------------------
diff --git a/components/camel-protobuf/src/main/docs/protobuf-dataformat.adoc 
b/components/camel-protobuf/src/main/docs/protobuf-dataformat.adoc
index 448cd01..091d742 100644
--- a/components/camel-protobuf/src/main/docs/protobuf-dataformat.adoc
+++ b/components/camel-protobuf/src/main/docs/protobuf-dataformat.adoc
@@ -7,19 +7,18 @@ Protobuf - Protocol Buffers
 
 "Protocol Buffers - Google's data interchange format"
 
-Camel provides a link:data-format.html[Data Format] to serialse between
+Camel provides a link:data-format.html[Data Format] to serialize between
 Java and the Protocol Buffer protocol. The project's site details why
 you may wish to
-https://developers.google.com/protocol-buffers/docs/overview[choose
-this format over xml]. Protocol Buffer is language-neutral and
+https://developers.google.com/protocol-buffers/docs/overview[choose this 
format over xml].
+Protocol Buffer is language-neutral and
 platform-neutral, so messages produced by your Camel routes may be
 consumed by other language implementations.
 
 https://developers.google.com/protocol-buffers/docs/reference/java/[API Site] +
 https://github.com/google/protobuf[Protobuf Implementation] +
 
-https://developers.google.com/protocol-buffers/docs/javatutorial[Protobuf
-Java Tutorial]
+https://developers.google.com/protocol-buffers/docs/javatutorial[Protobuf Java 
Tutorial]
 
 ### Protobuf Options
 
@@ -55,8 +54,7 @@ from("direct:marshal")
 ### Protobuf overview
 
 This quick overview of how to use Protobuf. For more detail see the
-http://code.google.com/apis/protocolbuffers/docs/javatutorial.html[complete
-tutorial]
+http://code.google.com/apis/protocolbuffers/docs/javatutorial.html[complete 
tutorial]
 
 ### Defining the proto format
 
@@ -145,7 +143,7 @@ You can also run the compiler for any additional supported 
languages you require
 This will generate a single Java class named AddressBookProtos which
 contains inner classes for Person and AddressBook. Builders are also
 implemented for you. The generated classes implement
-com.google.protobuf.Message which is required by the serialisation
+com.google.protobuf.Message which is required by the serialization
 mechanism. For this reason it important that only these classes are used
 in the body of your exchanges. Camel will throw an exception on route
 creation if you attempt to tell the link:data-format.html[Data Format]
@@ -156,7 +154,7 @@ domain classes.
 ### Java DSL
 
 You can use create the ProtobufDataFormat instance and pass it to Camel
-DataFormat marshal and unmarsha API like this.
+DataFormat marshal and unmarshal API like this.
 
 [source,java]
 
-----------------------------------------------------------------------------------
@@ -173,9 +171,9 @@ default instance class name like this.
 
--------------------------------------------------------------------------------------------------
    // You don't need to specify the default instance for protobuf marshaling   
            
    from("direct:marshal").marshal().protobuf();
-   from("direct:unmarshalA").unmarshal().
-       
protobuf("org.apache.camel.dataformat.protobuf.generated.AddressBookProtos$Person").
-       to ("mock:reverse");
+   from("direct:unmarshalA").unmarshal()
+       
.protobuf("org.apache.camel.dataformat.protobuf.generated.AddressBookProtos$Person")
+       .to("mock:reverse");
                 
    
from("direct:unmarshalB").unmarshal().protobuf(Person.getDefaultInstance()).to("mock:reverse");
 
--------------------------------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalSpringTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalSpringTest.java
 
b/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalSpringTest.java
index 9ec978e..a190ec4 100644
--- 
a/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalSpringTest.java
+++ 
b/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalSpringTest.java
@@ -16,12 +16,70 @@
  */
 package org.apache.camel.dataformat.protobuf;
 
+import org.apache.camel.CamelException;
+import org.apache.camel.FailedToCreateRouteException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.protobuf.generated.AddressBookProtos;
+import org.apache.camel.dataformat.protobuf.generated.AddressBookProtos.Person;
+import org.apache.camel.test.spring.CamelSpringTestSupport;
+
+import org.junit.Test;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
-public class ProtobufMarshalAndUnmarshalSpringTest extends 
ProtobufMarshalAndUnmarshalTest {
+public class ProtobufMarshalAndUnmarshalSpringTest extends 
CamelSpringTestSupport {
 
+    @Override
     protected ClassPathXmlApplicationContext createApplicationContext() {
         return new 
ClassPathXmlApplicationContext("org/apache/camel/dataformat/protobuf/springDataFormat.xml");
     }
+    
+    @Test
+    public void testMarshalAndUnmarshalWithDataFormat() throws Exception {
+        marshalAndUnmarshal("direct:in", "direct:back");
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalWithDSL1() throws Exception {
+        marshalAndUnmarshal("direct:marshal", "direct:unmarshalA");
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalWithDSL2() throws Exception {
+        marshalAndUnmarshal("direct:marshal", "direct:unmarshalB");
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalWithDSL3() throws Exception {
+        try {
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() throws Exception {
+                    from("direct:unmarshalC").unmarshal().protobuf(new 
CamelException("wrong instance")).to("mock:reverse");
+                }
+            });
+            fail("Expect the exception here");
+        } catch (Exception ex) {
+            assertTrue("Expect FailedToCreateRouteException", ex instanceof 
FailedToCreateRouteException);
+            assertTrue("Get a wrong reason", ex.getCause() instanceof 
IllegalArgumentException);
+        }
+    }
+
+    private void marshalAndUnmarshal(String inURI, String outURI) throws 
Exception {
+        AddressBookProtos.Person input = 
AddressBookProtos.Person.newBuilder().setName("Martin").setId(1234).build();
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Person.class);
+        mock.message(0).body().isEqualTo(input);
+
+        Object marshalled = template.requestBody(inURI, input);
 
+        template.sendBody(outURI, marshalled);
+
+        mock.assertIsSatisfied();
+
+        Person output = 
mock.getReceivedExchanges().get(0).getIn().getBody(Person.class);
+        assertEquals("Martin", output.getName());
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-protobuf/src/test/resources/org/apache/camel/dataformat/protobuf/springDataFormat.xml
----------------------------------------------------------------------
diff --git 
a/components/camel-protobuf/src/test/resources/org/apache/camel/dataformat/protobuf/springDataFormat.xml
 
b/components/camel-protobuf/src/test/resources/org/apache/camel/dataformat/protobuf/springDataFormat.xml
index 6716f51..eeeaafc 100644
--- 
a/components/camel-protobuf/src/test/resources/org/apache/camel/dataformat/protobuf/springDataFormat.xml
+++ 
b/components/camel-protobuf/src/test/resources/org/apache/camel/dataformat/protobuf/springDataFormat.xml
@@ -21,21 +21,8 @@
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
        xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
-       http://camel.apache.org/schema/spring 
http://camel.apache.org/schema/spring/camel-spring.xsd
-    ">
-
-  <!-- START SNIPPET: example 
-   from("direct:in").marshal(format);
-   from("direct:back").unmarshal(format).to("mock:reverse");
-             
-   from("direct:marshal").marshal().protobuf();
-   
from("direct:unmarshalA").unmarshal().protobuf("org.apache.camel.dataformat.protobuf.generated.AddressBookProtos$Person").to("mock:reverse");
-                
-   
from("direct:unmarshalB").unmarshal().protobuf(Person.getDefaultInstance()).to("mock:reverse");
-  -->
-  
-  
-    
+       http://camel.apache.org/schema/spring 
http://camel.apache.org/schema/spring/camel-spring.xsd";>
+        
   <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring";>
     <dataFormats>
       <protobuf id="protobuf1" 
instanceClass="org.apache.camel.dataformat.protobuf.generated.AddressBookProtos$Person"/>
@@ -69,8 +56,8 @@
     </route>
   </camelContext>
  
-  <bean id="protobuf2" 
class="org.apache.camel.datafromat.protobuf.ProtobufDataFormat">
-    <property name="instanceClassName" 
value="org.apache.camel.dataformat.protobuf.generated.AddressBookProtos$Person"/>
+  <bean id="protobuf2" 
class="org.apache.camel.dataformat.protobuf.ProtobufDataFormat">
+    <property name="instanceClass" 
value="org.apache.camel.dataformat.protobuf.generated.AddressBookProtos$Person"/>
   </bean>
 
 </beans>

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/ReadMe.md
----------------------------------------------------------------------
diff --git a/components/camel-thrift/ReadMe.md 
b/components/camel-thrift/ReadMe.md
new file mode 100644
index 0000000..0524974
--- /dev/null
+++ b/components/camel-thrift/ReadMe.md
@@ -0,0 +1,30 @@
+# How to upgrade Apache Thrift
+
+You need to install the thrift compiler from
+
+    https://github.com/apache/thrift/releases
+
+For linux/osx you download the .tar distro, and untar it, and then
+
+    sudo ./bootstrap.sh
+    export CXXFLAGS='-Os -ffunction-sections -Wl,--gc-sections 
-fno-asynchronous-unwind-tables -Wl,--strip-all'
+    sudo ./configure --without-c_glib --without-java --without-python 
--without-ruby --without-nodejs --disable-libs --disable-tests 
--disable-tutorial --disable-shared --enable-static
+    sudo ./make check
+    sudo ./make install
+
+If its succesful, you can type
+
+    thrift --version
+
+To display the version of the thrift compiler.
+
+You then need to compile the sample test source for the `camel-thrift` 
component.
+
+The sample test source is an example taken from the Thrift Java tutorial at: 
https://thrift.apache.org/tutorial/java
+
+    cd components/camel-thrift
+    cd src/test/thrift
+    thrift -r --gen java -out ../java/ ./tutorial-dataformat.thrift
+
+The generate source code will override the existing.
+

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-thrift/pom.xml b/components/camel-thrift/pom.xml
new file mode 100644
index 0000000..9e4bc91
--- /dev/null
+++ b/components/camel-thrift/pom.xml
@@ -0,0 +1,92 @@
+<?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.20.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>camel-thrift</artifactId>
+  <packaging>jar</packaging>
+  <name>Camel :: Thrift</name>
+  <description>Camel Apache Thrift data format and RPC support</description>
+
+  <properties>
+    
<camel.osgi.export.pkg>org.apache.camel.dataformat.thrift.*</camel.osgi.export.pkg>
+    
<camel.osgi.export.service>org.apache.camel.spi.DataFormatResolver;dataformat=thrift</camel.osgi.export.service>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-core</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.thrift</groupId>
+      <artifactId>libthrift</artifactId>
+      <version>${libthrift-version}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+    
+    <!-- testing -->
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-test-spring</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</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>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>${gson-version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/src/main/docs/thrift-dataformat.adoc
----------------------------------------------------------------------
diff --git a/components/camel-thrift/src/main/docs/thrift-dataformat.adoc 
b/components/camel-thrift/src/main/docs/thrift-dataformat.adoc
new file mode 100644
index 0000000..54a6267
--- /dev/null
+++ b/components/camel-thrift/src/main/docs/thrift-dataformat.adoc
@@ -0,0 +1,156 @@
+## Thrift DataFormat
+
+*Available as of Camel version 2.20*
+
+
+Camel provides a link:data-format.html[Data Format] to serialize between
+Java and the Apache Thrift . The project's site details why
+you may wish to
+https://thrift.apache.org/.
+Apache Thrift is language-neutral and
+platform-neutral, so messages produced by your Camel routes may be
+consumed by other language implementations.
+
+https://github.com/apache/thrift[Apache Thrift Implementation] +
+
+### Thrift Options
+
+// dataformat options: START
+The Thrift dataformat supports 3 options which are listed below.
+
+
+
+[width="100%",cols="2s,1m,1m,6",options="header"]
+|=======================================================================
+| Name | Default | Java Type | Description
+| instanceClass |  | String | Name of class to use when unarmshalling
+| contentTypeFormat | binary | String | Defines a content type format in which 
thrift message will be serialized/deserialized from(to) the Java been. The 
format can either be native or json for either native binary thrift json or 
simple json fields representation. The default value is binary.
+| contentTypeHeader | false | Boolean | Whether the data format should set the 
Content-Type header with the type from the data format if the data format is 
capable of doing so. For example application/xml for data formats marshalling 
to XML or application/json for data formats marshalling to JSon etc.
+|=======================================================================
+// dataformat options: END
+
+### Content type format
+
+It's possible to parse JSON message to convert it to the Thrift format and 
unparse it back using native util converter.
+To use this option, set contentTypeFormat value to 'json' or call thrift with 
second parameter.
+If default instance is not specified, always use native binary Thrift format.
+The simple JSON format is write-only (marshal) and produces a simple output 
format suitable for parsing by scripting languages.
+The sample code shows below:
+
+[source,java]
+--------------------------------------------------------------------------------------------------
+from("direct:marshal")
+    .unmarshal()
+    .thrift("org.apache.camel.dataformat.thrift.generated.Work", "json")
+    .to("mock:reverse");
+--------------------------------------------------------------------------------------------------
+
+### Thrift overview
+
+This quick overview of how to use Thrift. For more detail see the
+https://thrift.apache.org/tutorial/[complete tutorial]
+
+### Defining the thrift format
+
+The first step is to define the format for the body of your exchange.
+This is defined in a .thrift file as so:
+
+*tutorial.thrift*
+
+[source,java]
+------------------------------------------------------------
+namespace java org.apache.camel.dataformat.thrift.generated
+
+enum Operation {
+  ADD = 1,
+  SUBTRACT = 2,
+  MULTIPLY = 3,
+  DIVIDE = 4
+}
+
+struct Work {
+  1: i32 num1 = 0,
+  2: i32 num2,
+  3: Operation op,
+  4: optional string comment,
+}
+------------------------------------------------------------
+
+### Generating Java classes
+
+The Apache Thrift provides a compiler which will generate the Java
+classes for the format we defined in our .thrift file.
+
+You can also run the compiler for any additional supported languages you 
require manually.
+
+`thrift -r --gen java -out ../java/ ./tutorial-dataformat.thrift`
+
+This will generate separate Java class for each type defined in .thrift 
+file, i.e. struct or enum.
+The generated classes implement org.apache.thrift.TBase which is required
+by the serialization mechanism. For this reason it important that only
+these classes are used in the body of your exchanges.
+Camel will throw an exception on route creation if you attempt to tell 
+the link:data-format.html[Data Format] to use a class that does not implement 
+org.apache.thrift.TBase.
+
+### Java DSL
+
+You can use create the ThriftDataFormat instance and pass it to Camel
+DataFormat marshal and unmarshal API like this.
+
+[source,java]
+-----------------------------------------------------------------------------------
+   ThriftDataFormat format = new ThriftDataFormat(new Work());
+
+   from("direct:in").marshal(format);
+   from("direct:back").unmarshal(format).to("mock:reverse");
+-----------------------------------------------------------------------------------
+
+Or use the DSL thrift() passing the unmarshal default instance or
+default instance class name like this.
+
+[source,java]
+--------------------------------------------------------------------------------------------------
+   // You don't need to specify the default instance for the thrift marshaling 
              
+   from("direct:marshal").marshal().thrift();
+   from("direct:unmarshalA").unmarshal()
+       .thrift("org.apache.camel.dataformat.thrift.generated.Work")
+       .to("mock:reverse");
+                
+   from("direct:unmarshalB").unmarshal().thrift(new Work()).to("mock:reverse");
+--------------------------------------------------------------------------------------------------
+
+### Spring DSL
+
+The following example shows how to use Thrift to unmarshal using Spring
+configuring the thrift data type
+
+[source,java]
+----------------------------------------------------------------------------------------------------------
+<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring";>
+  <route>
+    <from uri="direct:start"/>
+    <unmarshal>
+      <thrift 
instanceClass="org.apache.camel.dataformat.thrift.generated.Work" />
+    </unmarshal>
+    <to uri="mock:result"/>
+  </route>
+</camelContext>
+----------------------------------------------------------------------------------------------------------
+
+### Dependencies
+
+To use Thrift in your camel routes you need to add the a dependency on
+*camel-thrift* which implements this data format.
+
+[source,xml]
+-----------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-thrift</artifactId>
+  <version>x.x.x</version>
+  <!-- use the same version as your Camel core version -->
+</dependency>
+-----------------------------------------
+### See Also

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/src/main/java/org/apache/camel/dataformat/thrift/ThriftDataFormat.java
----------------------------------------------------------------------
diff --git 
a/components/camel-thrift/src/main/java/org/apache/camel/dataformat/thrift/ThriftDataFormat.java
 
b/components/camel-thrift/src/main/java/org/apache/camel/dataformat/thrift/ThriftDataFormat.java
new file mode 100644
index 0000000..ecb9e69
--- /dev/null
+++ 
b/components/camel-thrift/src/main/java/org/apache/camel/dataformat/thrift/ThriftDataFormat.java
@@ -0,0 +1,204 @@
+/**
+ * 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.dataformat.thrift;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.CamelException;
+import org.apache.camel.Exchange;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.DataFormatName;
+import org.apache.camel.support.ServiceSupport;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
+import org.apache.commons.io.IOUtils;
+import org.apache.thrift.TBase;
+import org.apache.thrift.TDeserializer;
+import org.apache.thrift.TSerializer;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TJSONProtocol;
+import org.apache.thrift.protocol.TSimpleJSONProtocol;
+
+public class ThriftDataFormat extends ServiceSupport implements DataFormat, 
DataFormatName, CamelContextAware {
+
+    public static final String CONTENT_TYPE_FORMAT_BINARY = "binary";
+    public static final String CONTENT_TYPE_FORMAT_JSON = "json";
+    public static final String CONTENT_TYPE_FORMAT_SIMPLE_JSON = "sjson";
+
+    private static final String CONTENT_TYPE_HEADER_NATIVE = 
"application/octet-stream";
+    private static final String CONTENT_TYPE_HEADER_JSON = "application/json";
+
+    private CamelContext camelContext;
+    @SuppressWarnings("rawtypes")
+    private TBase defaultInstance;
+    private String instanceClassName;
+    private boolean contentTypeHeader;
+    private String contentTypeFormat = CONTENT_TYPE_FORMAT_BINARY;
+
+    public ThriftDataFormat() {
+    }
+
+    @SuppressWarnings("rawtypes")
+    public ThriftDataFormat(TBase defaultInstance) {
+        this.defaultInstance = defaultInstance;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public ThriftDataFormat(TBase defaultInstance, String contentTypeFormat) {
+        this.defaultInstance = defaultInstance;
+        this.contentTypeFormat = contentTypeFormat;
+    }
+
+    @Override
+    public String getDataFormatName() {
+        return "thrift";
+    }
+
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public void setDefaultInstance(TBase instance) {
+        this.defaultInstance = instance;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public void setDefaultInstance(Object instance) {
+        if (instance instanceof TBase) {
+            this.defaultInstance = (TBase)instance;
+        } else {
+            throw new IllegalArgumentException("The argument for 
setDefaultInstance should be subClass of org.apache.thrift.TBase");
+        }
+    }
+
+    public void setInstanceClass(String className) throws Exception {
+        ObjectHelper.notNull(className, "ThriftDataFormat instaceClass");
+        instanceClassName = className;
+    }
+
+    public void setContentTypeHeader(boolean contentTypeHeader) {
+        this.contentTypeHeader = contentTypeHeader;
+    }
+
+    public boolean isContentTypeHeader() {
+        return contentTypeHeader;
+    }
+
+    /*
+     * Defines a content type format in which thrift message will be
+     * serialized/deserialized from(to) the Java been. It can be native thrift
+     * format or JSON fields representation. The default value is 'native'.
+     */
+    public void setContentTypeFormat(String contentTypeFormat) {
+        StringHelper.notEmpty(contentTypeFormat, "ThriftDataFormat 
contentTypeFormat");
+        this.contentTypeFormat = contentTypeFormat;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.camel.spi.DataFormat#marshal(org.apache.camel.Exchange,
+     * java.lang.Object, java.io.OutputStream)
+     */
+    @SuppressWarnings("rawtypes")
+    public void marshal(final Exchange exchange, final Object graph, final 
OutputStream outputStream) throws Exception {
+        String contentTypeHeader = CONTENT_TYPE_HEADER_NATIVE;
+        TSerializer serializer;
+        
+        if (contentTypeFormat.equals(CONTENT_TYPE_FORMAT_JSON)) {
+            serializer = new TSerializer(new TJSONProtocol.Factory());
+            IOUtils.write(serializer.toString((TBase)graph, "UTF-8"), 
outputStream, "UTF-8");
+            contentTypeHeader = CONTENT_TYPE_HEADER_JSON;
+        } else if (contentTypeFormat.equals(CONTENT_TYPE_FORMAT_SIMPLE_JSON)) {
+            serializer = new TSerializer(new TSimpleJSONProtocol.Factory());
+            IOUtils.write(serializer.toString((TBase)graph, "UTF-8"), 
outputStream, "UTF-8");
+            contentTypeHeader = CONTENT_TYPE_HEADER_JSON;
+        } else if (contentTypeFormat.equals(CONTENT_TYPE_FORMAT_BINARY)) {
+            serializer = new TSerializer(new TBinaryProtocol.Factory());
+            IOUtils.write(serializer.serialize((TBase)graph), outputStream);
+        } else {
+            throw new CamelException("Invalid thrift content type format: " + 
contentTypeFormat);
+        }
+
+        if (isContentTypeHeader()) {
+            if (exchange.hasOut()) {
+                exchange.getOut().setHeader(Exchange.CONTENT_TYPE, 
contentTypeHeader);
+            } else {
+                exchange.getIn().setHeader(Exchange.CONTENT_TYPE, 
contentTypeHeader);
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see 
org.apache.camel.spi.DataFormat#unmarshal(org.apache.camel.Exchange,
+     * java.io.InputStream)
+     */
+    public Object unmarshal(final Exchange exchange, final InputStream 
inputStream) throws Exception {
+        TDeserializer deserializer;
+        ObjectHelper.notNull(defaultInstance, "defaultInstance or 
instanceClassName must be set", this);
+        
+        if (contentTypeFormat.equals(CONTENT_TYPE_FORMAT_JSON)) {
+            deserializer = new TDeserializer(new TJSONProtocol.Factory());
+            deserializer.deserialize(defaultInstance, 
IOUtils.toByteArray(inputStream));
+        } else if (contentTypeFormat.equals(CONTENT_TYPE_FORMAT_BINARY)) {
+            deserializer = new TDeserializer(new TBinaryProtocol.Factory());
+            deserializer.deserialize(defaultInstance, 
IOUtils.toByteArray(inputStream));
+        } else if (contentTypeFormat.equals(CONTENT_TYPE_FORMAT_SIMPLE_JSON)) {
+            throw new CamelException("Simple JSON format is avalable for the 
message marshalling only");
+        } else {
+            throw new CamelException("Invalid thrift content type format: " + 
contentTypeFormat);
+        }
+
+        return defaultInstance;
+    }
+
+    @SuppressWarnings("rawtypes")
+    protected TBase loadDefaultInstance(final String className, final 
CamelContext context) throws CamelException, ClassNotFoundException {
+        Class<?> instanceClass = 
context.getClassResolver().resolveMandatoryClass(className);
+        if (TBase.class.isAssignableFrom(instanceClass)) {
+            try {
+                return (TBase)instanceClass.newInstance();
+            } catch (final Exception ex) {
+                throw new CamelException("Can't set the defaultInstance of 
ThriftDataFormat with " + className + ", caused by " + ex);
+            }
+        } else {
+            throw new CamelException("Can't set the defaultInstance of 
ThriftDataFormat with " + className
+                                     + ", as the class is not a subClass of 
org.apache.thrift.TBase");
+        }
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        if (defaultInstance == null && instanceClassName != null) {
+            defaultInstance = loadDefaultInstance(instanceClassName, 
getCamelContext());
+        }
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        // noop
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/src/main/resources/META-INF/LICENSE.txt
----------------------------------------------------------------------
diff --git a/components/camel-thrift/src/main/resources/META-INF/LICENSE.txt 
b/components/camel-thrift/src/main/resources/META-INF/LICENSE.txt
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/components/camel-thrift/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.
+

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/src/main/resources/META-INF/NOTICE.txt
----------------------------------------------------------------------
diff --git a/components/camel-thrift/src/main/resources/META-INF/NOTICE.txt 
b/components/camel-thrift/src/main/resources/META-INF/NOTICE.txt
new file mode 100644
index 0000000..d92f2e3
--- /dev/null
+++ b/components/camel-thrift/src/main/resources/META-INF/NOTICE.txt
@@ -0,0 +1,14 @@
+   =========================================================================
+   ==  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/).
+
+   This product includes software developed by
+   The HAPI Project (http://hl7api.sourceforge.net/).
+
+   Please read the different LICENSE files present in the licenses directory of
+   this distribution.

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/src/main/resources/META-INF/services/org/apache/camel/dataformat/thrift
----------------------------------------------------------------------
diff --git 
a/components/camel-thrift/src/main/resources/META-INF/services/org/apache/camel/dataformat/thrift
 
b/components/camel-thrift/src/main/resources/META-INF/services/org/apache/camel/dataformat/thrift
new file mode 100644
index 0000000..1af7578
--- /dev/null
+++ 
b/components/camel-thrift/src/main/resources/META-INF/services/org/apache/camel/dataformat/thrift
@@ -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.dataformat.thrift.ThriftDataFormat

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/src/test/java/META-INF/MANIFEST.MF
----------------------------------------------------------------------
diff --git a/components/camel-thrift/src/test/java/META-INF/MANIFEST.MF 
b/components/camel-thrift/src/test/java/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..254272e
--- /dev/null
+++ b/components/camel-thrift/src/test/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: 
+

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalJsonTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalJsonTest.java
 
b/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalJsonTest.java
new file mode 100644
index 0000000..22d0c0f
--- /dev/null
+++ 
b/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalJsonTest.java
@@ -0,0 +1,106 @@
+/**
+ * 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.dataformat.thrift;
+
+import com.google.gson.Gson;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.thrift.generated.Operation;
+import org.apache.camel.dataformat.thrift.generated.Work;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class ThriftMarshalAndUnmarshalJsonTest extends CamelTestSupport {
+    
+    private static final String WORK_JSON_TEST = 
"{\"1\":{\"i32\":1},\"2\":{\"i32\":100},\"3\":{\"i32\":3},\"4\":{\"str\":\"This 
is a test thrift data\"}}";
+    private static final String WORK_TEST_COMMENT = "This is a test thrift 
data";
+    private static final int WORK_TEST_NUM1 = 1;
+    private static final int WORK_TEST_NUM2 = 100;
+    private static final Operation WORK_TEST_OPERATION = Operation.MULTIPLY;
+    
+    @Test
+    public void testMarshalAndUnmarshal() throws Exception {
+        marshalAndUnmarshal("direct:in", "direct:back");
+    }
+    
+    @Test
+    public void testMarshalAndUnmarshalWithDSL() throws Exception {
+        marshalAndUnmarshal("direct:marshal", "direct:unmarshalA");
+    }
+    
+    @Test
+    public void testMarshalSimpleJson() throws Exception {
+        Gson gson = new Gson();
+        Work input = new Work();
+        
+        MockEndpoint mock = getMockEndpoint("mock:reverse-sjson");
+        mock.expectedMessageCount(1);
+        
+        input.num1 = WORK_TEST_NUM1;
+        input.num2 = WORK_TEST_NUM2;
+        input.op = WORK_TEST_OPERATION;
+        input.comment = WORK_TEST_COMMENT;
+        
+        template.requestBody("direct:marshal-sjson", input);
+        mock.assertIsSatisfied();
+        
+        String body = 
mock.getReceivedExchanges().get(0).getIn().getBody(String.class);
+        Work output = gson.fromJson(body, Work.class);
+        
+        assertEquals(WORK_TEST_NUM1, output.getNum1());
+        assertEquals(WORK_TEST_NUM2, output.getNum2());
+        assertEquals(WORK_TEST_COMMENT, output.getComment());
+    }
+    
+    private void marshalAndUnmarshal(String inURI, String outURI) throws 
Exception {
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Work.class);
+        
+        Object marshalled = template.requestBody(inURI, WORK_JSON_TEST);
+
+        template.sendBody(outURI, marshalled);
+
+        mock.assertIsSatisfied();
+
+        Work output = 
mock.getReceivedExchanges().get(0).getIn().getBody(Work.class);
+        
+        assertEquals(WORK_TEST_NUM1, output.getNum1());
+        assertEquals(WORK_TEST_NUM2, output.getNum2());
+        assertEquals(WORK_TEST_OPERATION, output.getOp());
+        assertEquals(WORK_TEST_COMMENT, output.getComment());
+    }
+    
+    
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                ThriftDataFormat format = new ThriftDataFormat(new Work(), 
ThriftDataFormat.CONTENT_TYPE_FORMAT_JSON);
+
+                from("direct:in").unmarshal(format).to("mock:reverse");
+                from("direct:back").marshal(format);
+
+                
from("direct:marshal").unmarshal().thrift("org.apache.camel.dataformat.thrift.generated.Work",
 "json").to("mock:reverse");
+                from("direct:unmarshalA").marshal().thrift();
+                
+                
from("direct:marshal-sjson").marshal().thrift("org.apache.camel.dataformat.thrift.generated.Work",
 "sjson").convertBodyTo(String.class).to("mock:reverse-sjson");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalSpringTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalSpringTest.java
 
b/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalSpringTest.java
new file mode 100644
index 0000000..c4ca65b
--- /dev/null
+++ 
b/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalSpringTest.java
@@ -0,0 +1,95 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dataformat.thrift;
+
+import org.apache.camel.CamelException;
+import org.apache.camel.FailedToCreateRouteException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.thrift.generated.Operation;
+import org.apache.camel.dataformat.thrift.generated.Work;
+import org.apache.camel.test.spring.CamelSpringTestSupport;
+import org.junit.Test;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class ThriftMarshalAndUnmarshalSpringTest extends 
CamelSpringTestSupport {
+    private static final String WORK_TEST_COMMENT = "This is a test thrift 
data";
+    private static final int WORK_TEST_NUM1 = 1;
+    private static final int WORK_TEST_NUM2 = 100;
+    private static final Operation WORK_TEST_OPERATION = Operation.MULTIPLY;
+    
+    @Override
+    protected ClassPathXmlApplicationContext createApplicationContext() {
+        return new 
ClassPathXmlApplicationContext("org/apache/camel/dataformat/thrift/springDataFormat.xml");
+    }
+    
+    @Test
+    public void testMarshalAndUnmarshalWithDataFormat() throws Exception {
+        marshalAndUnmarshal("direct:in", "direct:back");
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalWithDSL1() throws Exception {
+        marshalAndUnmarshal("direct:marshal", "direct:unmarshalA");
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalWithDSL2() throws Exception {
+        marshalAndUnmarshal("direct:marshal", "direct:unmarshalB");
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalWithDSL3() throws Exception {
+        try {
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() throws Exception {
+                    from("direct:unmarshalC").unmarshal().thrift(new 
CamelException("wrong instance")).to("mock:reverse");
+                }
+            });
+            fail("Expect the exception here");
+        } catch (Exception ex) {
+            assertTrue("Expect FailedToCreateRouteException", ex instanceof 
FailedToCreateRouteException);
+            assertTrue("Get a wrong reason", ex.getCause() instanceof 
IllegalArgumentException);
+        }
+    }
+
+    private void marshalAndUnmarshal(String inURI, String outURI) throws 
Exception {
+        Work input = new Work();
+        
+        input.num1 = WORK_TEST_NUM1;
+        input.num2 = WORK_TEST_NUM2;
+        input.op = WORK_TEST_OPERATION;
+        input.comment = WORK_TEST_COMMENT;
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Work.class);
+        mock.message(0).body().isEqualTo(input);
+
+        Object marshalled = template.requestBody(inURI, input);
+
+        template.sendBody(outURI, marshalled);
+
+        mock.assertIsSatisfied();
+
+        Work output = 
mock.getReceivedExchanges().get(0).getIn().getBody(Work.class);
+        assertEquals(WORK_TEST_COMMENT, output.getComment());
+        assertEquals(WORK_TEST_OPERATION, output.getOp());
+        assertEquals(WORK_TEST_NUM2, output.getNum2());
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalTest.java
 
b/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalTest.java
new file mode 100644
index 0000000..6443432
--- /dev/null
+++ 
b/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/ThriftMarshalAndUnmarshalTest.java
@@ -0,0 +1,108 @@
+/**
+ * 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.dataformat.thrift;
+
+import org.apache.camel.CamelException;
+import org.apache.camel.FailedToCreateRouteException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.thrift.generated.Operation;
+import org.apache.camel.dataformat.thrift.generated.Work;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class ThriftMarshalAndUnmarshalTest extends CamelTestSupport {
+    private static final String WORK_TEST_COMMENT = "This is a test thrift 
data";
+    private static final int WORK_TEST_NUM1 = 1;
+    private static final int WORK_TEST_NUM2 = 100;
+    private static final Operation WORK_TEST_OPERATION = Operation.MULTIPLY;
+
+    @Test
+    public void testMarshalAndUnmarshalWithDataFormat() throws Exception {
+        marshalAndUnmarshal("direct:in", "direct:back");
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalWithDSL1() throws Exception {
+        marshalAndUnmarshal("direct:marshal", "direct:unmarshalA");
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalWithDSL2() throws Exception {
+        marshalAndUnmarshal("direct:marshal", "direct:unmarshalB");
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalWithDSL3() throws Exception {
+        try {
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() throws Exception {
+                    from("direct:unmarshalC").unmarshal().thrift(new 
CamelException("wrong instance")).to("mock:reverse");
+                }
+            });
+            fail("Expect the exception here");
+        } catch (Exception ex) {
+            assertTrue("Expect FailedToCreateRouteException", ex instanceof 
FailedToCreateRouteException);
+            assertTrue("Get a wrong reason", ex.getCause() instanceof 
IllegalArgumentException);
+        }
+    }
+
+    private void marshalAndUnmarshal(String inURI, String outURI) throws 
Exception {
+        Work input = new Work();
+        
+        input.num1 = WORK_TEST_NUM1;
+        input.num2 = WORK_TEST_NUM2;
+        input.op = WORK_TEST_OPERATION;
+        input.comment = WORK_TEST_COMMENT;
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Work.class);
+        mock.message(0).body().isEqualTo(input);
+
+        Object marshalled = template.requestBody(inURI, input);
+
+        template.sendBody(outURI, marshalled);
+
+        mock.assertIsSatisfied();
+
+        Work output = 
mock.getReceivedExchanges().get(0).getIn().getBody(Work.class);
+        assertEquals(WORK_TEST_COMMENT, output.getComment());
+        assertEquals(WORK_TEST_OPERATION, output.getOp());
+        assertEquals(WORK_TEST_NUM2, output.getNum2());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                ThriftDataFormat format = new ThriftDataFormat(new Work());
+
+                from("direct:in").marshal(format);
+                from("direct:back").unmarshal(format).to("mock:reverse");
+
+                from("direct:marshal").marshal().thrift();
+                
from("direct:unmarshalA").unmarshal().thrift("org.apache.camel.dataformat.thrift.generated.Work").to("mock:reverse");
+
+                from("direct:unmarshalB").unmarshal().thrift(new 
Work()).to("mock:reverse");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/362a8943/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/generated/Operation.java
----------------------------------------------------------------------
diff --git 
a/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/generated/Operation.java
 
b/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/generated/Operation.java
new file mode 100644
index 0000000..cb98641
--- /dev/null
+++ 
b/components/camel-thrift/src/test/java/org/apache/camel/dataformat/thrift/generated/Operation.java
@@ -0,0 +1,55 @@
+/**
+ * Autogenerated by Thrift Compiler (0.9.3)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.camel.dataformat.thrift.generated;
+
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.thrift.TEnum;
+
+/**
+ * You can define enums, which are just 32 bit integers. Values are optional
+ * and start at 1 if not supplied, C style again.
+ */
+public enum Operation implements org.apache.thrift.TEnum {
+  ADD(1),
+  SUBTRACT(2),
+  MULTIPLY(3),
+  DIVIDE(4);
+
+  private final int value;
+
+  private Operation(int value) {
+    this.value = value;
+  }
+
+  /**
+   * Get the integer value of this enum value, as defined in the Thrift IDL.
+   */
+  public int getValue() {
+    return value;
+  }
+
+  /**
+   * Find a the enum type by its integer value, as defined in the Thrift IDL.
+   * @return null if the value is not found.
+   */
+  public static Operation findByValue(int value) { 
+    switch (value) {
+      case 1:
+        return ADD;
+      case 2:
+        return SUBTRACT;
+      case 3:
+        return MULTIPLY;
+      case 4:
+        return DIVIDE;
+      default:
+        return null;
+    }
+  }
+}

Reply via email to