Add interceptForward methods for Client and Server

This commit is contained in:
William Thurston 2016-03-02 21:19:08 -08:00 committed by Eric Anderson
parent 3528467612
commit a574159c81
4 changed files with 151 additions and 0 deletions

View File

@ -33,7 +33,9 @@ package io.grpc;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
@ -44,6 +46,35 @@ public class ClientInterceptors {
// Prevent instantiation
private ClientInterceptors() {}
/**
* Create a new {@link Channel} that will call {@code interceptors} before starting a call on the
* given channel. The first interceptor will have its {@link ClientInterceptor#interceptCall}
* called first.
*
* @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 interceptForward(Channel channel, ClientInterceptor... interceptors) {
return interceptForward(channel, Arrays.asList(interceptors));
}
/**
* Create a new {@link Channel} that will call {@code interceptors} before starting a call on the
* given channel. The first interceptor will have its {@link ClientInterceptor#interceptCall}
* called first.
*
* @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 interceptForward(Channel channel,
List<? extends ClientInterceptor> interceptors) {
List<? extends ClientInterceptor> copy = new ArrayList<ClientInterceptor>(interceptors);
Collections.reverse(copy);
return intercept(channel, copy);
}
/**
* Create a new {@link Channel} that will call {@code interceptors} before starting a call on the
* given channel. The last interceptor will have its {@link ClientInterceptor#interceptCall}

View File

@ -35,7 +35,9 @@ import com.google.common.base.Preconditions;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
@ -45,6 +47,37 @@ 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}. The first
* interceptor will have its {@link ServerInterceptor#interceptCall} called first.
*
* @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 interceptForward(ServerServiceDefinition serviceDef,
ServerInterceptor... interceptors) {
return interceptForward(serviceDef, Arrays.asList(interceptors));
}
/**
* Create a new {@code ServerServiceDefinition} whose {@link ServerCallHandler}s will call
* {@code interceptors} before calling the pre-existing {@code ServerCallHandler}. The first
* interceptor will have its {@link ServerInterceptor#interceptCall} called first.
*
* @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 interceptForward(
ServerServiceDefinition serviceDef,
List<? extends ServerInterceptor> interceptors) {
List<? extends ServerInterceptor> copy = new ArrayList<ServerInterceptor>(interceptors);
Collections.reverse(copy);
return intercept(serviceDef, copy);
}
/**
* Create a new {@code ServerServiceDefinition} whose {@link ServerCallHandler}s will call
* {@code interceptors} before calling the pre-existing {@code ServerCallHandler}. The last

View File

@ -200,6 +200,48 @@ public class ClientInterceptorsTest {
assertEquals(Arrays.asList("i2", "i1", "channel"), order);
}
@Test
public void orderedForward() {
final List<String> order = new ArrayList<String>();
channel = new Channel() {
@SuppressWarnings("unchecked")
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> newCall(
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions) {
order.add("channel");
return (ClientCall<ReqT, RespT>) call;
}
@Override
public String authority() {
return null;
}
};
ClientInterceptor interceptor1 = new ClientInterceptor() {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
MethodDescriptor<ReqT, RespT> method,
CallOptions callOptions,
Channel next) {
order.add("i1");
return next.newCall(method, callOptions);
}
};
ClientInterceptor interceptor2 = new ClientInterceptor() {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
MethodDescriptor<ReqT, RespT> method,
CallOptions callOptions,
Channel next) {
order.add("i2");
return next.newCall(method, callOptions);
}
};
Channel intercepted = ClientInterceptors.interceptForward(channel, interceptor1, interceptor2);
assertSame(call, intercepted.newCall(method, CallOptions.DEFAULT));
assertEquals(Arrays.asList("i1", "i2", "channel"), order);
}
@Test
public void callOptions() {
final CallOptions initialCallOptions = CallOptions.DEFAULT.withDeadlineNanoTime(100L);

View File

@ -234,6 +234,51 @@ public class ServerInterceptorsTest {
assertEquals(Arrays.asList("i2", "i1", "handler"), order);
}
@Test
public void orderedForward() {
final List<String> order = new ArrayList<String>();
handler = new ServerCallHandler<String, Integer>() {
@Override
public ServerCall.Listener<String> startCall(
MethodDescriptor<String, Integer> method,
ServerCall<Integer> call,
Metadata headers) {
order.add("handler");
return listener;
}
};
ServerInterceptor interceptor1 = new ServerInterceptor() {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
MethodDescriptor<ReqT, RespT> method,
ServerCall<RespT> call,
Metadata headers,
ServerCallHandler<ReqT, RespT> next) {
order.add("i1");
return next.startCall(method, call, headers);
}
};
ServerInterceptor interceptor2 = new ServerInterceptor() {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
MethodDescriptor<ReqT, RespT> method,
ServerCall<RespT> call,
Metadata headers,
ServerCallHandler<ReqT, RespT> next) {
order.add("i2");
return next.startCall(method, call, headers);
}
};
ServerServiceDefinition serviceDefinition = ServerServiceDefinition.builder("basic")
.addMethod(MethodDescriptor.create(MethodType.UNKNOWN, "basic/flow",
requestMarshaller, responseMarshaller), handler).build();
ServerServiceDefinition intercepted = ServerInterceptors.interceptForward(
serviceDefinition, interceptor1, interceptor2);
assertSame(listener,
getSoleMethod(intercepted).getServerCallHandler().startCall(method, call, headers));
assertEquals(Arrays.asList("i1", "i2", "handler"), order);
}
@Test
public void argumentsPassed() {
final MethodDescriptor<String, Integer> method2 = MethodDescriptor.create(