netty: move internal channel builder code to a special accessor

This commit is contained in:
Carl Mastrangelo 2016-12-13 11:17:00 -08:00 committed by GitHub
parent 178b5260c2
commit 677f05d7fb
3 changed files with 106 additions and 33 deletions

View File

@ -0,0 +1,71 @@
/*
* Copyright 2016, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package io.grpc.netty;
import io.grpc.Internal;
import io.grpc.internal.ClientTransportFactory;
import io.grpc.internal.ConnectionClientTransport;
import io.grpc.netty.NettyChannelBuilder.NettyTransportFactory;
import java.net.SocketAddress;
/**
* Internal {@link NettyChannelBuilder} 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 InternalNettyChannelBuilder {
/**
* Checks authority upon channel construction. The purpose of this interface is to raise the
* visibility of {@link NettyChannelBuilder.OverrideAuthorityChecker}.
*/
public interface OverrideAuthorityChecker extends NettyChannelBuilder.OverrideAuthorityChecker {}
public static void overrideAuthorityChecker(
NettyChannelBuilder channelBuilder, OverrideAuthorityChecker authorityChecker) {
channelBuilder.overrideAuthorityChecker(authorityChecker);
}
/**
* Creates a custom client transport that allows overriding the protocol negotiator.
*/
public static ConnectionClientTransport newClientTransport(
ClientTransportFactory transportFactory, SocketAddress serverAddress, String authority,
String userAgent, ProtocolNegotiator negotiator) {
// Casting to avoid making {@link NettyTransportFactory} public.
return ((NettyTransportFactory) transportFactory)
.newClientTransport(serverAddress, authority, userAgent, negotiator);
}
private InternalNettyChannelBuilder() {}
}

View File

@ -41,7 +41,6 @@ import com.google.common.base.Preconditions;
import io.grpc.Attributes;
import io.grpc.ExperimentalApi;
import io.grpc.Internal;
import io.grpc.NameResolver;
import io.grpc.internal.AbstractManagedChannelImplBuilder;
import io.grpc.internal.ClientTransportFactory;
@ -67,7 +66,8 @@ import javax.net.ssl.SSLException;
* A builder to help simplify construction of channels using the Netty transport.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1784")
public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<NettyChannelBuilder> {
public final class NettyChannelBuilder
extends AbstractManagedChannelImplBuilder<NettyChannelBuilder> {
public static final int DEFAULT_FLOW_CONTROL_WINDOW = 1048576; // 1MiB
private final Map<ChannelOption<?>, Object> channelOptions =
@ -75,6 +75,7 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
private NegotiationType negotiationType = NegotiationType.TLS;
private ProtocolNegotiator protocolNegotiator;
private OverrideAuthorityChecker authorityChecker;
private Class<? extends Channel> channelType = NioSocketChannel.class;
@Nullable
@ -135,7 +136,7 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
/**
* Specifies the channel type to use, by default we use {@link NioSocketChannel}.
*/
public final NettyChannelBuilder channelType(Class<? extends Channel> channelType) {
public NettyChannelBuilder channelType(Class<? extends Channel> channelType) {
this.channelType = Preconditions.checkNotNull(channelType, "channelType");
return this;
}
@ -144,7 +145,7 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
* Specifies a channel option. As the underlying channel as well as network implementation may
* ignore this value applications should consider it a hint.
*/
public final <T> NettyChannelBuilder withOption(ChannelOption<T> option, T value) {
public <T> NettyChannelBuilder withOption(ChannelOption<T> option, T value) {
channelOptions.put(option, value);
return this;
}
@ -154,24 +155,11 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
*
* <p>Default: <code>TLS</code>
*/
public final NettyChannelBuilder negotiationType(NegotiationType type) {
public NettyChannelBuilder negotiationType(NegotiationType type) {
negotiationType = type;
return this;
}
/**
* Sets the {@link ProtocolNegotiator} to be used. If non-{@code null}, overrides the value
* specified in {@link #negotiationType(NegotiationType)} or {@link #usePlaintext(boolean)}.
*
* <p>Default: {@code null}.
*/
@Internal
public final NettyChannelBuilder protocolNegotiator(
@Nullable ProtocolNegotiator protocolNegotiator) {
this.protocolNegotiator = protocolNegotiator;
return this;
}
/**
* Provides an EventGroupLoop to be used by the netty transport.
*
@ -181,7 +169,7 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
* <p>The channel won't take ownership of the given EventLoopGroup. It's caller's responsibility
* to shut it down when it's desired.
*/
public final NettyChannelBuilder eventLoopGroup(@Nullable EventLoopGroup eventLoopGroup) {
public NettyChannelBuilder eventLoopGroup(@Nullable EventLoopGroup eventLoopGroup) {
this.eventLoopGroup = eventLoopGroup;
return this;
}
@ -190,7 +178,7 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
* SSL/TLS context to use instead of the system default. It must have been configured with {@link
* GrpcSslContexts}, but options could have been overridden.
*/
public final NettyChannelBuilder sslContext(SslContext sslContext) {
public NettyChannelBuilder sslContext(SslContext sslContext) {
if (sslContext != null) {
checkArgument(sslContext.isClient(),
"Server SSL context can not be used for client channel");
@ -204,7 +192,7 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
* Sets the flow control window in bytes. If not called, the default value
* is {@link #DEFAULT_FLOW_CONTROL_WINDOW}).
*/
public final NettyChannelBuilder flowControlWindow(int flowControlWindow) {
public NettyChannelBuilder flowControlWindow(int flowControlWindow) {
checkArgument(flowControlWindow > 0, "flowControlWindow must be positive");
this.flowControlWindow = flowControlWindow;
return this;
@ -216,7 +204,7 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
* @deprecated Use {@link #maxInboundMessageSize} instead
*/
@Deprecated
public final NettyChannelBuilder maxMessageSize(int maxMessageSize) {
public NettyChannelBuilder maxMessageSize(int maxMessageSize) {
maxInboundMessageSize(maxMessageSize);
return this;
}
@ -225,7 +213,7 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
* Sets the maximum size of header list allowed to be received on the channel. If not called,
* defaults to {@link GrpcUtil#DEFAULT_MAX_HEADER_LIST_SIZE}.
*/
public final NettyChannelBuilder maxHeaderListSize(int maxHeaderListSize) {
public NettyChannelBuilder maxHeaderListSize(int maxHeaderListSize) {
checkArgument(maxHeaderListSize > 0, "maxHeaderListSize must be > 0");
this.maxHeaderListSize = maxHeaderListSize;
return this;
@ -236,7 +224,7 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
* {@code PLAINTEXT_UPGRADE}.
*/
@Override
public final NettyChannelBuilder usePlaintext(boolean skipNegotiation) {
public NettyChannelBuilder usePlaintext(boolean skipNegotiation) {
if (skipNegotiation) {
negotiationType(NegotiationType.PLAINTEXT);
} else {
@ -297,6 +285,10 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
.set(NameResolver.Factory.PARAMS_DEFAULT_PORT, defaultPort).build();
}
void overrideAuthorityChecker(@Nullable OverrideAuthorityChecker authorityChecker) {
this.authorityChecker = authorityChecker;
}
@VisibleForTesting
static ProtocolNegotiator createProtocolNegotiator(
String authority,
@ -321,11 +313,22 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
}
}
interface OverrideAuthorityChecker {
String checkAuthority(String authority);
}
@Override
protected String checkAuthority(String authority) {
if (authorityChecker != null) {
return authorityChecker.checkAuthority(authority);
}
return super.checkAuthority(authority);
}
/**
* Creates Netty transports. Exposed for internal use, as it should be private.
*/
@Internal
protected static final class NettyTransportFactory implements ClientTransportFactory {
static class NettyTransportFactory implements ClientTransportFactory {
private final Class<? extends Channel> channelType;
private final Map<ChannelOption<?>, ?> channelOptions;
private final NegotiationType negotiationType;
@ -379,8 +382,7 @@ public class NettyChannelBuilder extends AbstractManagedChannelImplBuilder<Netty
return newClientTransport(serverAddress, authority, userAgent, negotiator);
}
@Internal // This is strictly for internal use. Depend on this at your own peril.
public ConnectionClientTransport newClientTransport(
ConnectionClientTransport newClientTransport(
SocketAddress serverAddress, String authority, String userAgent,
ProtocolNegotiator negotiator) {
if (closed) {

View File

@ -33,10 +33,10 @@ package io.grpc.netty;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import io.grpc.internal.ClientTransportFactory;
import io.grpc.netty.InternalNettyChannelBuilder.OverrideAuthorityChecker;
import io.grpc.netty.ProtocolNegotiators.TlsNegotiator;
import io.netty.handler.ssl.SslContext;
@ -59,13 +59,13 @@ public class NettyChannelBuilderTest {
@Test
public void overrideAllowsInvalidAuthority() {
NettyChannelBuilder builder = new NettyChannelBuilder(new SocketAddress(){}) {
NettyChannelBuilder builder = new NettyChannelBuilder(new SocketAddress(){});
InternalNettyChannelBuilder.overrideAuthorityChecker(builder, new OverrideAuthorityChecker() {
@Override
protected String checkAuthority(String authority) {
public String checkAuthority(String authority) {
return authority;
}
};
});
ClientTransportFactory factory = builder.overrideAuthority("[invalidauthority")
.negotiationType(NegotiationType.PLAINTEXT)
.buildTransportFactory();