下面列出了io.grpc.ExperimentalApi#io.grpc.MethodDescriptor.MethodType 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@GuardedBy("lock")
private void startStream(OkHttpClientStream stream) {
Preconditions.checkState(
stream.id() == OkHttpClientStream.ABSENT_ID, "StreamId already assigned");
streams.put(nextStreamId, stream);
setInUse(stream);
stream.transportState().start(nextStreamId);
// For unary and server streaming, there will be a data frame soon, no need to flush the header.
if ((stream.getType() != MethodType.UNARY && stream.getType() != MethodType.SERVER_STREAMING)
|| stream.useGet()) {
frameWriter.flush();
}
if (nextStreamId >= Integer.MAX_VALUE - 2) {
// Make sure nextStreamId greater than all used id, so that mayHaveCreatedStream() performs
// correctly.
nextStreamId = Integer.MAX_VALUE;
startGoAway(Integer.MAX_VALUE, ErrorCode.NO_ERROR,
Status.UNAVAILABLE.withDescription("Stream ids exhausted"));
} else {
nextStreamId += 2;
}
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
methodDescriptor = MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodDescriptor.MethodType.UNARY)
.setFullMethodName("testService/test")
.setRequestMarshaller(marshaller)
.setResponseMarshaller(marshaller)
.build();
stream = new OkHttpClientStream(
methodDescriptor,
new Metadata(),
frameWriter,
transport,
flowController,
lock,
MAX_MESSAGE_SIZE,
INITIAL_WINDOW_SIZE,
"localhost",
"userAgent",
StatsTraceContext.NOOP,
transportTracer,
CallOptions.DEFAULT);
}
ClientCallImpl(
MethodDescriptor<ReqT, RespT> method, Executor executor, CallOptions callOptions,
ClientTransportProvider clientTransportProvider,
ScheduledExecutorService deadlineCancellationExecutor,
CallTracer channelCallsTracer,
boolean retryEnabled) {
this.method = method;
// If we know that the executor is a direct executor, we don't need to wrap it with a
// SerializingExecutor. This is purely for performance reasons.
// See https://github.com/grpc/grpc-java/issues/368
this.callExecutor = executor == directExecutor()
? new SerializeReentrantCallsDirectExecutor()
: new SerializingExecutor(executor);
this.channelCallsTracer = channelCallsTracer;
// Propagate the context from the thread which initiated the call to all callbacks.
this.context = Context.current();
this.unaryRequest = method.getType() == MethodType.UNARY
|| method.getType() == MethodType.SERVER_STREAMING;
this.callOptions = callOptions;
this.clientTransportProvider = clientTransportProvider;
this.deadlineCancellationExecutor = deadlineCancellationExecutor;
this.retryEnabled = retryEnabled;
}
@Test
public void idempotent() {
MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.SERVER_STREAMING)
.setFullMethodName("package.service/method")
.setRequestMarshaller(new StringMarshaller())
.setResponseMarshaller(new StringMarshaller())
.build();
assertFalse(descriptor.isIdempotent());
// Create a new desriptor by setting idempotent to true
MethodDescriptor<String, String> newDescriptor =
descriptor.toBuilder().setIdempotent(true).build();
assertTrue(newDescriptor.isIdempotent());
// All other fields should staty the same
assertEquals(MethodType.SERVER_STREAMING, newDescriptor.getType());
assertEquals("package.service/method", newDescriptor.getFullMethodName());
}
@Test
public void safe() {
MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName("package.service/method")
.setRequestMarshaller(new StringMarshaller())
.setResponseMarshaller(new StringMarshaller())
.build();
assertFalse(descriptor.isSafe());
// Create a new desriptor by setting safe to true
MethodDescriptor<String, String> newDescriptor = descriptor.toBuilder().setSafe(true).build();
assertTrue(newDescriptor.isSafe());
// All other fields should staty the same
assertEquals(MethodType.UNARY, newDescriptor.getType());
assertEquals("package.service/method", newDescriptor.getFullMethodName());
}
@Test
public void toStringTest() {
MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName("package.service/method")
.setRequestMarshaller(StringMarshaller.INSTANCE)
.setResponseMarshaller(StringMarshaller.INSTANCE)
.setSampledToLocalTracing(true)
.setIdempotent(true)
.setSafe(true)
.setSchemaDescriptor(new Object())
.build();
String toString = descriptor.toString();
assertTrue(toString.contains("MethodDescriptor"));
assertTrue(toString.contains("fullMethodName=package.service/method"));
assertTrue(toString.contains("type=UNARY"));
assertTrue(toString.contains("idempotent=true"));
assertTrue(toString.contains("safe=true"));
assertTrue(toString.contains("sampledToLocalTracing=true"));
assertTrue(toString.contains("requestMarshaller=io.grpc.StringMarshaller"));
assertTrue(toString.contains("responseMarshaller=io.grpc.StringMarshaller"));
assertTrue(toString.contains("schemaDescriptor=java.lang.Object"));
}
/** Set up for test. */
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
flowMethod = MethodDescriptor.<String, Integer>newBuilder()
.setType(MethodType.UNKNOWN)
.setFullMethodName("basic/flow")
.setRequestMarshaller(requestMarshaller)
.setResponseMarshaller(responseMarshaller)
.build();
Mockito.when(handler.startCall(
Mockito.<ServerCall<String, Integer>>any(), Mockito.<Metadata>any()))
.thenReturn(listener);
serviceDefinition = ServerServiceDefinition.builder(new ServiceDescriptor("basic", flowMethod))
.addMethod(flowMethod, handler).build();
}
@Test
public void failsOnNonDuplicateNames() {
List<MethodDescriptor<?, ?>> descriptors = Arrays.<MethodDescriptor<?, ?>>asList(
MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName(MethodDescriptor.generateFullMethodName("name", "method"))
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build(),
MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName(MethodDescriptor.generateFullMethodName("name", "method"))
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build());
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("duplicate");
new ServiceDescriptor("name", descriptors);
}
@Test
public void toStringTest() {
ServiceDescriptor descriptor = new ServiceDescriptor("package.service",
Arrays.<MethodDescriptor<?, ?>>asList(
MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName(MethodDescriptor.generateFullMethodName("package.service",
"methodOne"))
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build(),
MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName(MethodDescriptor.generateFullMethodName("package.service",
"methodTwo"))
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build()));
String toString = descriptor.toString();
assertTrue(toString.contains("ServiceDescriptor"));
assertTrue(toString.contains("name=package.service"));
assertTrue(toString.contains("package.service/methodOne"));
assertTrue(toString.contains("package.service/methodTwo"));
}
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
MethodDescriptor<String, Integer> flowMethod = MethodDescriptor.<String, Integer>newBuilder()
.setType(MethodType.UNKNOWN)
.setFullMethodName("basic/flow")
.setRequestMarshaller(requestMarshaller)
.setResponseMarshaller(responseMarshaller)
.build();
basicServiceDefinition = ServerServiceDefinition.builder(
new ServiceDescriptor("basic", flowMethod))
.addMethod(flowMethod, flowHandler)
.build();
MethodDescriptor<String, Integer> coupleMethod =
flowMethod.toBuilder().setFullMethodName("multi/couple").build();
MethodDescriptor<String, Integer> fewMethod =
flowMethod.toBuilder().setFullMethodName("multi/few").build();
multiServiceDefinition = ServerServiceDefinition.builder(
new ServiceDescriptor("multi", coupleMethod, fewMethod))
.addMethod(coupleMethod, coupleHandler)
.addMethod(fewMethod, fewHandler)
.build();
flowMethodDefinition = getOnlyElement(basicServiceDefinition.getMethods());
}
@Test
public void replaceAndLookup() {
assertNull(registry.addService(basicServiceDefinition));
assertNotNull(registry.lookupMethod("basic/flow"));
MethodDescriptor<String, Integer> anotherMethod = MethodDescriptor.<String, Integer>newBuilder()
.setType(MethodType.UNKNOWN)
.setFullMethodName("basic/another")
.setRequestMarshaller(requestMarshaller)
.setResponseMarshaller(responseMarshaller)
.build();
ServerServiceDefinition replaceServiceDefinition = ServerServiceDefinition.builder(
new ServiceDescriptor("basic", anotherMethod))
.addMethod(anotherMethod, flowHandler).build();
ServerMethodDefinition<?, ?> anotherMethodDefinition =
replaceServiceDefinition.getMethod("basic/another");
assertSame(basicServiceDefinition, registry.addService(replaceServiceDefinition));
assertNull(registry.lookupMethod("basic/flow"));
ServerMethodDefinition<?, ?> method = registry.lookupMethod("basic/another");
assertSame(anotherMethodDefinition, method);
}
@Test
public void idempotent() {
MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.SERVER_STREAMING)
.setFullMethodName("package.service/method")
.setRequestMarshaller(new StringMarshaller())
.setResponseMarshaller(new StringMarshaller())
.build();
assertFalse(descriptor.isIdempotent());
// Create a new desriptor by setting idempotent to true
MethodDescriptor<String, String> newDescriptor =
descriptor.toBuilder().setIdempotent(true).build();
assertTrue(newDescriptor.isIdempotent());
// All other fields should staty the same
assertEquals(MethodType.SERVER_STREAMING, newDescriptor.getType());
assertEquals("package.service/method", newDescriptor.getFullMethodName());
}
@Test
public void safe() {
MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName("package.service/method")
.setRequestMarshaller(new StringMarshaller())
.setResponseMarshaller(new StringMarshaller())
.build();
assertFalse(descriptor.isSafe());
// Create a new desriptor by setting safe to true
MethodDescriptor<String, String> newDescriptor = descriptor.toBuilder().setSafe(true).build();
assertTrue(newDescriptor.isSafe());
// All other fields should staty the same
assertEquals(MethodType.UNARY, newDescriptor.getType());
assertEquals("package.service/method", newDescriptor.getFullMethodName());
}
@Test
public void toStringTest() {
MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName("package.service/method")
.setRequestMarshaller(StringMarshaller.INSTANCE)
.setResponseMarshaller(StringMarshaller.INSTANCE)
.setSampledToLocalTracing(true)
.setIdempotent(true)
.setSafe(true)
.setSchemaDescriptor(new Object())
.build();
String toString = descriptor.toString();
assertTrue(toString.contains("MethodDescriptor"));
assertTrue(toString.contains("fullMethodName=package.service/method"));
assertTrue(toString.contains("type=UNARY"));
assertTrue(toString.contains("idempotent=true"));
assertTrue(toString.contains("safe=true"));
assertTrue(toString.contains("sampledToLocalTracing=true"));
assertTrue(toString.contains("requestMarshaller=io.grpc.StringMarshaller"));
assertTrue(toString.contains("responseMarshaller=io.grpc.StringMarshaller"));
assertTrue(toString.contains("schemaDescriptor=java.lang.Object"));
}
/** Set up for test. */
@Before
public void setUp() {
flowMethod = MethodDescriptor.<String, Integer>newBuilder()
.setType(MethodType.UNKNOWN)
.setFullMethodName("basic/flow")
.setRequestMarshaller(requestMarshaller)
.setResponseMarshaller(responseMarshaller)
.build();
Mockito.when(
handler.startCall(
ArgumentMatchers.<ServerCall<String, Integer>>any(),
ArgumentMatchers.<Metadata>any()))
.thenReturn(listener);
serviceDefinition = ServerServiceDefinition.builder(new ServiceDescriptor("basic", flowMethod))
.addMethod(flowMethod, handler).build();
}
@Test
public void failsOnNonDuplicateNames() {
List<MethodDescriptor<?, ?>> descriptors = Arrays.<MethodDescriptor<?, ?>>asList(
MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName(MethodDescriptor.generateFullMethodName("name", "method"))
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build(),
MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName(MethodDescriptor.generateFullMethodName("name", "method"))
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build());
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("duplicate");
new ServiceDescriptor("name", descriptors);
}
@Test
public void toStringTest() {
ServiceDescriptor descriptor = new ServiceDescriptor("package.service",
Arrays.<MethodDescriptor<?, ?>>asList(
MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName(MethodDescriptor.generateFullMethodName("package.service",
"methodOne"))
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build(),
MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName(MethodDescriptor.generateFullMethodName("package.service",
"methodTwo"))
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build()));
String toString = descriptor.toString();
assertTrue(toString.contains("ServiceDescriptor"));
assertTrue(toString.contains("name=package.service"));
assertTrue(toString.contains("package.service/methodOne"));
assertTrue(toString.contains("package.service/methodTwo"));
}
@SuppressWarnings("GuardedBy")
@GuardedBy("lock")
private void startStream(OkHttpClientStream stream) {
Preconditions.checkState(
stream.id() == OkHttpClientStream.ABSENT_ID, "StreamId already assigned");
streams.put(nextStreamId, stream);
setInUse(stream);
// TODO(b/145386688): This access should be guarded by 'stream.transportState().lock'; instead
// found: 'this.lock'
stream.transportState().start(nextStreamId);
// For unary and server streaming, there will be a data frame soon, no need to flush the header.
if ((stream.getType() != MethodType.UNARY && stream.getType() != MethodType.SERVER_STREAMING)
|| stream.useGet()) {
frameWriter.flush();
}
if (nextStreamId >= Integer.MAX_VALUE - 2) {
// Make sure nextStreamId greater than all used id, so that mayHaveCreatedStream() performs
// correctly.
nextStreamId = Integer.MAX_VALUE;
startGoAway(Integer.MAX_VALUE, ErrorCode.NO_ERROR,
Status.UNAVAILABLE.withDescription("Stream ids exhausted"));
} else {
nextStreamId += 2;
}
}
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
MethodDescriptor<String, Integer> flowMethod = MethodDescriptor.<String, Integer>newBuilder()
.setType(MethodType.UNKNOWN)
.setFullMethodName("basic/flow")
.setRequestMarshaller(requestMarshaller)
.setResponseMarshaller(responseMarshaller)
.build();
basicServiceDefinition = ServerServiceDefinition.builder(
new ServiceDescriptor("basic", flowMethod))
.addMethod(flowMethod, flowHandler)
.build();
MethodDescriptor<String, Integer> coupleMethod =
flowMethod.toBuilder().setFullMethodName("multi/couple").build();
MethodDescriptor<String, Integer> fewMethod =
flowMethod.toBuilder().setFullMethodName("multi/few").build();
multiServiceDefinition = ServerServiceDefinition.builder(
new ServiceDescriptor("multi", coupleMethod, fewMethod))
.addMethod(coupleMethod, coupleHandler)
.addMethod(fewMethod, fewHandler)
.build();
flowMethodDefinition = getOnlyElement(basicServiceDefinition.getMethods());
}
@Test
public void replaceAndLookup() {
assertNull(registry.addService(basicServiceDefinition));
assertNotNull(registry.lookupMethod("basic/flow"));
MethodDescriptor<String, Integer> anotherMethod = MethodDescriptor.<String, Integer>newBuilder()
.setType(MethodType.UNKNOWN)
.setFullMethodName("basic/another")
.setRequestMarshaller(requestMarshaller)
.setResponseMarshaller(responseMarshaller)
.build();
ServerServiceDefinition replaceServiceDefinition = ServerServiceDefinition.builder(
new ServiceDescriptor("basic", anotherMethod))
.addMethod(anotherMethod, flowHandler).build();
ServerMethodDefinition<?, ?> anotherMethodDefinition =
replaceServiceDefinition.getMethod("basic/another");
assertSame(basicServiceDefinition, registry.addService(replaceServiceDefinition));
assertNull(registry.lookupMethod("basic/flow"));
ServerMethodDefinition<?, ?> method = registry.lookupMethod("basic/another");
assertSame(anotherMethodDefinition, method);
}
@Test
public void getUnaryRequest() {
MethodDescriptor<?, ?> getMethod = MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodDescriptor.MethodType.UNARY)
.setFullMethodName("service/method")
.setIdempotent(true)
.setSafe(true)
.setRequestMarshaller(marshaller)
.setResponseMarshaller(marshaller)
.build();
stream = new OkHttpClientStream(getMethod, new Metadata(), frameWriter, transport,
flowController, lock, MAX_MESSAGE_SIZE, INITIAL_WINDOW_SIZE, "localhost",
"good-application", StatsTraceContext.NOOP, transportTracer, CallOptions.DEFAULT);
stream.start(new BaseClientStreamListener());
// GET streams send headers after halfClose is called.
verify(frameWriter, times(0)).synStream(
eq(false), eq(false), eq(3), eq(0), headersCaptor.capture());
verify(transport, times(0)).streamReadyToStart(isA(OkHttpClientStream.class));
byte[] msg = "request".getBytes(Charset.forName("UTF-8"));
stream.writeMessage(new ByteArrayInputStream(msg));
stream.halfClose();
verify(transport).streamReadyToStart(eq(stream));
stream.transportState().start(3);
verify(frameWriter)
.synStream(eq(true), eq(false), eq(3), eq(0), headersCaptor.capture());
assertThat(headersCaptor.getValue()).contains(Headers.METHOD_GET_HEADER);
assertThat(headersCaptor.getValue()).contains(
new Header(Header.TARGET_PATH, "/" + getMethod.getFullMethodName() + "?"
+ BaseEncoding.base64().encode(msg)));
}
/**
* Creates a new method descriptor that always creates zero length messages, and always parses to
* null objects.
*
* @since 1.1.0
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/2600")
public static MethodDescriptor<Void, Void> voidMethod() {
return MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName(MethodDescriptor.generateFullMethodName("service_foo", "method_bar"))
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build();
}
@Test
public void createMethodDescriptor() {
MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.CLIENT_STREAMING)
.setFullMethodName("package.service/method")
.setRequestMarshaller(new StringMarshaller())
.setResponseMarshaller(new StringMarshaller())
.build();
assertEquals(MethodType.CLIENT_STREAMING, descriptor.getType());
assertEquals("package.service/method", descriptor.getFullMethodName());
assertFalse(descriptor.isIdempotent());
assertFalse(descriptor.isSafe());
}
@Test
public void safeAndNonUnary() {
MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.SERVER_STREAMING)
.setFullMethodName("package.service/method")
.setRequestMarshaller(new StringMarshaller())
.setResponseMarshaller(new StringMarshaller())
.build();
thrown.expect(IllegalArgumentException.class);
MethodDescriptor<String, String> unused = descriptor.toBuilder().setSafe(true).build();
}
@Test
public void sampledToLocalTracing() {
MethodDescriptor<String, String> md1 = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.SERVER_STREAMING)
.setFullMethodName("package.service/method")
.setRequestMarshaller(new StringMarshaller())
.setResponseMarshaller(new StringMarshaller())
.setSampledToLocalTracing(true)
.build();
assertTrue(md1.isSampledToLocalTracing());
MethodDescriptor<String, String> md2 = md1.toBuilder()
.setFullMethodName("package.service/method2")
.build();
assertTrue(md2.isSampledToLocalTracing());
// Same method name as md1, but not setting sampledToLocalTracing
MethodDescriptor<String, String> md3 = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.SERVER_STREAMING)
.setFullMethodName("package.service/method")
.setRequestMarshaller(new StringMarshaller())
.setResponseMarshaller(new StringMarshaller())
.build();
assertFalse(md3.isSampledToLocalTracing());
MethodDescriptor<String, String> md4 = md3.toBuilder()
.setFullMethodName("package.service/method2")
.setSampledToLocalTracing(true)
.build();
assertTrue(md4.isSampledToLocalTracing());
}
@Test
public void toBuilderTest() {
MethodDescriptor<String, String> md1 = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName("package.service/method")
.setRequestMarshaller(StringMarshaller.INSTANCE)
.setResponseMarshaller(StringMarshaller.INSTANCE)
.setSampledToLocalTracing(true)
.setIdempotent(true)
.setSafe(true)
.setSchemaDescriptor(new Object())
.build();
// Verify that we are not using any default builder values, so if md1 and md2 matches,
// it's because toBuilder explicitly copied it.
MethodDescriptor<String, String> defaults = MethodDescriptor.<String, String>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName("package.service/method")
.setRequestMarshaller(StringMarshaller.INSTANCE)
.setResponseMarshaller(StringMarshaller.INSTANCE)
.build();
assertNotEquals(md1.isSampledToLocalTracing(), defaults.isSampledToLocalTracing());
assertNotEquals(md1.isIdempotent(), defaults.isIdempotent());
assertNotEquals(md1.isSafe(), defaults.isSafe());
assertNotEquals(md1.getSchemaDescriptor(), defaults.getSchemaDescriptor());
// Verify that the builder correctly copied over the values
MethodDescriptor<Integer, Integer> md2 = md1.toBuilder(
IntegerMarshaller.INSTANCE,
IntegerMarshaller.INSTANCE).build();
assertSame(md1.getType(), md2.getType());
assertSame(md1.getFullMethodName(), md2.getFullMethodName());
assertSame(IntegerMarshaller.INSTANCE, md2.getRequestMarshaller());
assertSame(IntegerMarshaller.INSTANCE, md2.getResponseMarshaller());
assertEquals(md1.isSampledToLocalTracing(), md2.isSampledToLocalTracing());
assertEquals(md1.isIdempotent(), md2.isIdempotent());
assertEquals(md1.isSafe(), md2.isSafe());
assertSame(md1.getSchemaDescriptor(), md2.getSchemaDescriptor());
}
@Test
public void failsOnNonMatchingNames() {
List<MethodDescriptor<?, ?>> descriptors = Collections.<MethodDescriptor<?, ?>>singletonList(
MethodDescriptor.<Void, Void>newBuilder()
.setType(MethodType.UNARY)
.setFullMethodName(MethodDescriptor.generateFullMethodName("wrongservice", "method"))
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build());
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("service names");
new ServiceDescriptor("name", descriptors);
}
public static MethodType fetchMethodType(MethodDescriptor methodDescriptor) {
boolean clientStreaming = methodDescriptor.toProto().getClientStreaming();
boolean serverStreaming = methodDescriptor.toProto().getServerStreaming();
if (clientStreaming && serverStreaming) {
return MethodType.BIDI_STREAMING;
} else if (!clientStreaming && !serverStreaming) {
return MethodType.UNARY;
} else if (!clientStreaming) {
return MethodType.SERVER_STREAMING;
} else {
return MethodType.SERVER_STREAMING;
}
}
@Nullable
public ListenableFuture<Void> call(CallParams callParams) {
checkParams(callParams);
MethodType methodType = fetchMethodType(callParams.getMethodDescriptor());
List<DynamicMessage> requests = callParams.getRequests();
StreamObserver<DynamicMessage> responseObserver = callParams.getResponseObserver();
DoneObserver<DynamicMessage> doneObserver = new DoneObserver<>();
StreamObserver<DynamicMessage> compositeObserver = CompositeStreamObserver.of(responseObserver, doneObserver);
StreamObserver<DynamicMessage> requestObserver;
switch (methodType) {
case UNARY:
asyncUnaryCall(createCall(callParams), requests.get(0), compositeObserver);
return doneObserver.getCompletionFuture();
case SERVER_STREAMING:
asyncServerStreamingCall(createCall(callParams), requests.get(0), compositeObserver);
return doneObserver.getCompletionFuture();
case CLIENT_STREAMING:
requestObserver = asyncClientStreamingCall(createCall(callParams), compositeObserver);
requests.forEach(responseObserver::onNext);
requestObserver.onCompleted();
return doneObserver.getCompletionFuture();
case BIDI_STREAMING:
requestObserver = asyncBidiStreamingCall(createCall(callParams), compositeObserver);
requests.forEach(responseObserver::onNext);
requestObserver.onCompleted();
return doneObserver.getCompletionFuture();
default:
logger.info("Unknown methodType:{}", methodType);
return null;
}
}
/**
* Makes an rpc to the remote endpoint and respects the supplied callback. Returns a future which
* terminates once the call has ended. For calls which are single-request, this throws
* {@link IllegalArgumentException} if the size of {@code requests} is not exactly 1.
*/
public ListenableFuture<Void> call(
ImmutableList<DynamicMessage> requests,
StreamObserver<DynamicMessage> responseObserver,
CallOptions callOptions) {
Preconditions.checkArgument(!requests.isEmpty(), "Can't make call without any requests");
MethodType methodType = getMethodType();
long numRequests = requests.size();
if (methodType == MethodType.UNARY) {
logger.info("Making unary call");
Preconditions.checkArgument(numRequests == 1,
"Need exactly 1 request for unary call, but got: " + numRequests);
return callUnary(requests.get(0), responseObserver, callOptions);
} else if (methodType == MethodType.SERVER_STREAMING) {
logger.info("Making server streaming call");
Preconditions.checkArgument(numRequests == 1,
"Need exactly 1 request for server streaming call, but got: " + numRequests);
return callServerStreaming(requests.get(0), responseObserver, callOptions);
} else if (methodType == MethodType.CLIENT_STREAMING) {
logger.info("Making client streaming call with " + requests.size() + " requests");
return callClientStreaming(requests, responseObserver, callOptions);
} else {
// Bidi streaming.
logger.info("Making bidi streaming call with " + requests.size() + " requests");
return callBidiStreaming(requests, responseObserver, callOptions);
}
}