Skip to content

Commit efbcd1f

Browse files
core: change method descriptor to be builder based
1 parent e9fa8c9 commit efbcd1f

33 files changed

+470
-235
lines changed

auth/src/test/java/io/grpc/auth/ClientAuthInterceptorTest.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,12 @@ public class ClientAuthInterceptorTest {
111111
@Before
112112
public void startUp() {
113113
MockitoAnnotations.initMocks(this);
114-
descriptor = MethodDescriptor.create(
115-
MethodDescriptor.MethodType.UNKNOWN, "a.service/method", stringMarshaller, intMarshaller);
114+
descriptor = MethodDescriptor.<String, Integer>newBuilder()
115+
.setType(MethodDescriptor.MethodType.UNKNOWN)
116+
.setFullMethodName("a.service/method")
117+
.setRequestMarshaller(stringMarshaller)
118+
.setResponseMarshaller(intMarshaller)
119+
.build();
116120
when(channel.newCall(same(descriptor), any(CallOptions.class))).thenReturn(call);
117121
doReturn("localhost:443").when(channel).authority();
118122
interceptor = new ClientAuthInterceptor(credentials, executor);

auth/src/test/java/io/grpc/auth/GoogleAuthLibraryCallCredentialsTest.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,12 @@ public class GoogleAuthLibraryCallCredentialsTest {
127127
@Before
128128
public void setUp() throws Exception {
129129
MockitoAnnotations.initMocks(this);
130-
method = MethodDescriptor.create(
131-
MethodDescriptor.MethodType.UNKNOWN, "a.service/method", stringMarshaller, intMarshaller);
130+
method = MethodDescriptor.<String, Integer>newBuilder()
131+
.setType(MethodDescriptor.MethodType.UNKNOWN)
132+
.setFullMethodName("a.service/method")
133+
.setRequestMarshaller(stringMarshaller)
134+
.setResponseMarshaller(intMarshaller)
135+
.build();
132136
expectedUri = new URI("https://testauthority/a.service");
133137
doAnswer(new Answer<Void>() {
134138
@Override

benchmarks/src/jmh/java/io/grpc/benchmarks/netty/AbstractBenchmark.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -256,18 +256,20 @@ public void setup(ExecutorType clientExecutor,
256256
response.writerIndex(response.capacity() - 1);
257257

258258
// Simple method that sends and receives NettyByteBuf
259-
unaryMethod = MethodDescriptor.create(MethodType.UNARY,
260-
"benchmark/unary",
261-
new ByteBufOutputMarshaller(),
262-
new ByteBufOutputMarshaller());
263-
pingPongMethod = MethodDescriptor.create(MethodType.BIDI_STREAMING,
264-
"benchmark/pingPong",
265-
new ByteBufOutputMarshaller(),
266-
new ByteBufOutputMarshaller());
267-
flowControlledStreaming = MethodDescriptor.create(MethodType.BIDI_STREAMING,
268-
"benchmark/flowControlledStreaming",
269-
new ByteBufOutputMarshaller(),
270-
new ByteBufOutputMarshaller());
259+
unaryMethod = MethodDescriptor.<ByteBuf, ByteBuf>newBuilder()
260+
.setType(MethodType.UNARY)
261+
.setFullMethodName("benchmark/unary")
262+
.setRequestMarshaller(new ByteBufOutputMarshaller())
263+
.setResponseMarshaller(new ByteBufOutputMarshaller())
264+
.build();
265+
266+
pingPongMethod = unaryMethod.toBuilder()
267+
.setType(MethodType.BIDI_STREAMING)
268+
.setFullMethodName("benchmark/pingPong")
269+
.build();
270+
flowControlledStreaming = pingPongMethod.toBuilder()
271+
.setFullMethodName("benchmark/flowControlledStreaming")
272+
.build();
271273

272274
// Server implementation of unary & streaming methods
273275
serverBuilder.addService(

benchmarks/src/jmh/java/io/grpc/benchmarks/netty/HandlerRegistryBenchmark.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import io.grpc.ServerCallHandler;
3939
import io.grpc.ServerServiceDefinition;
4040
import io.grpc.ServiceDescriptor;
41+
import io.grpc.testing.TestMethodDescriptors;
4142
import io.grpc.util.MutableHandlerRegistry;
4243

4344
import org.openjdk.jmh.annotations.Benchmark;
@@ -88,13 +89,17 @@ public void setup() throws Exception {
8889
new ServiceDescriptor(serviceName));
8990
for (int methodIndex = 0; methodIndex < methodCountPerService; ++methodIndex) {
9091
String methodName = randomString();
91-
MethodDescriptor<Object, Object> methodDescriptor = MethodDescriptor.create(
92-
MethodDescriptor.MethodType.UNKNOWN,
93-
MethodDescriptor.generateFullMethodName(serviceName, methodName), null, null);
92+
93+
MethodDescriptor<Void, Void> methodDescriptor = MethodDescriptor.<Void, Void>newBuilder()
94+
.setType(MethodDescriptor.MethodType.UNKNOWN)
95+
.setFullMethodName(MethodDescriptor.generateFullMethodName(serviceName, methodName))
96+
.setRequestMarshaller(TestMethodDescriptors.noopMarshaller())
97+
.setResponseMarshaller(TestMethodDescriptors.noopMarshaller())
98+
.build();
9499
serviceBuilder.addMethod(methodDescriptor,
95-
new ServerCallHandler<Object, Object>() {
100+
new ServerCallHandler<Void, Void>() {
96101
@Override
97-
public Listener<Object> startCall(ServerCall<Object, Object> call,
102+
public Listener<Void> startCall(ServerCall<Void, Void> call,
98103
Metadata headers) {
99104
return null;
100105
}

benchmarks/src/jmh/java/io/grpc/netty/MethodDescriptorBenchmark.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,12 @@ public Void parse(InputStream stream) {
6666
}
6767
};
6868

69-
MethodDescriptor<Void, Void> method = MethodDescriptor.create(
70-
MethodDescriptor.MethodType.UNARY, "Service/Method", marshaller, marshaller);
69+
MethodDescriptor<Void, Void> method = MethodDescriptor.<Void, Void>newBuilder()
70+
.setType(MethodDescriptor.MethodType.UNARY)
71+
.setFullMethodName("Service/Method")
72+
.setRequestMarshaller(marshaller)
73+
.setResponseMarshaller(marshaller)
74+
.build();
7175

7276
InternalMethodDescriptor imd = new InternalMethodDescriptor(InternalKnownTransport.NETTY);
7377

benchmarks/src/main/java/io/grpc/benchmarks/driver/LoadServer.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
import io.grpc.Metadata;
4141
import io.grpc.MethodDescriptor;
42+
import io.grpc.MethodDescriptor.Marshaller;
4243
import io.grpc.Server;
4344
import io.grpc.ServerBuilder;
4445
import io.grpc.ServerCall;
@@ -73,25 +74,20 @@
7374
*/
7475
final class LoadServer {
7576

77+
private static final Marshaller<ByteBuf> marshaller = new ByteBufOutputMarshaller();
7678
/**
7779
* Generic version of the unary method call.
7880
*/
7981
static final MethodDescriptor<ByteBuf, ByteBuf> GENERIC_UNARY_METHOD =
80-
MethodDescriptor.create(
81-
BenchmarkServiceGrpc.METHOD_UNARY_CALL.getType(),
82-
BenchmarkServiceGrpc.METHOD_UNARY_CALL.getFullMethodName(),
83-
new ByteBufOutputMarshaller(),
84-
new ByteBufOutputMarshaller());
82+
BenchmarkServiceGrpc.METHOD_UNARY_CALL.toBuilder(marshaller, marshaller)
83+
.build();
8584

8685
/**
8786
* Generic version of the streaming ping-pong method call.
8887
*/
8988
static final MethodDescriptor<ByteBuf, ByteBuf> GENERIC_STREAMING_PING_PONG_METHOD =
90-
MethodDescriptor.create(
91-
BenchmarkServiceGrpc.METHOD_STREAMING_CALL.getType(),
92-
BenchmarkServiceGrpc.METHOD_STREAMING_CALL.getFullMethodName(),
93-
new ByteBufOutputMarshaller(),
94-
new ByteBufOutputMarshaller());
89+
BenchmarkServiceGrpc.METHOD_STREAMING_CALL.toBuilder(marshaller, marshaller)
90+
.build();
9591

9692
private static final Logger log = Logger.getLogger(LoadServer.class.getName());
9793

core/src/main/java/io/grpc/MethodDescriptor.java

Lines changed: 134 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.io.InputStream;
3939
import java.util.concurrent.atomic.AtomicReferenceArray;
4040

41+
import javax.annotation.CheckReturnValue;
4142
import javax.annotation.Nullable;
4243
import javax.annotation.concurrent.Immutable;
4344

@@ -208,7 +209,8 @@ public static <RequestT, ResponseT> MethodDescriptor<RequestT, ResponseT> create
208209
}
209210

210211
private MethodDescriptor(
211-
MethodType type, String fullMethodName,
212+
MethodType type,
213+
String fullMethodName,
212214
Marshaller<ReqT> requestMarshaller,
213215
Marshaller<RespT> responseMarshaller,
214216
boolean idempotent,
@@ -365,4 +367,135 @@ public static String extractFullServiceName(String fullMethodName) {
365367
}
366368
return fullMethodName.substring(0, index);
367369
}
370+
371+
/**
372+
* Creates a new builder for a {@link MethodDescriptor}.
373+
*/
374+
@CheckReturnValue
375+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/2641")
376+
public static <ReqT, RespT> Builder<ReqT, RespT> newBuilder() {
377+
return newBuilder(null, null);
378+
}
379+
380+
/**
381+
* Creates a new builder for a {@link MethodDescriptor}.
382+
*/
383+
@CheckReturnValue
384+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/2641")
385+
public static <ReqT, RespT> Builder<ReqT, RespT> newBuilder(
386+
Marshaller<ReqT> requestMarshaller, Marshaller<RespT> responseMarshaller) {
387+
return new Builder<ReqT, RespT>()
388+
.setRequestMarshaller(requestMarshaller)
389+
.setResponseMarshaller(responseMarshaller);
390+
}
391+
392+
/**
393+
* Turns this descriptor into a builder.
394+
*/
395+
@CheckReturnValue
396+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/2641")
397+
public Builder<ReqT, RespT> toBuilder() {
398+
return toBuilder(requestMarshaller, responseMarshaller);
399+
}
400+
401+
/**
402+
* Turns this descriptor into a builder, replacing the request and response marshallers.
403+
*/
404+
@CheckReturnValue
405+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/2641")
406+
public <NewReqT, NewRespT> Builder<NewReqT, NewRespT> toBuilder(
407+
Marshaller<NewReqT> requestMarshaller, Marshaller<NewRespT> responseMarshaller) {
408+
return MethodDescriptor.<NewReqT, NewRespT>newBuilder()
409+
.setRequestMarshaller(requestMarshaller)
410+
.setResponseMarshaller(responseMarshaller)
411+
.setType(type)
412+
.setFullMethodName(fullMethodName)
413+
.setIdempotent(idempotent)
414+
.setSafe(safe);
415+
}
416+
417+
/**
418+
* A builder for a {@link MethodDescriptor}.
419+
*/
420+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/2641")
421+
public static final class Builder<ReqT, RespT> {
422+
423+
private Marshaller<ReqT> requestMarshaller;
424+
private Marshaller<RespT> responseMarshaller;
425+
private MethodType type;
426+
private String fullMethodName;
427+
private boolean idempotent;
428+
private boolean safe;
429+
430+
private Builder() {}
431+
432+
/**
433+
* Sets the request marshaller.
434+
* @param requestMarshaller the marshaller to use.
435+
*/
436+
public Builder<ReqT, RespT> setRequestMarshaller(Marshaller<ReqT> requestMarshaller) {
437+
this.requestMarshaller = requestMarshaller;
438+
return this;
439+
}
440+
441+
/**
442+
* Sets the response marshaller.
443+
* @param responseMarshaller the marshaller to use.
444+
*/
445+
@SuppressWarnings("unchecked")
446+
public Builder<ReqT, RespT> setResponseMarshaller(Marshaller<RespT> responseMarshaller) {
447+
this.responseMarshaller = responseMarshaller;
448+
return this;
449+
}
450+
451+
/**
452+
* Sets the method type.
453+
* @param type the type of the method.
454+
*/
455+
public Builder<ReqT, RespT> setType(MethodType type) {
456+
this.type = type;
457+
return this;
458+
}
459+
460+
/**
461+
* Sets the fully qualified (service and method) method name.
462+
* @see MethodDescriptor#generateFullMethodName
463+
*/
464+
public Builder<ReqT, RespT> setFullMethodName(String fullMethodName) {
465+
this.fullMethodName = fullMethodName;
466+
return this;
467+
}
468+
469+
/**
470+
* Sets whether the method is idempotent. If true, calling this method more than once doesn't
471+
* have additional side effects.
472+
*/
473+
public Builder<ReqT, RespT> setIdempotent(boolean idempotent) {
474+
this.idempotent = idempotent;
475+
return this;
476+
}
477+
478+
/**
479+
* Sets whether this method is safe. If true, calling this method any number of times doesn't
480+
* have side effects.
481+
*/
482+
public Builder<ReqT, RespT> setSafe(boolean safe) {
483+
this.safe = safe;
484+
return this;
485+
}
486+
487+
/**
488+
* Builds the method descriptor.
489+
*/
490+
@CheckReturnValue
491+
public MethodDescriptor<ReqT, RespT> build() {
492+
return new MethodDescriptor<ReqT, RespT>(
493+
type,
494+
fullMethodName,
495+
requestMarshaller,
496+
responseMarshaller,
497+
idempotent,
498+
safe);
499+
}
500+
}
368501
}

core/src/main/java/io/grpc/ServerInterceptors.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,8 @@ public static <T> ServerServiceDefinition useMarshalledMessages(
197197
// Wrap the descriptors
198198
for (final ServerMethodDefinition<?, ?> definition : serviceDef.getMethods()) {
199199
final MethodDescriptor<?, ?> originalMethodDescriptor = definition.getMethodDescriptor();
200-
final MethodDescriptor<T, T> wrappedMethodDescriptor = MethodDescriptor
201-
.create(originalMethodDescriptor.getType(),
202-
originalMethodDescriptor.getFullMethodName(),
203-
marshaller,
204-
marshaller);
200+
final MethodDescriptor<T, T> wrappedMethodDescriptor =
201+
originalMethodDescriptor.toBuilder(marshaller, marshaller).build();
205202
wrappedDescriptors.add(wrappedMethodDescriptor);
206203
wrappedMethods.add(wrapMethod(definition, wrappedMethodDescriptor));
207204
}

core/src/test/java/io/grpc/MethodDescriptorTest.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,18 @@ public void createMethodDescriptor() {
6060

6161
@Test
6262
public void idempotent() {
63-
MethodDescriptor<String,String> descriptor = MethodDescriptor.<String, String>create(
64-
MethodType.SERVER_STREAMING, "/package.service/method", new StringMarshaller(),
65-
new StringMarshaller());
63+
MethodDescriptor<String,String> descriptor = MethodDescriptor.<String, String>newBuilder()
64+
.setType(MethodType.SERVER_STREAMING)
65+
.setFullMethodName("/package.service/method")
66+
.setRequestMarshaller(new StringMarshaller())
67+
.setResponseMarshaller(new StringMarshaller())
68+
.build();
69+
6670
assertFalse(descriptor.isIdempotent());
6771

6872
// Create a new desriptor by setting idempotent to true
69-
MethodDescriptor<String, String> newDescriptor = descriptor.withIdempotent(true);
73+
MethodDescriptor<String, String> newDescriptor =
74+
descriptor.toBuilder().setIdempotent(true).build();
7075
assertTrue(newDescriptor.isIdempotent());
7176
// All other fields should staty the same
7277
assertEquals(MethodType.SERVER_STREAMING, newDescriptor.getType());
@@ -75,13 +80,16 @@ public void idempotent() {
7580

7681
@Test
7782
public void safe() {
78-
MethodDescriptor<String,String> descriptor = MethodDescriptor.<String, String>create(
79-
MethodType.UNARY, "/package.service/method", new StringMarshaller(),
80-
new StringMarshaller());
83+
MethodDescriptor<String,String> descriptor = MethodDescriptor.<String, String>newBuilder()
84+
.setType(MethodType.UNARY)
85+
.setFullMethodName("/package.service/method")
86+
.setRequestMarshaller(new StringMarshaller())
87+
.setResponseMarshaller(new StringMarshaller())
88+
.build();
8189
assertFalse(descriptor.isSafe());
8290

8391
// Create a new desriptor by setting safe to true
84-
MethodDescriptor<String, String> newDescriptor = descriptor.withSafe(true);
92+
MethodDescriptor<String, String> newDescriptor = descriptor.toBuilder().setSafe(true).build();
8593
assertTrue(newDescriptor.isSafe());
8694
// All other fields should staty the same
8795
assertEquals(MethodType.UNARY, newDescriptor.getType());
@@ -90,10 +98,17 @@ public void safe() {
9098

9199
@Test(expected = IllegalArgumentException.class)
92100
public void safeAndNonUnary() {
93-
MethodDescriptor<String,String> descriptor = MethodDescriptor.<String, String>create(
94-
MethodType.SERVER_STREAMING, "/package.service/method", new StringMarshaller(),
95-
new StringMarshaller());
96-
MethodDescriptor<String, String> newDescriptor = descriptor.withSafe(true);
101+
MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder()
102+
.setType(MethodType.SERVER_STREAMING)
103+
.setFullMethodName("/package.service/method")
104+
.setRequestMarshaller(new StringMarshaller())
105+
.setResponseMarshaller(new StringMarshaller())
106+
.build();
107+
108+
109+
MethodDescriptor<String,String> discard = descriptor.toBuilder().setSafe(true).build();
110+
// Never reached
111+
assert discard == null;
97112
}
98113
}
99114

0 commit comments

Comments
 (0)