mirror of https://github.com/grpc/grpc-java.git
core: Add ChannelCredentials
This commit is contained in:
parent
c8a94d1059
commit
5733cd481a
|
|
@ -20,10 +20,11 @@ import static com.google.common.base.MoreObjects.firstNonNull;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallCredentials;
|
|
||||||
import io.grpc.CallCredentials.RequestInfo;
|
import io.grpc.CallCredentials.RequestInfo;
|
||||||
|
import io.grpc.CallCredentials;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
|
import io.grpc.CompositeCallCredentials;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.MethodDescriptor;
|
import io.grpc.MethodDescriptor;
|
||||||
import io.grpc.SecurityLevel;
|
import io.grpc.SecurityLevel;
|
||||||
|
|
@ -34,11 +35,14 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
final class CallCredentialsApplyingTransportFactory implements ClientTransportFactory {
|
final class CallCredentialsApplyingTransportFactory implements ClientTransportFactory {
|
||||||
private final ClientTransportFactory delegate;
|
private final ClientTransportFactory delegate;
|
||||||
|
private final CallCredentials channelCallCredentials;
|
||||||
private final Executor appExecutor;
|
private final Executor appExecutor;
|
||||||
|
|
||||||
CallCredentialsApplyingTransportFactory(
|
CallCredentialsApplyingTransportFactory(
|
||||||
ClientTransportFactory delegate, Executor appExecutor) {
|
ClientTransportFactory delegate, CallCredentials channelCallCredentials,
|
||||||
|
Executor appExecutor) {
|
||||||
this.delegate = checkNotNull(delegate, "delegate");
|
this.delegate = checkNotNull(delegate, "delegate");
|
||||||
|
this.channelCallCredentials = channelCallCredentials;
|
||||||
this.appExecutor = checkNotNull(appExecutor, "appExecutor");
|
this.appExecutor = checkNotNull(appExecutor, "appExecutor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,6 +82,11 @@ final class CallCredentialsApplyingTransportFactory implements ClientTransportFa
|
||||||
public ClientStream newStream(
|
public ClientStream newStream(
|
||||||
final MethodDescriptor<?, ?> method, Metadata headers, final CallOptions callOptions) {
|
final MethodDescriptor<?, ?> method, Metadata headers, final CallOptions callOptions) {
|
||||||
CallCredentials creds = callOptions.getCredentials();
|
CallCredentials creds = callOptions.getCredentials();
|
||||||
|
if (creds == null) {
|
||||||
|
creds = channelCallCredentials;
|
||||||
|
} else if (channelCallCredentials != null) {
|
||||||
|
creds = new CompositeCallCredentials(channelCallCredentials, creds);
|
||||||
|
}
|
||||||
if (creds != null) {
|
if (creds != null) {
|
||||||
MetadataApplierImpl applier = new MetadataApplierImpl(
|
MetadataApplierImpl applier = new MetadataApplierImpl(
|
||||||
delegate, method, headers, callOptions);
|
delegate, method, headers, callOptions);
|
||||||
|
|
|
||||||
|
|
@ -589,8 +589,8 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
||||||
this.timeProvider = checkNotNull(timeProvider, "timeProvider");
|
this.timeProvider = checkNotNull(timeProvider, "timeProvider");
|
||||||
this.executorPool = checkNotNull(builder.executorPool, "executorPool");
|
this.executorPool = checkNotNull(builder.executorPool, "executorPool");
|
||||||
this.executor = checkNotNull(executorPool.getObject(), "executor");
|
this.executor = checkNotNull(executorPool.getObject(), "executor");
|
||||||
this.transportFactory =
|
this.transportFactory = new CallCredentialsApplyingTransportFactory(
|
||||||
new CallCredentialsApplyingTransportFactory(clientTransportFactory, this.executor);
|
clientTransportFactory, builder.callCredentials, this.executor);
|
||||||
this.scheduledExecutor =
|
this.scheduledExecutor =
|
||||||
new RestrictedScheduledExecutor(transportFactory.getScheduledExecutorService());
|
new RestrictedScheduledExecutor(transportFactory.getScheduledExecutorService());
|
||||||
maxTraceEvents = builder.maxTraceEvents;
|
maxTraceEvents = builder.maxTraceEvents;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import com.google.common.base.Preconditions;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.BinaryLog;
|
import io.grpc.BinaryLog;
|
||||||
|
import io.grpc.CallCredentials;
|
||||||
import io.grpc.ClientInterceptor;
|
import io.grpc.ClientInterceptor;
|
||||||
import io.grpc.CompressorRegistry;
|
import io.grpc.CompressorRegistry;
|
||||||
import io.grpc.DecompressorRegistry;
|
import io.grpc.DecompressorRegistry;
|
||||||
|
|
@ -109,6 +110,8 @@ public final class ManagedChannelImplBuilder
|
||||||
private NameResolver.Factory nameResolverFactory = nameResolverRegistry.asFactory();
|
private NameResolver.Factory nameResolverFactory = nameResolverRegistry.asFactory();
|
||||||
|
|
||||||
final String target;
|
final String target;
|
||||||
|
@Nullable
|
||||||
|
final CallCredentials callCredentials;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final SocketAddress directServerAddress;
|
private final SocketAddress directServerAddress;
|
||||||
|
|
@ -222,7 +225,19 @@ public final class ManagedChannelImplBuilder
|
||||||
public ManagedChannelImplBuilder(String target,
|
public ManagedChannelImplBuilder(String target,
|
||||||
ClientTransportFactoryBuilder clientTransportFactoryBuilder,
|
ClientTransportFactoryBuilder clientTransportFactoryBuilder,
|
||||||
@Nullable ChannelBuilderDefaultPortProvider channelBuilderDefaultPortProvider) {
|
@Nullable ChannelBuilderDefaultPortProvider channelBuilderDefaultPortProvider) {
|
||||||
|
this(target, null, clientTransportFactoryBuilder, channelBuilderDefaultPortProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new managed channel builder with a target string, which can be either a valid {@link
|
||||||
|
* io.grpc.NameResolver}-compliant URI, or an authority string. Transport implementors must
|
||||||
|
* provide client transport factory builder, and may set custom channel default port provider.
|
||||||
|
*/
|
||||||
|
public ManagedChannelImplBuilder(String target, @Nullable CallCredentials callCreds,
|
||||||
|
ClientTransportFactoryBuilder clientTransportFactoryBuilder,
|
||||||
|
@Nullable ChannelBuilderDefaultPortProvider channelBuilderDefaultPortProvider) {
|
||||||
this.target = Preconditions.checkNotNull(target, "target");
|
this.target = Preconditions.checkNotNull(target, "target");
|
||||||
|
this.callCredentials = callCreds;
|
||||||
this.clientTransportFactoryBuilder = Preconditions
|
this.clientTransportFactoryBuilder = Preconditions
|
||||||
.checkNotNull(clientTransportFactoryBuilder, "clientTransportFactoryBuilder");
|
.checkNotNull(clientTransportFactoryBuilder, "clientTransportFactoryBuilder");
|
||||||
this.directServerAddress = null;
|
this.directServerAddress = null;
|
||||||
|
|
@ -258,6 +273,7 @@ public final class ManagedChannelImplBuilder
|
||||||
ClientTransportFactoryBuilder clientTransportFactoryBuilder,
|
ClientTransportFactoryBuilder clientTransportFactoryBuilder,
|
||||||
@Nullable ChannelBuilderDefaultPortProvider channelBuilderDefaultPortProvider) {
|
@Nullable ChannelBuilderDefaultPortProvider channelBuilderDefaultPortProvider) {
|
||||||
this.target = makeTargetStringForDirectAddress(directServerAddress);
|
this.target = makeTargetStringForDirectAddress(directServerAddress);
|
||||||
|
this.callCredentials = null;
|
||||||
this.clientTransportFactoryBuilder = Preconditions
|
this.clientTransportFactoryBuilder = Preconditions
|
||||||
.checkNotNull(clientTransportFactoryBuilder, "clientTransportFactoryBuilder");
|
.checkNotNull(clientTransportFactoryBuilder, "clientTransportFactoryBuilder");
|
||||||
this.directServerAddress = directServerAddress;
|
this.directServerAddress = directServerAddress;
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ public class CallCredentials2ApplyingTest {
|
||||||
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
|
ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
|
||||||
mockTransportFactory, mockExecutor);
|
mockTransportFactory, null, mockExecutor);
|
||||||
transport = (ForwardingConnectionClientTransport)
|
transport = (ForwardingConnectionClientTransport)
|
||||||
transportFactory.newClientTransport(address, clientTransportOptions, channelLogger);
|
transportFactory.newClientTransport(address, clientTransportOptions, channelLogger);
|
||||||
callOptions = CallOptions.DEFAULT.withCallCredentials(mockCreds);
|
callOptions = CallOptions.DEFAULT.withCallCredentials(mockCreds);
|
||||||
|
|
|
||||||
|
|
@ -102,24 +102,23 @@ public class CallCredentialsApplyingTest {
|
||||||
Metadata.Key.of("test-creds", Metadata.ASCII_STRING_MARSHALLER);
|
Metadata.Key.of("test-creds", Metadata.ASCII_STRING_MARSHALLER);
|
||||||
private static final String CREDS_VALUE = "some credentials";
|
private static final String CREDS_VALUE = "some credentials";
|
||||||
|
|
||||||
|
private final ClientTransportFactory.ClientTransportOptions clientTransportOptions =
|
||||||
|
new ClientTransportFactory.ClientTransportOptions()
|
||||||
|
.setAuthority(AUTHORITY)
|
||||||
|
.setUserAgent(USER_AGENT);
|
||||||
private final Metadata origHeaders = new Metadata();
|
private final Metadata origHeaders = new Metadata();
|
||||||
private ForwardingConnectionClientTransport transport;
|
private ForwardingConnectionClientTransport transport;
|
||||||
private CallOptions callOptions;
|
private CallOptions callOptions;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
ClientTransportFactory.ClientTransportOptions clientTransportOptions =
|
|
||||||
new ClientTransportFactory.ClientTransportOptions()
|
|
||||||
.setAuthority(AUTHORITY)
|
|
||||||
.setUserAgent(USER_AGENT);
|
|
||||||
|
|
||||||
origHeaders.put(ORIG_HEADER_KEY, ORIG_HEADER_VALUE);
|
origHeaders.put(ORIG_HEADER_KEY, ORIG_HEADER_VALUE);
|
||||||
when(mockTransportFactory.newClientTransport(address, clientTransportOptions, channelLogger))
|
when(mockTransportFactory.newClientTransport(address, clientTransportOptions, channelLogger))
|
||||||
.thenReturn(mockTransport);
|
.thenReturn(mockTransport);
|
||||||
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
|
ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
|
||||||
mockTransportFactory, mockExecutor);
|
mockTransportFactory, null, mockExecutor);
|
||||||
transport = (ForwardingConnectionClientTransport)
|
transport = (ForwardingConnectionClientTransport)
|
||||||
transportFactory.newClientTransport(address, clientTransportOptions, channelLogger);
|
transportFactory.newClientTransport(address, clientTransportOptions, channelLogger);
|
||||||
callOptions = CallOptions.DEFAULT.withCallCredentials(mockCreds);
|
callOptions = CallOptions.DEFAULT.withCallCredentials(mockCreds);
|
||||||
|
|
@ -185,19 +184,8 @@ public class CallCredentialsApplyingTest {
|
||||||
@Test
|
@Test
|
||||||
public void applyMetadata_inline() {
|
public void applyMetadata_inline() {
|
||||||
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
||||||
doAnswer(new Answer<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
|
||||||
CallCredentials.MetadataApplier applier =
|
|
||||||
(CallCredentials.MetadataApplier) invocation.getArguments()[2];
|
|
||||||
Metadata headers = new Metadata();
|
|
||||||
headers.put(CREDS_KEY, CREDS_VALUE);
|
|
||||||
applier.apply(headers);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).when(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
|
||||||
same(mockExecutor), any(CallCredentials.MetadataApplier.class));
|
|
||||||
|
|
||||||
|
callOptions = callOptions.withCallCredentials(new FakeCallCredentials(CREDS_KEY, CREDS_VALUE));
|
||||||
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
||||||
|
|
||||||
verify(mockTransport).newStream(method, origHeaders, callOptions);
|
verify(mockTransport).newStream(method, origHeaders, callOptions);
|
||||||
|
|
@ -279,4 +267,67 @@ public class CallCredentialsApplyingTest {
|
||||||
assertNull(origHeaders.get(CREDS_KEY));
|
assertNull(origHeaders.get(CREDS_KEY));
|
||||||
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void justCallOptionCreds() {
|
||||||
|
callOptions = callOptions.withCallCredentials(new FakeCallCredentials(CREDS_KEY, CREDS_VALUE));
|
||||||
|
|
||||||
|
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
||||||
|
|
||||||
|
assertSame(mockStream, stream);
|
||||||
|
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
||||||
|
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void justChannelCreds() {
|
||||||
|
ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
|
||||||
|
mockTransportFactory, new FakeCallCredentials(CREDS_KEY, CREDS_VALUE), mockExecutor);
|
||||||
|
transport = (ForwardingConnectionClientTransport)
|
||||||
|
transportFactory.newClientTransport(address, clientTransportOptions, channelLogger);
|
||||||
|
callOptions = callOptions.withCallCredentials(null);
|
||||||
|
|
||||||
|
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
||||||
|
|
||||||
|
assertSame(mockStream, stream);
|
||||||
|
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
||||||
|
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void callOptionAndChanelCreds() {
|
||||||
|
ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
|
||||||
|
mockTransportFactory, new FakeCallCredentials(CREDS_KEY, CREDS_VALUE), mockExecutor);
|
||||||
|
transport = (ForwardingConnectionClientTransport)
|
||||||
|
transportFactory.newClientTransport(address, clientTransportOptions, channelLogger);
|
||||||
|
Metadata.Key<String> creds2Key =
|
||||||
|
Metadata.Key.of("test-creds2", Metadata.ASCII_STRING_MARSHALLER);
|
||||||
|
String creds2Value = "some more credentials";
|
||||||
|
callOptions = callOptions.withCallCredentials(new FakeCallCredentials(creds2Key, creds2Value));
|
||||||
|
|
||||||
|
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
||||||
|
|
||||||
|
assertSame(mockStream, stream);
|
||||||
|
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
||||||
|
assertEquals(creds2Value, origHeaders.get(creds2Key));
|
||||||
|
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract static class BaseCallCredentials extends CallCredentials {
|
||||||
|
@Override public void thisUsesUnstableApi() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FakeCallCredentials extends BaseCallCredentials {
|
||||||
|
private final Metadata headers;
|
||||||
|
|
||||||
|
public <T> FakeCallCredentials(Metadata.Key<T> key, T value) {
|
||||||
|
headers = new Metadata();
|
||||||
|
headers.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void applyRequestMetadata(
|
||||||
|
RequestInfo requestInfo, Executor appExecutor, CallCredentials.MetadataApplier applier) {
|
||||||
|
applier.apply(headers);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue