AVRO

Avro Component

Available as of Apache Camel 2.10

The avro: component provides a data format for avro, which enables serialization and deserialization of messages using Apache Avro's binary data format. Moreover, it provides support for Apache Avro's rpc, by providing producer and consumer endpoints for use over netty or http.

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-avro</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>

Overview

Avro enables you to use a json-like format to define message types and a protocol, and then to generate java code for the specified types and messages. It does not, however, enforce a schema-first approach, so you can create schema for your existing classes. An example schema might look like this:

{"namespace": "org.apache.camel.avro.generated",
 "protocol": "KeyValueProtocol",
            
  "types": [
      {"name": "Key", "type": "record",
       "fields": [
           {"name": "key", "type": "string"}
       ]
                 
      },
      {"name": "Value", "type": "record",
       "fields": [
           {"name": "value", "type": "string"}
       ]
      }
   ],
   "messages": {
       "put": {
           "request": [{"name": "key", "type": "Key"}, {"name": "value", "type": "Value"}],
           "response": "null"
       },
       "get": {
           "request": [{"name": "key", "type": "Key"}],
           "response": "Value"
       }
   }
 }

You can easily generate classes from a schema, using Maven, ant, and so on. See the Apache Avro documentation for more details.

Using the Avro Data Format

Using the avro data format is as easy as specifying in your camel route the class that you want to marshal or unmarshal, like this:

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
   <route>
       <from uri="direct:in"/>
       <marshal>
           <avro instanceClass="org.apache.camel.dataformat.avro.Message"/>
       </marshal>
       <to uri="log:out"/>
   </route>
</camelContext>
        

An alternative is to specify the data format inside the context and reference it from your route, like this:

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
   <dataFormats>
       <avro id="avro" instanceClass="org.apache.camel.dataformat.avro.Message"/>
   </dataFormats>
   <route>
       <from uri="direct:in"/>
       <marshal ref="avro"/>
       <to uri="log:out"/>
   </route>
</camelContext>
        

You can use the avro data format in the same way to unmarshal data.

Using Avro RPC in Camel

Avro also provides RCP support over multiple transports, and Camel provides producers and consumers for these transports.

avro:[transport]:[host]:[port]

Currently, the supported transport values are http and netty.

When using camel producers for inter-process communication (ipc), the in message body must contain the arguments for the operation specified in the avro protocol. The response is added to the body of the out message.

Likewise, when using camel consumers for avro ipc, the request arguments are added to the in message body of the created exchange, and, once the exchange is processed, the body of the out message is sent as a response.

Avro RPC options

NameDescription
protocolClassName The class name of the avro protocol.

Avro RPC headers

NameDescription
CamelAvroMessageName The name of the message to send.

Avro RPC headers

You can produce messages using Camel Avro producers via http, like this:

<route>
    <from uri="direct:start"/>
    <to uri="avro:http:localhost:{{avroport}}?protocolClassName=org.apache.camel.avro.generated.KeyValueProtocol"/>
    <to uri="log:avro"/>
</route>
        

You can use consume messages using Camel Avro consumers via netty, like this:

<route>
    <from uri="avro:netty:localhost:{{avroport}}?protocolClassName=org.apache.camel.avro.generated.KeyValueProtocol"/>
    <choice>
       <when>
          <e1>${in.headers.CamelAvroMessageName == 'put'}</e1>         
          <process ref="putProcessor" />
       </when>
       <when>
          <e1>${in.headers.CamelAvroMessageName == 'get'}</e1>         
          <process ref="getProcessor" />
       </when>
    </choice>
</route>