mirror of https://github.com/grpc/grpc-java.git
netty: Add ServerCredentials
This commit is contained in:
parent
60319dad2d
commit
edcc6854a6
|
|
@ -21,9 +21,11 @@ import static com.google.common.truth.Truth.assertThat;
|
||||||
import io.grpc.ChannelCredentials;
|
import io.grpc.ChannelCredentials;
|
||||||
import io.grpc.Grpc;
|
import io.grpc.Grpc;
|
||||||
import io.grpc.InsecureChannelCredentials;
|
import io.grpc.InsecureChannelCredentials;
|
||||||
|
import io.grpc.InsecureServerCredentials;
|
||||||
import io.grpc.ManagedChannel;
|
import io.grpc.ManagedChannel;
|
||||||
import io.grpc.Server;
|
import io.grpc.Server;
|
||||||
import io.grpc.ServerBuilder;
|
import io.grpc.ServerCredentials;
|
||||||
|
import io.grpc.TlsServerCredentials;
|
||||||
import io.grpc.internal.testing.TestUtils;
|
import io.grpc.internal.testing.TestUtils;
|
||||||
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
|
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
|
||||||
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
|
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
|
||||||
|
|
@ -69,14 +71,15 @@ public final class ShadingTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serviceLoaderFindsNetty() throws Exception {
|
public void serviceLoaderFindsNetty() throws Exception {
|
||||||
assertThat(ServerBuilder.forPort(0)).isInstanceOf(NettyServerBuilder.class);
|
assertThat(Grpc.newServerBuilderForPort(0, InsecureServerCredentials.create()))
|
||||||
|
.isInstanceOf(NettyServerBuilder.class);
|
||||||
assertThat(Grpc.newChannelBuilder("localhost:1234", InsecureChannelCredentials.create()))
|
assertThat(Grpc.newChannelBuilder("localhost:1234", InsecureChannelCredentials.create()))
|
||||||
.isInstanceOf(NettyChannelBuilder.class);
|
.isInstanceOf(NettyChannelBuilder.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void basic() throws Exception {
|
public void basic() throws Exception {
|
||||||
server = ServerBuilder.forPort(0)
|
server = Grpc.newServerBuilderForPort(0, InsecureServerCredentials.create())
|
||||||
.addService(new SimpleServiceImpl())
|
.addService(new SimpleServiceImpl())
|
||||||
.build().start();
|
.build().start();
|
||||||
channel = Grpc.newChannelBuilder(
|
channel = Grpc.newChannelBuilder(
|
||||||
|
|
@ -89,8 +92,9 @@ public final class ShadingTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void tcnative() throws Exception {
|
public void tcnative() throws Exception {
|
||||||
server = NettyServerBuilder.forPort(0)
|
ServerCredentials serverCreds = TlsServerCredentials.create(
|
||||||
.useTransportSecurity(TestUtils.loadCert("server1.pem"), TestUtils.loadCert("server1.key"))
|
TestUtils.loadCert("server1.pem"), TestUtils.loadCert("server1.key"));
|
||||||
|
server = Grpc.newServerBuilderForPort(0, serverCreds)
|
||||||
.addService(new SimpleServiceImpl())
|
.addService(new SimpleServiceImpl())
|
||||||
.build().start();
|
.build().start();
|
||||||
ChannelCredentials creds = NettySslContextChannelCredentials.create(
|
ChannelCredentials creds = NettySslContextChannelCredentials.create(
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@ package io.grpc.netty;
|
||||||
|
|
||||||
import io.grpc.ChannelCredentials;
|
import io.grpc.ChannelCredentials;
|
||||||
import io.grpc.Internal;
|
import io.grpc.Internal;
|
||||||
import io.netty.channel.ChannelHandler;
|
|
||||||
import io.netty.util.AsciiString;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal {@link NettyChannelCredentials} accessor. This is intended for usage internal to the
|
* Internal {@link NettyChannelCredentials} accessor. This is intended for usage internal to the
|
||||||
|
|
@ -50,27 +48,8 @@ public final class InternalNettyChannelCredentials {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InternalProtocolNegotiator.ProtocolNegotiator newNegotiator() {
|
public InternalProtocolNegotiator.ProtocolNegotiator newNegotiator() {
|
||||||
final ProtocolNegotiator pn = result.negotiator.newNegotiator();
|
return new InternalProtocolNegotiator.ProtocolNegotiatorAdapter(
|
||||||
final class LocalProtocolNegotiator
|
result.negotiator.newNegotiator());
|
||||||
implements InternalProtocolNegotiator.ProtocolNegotiator {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsciiString scheme() {
|
|
||||||
return pn.scheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
|
|
||||||
return pn.newHandler(grpcHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
pn.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new LocalProtocolNegotiator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 The gRPC Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.grpc.netty;
|
||||||
|
|
||||||
|
import io.grpc.Internal;
|
||||||
|
import io.grpc.ServerCredentials;
|
||||||
|
import io.grpc.internal.ObjectPool;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal {@link NettyServerCredentials} accessor. This is intended for usage internal to the
|
||||||
|
* gRPC team. If you *really* think you need to use this, contact the gRPC team first.
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public final class InternalNettyServerCredentials {
|
||||||
|
private InternalNettyServerCredentials() {}
|
||||||
|
|
||||||
|
/** Creates a {@link ServerCredentials} that will use the provided {@code negotiator}. */
|
||||||
|
public static ServerCredentials create(InternalProtocolNegotiator.ProtocolNegotiator negotiator) {
|
||||||
|
return NettyServerCredentials.create(ProtocolNegotiators.fixedServerFactory(negotiator));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link ServerCredentials} that will use the provided {@code negotiator}. Use of
|
||||||
|
* {@link #create(io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator)} is preferred over
|
||||||
|
* this method when possible.
|
||||||
|
*/
|
||||||
|
public static ServerCredentials create(InternalProtocolNegotiator.ServerFactory negotiator) {
|
||||||
|
return NettyServerCredentials.create(negotiator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a {@link ServerCredentials} to a negotiator, in similar fashion as for a new server.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if unable to convert
|
||||||
|
*/
|
||||||
|
public static InternalProtocolNegotiator.ServerFactory toNegotiator(
|
||||||
|
ServerCredentials channelCredentials) {
|
||||||
|
final ProtocolNegotiators.FromServerCredentialsResult result =
|
||||||
|
ProtocolNegotiators.from(channelCredentials);
|
||||||
|
if (result.error != null) {
|
||||||
|
throw new IllegalArgumentException(result.error);
|
||||||
|
}
|
||||||
|
final class ServerFactory implements InternalProtocolNegotiator.ServerFactory {
|
||||||
|
@Override
|
||||||
|
public InternalProtocolNegotiator.ProtocolNegotiator newNegotiator(
|
||||||
|
ObjectPool<? extends Executor> offloadExecutorPool) {
|
||||||
|
return new InternalProtocolNegotiator.ProtocolNegotiatorAdapter(
|
||||||
|
result.negotiator.newNegotiator(offloadExecutorPool));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ServerFactory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,12 @@
|
||||||
|
|
||||||
package io.grpc.netty;
|
package io.grpc.netty;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import io.grpc.Internal;
|
import io.grpc.Internal;
|
||||||
|
import io.grpc.internal.ObjectPool;
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
|
import io.netty.util.AsciiString;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal accessor for {@link ProtocolNegotiator}.
|
* Internal accessor for {@link ProtocolNegotiator}.
|
||||||
|
|
@ -28,7 +33,35 @@ public final class InternalProtocolNegotiator {
|
||||||
|
|
||||||
public interface ProtocolNegotiator extends io.grpc.netty.ProtocolNegotiator {}
|
public interface ProtocolNegotiator extends io.grpc.netty.ProtocolNegotiator {}
|
||||||
|
|
||||||
|
static final class ProtocolNegotiatorAdapter
|
||||||
|
implements InternalProtocolNegotiator.ProtocolNegotiator {
|
||||||
|
private final io.grpc.netty.ProtocolNegotiator negotiator;
|
||||||
|
|
||||||
|
public ProtocolNegotiatorAdapter(io.grpc.netty.ProtocolNegotiator negotiator) {
|
||||||
|
this.negotiator = Preconditions.checkNotNull(negotiator, "negotiator");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AsciiString scheme() {
|
||||||
|
return negotiator.scheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
|
||||||
|
return negotiator.newHandler(grpcHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
negotiator.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public interface ClientFactory extends io.grpc.netty.ProtocolNegotiator.ClientFactory {
|
public interface ClientFactory extends io.grpc.netty.ProtocolNegotiator.ClientFactory {
|
||||||
@Override ProtocolNegotiator newNegotiator();
|
@Override ProtocolNegotiator newNegotiator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ServerFactory extends io.grpc.netty.ProtocolNegotiator.ServerFactory {
|
||||||
|
@Override ProtocolNegotiator newNegotiator(ObjectPool<? extends Executor> offloadExecutorPool);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
import io.grpc.ExperimentalApi;
|
import io.grpc.ExperimentalApi;
|
||||||
import io.grpc.Internal;
|
import io.grpc.Internal;
|
||||||
import io.grpc.ServerBuilder;
|
import io.grpc.ServerBuilder;
|
||||||
|
import io.grpc.ServerCredentials;
|
||||||
import io.grpc.ServerStreamTracer;
|
import io.grpc.ServerStreamTracer;
|
||||||
import io.grpc.internal.AbstractServerImplBuilder;
|
import io.grpc.internal.AbstractServerImplBuilder;
|
||||||
import io.grpc.internal.FixedObjectPool;
|
import io.grpc.internal.FixedObjectPool;
|
||||||
|
|
@ -58,7 +59,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.annotation.CheckReturnValue;
|
import javax.annotation.CheckReturnValue;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -98,8 +98,8 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
|
||||||
private ObjectPool<? extends EventLoopGroup> workerEventLoopGroupPool =
|
private ObjectPool<? extends EventLoopGroup> workerEventLoopGroupPool =
|
||||||
DEFAULT_WORKER_EVENT_LOOP_GROUP_POOL;
|
DEFAULT_WORKER_EVENT_LOOP_GROUP_POOL;
|
||||||
private boolean forceHeapBuffer;
|
private boolean forceHeapBuffer;
|
||||||
private SslContext sslContext;
|
private ProtocolNegotiator.ServerFactory protocolNegotiatorFactory;
|
||||||
private ProtocolNegotiator protocolNegotiator;
|
private final boolean freezeProtocolNegotiatorFactory;
|
||||||
private int maxConcurrentCallsPerConnection = Integer.MAX_VALUE;
|
private int maxConcurrentCallsPerConnection = Integer.MAX_VALUE;
|
||||||
private boolean autoFlowControl = true;
|
private boolean autoFlowControl = true;
|
||||||
private int flowControlWindow = DEFAULT_FLOW_CONTROL_WINDOW;
|
private int flowControlWindow = DEFAULT_FLOW_CONTROL_WINDOW;
|
||||||
|
|
@ -121,7 +121,18 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
|
||||||
*/
|
*/
|
||||||
@CheckReturnValue
|
@CheckReturnValue
|
||||||
public static NettyServerBuilder forPort(int port) {
|
public static NettyServerBuilder forPort(int port) {
|
||||||
return new NettyServerBuilder(port);
|
return forAddress(new InetSocketAddress(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a server builder that will bind to the given port.
|
||||||
|
*
|
||||||
|
* @param port the port on which the server is to be bound.
|
||||||
|
* @return the server builder.
|
||||||
|
*/
|
||||||
|
@CheckReturnValue
|
||||||
|
public static NettyServerBuilder forPort(int port, ServerCredentials creds) {
|
||||||
|
return forAddress(new InetSocketAddress(port), creds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -135,6 +146,21 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
|
||||||
return new NettyServerBuilder(address);
|
return new NettyServerBuilder(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a server builder configured with the given {@link SocketAddress}.
|
||||||
|
*
|
||||||
|
* @param address the socket address on which the server is to be bound.
|
||||||
|
* @return the server builder
|
||||||
|
*/
|
||||||
|
@CheckReturnValue
|
||||||
|
public static NettyServerBuilder forAddress(SocketAddress address, ServerCredentials creds) {
|
||||||
|
ProtocolNegotiators.FromServerCredentialsResult result = ProtocolNegotiators.from(creds);
|
||||||
|
if (result.error != null) {
|
||||||
|
throw new IllegalArgumentException(result.error);
|
||||||
|
}
|
||||||
|
return new NettyServerBuilder(address, result.negotiator);
|
||||||
|
}
|
||||||
|
|
||||||
private final class NettyClientTransportServersBuilder implements ClientTransportServersBuilder {
|
private final class NettyClientTransportServersBuilder implements ClientTransportServersBuilder {
|
||||||
@Override
|
@Override
|
||||||
public List<? extends InternalServer> buildClientTransportServers(
|
public List<? extends InternalServer> buildClientTransportServers(
|
||||||
|
|
@ -143,16 +169,21 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@CheckReturnValue
|
|
||||||
private NettyServerBuilder(int port) {
|
|
||||||
serverImplBuilder = new ServerImplBuilder(new NettyClientTransportServersBuilder());
|
|
||||||
this.listenAddresses.add(new InetSocketAddress(port));
|
|
||||||
}
|
|
||||||
|
|
||||||
@CheckReturnValue
|
@CheckReturnValue
|
||||||
private NettyServerBuilder(SocketAddress address) {
|
private NettyServerBuilder(SocketAddress address) {
|
||||||
serverImplBuilder = new ServerImplBuilder(new NettyClientTransportServersBuilder());
|
serverImplBuilder = new ServerImplBuilder(new NettyClientTransportServersBuilder());
|
||||||
this.listenAddresses.add(address);
|
this.listenAddresses.add(address);
|
||||||
|
this.protocolNegotiatorFactory = ProtocolNegotiators.serverPlaintextFactory();
|
||||||
|
this.freezeProtocolNegotiatorFactory = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@CheckReturnValue
|
||||||
|
NettyServerBuilder(
|
||||||
|
SocketAddress address, ProtocolNegotiator.ServerFactory negotiatorFactory) {
|
||||||
|
serverImplBuilder = new ServerImplBuilder(new NettyClientTransportServersBuilder());
|
||||||
|
this.listenAddresses.add(address);
|
||||||
|
this.protocolNegotiatorFactory = checkNotNull(negotiatorFactory, "negotiatorFactory");
|
||||||
|
this.freezeProtocolNegotiatorFactory = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Internal
|
@Internal
|
||||||
|
|
@ -317,25 +348,28 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
|
||||||
* have been configured with {@link GrpcSslContexts}, but options could have been overridden.
|
* have been configured with {@link GrpcSslContexts}, but options could have been overridden.
|
||||||
*/
|
*/
|
||||||
public NettyServerBuilder sslContext(SslContext sslContext) {
|
public NettyServerBuilder sslContext(SslContext sslContext) {
|
||||||
|
checkState(!freezeProtocolNegotiatorFactory,
|
||||||
|
"Cannot change security when using ServerCredentials");
|
||||||
if (sslContext != null) {
|
if (sslContext != null) {
|
||||||
checkArgument(sslContext.isServer(),
|
checkArgument(sslContext.isServer(),
|
||||||
"Client SSL context can not be used for server");
|
"Client SSL context can not be used for server");
|
||||||
GrpcSslContexts.ensureAlpnAndH2Enabled(sslContext.applicationProtocolNegotiator());
|
GrpcSslContexts.ensureAlpnAndH2Enabled(sslContext.applicationProtocolNegotiator());
|
||||||
|
protocolNegotiatorFactory = ProtocolNegotiators.serverTlsFactory(sslContext);
|
||||||
|
} else {
|
||||||
|
protocolNegotiatorFactory = ProtocolNegotiators.serverPlaintextFactory();
|
||||||
}
|
}
|
||||||
this.sslContext = sslContext;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link ProtocolNegotiator} to be used. If non-{@code null}, overrides the value
|
* Sets the {@link ProtocolNegotiator} to be used. Overrides the value specified in {@link
|
||||||
* specified in {@link #sslContext(SslContext)}.
|
* #sslContext(SslContext)}.
|
||||||
*
|
|
||||||
* <p>Default: {@code null}.
|
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
public final NettyServerBuilder protocolNegotiator(
|
public final NettyServerBuilder protocolNegotiator(ProtocolNegotiator protocolNegotiator) {
|
||||||
@Nullable ProtocolNegotiator protocolNegotiator) {
|
checkState(!freezeProtocolNegotiatorFactory,
|
||||||
this.protocolNegotiator = protocolNegotiator;
|
"Cannot change security when using ServerCredentials");
|
||||||
|
this.protocolNegotiatorFactory = ProtocolNegotiators.fixedServerFactory(protocolNegotiator);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -586,12 +620,8 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
|
||||||
List<? extends ServerStreamTracer.Factory> streamTracerFactories) {
|
List<? extends ServerStreamTracer.Factory> streamTracerFactories) {
|
||||||
assertEventLoopsAndChannelType();
|
assertEventLoopsAndChannelType();
|
||||||
|
|
||||||
ProtocolNegotiator negotiator = protocolNegotiator;
|
ProtocolNegotiator negotiator = protocolNegotiatorFactory.newNegotiator(
|
||||||
if (negotiator == null) {
|
this.serverImplBuilder.getExecutorPool());
|
||||||
negotiator = sslContext != null
|
|
||||||
? ProtocolNegotiators.serverTls(sslContext, this.serverImplBuilder.getExecutorPool())
|
|
||||||
: ProtocolNegotiators.serverPlaintext();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<NettyServer> transportServers = new ArrayList<>(listenAddresses.size());
|
List<NettyServer> transportServers = new ArrayList<>(listenAddresses.size());
|
||||||
for (SocketAddress listenAddress : listenAddresses) {
|
for (SocketAddress listenAddress : listenAddresses) {
|
||||||
|
|
@ -631,23 +661,31 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NettyServerBuilder useTransportSecurity(File certChain, File privateKey) {
|
public NettyServerBuilder useTransportSecurity(File certChain, File privateKey) {
|
||||||
|
checkState(!freezeProtocolNegotiatorFactory,
|
||||||
|
"Cannot change security when using ServerCredentials");
|
||||||
|
SslContext sslContext;
|
||||||
try {
|
try {
|
||||||
sslContext = GrpcSslContexts.forServer(certChain, privateKey).build();
|
sslContext = GrpcSslContexts.forServer(certChain, privateKey).build();
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
// This should likely be some other, easier to catch exception.
|
// This should likely be some other, easier to catch exception.
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
protocolNegotiatorFactory = ProtocolNegotiators.serverTlsFactory(sslContext);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NettyServerBuilder useTransportSecurity(InputStream certChain, InputStream privateKey) {
|
public NettyServerBuilder useTransportSecurity(InputStream certChain, InputStream privateKey) {
|
||||||
|
checkState(!freezeProtocolNegotiatorFactory,
|
||||||
|
"Cannot change security when using ServerCredentials");
|
||||||
|
SslContext sslContext;
|
||||||
try {
|
try {
|
||||||
sslContext = GrpcSslContexts.forServer(certChain, privateKey).build();
|
sslContext = GrpcSslContexts.forServer(certChain, privateKey).build();
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
// This should likely be some other, easier to catch exception.
|
// This should likely be some other, easier to catch exception.
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
protocolNegotiatorFactory = ProtocolNegotiators.serverTlsFactory(sslContext);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 The gRPC Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.grpc.netty;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import io.grpc.ServerCredentials;
|
||||||
|
|
||||||
|
/** A credential with full control over the security handshake. */
|
||||||
|
final class NettyServerCredentials extends ServerCredentials {
|
||||||
|
public static ServerCredentials create(ProtocolNegotiator.ServerFactory negotiator) {
|
||||||
|
return new NettyServerCredentials(negotiator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ProtocolNegotiator.ServerFactory negotiator;
|
||||||
|
|
||||||
|
private NettyServerCredentials(ProtocolNegotiator.ServerFactory negotiator) {
|
||||||
|
this.negotiator = Preconditions.checkNotNull(negotiator, "negotiator");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProtocolNegotiator.ServerFactory getNegotiator() {
|
||||||
|
return negotiator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,10 +17,11 @@
|
||||||
package io.grpc.netty;
|
package io.grpc.netty;
|
||||||
|
|
||||||
import io.grpc.Internal;
|
import io.grpc.Internal;
|
||||||
|
import io.grpc.ServerCredentials;
|
||||||
import io.grpc.ServerProvider;
|
import io.grpc.ServerProvider;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
/** Provider for {@link NettyServerBuilder} instances. */
|
||||||
/** Provider for {@link NettyChannelBuilder} instances. */
|
|
||||||
@Internal
|
@Internal
|
||||||
public final class NettyServerProvider extends ServerProvider {
|
public final class NettyServerProvider extends ServerProvider {
|
||||||
|
|
||||||
|
|
@ -38,5 +39,15 @@ public final class NettyServerProvider extends ServerProvider {
|
||||||
protected NettyServerBuilder builderForPort(int port) {
|
protected NettyServerBuilder builderForPort(int port) {
|
||||||
return NettyServerBuilder.forPort(port);
|
return NettyServerBuilder.forPort(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NewServerBuilderResult newServerBuilderForPort(int port, ServerCredentials creds) {
|
||||||
|
ProtocolNegotiators.FromServerCredentialsResult result = ProtocolNegotiators.from(creds);
|
||||||
|
if (result.error != null) {
|
||||||
|
return NewServerBuilderResult.error(result.error);
|
||||||
|
}
|
||||||
|
return NewServerBuilderResult.serverBuilder(
|
||||||
|
new NettyServerBuilder(new InetSocketAddress(port), result.negotiator));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package io.grpc.netty;
|
package io.grpc.netty;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import io.grpc.ChannelCredentials;
|
import io.grpc.ChannelCredentials;
|
||||||
import io.grpc.ExperimentalApi;
|
import io.grpc.ExperimentalApi;
|
||||||
import io.netty.handler.ssl.SslContext;
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
|
@ -30,6 +31,9 @@ public final class NettySslContextChannelCredentials {
|
||||||
* with {@link GrpcSslContexts}, but options could have been overridden.
|
* with {@link GrpcSslContexts}, but options could have been overridden.
|
||||||
*/
|
*/
|
||||||
public static ChannelCredentials create(SslContext sslContext) {
|
public static ChannelCredentials create(SslContext sslContext) {
|
||||||
|
Preconditions.checkArgument(sslContext.isClient(),
|
||||||
|
"Server SSL context can not be used for client channel");
|
||||||
|
GrpcSslContexts.ensureAlpnAndH2Enabled(sslContext.applicationProtocolNegotiator());
|
||||||
return NettyChannelCredentials.create(ProtocolNegotiators.tlsClientFactory(sslContext));
|
return NettyChannelCredentials.create(ProtocolNegotiators.tlsClientFactory(sslContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 The gRPC Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.grpc.netty;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import io.grpc.ExperimentalApi;
|
||||||
|
import io.grpc.ServerCredentials;
|
||||||
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
|
||||||
|
/** A credential that performs TLS with Netty's SslContext as configuration. */
|
||||||
|
@ExperimentalApi("There is no plan to make this API stable, given transport API instability")
|
||||||
|
public final class NettySslContextServerCredentials {
|
||||||
|
private NettySslContextServerCredentials() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a credential using Netty's SslContext as configuration. It must have been configured
|
||||||
|
* with {@link GrpcSslContexts}, but options could have been overridden.
|
||||||
|
*/
|
||||||
|
public static ServerCredentials create(SslContext sslContext) {
|
||||||
|
Preconditions.checkArgument(sslContext.isServer(),
|
||||||
|
"Client SSL context can not be used for server");
|
||||||
|
GrpcSslContexts.ensureAlpnAndH2Enabled(sslContext.applicationProtocolNegotiator());
|
||||||
|
return NettyServerCredentials.create(ProtocolNegotiators.serverTlsFactory(sslContext));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,8 +16,10 @@
|
||||||
|
|
||||||
package io.grpc.netty;
|
package io.grpc.netty;
|
||||||
|
|
||||||
|
import io.grpc.internal.ObjectPool;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An class that provides a Netty handler to control protocol negotiation.
|
* An class that provides a Netty handler to control protocol negotiation.
|
||||||
|
|
@ -52,4 +54,13 @@ interface ProtocolNegotiator {
|
||||||
/** Returns the implicit port to use if no port was specified explicitly by the user. */
|
/** Returns the implicit port to use if no port was specified explicitly by the user. */
|
||||||
int getDefaultPort();
|
int getDefaultPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ServerFactory {
|
||||||
|
/**
|
||||||
|
* Creates a new negotiator.
|
||||||
|
*
|
||||||
|
* @param offloadExecutorPool an executor pool for time-consuming tasks
|
||||||
|
*/
|
||||||
|
ProtocolNegotiator newNegotiator(ObjectPool<? extends Executor> offloadExecutorPool);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,15 +28,19 @@ import io.grpc.ChannelCredentials;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
import io.grpc.ChannelLogger.ChannelLogLevel;
|
import io.grpc.ChannelLogger.ChannelLogLevel;
|
||||||
import io.grpc.ChoiceChannelCredentials;
|
import io.grpc.ChoiceChannelCredentials;
|
||||||
|
import io.grpc.ChoiceServerCredentials;
|
||||||
import io.grpc.CompositeCallCredentials;
|
import io.grpc.CompositeCallCredentials;
|
||||||
import io.grpc.CompositeChannelCredentials;
|
import io.grpc.CompositeChannelCredentials;
|
||||||
import io.grpc.Grpc;
|
import io.grpc.Grpc;
|
||||||
import io.grpc.InsecureChannelCredentials;
|
import io.grpc.InsecureChannelCredentials;
|
||||||
|
import io.grpc.InsecureServerCredentials;
|
||||||
import io.grpc.InternalChannelz.Security;
|
import io.grpc.InternalChannelz.Security;
|
||||||
import io.grpc.InternalChannelz.Tls;
|
import io.grpc.InternalChannelz.Tls;
|
||||||
import io.grpc.SecurityLevel;
|
import io.grpc.SecurityLevel;
|
||||||
|
import io.grpc.ServerCredentials;
|
||||||
import io.grpc.Status;
|
import io.grpc.Status;
|
||||||
import io.grpc.TlsChannelCredentials;
|
import io.grpc.TlsChannelCredentials;
|
||||||
|
import io.grpc.TlsServerCredentials;
|
||||||
import io.grpc.internal.GrpcAttributes;
|
import io.grpc.internal.GrpcAttributes;
|
||||||
import io.grpc.internal.GrpcUtil;
|
import io.grpc.internal.GrpcUtil;
|
||||||
import io.grpc.internal.ObjectPool;
|
import io.grpc.internal.ObjectPool;
|
||||||
|
|
@ -57,12 +61,14 @@ import io.netty.handler.proxy.ProxyConnectionEvent;
|
||||||
import io.netty.handler.ssl.OpenSsl;
|
import io.netty.handler.ssl.OpenSsl;
|
||||||
import io.netty.handler.ssl.OpenSslEngine;
|
import io.netty.handler.ssl.OpenSslEngine;
|
||||||
import io.netty.handler.ssl.SslContext;
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
import io.netty.handler.ssl.SslHandler;
|
import io.netty.handler.ssl.SslHandler;
|
||||||
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
|
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
|
||||||
import io.netty.handler.ssl.SslProvider;
|
import io.netty.handler.ssl.SslProvider;
|
||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import io.netty.util.Attribute;
|
import io.netty.util.Attribute;
|
||||||
import io.netty.util.AttributeMap;
|
import io.netty.util.AttributeMap;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.channels.ClosedChannelException;
|
import java.nio.channels.ClosedChannelException;
|
||||||
|
|
@ -85,6 +91,8 @@ final class ProtocolNegotiators {
|
||||||
private static final Logger log = Logger.getLogger(ProtocolNegotiators.class.getName());
|
private static final Logger log = Logger.getLogger(ProtocolNegotiators.class.getName());
|
||||||
private static final EnumSet<TlsChannelCredentials.Feature> understoodTlsFeatures =
|
private static final EnumSet<TlsChannelCredentials.Feature> understoodTlsFeatures =
|
||||||
EnumSet.noneOf(TlsChannelCredentials.Feature.class);
|
EnumSet.noneOf(TlsChannelCredentials.Feature.class);
|
||||||
|
private static final EnumSet<TlsServerCredentials.Feature> understoodServerTlsFeatures =
|
||||||
|
EnumSet.noneOf(TlsServerCredentials.Feature.class);
|
||||||
|
|
||||||
|
|
||||||
private ProtocolNegotiators() {
|
private ProtocolNegotiators() {
|
||||||
|
|
@ -167,6 +175,72 @@ final class ProtocolNegotiators {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FromServerCredentialsResult from(ServerCredentials creds) {
|
||||||
|
if (creds instanceof TlsServerCredentials) {
|
||||||
|
TlsServerCredentials tlsCreds = (TlsServerCredentials) creds;
|
||||||
|
Set<TlsServerCredentials.Feature> incomprehensible =
|
||||||
|
tlsCreds.incomprehensible(understoodServerTlsFeatures);
|
||||||
|
if (!incomprehensible.isEmpty()) {
|
||||||
|
return FromServerCredentialsResult.error(
|
||||||
|
"TLS features not understood: " + incomprehensible);
|
||||||
|
}
|
||||||
|
SslContextBuilder builder = GrpcSslContexts.forServer(
|
||||||
|
new ByteArrayInputStream(tlsCreds.getCertificateChain()),
|
||||||
|
new ByteArrayInputStream(tlsCreds.getPrivateKey()),
|
||||||
|
tlsCreds.getPrivateKeyPassword());
|
||||||
|
SslContext sslContext;
|
||||||
|
try {
|
||||||
|
sslContext = builder.build();
|
||||||
|
} catch (SSLException ex) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unexpected error converting ServerCredentials to Netty SslContext", ex);
|
||||||
|
}
|
||||||
|
return FromServerCredentialsResult.negotiator(serverTlsFactory(sslContext));
|
||||||
|
|
||||||
|
} else if (creds instanceof InsecureServerCredentials) {
|
||||||
|
return FromServerCredentialsResult.negotiator(serverPlaintextFactory());
|
||||||
|
|
||||||
|
} else if (creds instanceof NettyServerCredentials) {
|
||||||
|
NettyServerCredentials nettyCreds = (NettyServerCredentials) creds;
|
||||||
|
return FromServerCredentialsResult.negotiator(nettyCreds.getNegotiator());
|
||||||
|
|
||||||
|
} else if (creds instanceof ChoiceServerCredentials) {
|
||||||
|
ChoiceServerCredentials choiceCreds = (ChoiceServerCredentials) creds;
|
||||||
|
StringBuilder error = new StringBuilder();
|
||||||
|
for (ServerCredentials innerCreds : choiceCreds.getCredentialsList()) {
|
||||||
|
FromServerCredentialsResult result = from(innerCreds);
|
||||||
|
if (result.error == null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
error.append(", ");
|
||||||
|
error.append(result.error);
|
||||||
|
}
|
||||||
|
return FromServerCredentialsResult.error(error.substring(2));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return FromServerCredentialsResult.error(
|
||||||
|
"Unsupported credential type: " + creds.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class FromServerCredentialsResult {
|
||||||
|
public final ProtocolNegotiator.ServerFactory negotiator;
|
||||||
|
public final String error;
|
||||||
|
|
||||||
|
private FromServerCredentialsResult(ProtocolNegotiator.ServerFactory negotiator, String error) {
|
||||||
|
this.negotiator = negotiator;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FromServerCredentialsResult error(String error) {
|
||||||
|
return new FromServerCredentialsResult(null, Preconditions.checkNotNull(error, "error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FromServerCredentialsResult negotiator(ProtocolNegotiator.ServerFactory factory) {
|
||||||
|
return new FromServerCredentialsResult(Preconditions.checkNotNull(factory, "factory"), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ChannelLogger negotiationLogger(ChannelHandlerContext ctx) {
|
static ChannelLogger negotiationLogger(ChannelHandlerContext ctx) {
|
||||||
return negotiationLogger(ctx.channel());
|
return negotiationLogger(ctx.channel());
|
||||||
}
|
}
|
||||||
|
|
@ -190,6 +264,26 @@ final class ProtocolNegotiators {
|
||||||
return new NoopChannelLogger();
|
return new NoopChannelLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ProtocolNegotiator.ServerFactory fixedServerFactory(
|
||||||
|
ProtocolNegotiator negotiator) {
|
||||||
|
return new FixedProtocolNegotiatorServerFactory(negotiator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class FixedProtocolNegotiatorServerFactory
|
||||||
|
implements ProtocolNegotiator.ServerFactory {
|
||||||
|
private final ProtocolNegotiator protocolNegotiator;
|
||||||
|
|
||||||
|
public FixedProtocolNegotiatorServerFactory(ProtocolNegotiator protocolNegotiator) {
|
||||||
|
this.protocolNegotiator =
|
||||||
|
Preconditions.checkNotNull(protocolNegotiator, "protocolNegotiator");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProtocolNegotiator newNegotiator(ObjectPool<? extends Executor> offloadExecutorPool) {
|
||||||
|
return protocolNegotiator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a server plaintext handler for gRPC.
|
* Create a server plaintext handler for gRPC.
|
||||||
*/
|
*/
|
||||||
|
|
@ -197,6 +291,41 @@ final class ProtocolNegotiators {
|
||||||
return new PlaintextProtocolNegotiator();
|
return new PlaintextProtocolNegotiator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a server plaintext handler factory for gRPC.
|
||||||
|
*/
|
||||||
|
public static ProtocolNegotiator.ServerFactory serverPlaintextFactory() {
|
||||||
|
return new PlaintextProtocolNegotiatorServerFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static final class PlaintextProtocolNegotiatorServerFactory
|
||||||
|
implements ProtocolNegotiator.ServerFactory {
|
||||||
|
@Override
|
||||||
|
public ProtocolNegotiator newNegotiator(ObjectPool<? extends Executor> offloadExecutorPool) {
|
||||||
|
return serverPlaintext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProtocolNegotiator.ServerFactory serverTlsFactory(SslContext sslContext) {
|
||||||
|
return new TlsProtocolNegotiatorServerFactory(sslContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static final class TlsProtocolNegotiatorServerFactory
|
||||||
|
implements ProtocolNegotiator.ServerFactory {
|
||||||
|
private final SslContext sslContext;
|
||||||
|
|
||||||
|
public TlsProtocolNegotiatorServerFactory(SslContext sslContext) {
|
||||||
|
this.sslContext = Preconditions.checkNotNull(sslContext, "sslContext");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProtocolNegotiator newNegotiator(ObjectPool<? extends Executor> offloadExecutorPool) {
|
||||||
|
return serverTls(sslContext, offloadExecutorPool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a server TLS handler for HTTP/2 capable of using ALPN/NPN.
|
* Create a server TLS handler for HTTP/2 capable of using ALPN/NPN.
|
||||||
* @param executorPool a dedicated {@link Executor} pool for time-consuming TLS tasks
|
* @param executorPool a dedicated {@link Executor} pool for time-consuming TLS tasks
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,13 @@
|
||||||
|
|
||||||
package io.grpc.netty;
|
package io.grpc.netty;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.Assert.assertSame;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import io.grpc.InsecureServerCredentials;
|
||||||
|
import io.grpc.ServerCredentials;
|
||||||
import io.grpc.ServerProvider;
|
import io.grpc.ServerProvider;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
@ -45,4 +48,20 @@ public class NettyServerProviderTest {
|
||||||
public void builderIsANettyBuilder() {
|
public void builderIsANettyBuilder() {
|
||||||
assertSame(NettyServerBuilder.class, provider.builderForPort(443).getClass());
|
assertSame(NettyServerBuilder.class, provider.builderForPort(443).getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void newServerBuilderForPort_success() {
|
||||||
|
ServerProvider.NewServerBuilderResult result =
|
||||||
|
provider.newServerBuilderForPort(80, InsecureServerCredentials.create());
|
||||||
|
assertThat(result.getServerBuilder()).isInstanceOf(NettyServerBuilder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void newServerBuilderForPort_fail() {
|
||||||
|
ServerProvider.NewServerBuilderResult result = provider.newServerBuilderForPort(
|
||||||
|
80, new FakeServerCredentials());
|
||||||
|
assertThat(result.getError()).contains("FakeServerCredentials");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class FakeServerCredentials extends ServerCredentials {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,14 +33,18 @@ import io.grpc.Attributes;
|
||||||
import io.grpc.CallCredentials;
|
import io.grpc.CallCredentials;
|
||||||
import io.grpc.ChannelCredentials;
|
import io.grpc.ChannelCredentials;
|
||||||
import io.grpc.ChoiceChannelCredentials;
|
import io.grpc.ChoiceChannelCredentials;
|
||||||
|
import io.grpc.ChoiceServerCredentials;
|
||||||
import io.grpc.CompositeChannelCredentials;
|
import io.grpc.CompositeChannelCredentials;
|
||||||
import io.grpc.Grpc;
|
import io.grpc.Grpc;
|
||||||
import io.grpc.InsecureChannelCredentials;
|
import io.grpc.InsecureChannelCredentials;
|
||||||
|
import io.grpc.InsecureServerCredentials;
|
||||||
import io.grpc.InternalChannelz.Security;
|
import io.grpc.InternalChannelz.Security;
|
||||||
import io.grpc.SecurityLevel;
|
import io.grpc.SecurityLevel;
|
||||||
|
import io.grpc.ServerCredentials;
|
||||||
import io.grpc.Status;
|
import io.grpc.Status;
|
||||||
import io.grpc.StatusRuntimeException;
|
import io.grpc.StatusRuntimeException;
|
||||||
import io.grpc.TlsChannelCredentials;
|
import io.grpc.TlsChannelCredentials;
|
||||||
|
import io.grpc.TlsServerCredentials;
|
||||||
import io.grpc.internal.GrpcAttributes;
|
import io.grpc.internal.GrpcAttributes;
|
||||||
import io.grpc.internal.testing.TestUtils;
|
import io.grpc.internal.testing.TestUtils;
|
||||||
import io.grpc.netty.ProtocolNegotiators.ClientTlsHandler;
|
import io.grpc.netty.ProtocolNegotiators.ClientTlsHandler;
|
||||||
|
|
@ -110,6 +114,7 @@ import javax.net.ssl.SSLException;
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.DisableOnDebug;
|
import org.junit.rules.DisableOnDebug;
|
||||||
|
|
@ -128,6 +133,15 @@ public class ProtocolNegotiatorsTest {
|
||||||
@Override public void run() {}
|
@Override public void run() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static File server1Cert;
|
||||||
|
private static File server1Key;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void loadCerts() throws Exception {
|
||||||
|
server1Cert = TestUtils.loadCert("server1.pem");
|
||||||
|
server1Key = TestUtils.loadCert("server1.key");
|
||||||
|
}
|
||||||
|
|
||||||
private static final int TIMEOUT_SECONDS = 60;
|
private static final int TIMEOUT_SECONDS = 60;
|
||||||
@Rule public final TestRule globalTimeout = new DisableOnDebug(Timeout.seconds(TIMEOUT_SECONDS));
|
@Rule public final TestRule globalTimeout = new DisableOnDebug(Timeout.seconds(TIMEOUT_SECONDS));
|
||||||
@SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467
|
@SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467
|
||||||
|
|
@ -168,7 +182,7 @@ public class ProtocolNegotiatorsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void from_unknown() {
|
public void fromClient_unknown() {
|
||||||
ProtocolNegotiators.FromChannelCredentialsResult result =
|
ProtocolNegotiators.FromChannelCredentialsResult result =
|
||||||
ProtocolNegotiators.from(new ChannelCredentials() {});
|
ProtocolNegotiators.from(new ChannelCredentials() {});
|
||||||
assertThat(result.error).isNotNull();
|
assertThat(result.error).isNotNull();
|
||||||
|
|
@ -177,7 +191,7 @@ public class ProtocolNegotiatorsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void from_tls() {
|
public void fromClient_tls() {
|
||||||
ProtocolNegotiators.FromChannelCredentialsResult result =
|
ProtocolNegotiators.FromChannelCredentialsResult result =
|
||||||
ProtocolNegotiators.from(TlsChannelCredentials.create());
|
ProtocolNegotiators.from(TlsChannelCredentials.create());
|
||||||
assertThat(result.error).isNull();
|
assertThat(result.error).isNull();
|
||||||
|
|
@ -187,7 +201,7 @@ public class ProtocolNegotiatorsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void from_unspportedTls() {
|
public void fromClient_unsupportedTls() {
|
||||||
ProtocolNegotiators.FromChannelCredentialsResult result =
|
ProtocolNegotiators.FromChannelCredentialsResult result =
|
||||||
ProtocolNegotiators.from(TlsChannelCredentials.newBuilder().requireFakeFeature().build());
|
ProtocolNegotiators.from(TlsChannelCredentials.newBuilder().requireFakeFeature().build());
|
||||||
assertThat(result.error).contains("FAKE");
|
assertThat(result.error).contains("FAKE");
|
||||||
|
|
@ -196,7 +210,7 @@ public class ProtocolNegotiatorsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void from_insecure() {
|
public void fromClient_insecure() {
|
||||||
ProtocolNegotiators.FromChannelCredentialsResult result =
|
ProtocolNegotiators.FromChannelCredentialsResult result =
|
||||||
ProtocolNegotiators.from(InsecureChannelCredentials.create());
|
ProtocolNegotiators.from(InsecureChannelCredentials.create());
|
||||||
assertThat(result.error).isNull();
|
assertThat(result.error).isNull();
|
||||||
|
|
@ -206,7 +220,7 @@ public class ProtocolNegotiatorsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void from_composite() {
|
public void fromClient_composite() {
|
||||||
CallCredentials callCredentials = mock(CallCredentials.class);
|
CallCredentials callCredentials = mock(CallCredentials.class);
|
||||||
ProtocolNegotiators.FromChannelCredentialsResult result =
|
ProtocolNegotiators.FromChannelCredentialsResult result =
|
||||||
ProtocolNegotiators.from(CompositeChannelCredentials.create(
|
ProtocolNegotiators.from(CompositeChannelCredentials.create(
|
||||||
|
|
@ -225,7 +239,7 @@ public class ProtocolNegotiatorsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void from_netty() {
|
public void fromClient_netty() {
|
||||||
ProtocolNegotiator.ClientFactory factory = mock(ProtocolNegotiator.ClientFactory.class);
|
ProtocolNegotiator.ClientFactory factory = mock(ProtocolNegotiator.ClientFactory.class);
|
||||||
ProtocolNegotiators.FromChannelCredentialsResult result =
|
ProtocolNegotiators.FromChannelCredentialsResult result =
|
||||||
ProtocolNegotiators.from(NettyChannelCredentials.create(factory));
|
ProtocolNegotiators.from(NettyChannelCredentials.create(factory));
|
||||||
|
|
@ -235,7 +249,7 @@ public class ProtocolNegotiatorsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void from_choice() {
|
public void fromClient_choice() {
|
||||||
ProtocolNegotiators.FromChannelCredentialsResult result =
|
ProtocolNegotiators.FromChannelCredentialsResult result =
|
||||||
ProtocolNegotiators.from(ChoiceChannelCredentials.create(
|
ProtocolNegotiators.from(ChoiceChannelCredentials.create(
|
||||||
new ChannelCredentials() {},
|
new ChannelCredentials() {},
|
||||||
|
|
@ -257,7 +271,7 @@ public class ProtocolNegotiatorsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void from_choice_unknown() {
|
public void fromClient_choice_unknown() {
|
||||||
ProtocolNegotiators.FromChannelCredentialsResult result =
|
ProtocolNegotiators.FromChannelCredentialsResult result =
|
||||||
ProtocolNegotiators.from(ChoiceChannelCredentials.create(
|
ProtocolNegotiators.from(ChoiceChannelCredentials.create(
|
||||||
new ChannelCredentials() {}));
|
new ChannelCredentials() {}));
|
||||||
|
|
@ -266,6 +280,82 @@ public class ProtocolNegotiatorsTest {
|
||||||
assertThat(result.negotiator).isNull();
|
assertThat(result.negotiator).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromServer_unknown() {
|
||||||
|
ProtocolNegotiators.FromServerCredentialsResult result =
|
||||||
|
ProtocolNegotiators.from(new ServerCredentials() {});
|
||||||
|
assertThat(result.error).isNotNull();
|
||||||
|
assertThat(result.negotiator).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromServer_tls() throws Exception {
|
||||||
|
ProtocolNegotiators.FromServerCredentialsResult result =
|
||||||
|
ProtocolNegotiators.from(TlsServerCredentials.create(server1Cert, server1Key));
|
||||||
|
assertThat(result.error).isNull();
|
||||||
|
assertThat(result.negotiator)
|
||||||
|
.isInstanceOf(ProtocolNegotiators.TlsProtocolNegotiatorServerFactory.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromServer_unsupportedTls() throws Exception {
|
||||||
|
ProtocolNegotiators.FromServerCredentialsResult result = ProtocolNegotiators.from(
|
||||||
|
TlsServerCredentials.newBuilder()
|
||||||
|
.keyManager(server1Cert, server1Key)
|
||||||
|
.requireFakeFeature()
|
||||||
|
.build());
|
||||||
|
assertThat(result.error).contains("FAKE");
|
||||||
|
assertThat(result.negotiator).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromServer_insecure() {
|
||||||
|
ProtocolNegotiators.FromServerCredentialsResult result =
|
||||||
|
ProtocolNegotiators.from(InsecureServerCredentials.create());
|
||||||
|
assertThat(result.error).isNull();
|
||||||
|
assertThat(result.negotiator)
|
||||||
|
.isInstanceOf(ProtocolNegotiators.PlaintextProtocolNegotiatorServerFactory.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromServer_netty() {
|
||||||
|
ProtocolNegotiator.ServerFactory factory = mock(ProtocolNegotiator.ServerFactory.class);
|
||||||
|
ProtocolNegotiators.FromServerCredentialsResult result =
|
||||||
|
ProtocolNegotiators.from(NettyServerCredentials.create(factory));
|
||||||
|
assertThat(result.error).isNull();
|
||||||
|
assertThat(result.negotiator).isSameInstanceAs(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromServer_choice() throws Exception {
|
||||||
|
ProtocolNegotiators.FromServerCredentialsResult result =
|
||||||
|
ProtocolNegotiators.from(ChoiceServerCredentials.create(
|
||||||
|
new ServerCredentials() {},
|
||||||
|
TlsServerCredentials.create(server1Cert, server1Key),
|
||||||
|
InsecureServerCredentials.create()));
|
||||||
|
assertThat(result.error).isNull();
|
||||||
|
assertThat(result.negotiator)
|
||||||
|
.isInstanceOf(ProtocolNegotiators.TlsProtocolNegotiatorServerFactory.class);
|
||||||
|
|
||||||
|
result = ProtocolNegotiators.from(ChoiceServerCredentials.create(
|
||||||
|
InsecureServerCredentials.create(),
|
||||||
|
new ServerCredentials() {},
|
||||||
|
TlsServerCredentials.create(server1Cert, server1Key)));
|
||||||
|
assertThat(result.error).isNull();
|
||||||
|
assertThat(result.negotiator)
|
||||||
|
.isInstanceOf(ProtocolNegotiators.PlaintextProtocolNegotiatorServerFactory.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromServer_choice_unknown() {
|
||||||
|
ProtocolNegotiators.FromServerCredentialsResult result =
|
||||||
|
ProtocolNegotiators.from(ChoiceServerCredentials.create(
|
||||||
|
new ServerCredentials() {}));
|
||||||
|
assertThat(result.error).isNotNull();
|
||||||
|
assertThat(result.negotiator).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void waitUntilActiveHandler_handlerAdded() throws Exception {
|
public void waitUntilActiveHandler_handlerAdded() throws Exception {
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue