diff --git a/core/src/main/java/io/grpc/Call.java b/core/src/main/java/io/grpc/Call.java
index e3aaa66f50..7e53c3a86e 100644
--- a/core/src/main/java/io/grpc/Call.java
+++ b/core/src/main/java/io/grpc/Call.java
@@ -31,30 +31,31 @@
package io.grpc;
-
/**
- * Low-level methods for communicating with a remote server during a single RPC. Unlike normal RPCs,
- * calls may stream any number of requests and responses, although a single request and single
- * response is most common. This API is generally intended for use by stubs, but advanced
- * applications may have need for it.
+ * An instance of a call to to a remote method. A call will send zero or more
+ * request messages to the server and receive zero or more response messages back.
*
- *
{@link #start} is required to be the first of any methods called.
+ *
Instances are created
+ * by a {@link Channel} and used by stubs to invoke their remote behavior.
*
- *
Any headers must be sent before any payloads, which must be sent before half closing.
+ *
More advanced usages may consume this interface directly as opposed to using a stub. Common
+ * reasons for doing so would be the need to interact with flow-control or when acting as a generic
+ * proxy for arbitrary operations.
+ *
+ *
{@link #start} must be called prior to calling any other methods.
*
*
No generic method for determining message receipt or providing acknowledgement is provided.
* Applications are expected to utilize normal payload messages for such signals, as a response
- * natually acknowledges its request.
+ * naturally acknowledges its request.
*
*
Methods are guaranteed to be non-blocking. Implementations are not required to be thread-safe.
+ *
+ * @param type of message sent one or more times to the server.
+ * @param type of message received one or more times from the server.
*/
public abstract class Call {
/**
- * Callbacks for consuming incoming RPC messages.
- *
- * Response headers are guaranteed to arrive before any payloads, which are guaranteed
- * to arrive before close. An additional block of headers called 'trailers' can be delivered with
- * close.
+ * Callbacks for receiving metadata, response messages and completion status from the server.
*
*
Implementations are free to block for extended periods of time. Implementations are not
* required to be thread-safe.
@@ -65,20 +66,27 @@ public abstract class Call {
* The response headers have been received. Headers always precede payloads.
* This method is always called, if no headers were received then an empty {@link Metadata}
* is passed.
+ *
+ * @param headers containing metadata sent by the server at the start of the response.
*/
public abstract void onHeaders(Metadata.Headers headers);
/**
- * A response payload has been received. For streaming calls, there may be zero payload
- * messages.
+ * A response payload has been received. May be called zero or more times depending on whether
+ * the call response is empty, a single message or a stream of messages.
+ *
+ * @param payload returned by the server
*/
public abstract void onPayload(T payload);
/**
* The Call has been closed. No further sending or receiving can occur. If {@code status} is
- * not equal to {@link Status#OK}, then the call failed. An additional block of headers may be
- * received at the end of the call from the server. An empty {@link Metadata} object is passed
- * if no trailers are received.
+ * not equal to {@link Status#OK}, then the call failed. An additional block of trailer metadata
+ * may be received at the end of the call from the server. An empty {@link Metadata} object is
+ * passed if no trailers are received.
+ *
+ * @param status the result of the remote call.
+ * @param trailers metadata provided at call completion.
*/
public abstract void onClose(Status status, Metadata.Trailers trailers);
}
@@ -87,10 +95,9 @@ public abstract class Call {
* Start a call, using {@code responseListener} for processing response messages.
*
* @param responseListener receives response messages
- * @param headers which can contain extra information like authentication.
+ * @param headers which can contain extra call metadata, e.g. authentication credentials.
* @throws IllegalStateException if call is already started
*/
- // TODO(louiscryan): Might be better to put into Channel#newCall, might reduce decoration burden
public abstract void start(Listener responseListener, Metadata.Headers headers);
/**
@@ -117,17 +124,17 @@ public abstract class Call {
public abstract void cancel();
/**
- * Close call for message sending. Incoming messages are unaffected.
+ * Close the call for request message sending. Incoming response messages are unaffected.
*
* @throws IllegalStateException if call is already {@code halfClose()}d or {@link #cancel}ed
*/
public abstract void halfClose();
/**
- * Send a payload message. Payload messages are the primary form of communication associated with
- * RPCs. Multiple payload messages may exist for streaming calls.
+ * Send a request message to the server. May be called zero or more times depending on how many
+ * messages the server is willing to accept for the operation.
*
- * @param payload message
+ * @param payload message to be sent to the server.
* @throws IllegalStateException if call is {@link #halfClose}d or explicitly {@link #cancel}ed
*/
public abstract void sendPayload(RequestT payload);
diff --git a/core/src/main/java/io/grpc/Channel.java b/core/src/main/java/io/grpc/Channel.java
index 51fb49a96b..dcfc7812a4 100644
--- a/core/src/main/java/io/grpc/Channel.java
+++ b/core/src/main/java/io/grpc/Channel.java
@@ -34,16 +34,29 @@ package io.grpc;
import javax.annotation.concurrent.ThreadSafe;
/**
- * An abstraction layer between stubs and the transport details for use with outgoing calls.
- * Channels are responsible for call initiation and tracking. Channels can be decorated to provide
- * cross-cutting behaviors across all operations in a stub.
+ * A Channel provides an abstraction over the transport layer that is designed to be consumed
+ * by stub implementations. Channel and its associated types {@link Call} and
+ * {@link Call.Listener} exchange parsed request and response objects whereas the
+ * transport layer only works with serialized data.
+ *
+ * Applications can add common cross-cutting behaviors to stubs by decorating Channel
+ * implementations using {@link ClientInterceptor}. It is expected that most application
+ * code will not use this interface directly but rather work with stubs that have been bound to a
+ * Channel that was decorated during application initialization,
*/
@ThreadSafe
public interface Channel {
/**
- * Create a call to the given service method.
+ * Create a {@link Call} to the remote operation specified by the given
+ * {@link MethodDescriptor}. The returned {@link Call} does not trigger any remote
+ * behavior until {@link Call#start(Call.Listener, Metadata.Headers)} is
+ * invoked.
+ *
+ * @param methodDescriptor describes the name and parameter types of the operation to call.
+ * @return a {@link Call} bound to the specified method.
+ *
*/
- // TODO(ejona86): perform start() as part of new Call creation?
- public Call newCall(MethodDescriptor method);
+ public Call newCall(
+ MethodDescriptor methodDescriptor);
}
diff --git a/core/src/main/java/io/grpc/ClientInterceptor.java b/core/src/main/java/io/grpc/ClientInterceptor.java
index 1a44a51ab5..a100b47c77 100644
--- a/core/src/main/java/io/grpc/ClientInterceptor.java
+++ b/core/src/main/java/io/grpc/ClientInterceptor.java
@@ -34,19 +34,30 @@ package io.grpc;
import javax.annotation.concurrent.ThreadSafe;
/**
- * Interface for intercepting outgoing RPCs before it reaches the channel.
+ * Interface for intercepting outgoing calls before they are dispatched by a {@link Channel}.
+ *
+ * Implementers use this mechanism to add cross-cutting behavior to {@link Channel} and
+ * stub implementations. Common examples of such behavior include:
+ *
+ * - Adding credentials to header metadata
+ * - Logging and monitoring call behavior
+ * - Request and response rewriting
+ *
*/
@ThreadSafe
public interface ClientInterceptor {
/**
- * Intercept a new call. General semantics of {@link Channel#newCall} apply. {@code next} may only
- * be called once. Returned {@link Call} must not be null.
+ * Intercept {@link Call} creation by the {@code next} {@link Channel}.
+ *
+ * Many variations of interception are possible. Complex implementations may return a wrapper
+ * around the result of {@code next.newCall()}, whereas a simpler implementation may just modify
+ * the header metadata prior to returning the result of {@code next.newCall()}.
*
- * If the implementation throws an exception, the RPC will not be started.
- *
- * @param method the method to be called
- * @param next next processor in the interceptor chain
- * @return the call object for the new RPC
+ * @param method the remote method to be called.
+ * @param next the channel which is being intercepted.
+ * @return the call object for the remote operation, never {@code null}.
*/
- Call interceptCall(MethodDescriptor method, Channel next);
+ Call interceptCall(
+ MethodDescriptor method,
+ Channel next);
}
diff --git a/core/src/main/java/io/grpc/ClientInterceptors.java b/core/src/main/java/io/grpc/ClientInterceptors.java
index 787c464de4..22e163bc34 100644
--- a/core/src/main/java/io/grpc/ClientInterceptors.java
+++ b/core/src/main/java/io/grpc/ClientInterceptors.java
@@ -39,7 +39,7 @@ import java.util.Iterator;
import java.util.List;
/**
- * Utility class for {@link ClientInterceptor}s
+ * Utility methods for working with {@link ClientInterceptor}s
*/
public class ClientInterceptors {
@@ -47,16 +47,24 @@ public class ClientInterceptors {
private ClientInterceptors() {}
/**
- * Create a new {@code Channel} that will call {@code interceptors} before starting an RPC on the
+ * Create a new {@link Channel} that will call {@code interceptors} before starting a call on the
* given channel.
+ *
+ * @param channel the underlying channel to intercept.
+ * @param interceptors array of interceptors to bind to {@code channel}.
+ * @return a new channel instance with the interceptors applied.
*/
public static Channel intercept(Channel channel, ClientInterceptor... interceptors) {
return intercept(channel, Arrays.asList(interceptors));
}
/**
- * Create a new {@code Channel} that will call {@code interceptors} before starting an RPC on the
+ * Create a new {@link Channel} that will call {@code interceptors} before starting a call on the
* given channel.
+ *
+ * @param channel the underlying channel to intercept.
+ * @param interceptors a list of interceptors to bind to {@code channel}.
+ * @return a new channel instance with the interceptors applied.
*/
public static Channel intercept(Channel channel, List interceptors) {
Preconditions.checkNotNull(channel);
@@ -142,8 +150,8 @@ public class ClientInterceptors {
}
/**
- * A {@link io.grpc.Call.Listener} which forwards all of its methods to another
- * {@link io.grpc.Call.Listener}.
+ * A {@link Call.Listener} which forwards all of its methods to another
+ * {@link Call.Listener}.
*/
public static class ForwardingListener extends Call.Listener {
diff --git a/core/src/main/java/io/grpc/DeferredInputStream.java b/core/src/main/java/io/grpc/DeferredInputStream.java
index 152bb73ac9..ee1cabb12f 100644
--- a/core/src/main/java/io/grpc/DeferredInputStream.java
+++ b/core/src/main/java/io/grpc/DeferredInputStream.java
@@ -45,15 +45,16 @@ import javax.annotation.Nullable;
public abstract class DeferredInputStream extends InputStream {
/**
- * Produce the entire contents of this stream to the specified target
+ * Produce the entire contents of this stream to the specified target.
*
- * @return number of bytes written
+ * @param target to write to.
+ * @return number of bytes written.
*/
public abstract int flushTo(OutputStream target) throws IOException;
/**
- * Returns the object that backs the stream. If any bytes have been read from the stream
- * then {@code null} is returned.
+ * Returns the object that backs the stream. If any bytes have been read from the stream
+ * then {@code null} is returned.
*/
@Nullable
public abstract T getDeferred();
diff --git a/core/src/main/java/io/grpc/HandlerRegistry.java b/core/src/main/java/io/grpc/HandlerRegistry.java
index c49d70958b..e57f7eb6f3 100644
--- a/core/src/main/java/io/grpc/HandlerRegistry.java
+++ b/core/src/main/java/io/grpc/HandlerRegistry.java
@@ -34,14 +34,25 @@ package io.grpc;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
-/** Registry of services and their methods for dispatching incoming calls. */
+/**
+ * Registry of services and their methods used by servers to dispatching incoming calls.
+ */
@ThreadSafe
public abstract class HandlerRegistry {
- /** Lookup full method name, starting with '/'. Returns {@code null} if method not found. */
+
+ /**
+ * Lookup a {@link Method} by its fully-qualified name. All names are expected to be absolute
+ * paths that start with '/'.
+ *
+ * @param methodName to lookup {@link Method} for.
+ * @return the resolved method or {@code null} if no method for that name exists.
+ */
@Nullable
public abstract Method lookupMethod(String methodName);
- /** A method definition and its parent's service definition. */
+ /**
+ * A method belonging to a service to be exposed to remote callers.
+ */
public static final class Method {
private final ServerServiceDefinition serviceDef;
private final ServerMethodDefinition, ?> methodDef;
diff --git a/core/src/main/java/io/grpc/Marshaller.java b/core/src/main/java/io/grpc/Marshaller.java
index 4791f248ed..5adb825560 100644
--- a/core/src/main/java/io/grpc/Marshaller.java
+++ b/core/src/main/java/io/grpc/Marshaller.java
@@ -34,18 +34,29 @@ package io.grpc;
import java.io.InputStream;
/**
- * An typed abstraction over message serialization.
+ * A typed abstraction over message parsing and serialization.
+ *
+ * Stub implementations will define implementations of this interface for each of the request and
+ * response messages provided by a service.
+ *
+ * @param type of serializable message
*/
public interface Marshaller {
/**
- * Given a message produce an {@link InputStream} for it.
+ * Given a message, produce an {@link InputStream} for it so that it can be written to the wire.
+ *
+ * @param value to serialize.
+ * @return serialized value as stream of bytes.
*/
- // TODO(louiscryan): Switch to ByteSource equivalent when ready
public InputStream stream(T value);
/**
- * Given an {@link InputStream} parse it into an instance of the declared type.
+ * Given an {@link InputStream} parse it into an instance of the declared type so that it can be
+ * passed to application code.
+ *
+ * @param stream of bytes for serialized value
+ * @return parsed value
*/
public T parse(InputStream stream);
}
diff --git a/core/src/main/java/io/grpc/MethodDescriptor.java b/core/src/main/java/io/grpc/MethodDescriptor.java
index 8acba1d9f6..6a5fe0e2b1 100644
--- a/core/src/main/java/io/grpc/MethodDescriptor.java
+++ b/core/src/main/java/io/grpc/MethodDescriptor.java
@@ -39,7 +39,12 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.concurrent.Immutable;
/**
- * Descriptor for a single operation, used by Channel to execute a call.
+ * Description of a remote method used by {@link Channel} to initiate a call.
+ *
+ * Provides the name of the operation to execute as well as {@link Marshaller} instances
+ * used to parse and serialize request and response messages.
+ *
+ *
Can be constructed manually but will often be generated by stub code generators.
*/
@Immutable
public class MethodDescriptor {
@@ -77,35 +82,45 @@ public class MethodDescriptor {
}
/**
- * The fully qualified name of the method
+ * The fully qualified name of the method.
*/
public String getName() {
return name;
}
/**
- * Timeout for the operation in microseconds
+ * Timeout for the operation in microseconds.
*/
public long getTimeout() {
return timeoutMicros;
}
/**
- * Parse a response payload from the given {@link InputStream}
+ * Parse a response payload from the given {@link InputStream}.
+ *
+ * @param input stream containing response message to parse.
+ * @return parsed response message object.
*/
public ResponseT parseResponse(InputStream input) {
return responseMarshaller.parse(input);
}
/**
- * Convert a request message to an {@link InputStream}
+ * Convert a request message to an {@link InputStream}.
+ *
+ * @param requestMessage to serialize using the request {@link io.grpc.Marshaller}.
+ * @return serialized request message.
*/
public InputStream streamRequest(RequestT requestMessage) {
return requestMarshaller.stream(requestMessage);
}
/**
- * Create a new descriptor with a different timeout
+ * Create a new descriptor with a different timeout.
+ *
+ * @param timeout to set on cloned descriptor.
+ * @param unit of time for {@code timeout}.
+ * @return a cloned instance with the specified timeout set.
*/
public MethodDescriptor withTimeout(long timeout, TimeUnit unit) {
return new MethodDescriptor(type, name, unit.toMicros(timeout),
diff --git a/core/src/main/java/io/grpc/MethodType.java b/core/src/main/java/io/grpc/MethodType.java
index 396c8724a9..6237ddad40 100644
--- a/core/src/main/java/io/grpc/MethodType.java
+++ b/core/src/main/java/io/grpc/MethodType.java
@@ -35,9 +35,29 @@ package io.grpc;
* The call type of a method.
*/
public enum MethodType {
+ /**
+ * One request message followed by one response message.
+ */
UNARY,
+
+ /**
+ * Zero or more request messages followed by one response message.
+ */
CLIENT_STREAMING,
+
+ /**
+ * One request message followed by zero or more response messages.
+ */
SERVER_STREAMING,
+
+ /**
+ * Zero or more request and response messages arbitrarily interleaved in time.
+ */
DUPLEX_STREAMING,
+
+ /**
+ * Cardinality and temporal relationships are not known. Implementations should not make
+ * buffering assumptions and should largely treat the same as {@link #DUPLEX_STREAMING}.
+ */
UNKNOWN
}
diff --git a/core/src/main/java/io/grpc/MutableHandlerRegistry.java b/core/src/main/java/io/grpc/MutableHandlerRegistry.java
index 9e58e125cd..f078fd516f 100644
--- a/core/src/main/java/io/grpc/MutableHandlerRegistry.java
+++ b/core/src/main/java/io/grpc/MutableHandlerRegistry.java
@@ -34,7 +34,10 @@ package io.grpc;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
-/** Mutable registry of services and their methods for dispatching incoming calls. */
+/**
+ * Mutable implementation of {@link HandlerRegistry}. Used by server implementations
+ * that need to bind and unbind services that are exposed to remote clients.
+ */
@ThreadSafe
public abstract class MutableHandlerRegistry extends HandlerRegistry {
/**
@@ -43,7 +46,9 @@ public abstract class MutableHandlerRegistry extends HandlerRegistry {
@Nullable
public abstract ServerServiceDefinition addService(ServerServiceDefinition service);
- /** Returns {@code false} if {@code service} was not registered. */
+ /**
+ * Returns {@code false} if {@code service} was not registered.
+ */
@Nullable
public abstract boolean removeService(ServerServiceDefinition service);
}
diff --git a/core/src/main/java/io/grpc/MutableHandlerRegistryImpl.java b/core/src/main/java/io/grpc/MutableHandlerRegistryImpl.java
index 6412093fa1..35f53fee83 100644
--- a/core/src/main/java/io/grpc/MutableHandlerRegistryImpl.java
+++ b/core/src/main/java/io/grpc/MutableHandlerRegistryImpl.java
@@ -37,7 +37,12 @@ import java.util.concurrent.ConcurrentMap;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
-/** Mutable registry implementation of services and their methods for dispatching incoming calls. */
+/**
+ * Default implementation of {@link MutableHandlerRegistry}.
+ *
+ * Uses {@link ConcurrentHashMap} to avoid service registration excessively
+ * blocking method lookup.
+ */
@ThreadSafe
public final class MutableHandlerRegistryImpl extends MutableHandlerRegistry {
private final ConcurrentMap services
diff --git a/core/src/main/java/io/grpc/SerializingExecutor.java b/core/src/main/java/io/grpc/SerializingExecutor.java
index 9e76b5de99..cca19a987f 100644
--- a/core/src/main/java/io/grpc/SerializingExecutor.java
+++ b/core/src/main/java/io/grpc/SerializingExecutor.java
@@ -42,13 +42,10 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.GuardedBy;
/**
- * Executor ensuring that all Runnables submitted are executed in order,
- * using the provided Executor, and serially such that no two will ever
- * be running at the same time.
- *
- * @author JJ Furman
+ * Executor ensuring that all {@link Runnable} tasks submitted are executed in order
+ * using the provided {@link Executor}, and serially such that no two will ever be
+ * running at the same time.
*/
-
// TODO(madongfly): figure out a way to not expose it or move it to transport package.
public final class SerializingExecutor implements Executor {
private static final Logger log =
diff --git a/core/src/main/java/io/grpc/ServerCall.java b/core/src/main/java/io/grpc/ServerCall.java
index fdb682998b..ced1c248a7 100644
--- a/core/src/main/java/io/grpc/ServerCall.java
+++ b/core/src/main/java/io/grpc/ServerCall.java
@@ -33,10 +33,10 @@ package io.grpc;
/**
- * Low-level method for communicating with a remote client during a single RPC. Unlike normal RPCs,
- * calls may stream any number of requests and responses, although a single request and single
- * response is most common. This API is generally intended for use generated handlers, but advanced
- * applications may have need for it.
+ * Encapsulates a single call received from a remote client. Calls may not simply be unary
+ * request-response even though this is the most common pattern. Calls may stream any number of
+ * requests and responses. This API is generally intended for use by generated handlers,
+ * but applications may use it directly if they need to.
*
* Headers must be sent before any payloads, which must be sent before closing.
*
@@ -45,6 +45,8 @@ package io.grpc;
* naturally acknowledges its request.
*
*
Methods are guaranteed to be non-blocking. Implementations are not required to be thread-safe.
+ *
+ * @param parsed type of response message.
*/
public abstract class ServerCall {
/**
@@ -61,8 +63,10 @@ public abstract class ServerCall {
// a case then we either get to generate a half close or purposefully omit it.
public abstract static class Listener {
/**
- * A request payload has been received. For streaming calls, there may be zero payload
+ * A request message has been received. For streaming calls, there may be zero or more request
* messages.
+ *
+ * @param payload a received request message.
*/
public abstract void onPayload(RequestT payload);
@@ -74,7 +78,7 @@ public abstract class ServerCall {
/**
* The call was cancelled and the server is encouraged to abort processing to save resources,
* since the client will not process any further messages. Cancellations can be caused by
- * timeouts, explicit cancel by client, network errors, and similar.
+ * timeouts, explicit cancellation by the client, network errors, etc.
*
* There will be no further callbacks for the call.
*/
@@ -91,7 +95,11 @@ public abstract class ServerCall {
/**
* Requests up to the given number of messages from the call to be delivered to
- * {@link Listener#onPayload(Object)}. No additional messages will be delivered.
+ * {@link Listener#onPayload(Object)}. Once {@code numMessages} have been delivered
+ * no further request messages will be delivered until more messages are requested by
+ * calling this method again.
+ *
+ * Servers use this mechanism to provide back-pressure to the client for flow-control.
*
* @param numMessages the requested number of messages to be delivered to the listener.
*/
@@ -108,10 +116,10 @@ public abstract class ServerCall {
public abstract void sendHeaders(Metadata.Headers headers);
/**
- * Send a payload message. Payload messages are the primary form of communication associated with
- * RPCs. Multiple payload messages may exist for streaming calls.
+ * Send a response message. Payload messages are the primary form of communication associated with
+ * RPCs. Multiple response messages may exist for streaming calls.
*
- * @param payload message
+ * @param payload response message.
* @throws IllegalStateException if call is {@link #close}d
*/
public abstract void sendPayload(ResponseT payload);
diff --git a/core/src/main/java/io/grpc/ServerCallHandler.java b/core/src/main/java/io/grpc/ServerCallHandler.java
index ab767cb32d..566c6ec723 100644
--- a/core/src/main/java/io/grpc/ServerCallHandler.java
+++ b/core/src/main/java/io/grpc/ServerCallHandler.java
@@ -34,11 +34,11 @@ package io.grpc;
import javax.annotation.concurrent.ThreadSafe;
/**
- * Interface to begin processing incoming RPCs. Advanced applications and generated code implement
- * this interface to implement service methods.
+ * Interface to initiate processing of incoming remote calls. Advanced applications and generated
+ * code will implement this interface to allows {@link Server}s to invoke service methods.
*/
@ThreadSafe
-public interface ServerCallHandler {
+public interface ServerCallHandler {
/**
* Produce a non-{@code null} listener for the incoming call. Implementations are free to call
* methods on {@code call} before this method has returned.
@@ -47,10 +47,10 @@ public interface ServerCallHandler {
* Implementations must not throw an exception if they started processing that may use {@code
* call} on another thread.
*
- * @param fullMethodName full method name of call
- * @param call object for responding
- * @return listener for processing incoming messages for {@code call}
+ * @param fullMethodName full qualified method name of call.
+ * @param call object for responding to the remote client.
+ * @return listener for processing incoming request messages for {@code call}
*/
- ServerCall.Listener startCall(String fullMethodName, ServerCall call,
+ ServerCall.Listener startCall(String fullMethodName, ServerCall call,
Metadata.Headers headers);
}
diff --git a/core/src/main/java/io/grpc/ServerImpl.java b/core/src/main/java/io/grpc/ServerImpl.java
index 3bed1360eb..991d3ff1f2 100644
--- a/core/src/main/java/io/grpc/ServerImpl.java
+++ b/core/src/main/java/io/grpc/ServerImpl.java
@@ -85,7 +85,8 @@ public class ServerImpl implements Server {
* Construct a server. {@link #setTransportServer(Service)} must be called before starting the
* server.
*
- * @param executor
+ * @param executor to call methods on behalf of remote clients
+ * @param registry of methods to expose to remote clients.
*/
public ServerImpl(Executor executor, HandlerRegistry registry) {
this.executor = Preconditions.checkNotNull(executor);
diff --git a/core/src/main/java/io/grpc/ServerInterceptor.java b/core/src/main/java/io/grpc/ServerInterceptor.java
index 7f9cb37591..4a3d9cbef5 100644
--- a/core/src/main/java/io/grpc/ServerInterceptor.java
+++ b/core/src/main/java/io/grpc/ServerInterceptor.java
@@ -34,23 +34,36 @@ package io.grpc;
import javax.annotation.concurrent.ThreadSafe;
/**
- * Interface for intercepting incoming RPCs before the handler receives them.
+ * Interface for intercepting incoming calls before that are dispatched by
+ * {@link ServerCallHandler}.
+ *
+ * Implementers use this mechanism to add cross-cutting behavior to server-side calls. Common
+ * example of such behavior include:
+ *
+ * - Enforcing valid authentication credentials
+ * - Logging and monitoring call behavior
+ * - Delegating calls to other servers
+ *
*/
@ThreadSafe
public interface ServerInterceptor {
/**
- * Intercept a new call. General semantics of {@link ServerCallHandler#startCall} apply. {@code
- * next} may only be called once. Returned listener must not be {@code null}.
+ * Intercept {@link ServerCall} dispatch by the {@code next} {@link ServerCallHandler}. General
+ * semantics of {@link ServerCallHandler#startCall} apply and the returned
+ * {@link io.grpc.ServerCall.Listener} must not be {@code null}.
*
* If the implementation throws an exception, {@code call} will be closed with an error.
* Implementations must not throw an exception if they started processing that may use {@code
* call} on another thread.
*
- * @param method full method name of the call
- * @param call object for responding
+ * @param method fully qualified method name of the call
+ * @param call object to receive response messages
* @param next next processor in the interceptor chain
- * @return listener for processing incoming messages for {@code call}
+ * @return listener for processing incoming messages for {@code call}, never {@code null}.
*/
- ServerCall.Listener interceptCall(String method, ServerCall call,
- Metadata.Headers headers, ServerCallHandler next);
+ ServerCall.Listener interceptCall(
+ String method,
+ ServerCall call,
+ Metadata.Headers headers,
+ ServerCallHandler next);
}
diff --git a/core/src/main/java/io/grpc/ServerInterceptors.java b/core/src/main/java/io/grpc/ServerInterceptors.java
index 13df6e4f5d..c05a47f58c 100644
--- a/core/src/main/java/io/grpc/ServerInterceptors.java
+++ b/core/src/main/java/io/grpc/ServerInterceptors.java
@@ -38,14 +38,20 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
-/** Utility class for {@link ServerInterceptor}s. */
+/**
+ * Utility methods for working with {@link ServerInterceptor}s.
+ */
public class ServerInterceptors {
// Prevent instantiation
private ServerInterceptors() {}
/**
- * Create a new {@code ServerServiceDefinition} whose {@link ServerCallHandler}s will call {@code
- * interceptors} before calling the pre-existing {@code ServerCallHandler}.
+ * Create a new {@code ServerServiceDefinition} whose {@link ServerCallHandler}s will call
+ * {@code interceptors} before calling the pre-existing {@code ServerCallHandler}.
+ *
+ * @param serviceDef the service definition for which to intercept all its methods.
+ * @param interceptors array of interceptors to apply to the service.
+ * @return a wrapped version of {@code serviceDef} with the interceptors applied.
*/
public static ServerServiceDefinition intercept(ServerServiceDefinition serviceDef,
ServerInterceptor... interceptors) {
@@ -53,8 +59,12 @@ public class ServerInterceptors {
}
/**
- * Create a new {@code ServerServiceDefinition} whose {@link ServerCallHandler}s will call {@code
- * interceptors} before calling the pre-existing {@code ServerCallHandler}.
+ * Create a new {@code ServerServiceDefinition} whose {@link ServerCallHandler}s will call
+ * {@code interceptors} before calling the pre-existing {@code ServerCallHandler}.
+ *
+ * @param serviceDef the service definition for which to intercept all its methods.
+ * @param interceptors list of interceptors to apply to the service.
+ * @return a wrapped version of {@code serviceDef} with the interceptors applied.
*/
public static ServerServiceDefinition intercept(ServerServiceDefinition serviceDef,
List interceptors) {
diff --git a/core/src/main/java/io/grpc/ServerMethodDefinition.java b/core/src/main/java/io/grpc/ServerMethodDefinition.java
index be94639c7b..f4fa45b62e 100644
--- a/core/src/main/java/io/grpc/ServerMethodDefinition.java
+++ b/core/src/main/java/io/grpc/ServerMethodDefinition.java
@@ -33,7 +33,10 @@ package io.grpc;
import java.io.InputStream;
-/** Definition of a method supported by a service. */
+/**
+ * Definition of a method bound by a {@link io.grpc.HandlerRegistry} and exposed
+ * by a {@link Server}.
+ */
public final class ServerMethodDefinition {
private final String name;
private final Marshaller requestMarshaller;
@@ -50,6 +53,15 @@ public final class ServerMethodDefinition {
this.handler = handler;
}
+ /**
+ * Create a new instance.
+ *
+ * @param name the simple name of a method.
+ * @param requestMarshaller marshaller for request messages.
+ * @param responseMarshaller marshaller for response messages.
+ * @param handler to dispatch calls to.
+ * @return a new instance.
+ */
public static ServerMethodDefinition create(
String name, Marshaller requestMarshaller,
Marshaller responseMarshaller, ServerCallHandler handler) {
@@ -62,12 +74,22 @@ public final class ServerMethodDefinition {
return name;
}
- /** Deserialize an incoming request message. */
+ /**
+ * Parse an incoming request message.
+ *
+ * @param input the serialized message as a byte stream.
+ * @return a parsed instance of the message.
+ */
public RequestT parseRequest(InputStream input) {
return requestMarshaller.parse(input);
}
- /** Serialize an outgoing response message. */
+ /**
+ * Serialize an outgoing response message.
+ *
+ * @param response the response message to serialize.
+ * @return the serialized message as a byte stream.
+ */
public InputStream streamResponse(ResponseT response) {
return responseMarshaller.stream(response);
}
@@ -77,7 +99,12 @@ public final class ServerMethodDefinition {
return handler;
}
- /** Create a new method definition with a different call handler. */
+ /**
+ * Create a new method definition with a different call handler.
+ *
+ * @param handler to bind to a cloned instance of this.
+ * @return a cloned instance of this with the new handler bound.
+ */
public ServerMethodDefinition withServerCallHandler(
ServerCallHandler handler) {
return new ServerMethodDefinition(
diff --git a/core/src/main/java/io/grpc/Status.java b/core/src/main/java/io/grpc/Status.java
index f1e39d983b..246a20abf3 100644
--- a/core/src/main/java/io/grpc/Status.java
+++ b/core/src/main/java/io/grpc/Status.java
@@ -43,122 +43,166 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/**
- * Defines the status of an operation using the canonical error space.
+ * Defines the status of an operation by providing a standard {@link Code} in conjunction with an
+ * optional descriptive message.
+ *
+ * For clients, every remote call will return a status on completion. In the case of errors this
+ * status may be propagated to blocking stubs as a {@link java.lang.RuntimeException} or to
+ * a listener as an explicit parameter.
+ *
+ *
Similarly servers can report a status by throwing {@link OperationRuntimeException}
+ * or by passing the status to a callback.
+ *
+ *
Utility functions are provided to convert a status to an exception and to extract them
+ * back out.
*/
@Immutable
public final class Status {
/**
- * The set of canonical error codes. If new codes are added over time they must choose
- * a numerical value that does not collide with any previously defined code.
+ * The set of canonical status codes. If new codes are added over time they must choose
+ * a numerical value that does not collide with any previously used value.
*/
public enum Code {
+ /**
+ * The operation completed successfully.
+ */
OK(0),
- // The operation was cancelled (typically by the caller).
+ /**
+ * The operation was cancelled (typically by the caller).
+ */
CANCELLED(1),
- // Unknown error. An example of where this error may be returned is
- // if a Status value received from another address space belongs to
- // an error-space that is not known in this address space. Also
- // errors raised by APIs that do not return enough error information
- // may be converted to this error.
+ /**
+ * Unknown error. An example of where this error may be returned is
+ * if a Status value received from another address space belongs to
+ * an error-space that is not known in this address space. Also
+ * errors raised by APIs that do not return enough error information
+ * may be converted to this error.
+ */
UNKNOWN(2),
- // Client specified an invalid argument. Note that this differs
- // from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments
- // that are problematic regardless of the state of the system
- // (e.g., a malformed file name).
+ /**
+ * Client specified an invalid argument. Note that this differs
+ * from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments
+ * that are problematic regardless of the state of the system
+ * (e.g., a malformed file name).
+ */
INVALID_ARGUMENT(3),
- // Deadline expired before operation could complete. For operations
- // that change the state of the system, this error may be returned
- // even if the operation has completed successfully. For example, a
- // successful response from a server could have been delayed long
- // enough for the deadline to expire.
+ /**
+ * Deadline expired before operation could complete. For operations
+ * that change the state of the system, this error may be returned
+ * even if the operation has completed successfully. For example, a
+ * successful response from a server could have been delayed long
+ * enough for the deadline to expire.
+ */
DEADLINE_EXCEEDED(4),
- // Some requested entity (e.g., file or directory) was not found.
+ /**
+ * Some requested entity (e.g., file or directory) was not found.
+ */
NOT_FOUND(5),
- // Some entity that we attempted to create (e.g., file or directory)
- // already exists.
+ /**
+ * Some entity that we attempted to create (e.g., file or directory) already exists.
+ */
ALREADY_EXISTS(6),
- // The caller does not have permission to execute the specified
- // operation. PERMISSION_DENIED must not be used for rejections
- // caused by exhausting some resource (use RESOURCE_EXHAUSTED
- // instead for those errors). PERMISSION_DENIED must not be
- // used if the caller cannot be identified (use UNAUTHENTICATED
- // instead for those errors).
+ /**
+ * The caller does not have permission to execute the specified
+ * operation. PERMISSION_DENIED must not be used for rejections
+ * caused by exhausting some resource (use RESOURCE_EXHAUSTED
+ * instead for those errors). PERMISSION_DENIED must not be
+ * used if the caller cannot be identified (use UNAUTHENTICATED
+ * instead for those errors).
+ */
PERMISSION_DENIED(7),
- // Some resource has been exhausted, perhaps a per-user quota, or
- // perhaps the entire file system is out of space.
+ /**
+ * Some resource has been exhausted, perhaps a per-user quota, or
+ * perhaps the entire file system is out of space.
+ */
RESOURCE_EXHAUSTED(8),
- // Operation was rejected because the system is not in a state
- // required for the operation's execution. For example, directory
- // to be deleted may be non-empty, an rmdir operation is applied to
- // a non-directory, etc.
- //
- // A litmus test that may help a service implementor in deciding
- // between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
- // (a) Use UNAVAILABLE if the client can retry just the failing call.
- // (b) Use ABORTED if the client should retry at a higher-level
- // (e.g., restarting a read-modify-write sequence).
- // (c) Use FAILED_PRECONDITION if the client should not retry until
- // the system state has been explicitly fixed. E.g., if an "rmdir"
- // fails because the directory is non-empty, FAILED_PRECONDITION
- // should be returned since the client should not retry unless
- // they have first fixed up the directory by deleting files from it.
+ /**
+ * Operation was rejected because the system is not in a state
+ * required for the operation's execution. For example, directory
+ * to be deleted may be non-empty, an rmdir operation is applied to
+ * a non-directory, etc.
+ *
+ *
A litmus test that may help a service implementor in deciding
+ * between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
+ * (a) Use UNAVAILABLE if the client can retry just the failing call.
+ * (b) Use ABORTED if the client should retry at a higher-level
+ * (e.g., restarting a read-modify-write sequence).
+ * (c) Use FAILED_PRECONDITION if the client should not retry until
+ * the system state has been explicitly fixed. E.g., if an "rmdir"
+ * fails because the directory is non-empty, FAILED_PRECONDITION
+ * should be returned since the client should not retry unless
+ * they have first fixed up the directory by deleting files from it.
+ */
FAILED_PRECONDITION(9),
- // The operation was aborted, typically due to a concurrency issue
- // like sequencer check failures, transaction aborts, etc.
- //
- // See litmus test above for deciding between FAILED_PRECONDITION,
- // ABORTED, and UNAVAILABLE.
+ /**
+ * The operation was aborted, typically due to a concurrency issue
+ * like sequencer check failures, transaction aborts, etc.
+ *
+ *
See litmus test above for deciding between FAILED_PRECONDITION,
+ * ABORTED, and UNAVAILABLE.
+ */
ABORTED(10),
- // Operation was attempted past the valid range. E.g., seeking or
- // reading past end of file.
- //
- // Unlike INVALID_ARGUMENT, this error indicates a problem that may
- // be fixed if the system state changes. For example, a 32-bit file
- // system will generate INVALID_ARGUMENT if asked to read at an
- // offset that is not in the range [0,2^32-1], but it will generate
- // OUT_OF_RANGE if asked to read from an offset past the current
- // file size.
- //
- // There is a fair bit of overlap between FAILED_PRECONDITION and
- // OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific
- // error) when it applies so that callers who are iterating through
- // a space can easily look for an OUT_OF_RANGE error to detect when
- // they are done.
+ /**
+ * Operation was attempted past the valid range. E.g., seeking or
+ * reading past end of file.
+ *
+ *
Unlike INVALID_ARGUMENT, this error indicates a problem that may
+ * be fixed if the system state changes. For example, a 32-bit file
+ * system will generate INVALID_ARGUMENT if asked to read at an
+ * offset that is not in the range [0,2^32-1], but it will generate
+ * OUT_OF_RANGE if asked to read from an offset past the current
+ * file size.
+ *
+ *
There is a fair bit of overlap between FAILED_PRECONDITION and OUT_OF_RANGE.
+ * We recommend using OUT_OF_RANGE (the more specific error) when it applies
+ * so that callers who are iterating through
+ * a space can easily look for an OUT_OF_RANGE error to detect when they are done.
+ */
OUT_OF_RANGE(11),
- // Operation is not implemented or not supported/enabled in this service.
+ /**
+ * Operation is not implemented or not supported/enabled in this service.
+ */
UNIMPLEMENTED(12),
- // Internal errors. Means some invariants expected by underlying
- // system has been broken. If you see one of these errors,
- // something is very broken.
+ /**
+ * Internal errors. Means some invariants expected by underlying
+ * system has been broken. If you see one of these errors,
+ * something is very broken.
+ */
INTERNAL(13),
- // The service is currently unavailable. This is a most likely a
- // transient condition and may be corrected by retrying with
- // a backoff.
- //
- // See litmus test above for deciding between FAILED_PRECONDITION,
- // ABORTED, and UNAVAILABLE.
+ /**
+ * The service is currently unavailable. This is a most likely a
+ * transient condition and may be corrected by retrying with
+ * a backoff.
+ *
+ *
See litmus test above for deciding between FAILED_PRECONDITION,
+ * ABORTED, and UNAVAILABLE.
+ */
UNAVAILABLE(14),
- // Unrecoverable data loss or corruption.
+ /**
+ * Unrecoverable data loss or corruption.
+ */
DATA_LOSS(15),
- // The request does not have valid authentication credentials for the
- // operation.
+ /**
+ * The request does not have valid authentication credentials for the
+ * operation.
+ */
UNAUTHENTICATED(16);
private final int value;
@@ -169,6 +213,9 @@ public final class Status {
this.valueAscii = Integer.toString(value);
}
+ /**
+ * The numerical value of the code.
+ */
public int value() {
return value;
}
@@ -229,13 +276,13 @@ public final class Status {
}
/**
- * Key to bind status code to trailers.
+ * Key to bind status code to trailing metadata.
*/
public static final Metadata.Key CODE_KEY
= Metadata.Key.of("grpc-status", new StatusCodeMarshaller());
/**
- * Key to bind status message to trailers.
+ * Key to bind status message to trailing metadata.
*/
public static final Metadata.Key MESSAGE_KEY
= Metadata.Key.of("grpc-message", Metadata.ASCII_STRING_MARSHALLER);
@@ -290,7 +337,8 @@ public final class Status {
}
/**
- * Create a derived instance of {@link Status} with the given description.
+ * Create a derived instance of {@link Status} augmenting the current description with
+ * additional detail.
*/
public Status augmentDescription(String additionalDetail) {
if (additionalDetail == null) {
@@ -302,15 +350,24 @@ public final class Status {
}
}
+ /**
+ * The canonical status code.
+ */
public Code getCode() {
return code;
}
+ /**
+ * A description of this status for human consumption.
+ */
@Nullable
public String getDescription() {
return description;
}
+ /**
+ * The underlying cause of an error.
+ */
@Nullable
public Throwable getCause() {
return cause;