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>
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 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.
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.
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>