use of io.grpc.CallCredentials.MetadataApplier in project grpc-java by grpc.
the class ManagedChannelImplTest method informationPropagatedToNewStreamAndCallCredentials.
/**
* Test that information such as the Call's context, MethodDescriptor, authority, executor are
* propagated to newStream() and applyRequestMetadata().
*/
@Test
public void informationPropagatedToNewStreamAndCallCredentials() {
ResolvedServerInfoGroup serverInfoGroup = ResolvedServerInfoGroup.builder().add(server).build();
createChannel(new FakeNameResolverFactory(true), NO_INTERCEPTOR);
CallOptions callOptions = CallOptions.DEFAULT.withCallCredentials(creds);
final Context.Key<String> testKey = Context.key("testing");
Context ctx = Context.current().withValue(testKey, "testValue");
final LinkedList<Context> credsApplyContexts = new LinkedList<Context>();
final LinkedList<Context> newStreamContexts = new LinkedList<Context>();
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock in) throws Throwable {
credsApplyContexts.add(Context.current());
return null;
}
}).when(creds).applyRequestMetadata(any(MethodDescriptor.class), any(Attributes.class), any(Executor.class), any(MetadataApplier.class));
// First call will be on delayed transport. Only newCall() is run within the expected context,
// so that we can verify that the context is explicitly attached before calling newStream() and
// applyRequestMetadata(), which happens after we detach the context from the thread.
Context origCtx = ctx.attach();
assertEquals("testValue", testKey.get());
ClientCall<String, Integer> call = channel.newCall(method, callOptions);
ctx.detach(origCtx);
assertNull(testKey.get());
call.start(mockCallListener, new Metadata());
// Simulate name resolution results
Subchannel subchannel = helper.createSubchannel(serverInfoGroup.toEquivalentAddressGroup(), Attributes.EMPTY);
subchannel.requestConnection();
verify(mockTransportFactory).newClientTransport(same(socketAddress), eq(authority), eq(userAgent));
MockClientTransportInfo transportInfo = transports.poll();
final ConnectionClientTransport transport = transportInfo.transport;
when(transport.getAttributes()).thenReturn(Attributes.EMPTY);
doAnswer(new Answer<ClientStream>() {
@Override
public ClientStream answer(InvocationOnMock in) throws Throwable {
newStreamContexts.add(Context.current());
return mock(ClientStream.class);
}
}).when(transport).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), any(StatsTraceContext.class));
verify(creds, never()).applyRequestMetadata(any(MethodDescriptor.class), any(Attributes.class), any(Executor.class), any(MetadataApplier.class));
// applyRequestMetadata() is called after the transport becomes ready.
transportInfo.listener.transportReady();
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
helper.updatePicker(mockPicker);
executor.runDueTasks();
ArgumentCaptor<Attributes> attrsCaptor = ArgumentCaptor.forClass(Attributes.class);
ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(MetadataApplier.class);
verify(creds).applyRequestMetadata(same(method), attrsCaptor.capture(), same(executor.getScheduledExecutorService()), applierCaptor.capture());
assertEquals("testValue", testKey.get(credsApplyContexts.poll()));
assertEquals(authority, attrsCaptor.getValue().get(CallCredentials.ATTR_AUTHORITY));
assertEquals(SecurityLevel.NONE, attrsCaptor.getValue().get(CallCredentials.ATTR_SECURITY_LEVEL));
verify(transport, never()).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), any(StatsTraceContext.class));
// newStream() is called after apply() is called
applierCaptor.getValue().apply(new Metadata());
verify(transport).newStream(same(method), any(Metadata.class), same(callOptions), any(StatsTraceContext.class));
assertEquals("testValue", testKey.get(newStreamContexts.poll()));
// The context should not live beyond the scope of newStream() and applyRequestMetadata()
assertNull(testKey.get());
// Second call will not be on delayed transport
origCtx = ctx.attach();
call = channel.newCall(method, callOptions);
ctx.detach(origCtx);
call.start(mockCallListener, new Metadata());
verify(creds, times(2)).applyRequestMetadata(same(method), attrsCaptor.capture(), same(executor.getScheduledExecutorService()), applierCaptor.capture());
assertEquals("testValue", testKey.get(credsApplyContexts.poll()));
assertEquals(authority, attrsCaptor.getValue().get(CallCredentials.ATTR_AUTHORITY));
assertEquals(SecurityLevel.NONE, attrsCaptor.getValue().get(CallCredentials.ATTR_SECURITY_LEVEL));
// This is from the first call
verify(transport).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), any(StatsTraceContext.class));
// Still, newStream() is called after apply() is called
applierCaptor.getValue().apply(new Metadata());
verify(transport, times(2)).newStream(same(method), any(Metadata.class), same(callOptions), any(StatsTraceContext.class));
assertEquals("testValue", testKey.get(newStreamContexts.poll()));
assertNull(testKey.get());
}
use of io.grpc.CallCredentials.MetadataApplier in project grpc-java by grpc.
the class CallCredentialsApplyingTest method applyMetadata_inline.
@Test
public void applyMetadata_inline() {
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
MetadataApplier applier = (MetadataApplier) invocation.getArguments()[3];
Metadata headers = new Metadata();
headers.put(CREDS_KEY, CREDS_VALUE);
applier.apply(headers);
return null;
}
}).when(mockCreds).applyRequestMetadata(same(method), any(Attributes.class), same(mockExecutor), any(MetadataApplier.class));
ClientStream stream = transport.newStream(method, origHeaders, callOptions, statsTraceCtx);
verify(mockTransport).newStream(method, origHeaders, callOptions, statsTraceCtx);
assertSame(mockStream, stream);
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
}
use of io.grpc.CallCredentials.MetadataApplier in project grpc-java by grpc.
the class CallCredentialsApplyingTest method applyMetadata_delayed.
@Test
public void applyMetadata_delayed() {
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
// Will call applyRequestMetadata(), which is no-op.
DelayedStream stream = (DelayedStream) transport.newStream(method, origHeaders, callOptions, statsTraceCtx);
ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
verify(mockCreds).applyRequestMetadata(same(method), any(Attributes.class), same(mockExecutor), applierCaptor.capture());
verify(mockTransport, never()).newStream(method, origHeaders, callOptions, statsTraceCtx);
Metadata headers = new Metadata();
headers.put(CREDS_KEY, CREDS_VALUE);
applierCaptor.getValue().apply(headers);
verify(mockTransport).newStream(method, origHeaders, callOptions, statsTraceCtx);
assertSame(mockStream, stream.getRealStream());
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
}
use of io.grpc.CallCredentials.MetadataApplier in project grpc-java by grpc.
the class CallCredentialsApplyingTest method fail_inline.
@Test
public void fail_inline() {
final Status error = Status.FAILED_PRECONDITION.withDescription("channel not secure for creds");
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
MetadataApplier applier = (MetadataApplier) invocation.getArguments()[3];
applier.fail(error);
return null;
}
}).when(mockCreds).applyRequestMetadata(same(method), any(Attributes.class), same(mockExecutor), any(MetadataApplier.class));
FailingClientStream stream = (FailingClientStream) transport.newStream(method, origHeaders, callOptions, statsTraceCtx);
verify(mockTransport, never()).newStream(method, origHeaders, callOptions, statsTraceCtx);
assertSame(error, stream.getError());
}
use of io.grpc.CallCredentials.MetadataApplier in project grpc-java by grpc.
the class CallCredentialsApplyingTest method fail_delayed.
@Test
public void fail_delayed() {
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
// Will call applyRequestMetadata(), which is no-op.
DelayedStream stream = (DelayedStream) transport.newStream(method, origHeaders, callOptions, statsTraceCtx);
ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
verify(mockCreds).applyRequestMetadata(same(method), any(Attributes.class), same(mockExecutor), applierCaptor.capture());
Status error = Status.FAILED_PRECONDITION.withDescription("channel not secure for creds");
applierCaptor.getValue().fail(error);
verify(mockTransport, never()).newStream(method, origHeaders, callOptions, statsTraceCtx);
FailingClientStream failingStream = (FailingClientStream) stream.getRealStream();
assertSame(error, failingStream.getError());
}
Aggregations