We will start with Apache Avro Protocols and will then define schema and generate RPC interfaces from it and end with example code.
Avro protocol describes RPC interfaces. They are defined as JSON similar to Schema.
A protocol has following attributes:
- protocol: a string, defining name of the protocol.
- namespace: an optional that qualifies the name.
- types: an optional list of definitions of named types (like record, enum, fixed and errors).
- messages: an optional JSON object whose keys are method names of protocol and whose values are objects whose attributes are described below. No two messages may have the same name.
Further,
Message
have following attributes:request: a list of named, typed parameter schemas. response: a response schema. error: an optional union of declared error schemas.
Let's define a simple protocol to exchange email message between client and server.
{
"namespace": "cc.gaurav.blog.avro",
"protocol": "EmailSender",
"types": [
{
"name": "EmailMessage",
"type": "record",
"fields": [
{
"name": "to",
"type": "string"
},
{
"name": "from",
"type": "string"
},
{
"name": "body",
"type": "string"
}
]
}
],
"messages": {
"send": {
"request": [
{
"name": "email",
"type": "EmailMessage"
}
],
"response": "string"
}
}
}
Here, The protocol defines an interface EmailSender
which takes an EmailMessage
as request and return string response. We have created a mock implementation of EmailSender
.
public class EmailSenderImpl implements EmailSender {
@Override
public CharSequence send(EmailMessage email) throws AvroRemoteException {
return email.toString();
}
}
Now, we create a server, Apache Avro uses Netty for the same.
NettyServer server = new NettyServer(new SpecificResponder(EmailSender.class, new EmailSenderImpl()), new InetSocketAddress(65333));
Now, we create a client which sends request to the server.
NettyTransceiver client = new NettyTransceiver(new InetSocketAddress(65333));
// client code - attach to the server and send a message
EmailSender proxy = SpecificRequestor.getClient(EmailSender.class, client);
logger.info("Client built, got proxy");
// fill in the Message record and send it
EmailMessage message = new EmailMessage();
message.setTo(new Utf8(args[0]));
message.setFrom(new Utf8(args[1]));
message.setBody(new Utf8(args[2]));
logger.info("Calling proxy.send with message: {} ", message.toString());
logger.info("Result: {}", proxy.send(message));
// cleanup
client.close();
This is how we can use Apache Avro as RPC framework. I hope you found this post useful. You can download the full example code from Github.