Avro inter-process communication components providing RPC framework with multiple transport mechanisms and protocol implementations
npx @tessl/cli install tessl/maven-org-apache-avro--avro-ipc@1.12.0Apache Avro IPC provides a comprehensive RPC (Remote Procedure Call) framework for Java applications using Avro's data serialization format. It enables type-safe inter-process communication with support for multiple transport mechanisms, protocol implementations, and authentication methods.
org.apache.avro:avro-ipc:1.12.0org.apache.avro:avro-ipcimport org.apache.avro.ipc.*; // Core IPC classes
import org.apache.avro.ipc.generic.*; // Generic protocol support
import org.apache.avro.ipc.specific.*; // Generated interface support
import org.apache.avro.ipc.reflect.*; // Reflection-based protocol supportCommon transport imports:
import org.apache.avro.ipc.HttpTransceiver;
import org.apache.avro.ipc.SaslSocketTransceiver;
import org.apache.avro.ipc.ResponderServlet;
import org.apache.avro.ipc.SaslSocketServer;import org.apache.avro.Protocol;
import org.apache.avro.ipc.HttpTransceiver;
import org.apache.avro.ipc.ResponderServlet;
import org.apache.avro.ipc.specific.SpecificRequestor;
import org.apache.avro.ipc.specific.SpecificResponder;
import java.net.URL;
// Client side - using generated interface
MyService client = SpecificRequestor.getClient(MyService.class,
new HttpTransceiver(new URL("http://localhost:8080/rpc")));
// Server side - servlet deployment
MyServiceImpl implementation = new MyServiceImpl();
SpecificResponder responder = new SpecificResponder(MyService.class, implementation);
ResponderServlet servlet = new ResponderServlet(responder);
// Deploy servlet to web containerimport org.apache.avro.ipc.SaslSocketServer;
import org.apache.avro.ipc.SaslSocketTransceiver;
import java.net.InetSocketAddress;
// Server with SASL authentication
SpecificResponder responder = new SpecificResponder(MyService.class, implementation);
SaslSocketServer server = new SaslSocketServer(responder,
new InetSocketAddress(65001));
server.start();
// Client with SASL authentication
SaslSocketTransceiver transceiver = new SaslSocketTransceiver(
new InetSocketAddress("localhost", 65001));
MyService client = SpecificRequestor.getClient(MyService.class, transceiver);The Avro IPC framework follows a layered architecture:
Key components:
Foundation classes for client-server RPC communication including base requestor/responder abstractions, transport interfaces, and server lifecycle management.
// Client-side RPC base class
public abstract class Requestor {
protected Requestor(Protocol local, Transceiver transceiver) throws IOException;
public Protocol getLocal();
public Transceiver getTransceiver();
public Protocol getRemote() throws IOException;
public void addRPCPlugin(RPCPlugin plugin);
public Object request(String messageName, Object request) throws Exception;
public <T> void request(String messageName, Object request, Callback<T> callback) throws Exception;
// Abstract methods for protocol-specific implementations
public abstract void writeRequest(Schema schema, Object request, Encoder out) throws IOException;
public abstract Object readResponse(Schema writer, Schema reader, Decoder in) throws IOException;
public abstract Exception readError(Schema writer, Schema reader, Decoder in) throws IOException;
}
// Server-side RPC base class
public abstract class Responder {
protected Responder(Protocol local);
public static Protocol getRemote();
public Protocol getLocal();
public void addRPCPlugin(RPCPlugin plugin);
public List<ByteBuffer> respond(List<ByteBuffer> buffers) throws IOException;
public List<ByteBuffer> respond(List<ByteBuffer> buffers, Transceiver connection) throws IOException;
public abstract Object respond(Message message, Object request) throws Exception;
// Abstract methods for protocol-specific implementations
public abstract Object readRequest(Schema actual, Schema expected, Decoder in) throws IOException;
public abstract void writeResponse(Schema schema, Object response, Encoder out) throws IOException;
public abstract void writeError(Schema schema, Object error, Encoder out) throws IOException;
}
// Transport abstraction
public abstract class Transceiver implements Closeable {
public abstract String getRemoteName() throws IOException;
public boolean isConnected();
public void setRemote(Protocol protocol);
public Protocol getRemote();
public void lockChannel();
public void unlockChannel();
public List<ByteBuffer> transceive(List<ByteBuffer> request) throws IOException;
public void transceive(List<ByteBuffer> request, Callback<List<ByteBuffer>> callback) throws IOException;
// Abstract I/O methods
public abstract List<ByteBuffer> readBuffers() throws IOException;
public abstract void writeBuffers(List<ByteBuffer> buffers) throws IOException;
public void close() throws IOException;
}
// Server interface
public interface Server {
int getPort();
void start();
void close();
void join() throws InterruptedException;
}Multiple transport implementations for different networking requirements including HTTP, socket-based, datagram, and in-process communication options.
// HTTP transport
public class HttpTransceiver extends Transceiver {
public HttpTransceiver(URL url) throws IOException;
public HttpTransceiver(URL url, Proxy proxy) throws IOException;
public void setTimeout(int timeout);
}
// SASL-authenticated socket transport
public class SaslSocketTransceiver extends Transceiver {
public SaslSocketTransceiver(SocketAddress address) throws IOException;
public SaslSocketTransceiver(SocketAddress address, SaslClient saslClient) throws IOException;
public SaslSocketTransceiver(SocketChannel channel, SaslServer saslServer) throws IOException;
}
// Socket servers
public class SaslSocketServer extends SocketServer {
public SaslSocketServer(Responder responder, SocketAddress addr) throws IOException;
public SaslSocketServer(Responder responder, SocketAddress addr, String mechanism,
String protocol, String serverName, Map<String, ?> props,
CallbackHandler cbh) throws IOException;
}
// HTTP servlet
public class ResponderServlet extends HttpServlet {
public ResponderServlet(Responder responder);
}Three protocol implementations supporting different Java object models: generic (no code generation), specific (generated classes), and reflect (existing interfaces).
// Generic protocol - no code generation required
public class GenericRequestor extends Requestor {
public GenericRequestor(Protocol protocol, Transceiver transceiver) throws IOException;
public GenericRequestor(Protocol protocol, Transceiver transceiver, GenericData data) throws IOException;
public GenericData getGenericData();
}
public abstract class GenericResponder extends Responder {
public GenericResponder(Protocol local);
public GenericResponder(Protocol local, GenericData data);
public GenericData getGenericData();
}
// Specific protocol - generated Java classes
public class SpecificRequestor extends Requestor implements InvocationHandler {
public SpecificRequestor(Class<?> iface, Transceiver transceiver) throws IOException;
public SpecificRequestor(Class<?> iface, Transceiver transceiver, SpecificData data) throws IOException;
public SpecificRequestor(Protocol protocol, Transceiver transceiver, SpecificData data) throws IOException;
public static <T> T getClient(Class<T> iface, Transceiver transceiver) throws IOException;
public static <T> T getClient(Class<T> iface, Transceiver transceiver, SpecificData data) throws IOException;
public static <T> T getClient(Class<T> iface, SpecificRequestor requestor) throws IOException;
public SpecificData getSpecificData();
}
public class SpecificResponder extends GenericResponder {
public SpecificResponder(Class iface, Object impl);
public SpecificData getSpecificData();
}
// Reflect protocol - existing Java interfaces
public class ReflectRequestor extends SpecificRequestor {
public ReflectRequestor(Class<?> iface, Transceiver transceiver) throws IOException;
public static <T> T getClient(Class<T> iface, Transceiver transceiver) throws IOException;
public ReflectData getReflectData();
}
public class ReflectResponder extends SpecificResponder {
public ReflectResponder(Class iface, Object impl);
public ReflectData getReflectData();
}Callback-based and Future-based patterns for non-blocking RPC operations with comprehensive error handling support.
// Callback interface
public interface Callback<T> {
void handleResult(T result);
void handleError(Throwable error);
}
// Future implementation
public class CallFuture<T> implements Future<T>, Callback<T> {
public CallFuture();
public CallFuture(Callback<T> chainedCallback);
public T getResult() throws Exception;
public Throwable getError();
public void await() throws InterruptedException;
public void await(long timeout, TimeUnit unit) throws InterruptedException;
}Extensible instrumentation framework for RPC metadata manipulation, performance monitoring, and custom cross-cutting concerns.
// Plugin base class
public class RPCPlugin {
public void clientStartConnect(RPCContext context);
public void serverConnecting(RPCContext context);
public void clientFinishConnect(RPCContext context);
public void clientSendRequest(RPCContext context);
public void serverReceiveRequest(RPCContext context);
public void serverSendResponse(RPCContext context);
public void clientReceiveResponse(RPCContext context);
}
// RPC context
public class RPCContext {
public Map<String, ByteBuffer> requestHandshakeMeta();
public Map<String, ByteBuffer> responseHandshakeMeta();
public Map<String, ByteBuffer> requestCallMeta();
public Map<String, ByteBuffer> responseCallMeta();
public Message getMessage();
public Object response();
public Exception error();
public boolean isError();
}Built-in performance monitoring with histograms, latency tracking, payload size analysis, and web-based statistics viewer.
// Statistics collection plugin
public class StatsPlugin extends RPCPlugin {
public StatsPlugin();
public Date startupTime;
public static final Segmenter<String, Float> LATENCY_SEGMENTER;
public static final Segmenter<String, Integer> PAYLOAD_SEGMENTER;
public static float nanosToMillis(long elapsedNanos);
}
// Web-based statistics viewer
public class StatsServlet extends HttpServlet {
public StatsServlet(StatsPlugin statsPlugin);
public void writeStats(Writer w) throws IOException;
}
// Histogram utilities
public class Histogram<B,T> {
public Histogram(Segmenter<B,T> segmenter);
public void add(T value);
public int[] getHistogram();
public int getCount();
}// Factory methods for URI-based creation
public class Ipc {
public static Transceiver createTransceiver(URI uri) throws IOException;
public static Server createServer(Responder responder, URI uri) throws IOException;
}All types are provided by the core Avro library (org.apache.avro:avro) and are automatically available when using the IPC library.
// Core Avro types used throughout IPC
import org.apache.avro.Protocol;
import org.apache.avro.Protocol.Message;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import org.apache.avro.specific.SpecificData;
import org.apache.avro.reflect.ReflectData;
// Standard Java types
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.net.URI;
import java.net.URL;
import java.net.SocketAddress;