You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2017/04/11 18:04:50 UTC

[4/5] camel git commit: CAMEL-11135: camel-protobuf component improvements

CAMEL-11135: camel-protobuf component improvements

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

Branch: refs/heads/master
Commit: 327dfcbd8f312c78ffe1cc4a293612c2432d3867
Parents: 3b977b0
Author: Dmitry Volodin <dm...@gmail.com>
Authored: Tue Apr 11 17:49:27 2017 +0300
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Apr 11 19:53:20 2017 +0200

----------------------------------------------------------------------
 .../apache/camel/builder/DataFormatClause.java  |   11 +
 .../model/dataformat/ProtobufDataFormat.java    |   20 +
 components/camel-protobuf/ReadMe.md             |    5 +-
 components/camel-protobuf/pom.xml               |   42 +-
 .../src/main/docs/protobuf-dataformat.adoc      |   82 +-
 .../dataformat/protobuf/ProtobufDataFormat.java |   84 +-
 .../ProtobufMarshalAndUnmarshalJsonTest.java    |   73 +
 .../ProtobufMarshalAndUnmarshalSpringTest.java  |    2 +-
 .../ProtobufMarshalAndUnmarshalTest.java        |   97 +
 .../ProtobufMarshalAndUnmarshallTest.java       |  100 -
 .../protobuf/generated/AddressBookProtos.java   | 2548 ------------------
 .../src/test/proto/addressbook.proto            |   29 +
 .../camel-protobuf/src/test/proto/readme.txt    |    5 +
 .../src/test/resources/addressbook.proto        |   27 -
 .../src/test/resources/readme.txt               |    5 -
 .../ProtobufDataFormatConfiguration.java        |   14 +
 16 files changed, 432 insertions(+), 2712 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/327dfcbd/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 25bea0f..0b18e91 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
@@ -714,10 +714,21 @@ public class DataFormatClause<T extends ProcessorDefinition<?>> {
         dataFormat.setDefaultInstance(defaultInstance);
         return dataFormat(dataFormat);
     }
+    
+    public T protobuf(Object defaultInstance, String contentTypeFormat) {
+        ProtobufDataFormat dataFormat = new ProtobufDataFormat();
+        dataFormat.setDefaultInstance(defaultInstance);
+        dataFormat.setContentTypeFormat(contentTypeFormat);
+        return dataFormat(dataFormat);
+    }
 
     public T protobuf(String instanceClassName) {
         return dataFormat(new ProtobufDataFormat(instanceClassName));
     }
+    
+    public T protobuf(String instanceClassName, String contentTypeFormat) {
+        return dataFormat(new ProtobufDataFormat(instanceClassName, contentTypeFormat));
+    }
 
     /**
      * Uses the RSS data format

http://git-wip-us.apache.org/repos/asf/camel/blob/327dfcbd/camel-core/src/main/java/org/apache/camel/model/dataformat/ProtobufDataFormat.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/ProtobufDataFormat.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/ProtobufDataFormat.java
index 723a6f6..dee0ec4 100644
--- a/camel-core/src/main/java/org/apache/camel/model/dataformat/ProtobufDataFormat.java
+++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/ProtobufDataFormat.java
@@ -38,6 +38,8 @@ import org.apache.camel.spi.Metadata;
 public class ProtobufDataFormat extends DataFormatDefinition {
     @XmlAttribute
     private String instanceClass;
+    @XmlAttribute
+    private String contentTypeFormat;
     @XmlTransient
     private Object defaultInstance;
     
@@ -49,6 +51,12 @@ public class ProtobufDataFormat extends DataFormatDefinition {
         this();
         setInstanceClass(instanceClass); 
     }
+    
+    public ProtobufDataFormat(String instanceClass, String contentTypeFormat) {
+        this();
+        setInstanceClass(instanceClass);
+        setContentTypeFormat(contentTypeFormat);
+    }
 
     public String getInstanceClass() {
         return instanceClass;
@@ -60,6 +68,15 @@ public class ProtobufDataFormat extends DataFormatDefinition {
     public void setInstanceClass(String instanceClass) {
         this.instanceClass = instanceClass;
     }
+    
+    /**
+     * Defines a content type format in which protobuf message will be
+     * serialized/deserialized from(to) the Java been. It can be native protobuf
+     * format or json fields representation. The default value is 'native'.
+     */
+    public void setContentTypeFormat(String contentTypeFormat) {
+        this.contentTypeFormat = contentTypeFormat;
+    }
 
     public Object getDefaultInstance() {
         return defaultInstance;
@@ -74,6 +91,9 @@ public class ProtobufDataFormat extends DataFormatDefinition {
         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/327dfcbd/components/camel-protobuf/ReadMe.md
----------------------------------------------------------------------
diff --git a/components/camel-protobuf/ReadMe.md b/components/camel-protobuf/ReadMe.md
index e7a7c35..a04e533 100644
--- a/components/camel-protobuf/ReadMe.md
+++ b/components/camel-protobuf/ReadMe.md
@@ -1,4 +1,5 @@
 # How to upgrade protobuf
+# Use this guide, if your operating system is not supporting by Protobuf Java code generator maven plugin
 
 You need to install the protoc compiler from
 
@@ -18,10 +19,10 @@ To list the version of the proto compiler.
 
 You then need to compile the sample test source for the `camel-protobuf` component.
 
-The sample test source is an example taken from the Protobuf Java tutorial at: http://code.google.com/apis/protocolbuffers/docs/javatutorial.html
+The sample test source is an example taken from the Protobuf Java tutorial at: https://developers.google.com/protocol-buffers/docs/javatutorial
 
     cd components/camel-protobuf
-	cd src/test/resources
+	cd src/test/proto
 	protoc --java_out=../java ./addressbook.proto
 
 The generate source code will override the existing. You then need to insert back the checkstyle:off rule. For that take a git diff to see the code changes.

http://git-wip-us.apache.org/repos/asf/camel/blob/327dfcbd/components/camel-protobuf/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-protobuf/pom.xml b/components/camel-protobuf/pom.xml
old mode 100755
new mode 100644
index 1a7e538..6785890
--- a/components/camel-protobuf/pom.xml
+++ b/components/camel-protobuf/pom.xml
@@ -45,6 +45,15 @@
       <artifactId>protobuf-java</artifactId>
       <version>${protobuf-version}</version>
     </dependency>
+    <dependency>
+      <groupId>com.google.protobuf</groupId>
+      <artifactId>protobuf-java-util</artifactId>
+      <version>${protobuf-version}</version>
+    </dependency>
+    <dependency>
+    <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
 
     <!-- testing -->
     <dependency>
@@ -73,4 +82,35 @@
       <scope>test</scope>
     </dependency>
   </dependencies>
-</project>
+  
+  <build>
+    <extensions>
+      <!-- Operating system and CPU architecture detection extension -->
+      <extension>
+        <groupId>kr.motd.maven</groupId>
+        <artifactId>os-maven-plugin</artifactId>
+        <version>1.4.1.Final</version>
+      </extension>
+    </extensions>
+    
+    <plugins>
+      <!-- Protobuf Java code generator plugin -->
+      <plugin>
+        <groupId>org.xolstice.maven.plugins</groupId>
+        <artifactId>protobuf-maven-plugin</artifactId>
+        <version>0.5.0</version>
+        <extensions>true</extensions>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-compile</goal>
+            </goals>
+            <configuration>
+              <protocArtifact>com.google.protobuf:protoc:${protobuf-version}:exe:${os.detected.classifier}</protocArtifact>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/327dfcbd/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 b35cfc3..61276e3 100644
--- a/components/camel-protobuf/src/main/docs/protobuf-dataformat.adoc
+++ b/components/camel-protobuf/src/main/docs/protobuf-dataformat.adoc
@@ -10,21 +10,21 @@ Protobuf - Protocol Buffers
 Camel provides a link:data-format.html[Data Format] to serialse between
 Java and the Protocol Buffer protocol. The project's site details why
 you may wish to
-http://code.google.com/apis/protocolbuffers/docs/overview.html[choose
+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.
 
-http://code.google.com/apis/protocolbuffers/[API Site] +
- http://code.google.com/p/protobuf/[Protobuf Implementation] +
+https://developers.google.com/protocol-buffers/docs/reference/java/[API Site] +
+https://github.com/google/protobuf[Protobuf Implementation] +
 
-http://code.google.com/apis/protocolbuffers/docs/javatutorial.html[Protobuf
+https://developers.google.com/protocol-buffers/docs/javatutorial[Protobuf
 Java Tutorial]
 
 ### Protobuf Options
 
 // dataformat options: START
-The Protobuf dataformat supports 2 options which are listed below.
+The Protobuf dataformat supports 3 options which are listed below.
 
 
 
@@ -32,10 +32,26 @@ The Protobuf dataformat supports 2 options which are listed below.
 |=======================================================================
 | Name | Default | Java Type | Description
 | instanceClass |  | String | Name of class to use when unarmshalling
+| contentTypeFormat |  | String | Defines a content type format in which protobuf message will be serialized/deserialized from(to) the Java been. It can be native protobuf format or json fields representation. The default value is 'native'.
 | 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 (starting from *Camel 2.19*)
+
+It's possible to parse JSON message to convert it to the protobuf format and unparse it back using native util converter.
+To use this option, set contentTypeFormat value to 'json' or call protobuf with second parameter.
+If default instance is not specified, always use native protobuf format.
+The sample code shows below:
+
+[source,java]
+--------------------------------------------------------------------------------------------------
+from("direct:marshal")
+    .unmarshal()
+    .protobuf("org.apache.camel.dataformat.protobuf.generated.AddressBookProtos$Person", "json")
+    .to("mock:reverse");
+--------------------------------------------------------------------------------------------------
+
 ### Protobuf overview
 
 This quick overview of how to use Protobuf. For more detail see the
@@ -51,6 +67,7 @@ This is defined in a .proto file as so:
 
 [source,java]
 ------------------------------------------------------------
+syntax = "proto2";
 
 package org.apache.camel.component.protobuf;
 
@@ -84,10 +101,46 @@ message AddressBook {
 ### Generating Java classes
 
 The Protobuf SDK provides a compiler which will generate the Java
-classes for the format we defined in our .proto file. You can run the
-compiler for any additional supported languages you require.
-
-`protoc --java_out=. ./addressbook.proto`
+classes for the format we defined in our .proto file.
+If your operating system is supporting by https://www.xolstice.org/protobuf-maven-plugin[Protobuf Java code generator maven plugin],
+you can automate protobuf Java code generating by adding following configurations to your pom.xml:
+
+Insert operating system and CPU architecture detection extension inside **<build>** tag of the project pom.xml or set ${os.detected.classifier} parameter manually 
+[source,xml]
+-------------------------------------------------------------------------
+<extensions>
+  <extension>
+    <groupId>kr.motd.maven</groupId>
+    <artifactId>os-maven-plugin</artifactId>
+    <version>1.4.1.Final</version>
+  </extension>
+</extensions>
+-------------------------------------------------------------------------
+Insert gRPC and protobuf Java code generator plugin **<plugins>** tag of the project pom.xml
+[source,xml]
+-------------------------------------------------------------------------
+<plugin>
+  <groupId>org.xolstice.maven.plugins</groupId>
+  <artifactId>protobuf-maven-plugin</artifactId>
+  <version>0.5.0</version>
+  <extensions>true</extensions>
+  <executions>
+    <execution>
+      <goals>
+        <goal>test-compile</goal>
+        <goal>compile</goal>
+      </goals>
+      <configuration>
+        <protocArtifact>com.google.protobuf:protoc:${protobuf-version}:exe:${os.detected.classifier}</protocArtifact>
+      </configuration>
+    </execution>
+  </executions>
+</plugin>
+-------------------------------------------------------------------------
+
+You can also run the compiler for any additional supported languages you require manually.
+
+`protoc --java_out=. ./proto/addressbook.proto`
 
 This will generate a single Java class named AddressBookProtos which
 contains inner classes for Person and AddressBook. Builders are also
@@ -150,15 +203,14 @@ configuring the protobuf data type
 To use Protobuf in your camel routes you need to add the a dependency on
 *camel-protobuf* which implements this data format.
 
-If you use maven you could just add the following to your pom.xml,
-substituting the version number for the latest & greatest release (see
-link:download.html[the download page for the latest versions]).
-
-[source,java]
+[source,xml]
 -----------------------------------------
 <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-protobuf</artifactId>
-  <version>2.2.0</version>
+  <version>x.x.x</version>
+  <!-- use the same version as your Camel core version -->
 </dependency>
 -----------------------------------------
+### See Also
+* link:grpc.html[Camel gRPC component]

http://git-wip-us.apache.org/repos/asf/camel/blob/327dfcbd/components/camel-protobuf/src/main/java/org/apache/camel/dataformat/protobuf/ProtobufDataFormat.java
----------------------------------------------------------------------
diff --git a/components/camel-protobuf/src/main/java/org/apache/camel/dataformat/protobuf/ProtobufDataFormat.java b/components/camel-protobuf/src/main/java/org/apache/camel/dataformat/protobuf/ProtobufDataFormat.java
index dcd7f4c..b8cba4f 100755
--- a/components/camel-protobuf/src/main/java/org/apache/camel/dataformat/protobuf/ProtobufDataFormat.java
+++ b/components/camel-protobuf/src/main/java/org/apache/camel/dataformat/protobuf/ProtobufDataFormat.java
@@ -17,11 +17,13 @@
 package org.apache.camel.dataformat.protobuf;
 
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.lang.reflect.Method;
+
 import com.google.protobuf.Message;
 import com.google.protobuf.Message.Builder;
-
+import com.google.protobuf.util.JsonFormat;
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.CamelException;
@@ -31,13 +33,23 @@ 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;
 
 public class ProtobufDataFormat extends ServiceSupport implements DataFormat, DataFormatName, CamelContextAware {
 
+    public static final String CONTENT_TYPE_FORMAT_NATIVE = "native";
+    public static final String CONTENT_TYPE_FORMAT_JSON = "json";
+
+    private static final String CONTENT_TYPE_HEADER_NATIVE = "application/octet-stream";
+    private static final String CONTENT_TYPE_HEADER_JSON = "application/json";
+
     private CamelContext camelContext;
     private Message defaultInstance;
     private String instanceClassName;
-    
+    private boolean contentTypeHeader = false;
+    private String contentTypeFormat = CONTENT_TYPE_FORMAT_NATIVE;
+
     public ProtobufDataFormat() {
     }
 
@@ -45,6 +57,11 @@ public class ProtobufDataFormat extends ServiceSupport implements DataFormat, Da
         this.defaultInstance = defaultInstance;
     }
 
+    public ProtobufDataFormat(Message defaultInstance, String contentTypeFormat) {
+        this.defaultInstance = defaultInstance;
+        this.contentTypeFormat = contentTypeFormat;
+    }
+
     @Override
     public String getDataFormatName() {
         return "protobuf";
@@ -61,27 +78,61 @@ public class ProtobufDataFormat extends ServiceSupport implements DataFormat, Da
     public void setDefaultInstance(Message instance) {
         this.defaultInstance = instance;
     }
-    
+
     public void setDefaultInstance(Object instance) {
         if (instance instanceof Message) {
-            this.defaultInstance = (Message) instance;
+            this.defaultInstance = (Message)instance;
         } else {
             throw new IllegalArgumentException("The argument for setDefaultInstance should be subClass of com.google.protobuf.Message");
         }
     }
-    
+
     public void setInstanceClass(String className) throws Exception {
         ObjectHelper.notNull(className, "ProtobufDataFormat instaceClass");
         instanceClassName = className;
     }
-    
+
+    public void setContentTypeHeader(boolean contentTypeHeader) {
+        this.contentTypeHeader = contentTypeHeader;
+    }
+
+    public boolean isContentTypeHeader() {
+        return contentTypeHeader;
+    }
+
+    /*
+     * Defines a content type format in which protobuf message will be
+     * serialized/deserialized from(to) the Java been. It can be native protobuf
+     * format or json fields representation. The default value is 'native'.
+     */
+    public void setContentTypeFormat(String contentTypeFormat) {
+        StringHelper.notEmpty(contentTypeFormat, "ProtobufDataFormat contentTypeFormat");
+        this.contentTypeFormat = contentTypeFormat;
+    }
+
     /*
      * (non-Javadoc)
      * @see org.apache.camel.spi.DataFormat#marshal(org.apache.camel.Exchange,
      * java.lang.Object, java.io.OutputStream)
      */
     public void marshal(final Exchange exchange, final Object graph, final OutputStream outputStream) throws Exception {
-        ((Message)graph).writeTo(outputStream);
+        String contentTypeHeader = CONTENT_TYPE_HEADER_NATIVE;
+        if (contentTypeFormat.equals(CONTENT_TYPE_FORMAT_JSON)) {
+            IOUtils.write(JsonFormat.printer().print((Message)graph), outputStream, "UTF-8");
+            contentTypeHeader = CONTENT_TYPE_HEADER_JSON;
+        } else if (contentTypeFormat.equals(CONTENT_TYPE_FORMAT_NATIVE)) {
+            ((Message)graph).writeTo(outputStream);
+        } else {
+            throw new CamelException("Invalid protobuf content type format: " + contentTypeFormat);
+        }
+
+        if (isContentTypeHeader()) {
+            if (exchange.hasOut()) {
+                exchange.getOut().setHeader(Exchange.CONTENT_TYPE, contentTypeHeader);
+            } else {
+                exchange.getIn().setHeader(Exchange.CONTENT_TYPE, contentTypeHeader);
+            }
+        }
     }
 
     /*
@@ -91,8 +142,16 @@ public class ProtobufDataFormat extends ServiceSupport implements DataFormat, Da
      */
     public Object unmarshal(final Exchange exchange, final InputStream inputStream) throws Exception {
         ObjectHelper.notNull(defaultInstance, "defaultInstance or instanceClassName must be set", this);
+        Builder builder = defaultInstance.newBuilderForType();
+
+        if (contentTypeFormat.equals(CONTENT_TYPE_FORMAT_JSON)) {
+            JsonFormat.parser().ignoringUnknownFields().merge(new InputStreamReader(inputStream), builder);
+        } else if (contentTypeFormat.equals(CONTENT_TYPE_FORMAT_NATIVE)) {
+            builder = defaultInstance.newBuilderForType().mergeFrom(inputStream);
+        } else {
+            throw new CamelException("Invalid protobuf content type format: " + contentTypeFormat);
+        }
 
-        Builder builder = defaultInstance.newBuilderForType().mergeFrom(inputStream);
         if (!builder.isInitialized()) {
             // TODO which exception should be thrown here?
             throw new InvalidPayloadException(exchange, defaultInstance.getClass());
@@ -106,14 +165,13 @@ public class ProtobufDataFormat extends ServiceSupport implements DataFormat, Da
         if (Message.class.isAssignableFrom(instanceClass)) {
             try {
                 Method method = instanceClass.getMethod("getDefaultInstance");
-                return (Message) method.invoke(null);
+                return (Message)method.invoke(null);
             } catch (final Exception ex) {
-                throw new CamelException("Can't set the defaultInstance of ProtobufferDataFormat with "
-                        + className + ", caused by " + ex);
+                throw new CamelException("Can't set the defaultInstance of ProtobufferDataFormat with " + className + ", caused by " + ex);
             }
         } else {
-            throw new CamelException("Can't set the defaultInstance of ProtobufferDataFormat with "
-                    + className + ", as the class is not a subClass of com.google.protobuf.Message");
+            throw new CamelException("Can't set the defaultInstance of ProtobufferDataFormat with " + className
+                                     + ", as the class is not a subClass of com.google.protobuf.Message");
         }
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/327dfcbd/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalJsonTest.java
----------------------------------------------------------------------
diff --git a/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalJsonTest.java b/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalJsonTest.java
new file mode 100644
index 0000000..b1e789e
--- /dev/null
+++ b/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalJsonTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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.protobuf;
+
+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.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class ProtobufMarshalAndUnmarshalJsonTest extends CamelTestSupport {
+    
+    private final static String PERSON_TEST_NAME = "Martin";
+    private final static int PERSON_TEST_ID = 1234;
+    private final static String PERSON_TEST_JSON = "{\"name\": \"Martin\",\"id\": 1234}";
+    
+    @Test
+    public void testMarshalAndUnmarshal() throws Exception {
+        marshalAndUnmarshal("direct:in", "direct:back");
+    }
+    
+    @Test
+    public void testMarshalAndUnmarshalWithDSL() throws Exception {
+        marshalAndUnmarshal("direct:marshal", "direct:unmarshalA");
+    }
+    
+    private void marshalAndUnmarshal(String inURI, String outURI) throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Person.class);
+        
+        Object marshalled = template.requestBody(inURI, PERSON_TEST_JSON);
+
+        template.sendBody(outURI, marshalled);
+
+        mock.assertIsSatisfied();
+
+        Person output = mock.getReceivedExchanges().get(0).getIn().getBody(Person.class);
+        assertEquals(PERSON_TEST_NAME, output.getName());
+        assertEquals(PERSON_TEST_ID, output.getId());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                ProtobufDataFormat format = new ProtobufDataFormat(Person.getDefaultInstance(), ProtobufDataFormat.CONTENT_TYPE_FORMAT_JSON);
+
+                from("direct:in").unmarshal(format).to("mock:reverse");
+                from("direct:back").marshal(format);
+
+                from("direct:marshal").unmarshal().protobuf("org.apache.camel.dataformat.protobuf.generated.AddressBookProtos$Person", "json").to("mock:reverse");
+                from("direct:unmarshalA").marshal().protobuf();
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/327dfcbd/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 5a40f44..9ec978e 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
@@ -18,7 +18,7 @@ package org.apache.camel.dataformat.protobuf;
 
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
-public class ProtobufMarshalAndUnmarshalSpringTest extends ProtobufMarshalAndUnmarshallTest {
+public class ProtobufMarshalAndUnmarshalSpringTest extends ProtobufMarshalAndUnmarshalTest {
 
     protected ClassPathXmlApplicationContext createApplicationContext() {
         return new ClassPathXmlApplicationContext("org/apache/camel/dataformat/protobuf/springDataFormat.xml");

http://git-wip-us.apache.org/repos/asf/camel/blob/327dfcbd/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalTest.java
----------------------------------------------------------------------
diff --git a/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalTest.java b/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalTest.java
new file mode 100644
index 0000000..b407dac
--- /dev/null
+++ b/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshalTest.java
@@ -0,0 +1,97 @@
+/**
+ * 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.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.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class ProtobufMarshalAndUnmarshalTest extends CamelTestSupport {
+
+    @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());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                ProtobufDataFormat format = new ProtobufDataFormat(Person.getDefaultInstance());
+
+                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://git-wip-us.apache.org/repos/asf/camel/blob/327dfcbd/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshallTest.java
----------------------------------------------------------------------
diff --git a/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshallTest.java b/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshallTest.java
deleted file mode 100755
index 302f74e..0000000
--- a/components/camel-protobuf/src/test/java/org/apache/camel/dataformat/protobuf/ProtobufMarshalAndUnmarshallTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.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.junit4.CamelTestSupport;
-import org.junit.Test;
-
-public class ProtobufMarshalAndUnmarshallTest extends CamelTestSupport {
-
-    @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 {
-        org.apache.camel.dataformat.protobuf.generated.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());
-    }
-
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
-            @Override
-            public void configure() throws Exception {
-                ProtobufDataFormat format = new ProtobufDataFormat(Person.getDefaultInstance());
-
-                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");
-            }
-        };
-    }
-
-}