Date: Tue, 19 Mar 2024 04:53:10 +0000 (UTC) Message-ID: <1641381755.54315.1710823990095@cwiki-he-fi.apache.org> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_54314_1730755565.1710823990095" ------=_Part_54314_1730755565.1710823990095 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
Available as of Camel 2.10
This component provides a dataformat for avro, which allows serializatio= n and deserialization of messages using Apache Avro's binary dataformat. Mo= reover, it provides support for Apache Avro's rpc, by providing producers a= nd consumers endpoint for using avro over netty or http.
Maven users will need to add the following dependency to their pom=
.xml
for this component:
<dependenc= y> <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 allows you to define message types and a protocol using a json like= format and then generate java code for the specified types and messages. A= n example of how a schema looks like is below.
{"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", "typ= e": "Value"} ], "response": "null" }, "get": { "request": [{"name": "key", "type": "Key"}], "response": "Value" } } }
You can easily generate classes from a schema, using maven, ant etc. Mor= e details can be found at the Apache Avro documentation.=
However, it doesn't enforce a schema first approach and you can create s= chema for your existing classes. Since 2.12 you can use ex= isting protocol interfaces to make RCP calls. You should use interface for = the protocol itself and POJO beans or primitive/String classes for paramete= r and result types. Here is an example of the class that corresponds to sch= ema above:
package org.a= pache.camel.avro.reflection; public interface KeyValueProtocol { void put(String key, Value value); Value get(String key); } class Value { private String value; public String getValue() { return value; } public void setValue(String value) { this.value =3D value; } }
Note: Existing classes can be used only for RPC (see below), not in = data format.
Using the avro data format is as easy as specifying that the class that = you want to marshal or unmarshal in your route.
<camel= Context id=3D"camel" xmlns=3D"http://camel.apache.org/schema/spring"> <route> <from uri=3D"direct:in"/> <marshal> <avro instanceClass=3D"org.apache.camel.dataformat.avro.= Message"/> </marshal> <to uri=3D"log:out"/> </route> </camelContext>
An alternative can be to specify the dataformat inside the context and r= eference it from your route.
<camel= Context id=3D"camel" xmlns=3D"http://camel.apache.org/schema/spring"> <dataFormats> <avro id=3D"avro" instanceClass=3D"org.apache.camel.dataform= at.avro.Message"/> </dataFormats> <route> <from uri=3D"direct:in"/> <marshal ref=3D"avro"/> <to uri=3D"log:out"/> </route> </camelContext>
In the same manner you can umarshal using the avro data format.
As mentioned above Avro also provides RPC support over multiple transpor= ts such as http and netty. Camel provides consumers and producers for these= two transports.
avro:[transpo= rt]:[host]:[port][?options]
The supported transport values are currently http or netty.
Since 2.12 you can specify message name right in the UR= I:
avro:[transpo= rt]:[host]:[port][/messageName][?options]
For consumers this allows you to have multiple routes attached to the sa= me socket. Dispatching to correct route will be done by the avro component = automatically. Route with no messageName specified (if any) will be used as= default.
When using camel producers for avro ipc, the "in" message body needs to = contain the parameters of the operation specified in the avro protocol. The= response will be added in the body of the "out" message.
In a similar manner when using camel avro consumers for avro ipc, the re= quests parameters will be placed inside the "in" message body of the create= d exchange and once the exchange is processed the body of the "out" message= will be send as a response.
Note: By default consumer parameters are wrapped into a=
rray. If you've got only one parameter, since 2.12 you can=
use singleParameter
URI option to receive it direcly in the "=
in" message body without array wrapping.
Name |
Version |
Description |
---|---|---|
|
|
The class name of the avro protocol. |
|
2.12 |
If true, consumer parameter won't be wrapped = into array. Will fail if protocol specifies more then 1 parameter for the m= essage |
|
|
Avro procol object. Can be used instead of |
|
2.12 |
If protocol object provided is reflection pro=
tocol. Should be used only with |
Name |
Description |
---|---|
|
The name of the message to send. In consumer = overrides message name from URI (if any) |
An example of using camel avro producers via http:
<r= oute> <from uri=3D"direct:start"/> <to uri=3D"avro:http:localhost:{{avroport}}?protocolClassNam= e=3Dorg.apache.camel.avro.generated.KeyValueProtocol"/> <to uri=3D"log:avro"/> </route>
In the example above you need to fill CamelAvroMessageName
=
header. Since 2.12 you can use following syntax to call co=
nstant messages:
= <route> <from uri=3D"direct:start"/>= ; <to uri=3D"avro:http:localhost= :{{avroport}}/put?protocolClassName=3Dorg.apache.camel.avro.generated.KeyVa= lueProtocol"/> <to uri=3D"log:avro"/> </route>
An example of consuming messages using camel avro consumers via netty:= p>
<r= oute> <from uri=3D"avro:netty:localhost:{{avroport}}?protocolClass= Name=3Dorg.apache.camel.avro.generated.KeyValueProtocol"/> <choice> <when> <el>${in.headers.CamelAvroMessageName =3D=3D 'put= '}</el> <process ref=3D"putProcessor"/> </when> <when> <el>${in.headers.CamelAvroMessageName =3D=3D 'get= '}</el> <process ref=3D"getProcessor"/> </when> </choice> </route>
Since 2.12 you can set up two distinct routes to perfor= m the same task:
<r= oute> <from uri=3D"avro:netty:localhost:{{avroport}}/put?protocolC= lassName=3Dorg.apache.camel.avro.generated.KeyValueProtocol"> <process ref=3D"putProcessor"/> </route> <route> <from uri=3D"avro:netty:localhost:{{avroport}}/get?protocolC= lassName=3Dorg.apache.camel.avro.generated.KeyValueProtocol&singleParam= eter=3Dtrue"/> <process ref=3D"getProcessor"/> </route>
In the example above, get takes only one parameter, so singleParam=
eter
is used and getProcessor
will receive Value class =
directly in body, while putProcessor
will receive an array of =
size 2 with String key and Value value filled as array contents.