mirror of https://github.com/grpc/grpc-java.git
xds: Avoid NPE for no filter chain match on server-side
This commit is contained in:
parent
7644350ecb
commit
4814d975a5
|
|
@ -313,7 +313,7 @@ public final class EnvoyServerProtoData {
|
|||
/**
|
||||
* Corresponds to Envoy proto message {@link io.envoyproxy.envoy.api.v2.listener.FilterChain}.
|
||||
*/
|
||||
static final class FilterChain {
|
||||
public static final class FilterChain {
|
||||
// Unique name for the FilterChain.
|
||||
private final String name;
|
||||
// TODO(sanjaypujare): flatten structure by moving FilterChainMatch class members here.
|
||||
|
|
@ -391,7 +391,7 @@ public final class EnvoyServerProtoData {
|
|||
* Corresponds to Envoy proto message {@link io.envoyproxy.envoy.api.v2.Listener} & related
|
||||
* classes.
|
||||
*/
|
||||
static final class Listener {
|
||||
public static final class Listener {
|
||||
private final String name;
|
||||
@Nullable
|
||||
private final String address;
|
||||
|
|
@ -399,7 +399,8 @@ public final class EnvoyServerProtoData {
|
|||
@Nullable
|
||||
private final FilterChain defaultFilterChain;
|
||||
|
||||
Listener(String name, @Nullable String address,
|
||||
/** Construct a Listener. */
|
||||
public Listener(String name, @Nullable String address,
|
||||
List<FilterChain> filterChains, @Nullable FilterChain defaultFilterChain) {
|
||||
this.name = checkNotNull(name, "name");
|
||||
this.address = address;
|
||||
|
|
|
|||
|
|
@ -238,6 +238,11 @@ public final class XdsClientWrapperForServerSds {
|
|||
} else if (filterChains.size() == 1) {
|
||||
return filterChains.get(0).getSslContextProviderSupplier();
|
||||
}
|
||||
if (listener.getDefaultFilterChain() == null) {
|
||||
// close the connection
|
||||
throw new RuntimeException(
|
||||
"no matching filter chain. local: " + localInetAddr + " remote: " + remoteInetAddr);
|
||||
}
|
||||
return listener.getDefaultFilterChain().getSslContextProviderSupplier();
|
||||
}
|
||||
|
||||
|
|
@ -428,7 +433,7 @@ public final class XdsClientWrapperForServerSds {
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
XdsClient.LdsResourceWatcher getListenerWatcher() {
|
||||
public XdsClient.LdsResourceWatcher getListenerWatcher() {
|
||||
return listenerWatcher;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import org.mockito.ArgumentCaptor;
|
|||
/**
|
||||
* Helper methods related to {@link XdsServerBuilder} and related classes.
|
||||
*/
|
||||
class XdsServerTestHelper {
|
||||
public class XdsServerTestHelper {
|
||||
|
||||
private static final String SERVER_URI = "trafficdirector.googleapis.com";
|
||||
private static final String NODE_ID =
|
||||
|
|
@ -88,7 +88,8 @@ class XdsServerTestHelper {
|
|||
}
|
||||
}
|
||||
|
||||
static XdsClientWrapperForServerSds createXdsClientWrapperForServerSds(int port,
|
||||
/** Create an XdsClientWrapperForServerSds with a mock XdsClient. */
|
||||
public static XdsClientWrapperForServerSds createXdsClientWrapperForServerSds(int port,
|
||||
TlsContextManager tlsContextManager) {
|
||||
FakeXdsClientPoolFactory fakeXdsClientPoolFactory = new FakeXdsClientPoolFactory(
|
||||
buildMockXdsClient(tlsContextManager));
|
||||
|
|
@ -139,6 +140,11 @@ class XdsServerTestHelper {
|
|||
registeredWatcher.onChanged(listenerUpdate);
|
||||
}
|
||||
|
||||
public static void generateListenerUpdate(
|
||||
XdsClient.LdsResourceWatcher registeredWatcher, EnvoyServerProtoData.Listener listener) {
|
||||
registeredWatcher.onChanged(LdsUpdate.forTcpListener(listener));
|
||||
}
|
||||
|
||||
static int findFreePort() throws IOException {
|
||||
try (ServerSocket socket = new ServerSocket(0)) {
|
||||
socket.setReuseAddress(true);
|
||||
|
|
|
|||
|
|
@ -44,12 +44,14 @@ import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator;
|
|||
import io.grpc.netty.InternalProtocolNegotiators;
|
||||
import io.grpc.xds.Bootstrapper;
|
||||
import io.grpc.xds.CommonBootstrapperTestUtils;
|
||||
import io.grpc.xds.EnvoyServerProtoData;
|
||||
import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
|
||||
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
|
||||
import io.grpc.xds.InternalXdsAttributes;
|
||||
import io.grpc.xds.TlsContextManager;
|
||||
import io.grpc.xds.XdsClientWrapperForServerSds;
|
||||
import io.grpc.xds.XdsClientWrapperForServerSdsTestMisc;
|
||||
import io.grpc.xds.XdsServerTestHelper;
|
||||
import io.grpc.xds.internal.sds.SdsProtocolNegotiators.ClientSdsHandler;
|
||||
import io.grpc.xds.internal.sds.SdsProtocolNegotiators.ClientSdsProtocolNegotiator;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
|
|
@ -72,6 +74,7 @@ import java.io.IOException;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.security.cert.CertStoreException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
|
@ -348,6 +351,54 @@ public class SdsProtocolNegotiatorsTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noMatchingFilterChain_expectException() {
|
||||
// we need InetSocketAddress instead of EmbeddedSocketAddress as localAddress for this test
|
||||
channel =
|
||||
new EmbeddedChannel() {
|
||||
@Override
|
||||
public SocketAddress localAddress() {
|
||||
return new InetSocketAddress("172.168.1.1", 80);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocketAddress remoteAddress() {
|
||||
return new InetSocketAddress("172.168.2.2", 90);
|
||||
}
|
||||
};
|
||||
pipeline = channel.pipeline();
|
||||
Bootstrapper.BootstrapInfo bootstrapInfoForServer = CommonBootstrapperTestUtils
|
||||
.buildBootstrapInfo("google_cloud_private_spiffe-server", SERVER_1_KEY_FILE,
|
||||
SERVER_1_PEM_FILE, CA_PEM_FILE, null, null, null, null);
|
||||
|
||||
TlsContextManagerImpl tlsContextManager = new TlsContextManagerImpl(bootstrapInfoForServer);
|
||||
XdsClientWrapperForServerSds xdsClientWrapperForServerSds =
|
||||
XdsServerTestHelper.createXdsClientWrapperForServerSds(80, tlsContextManager);
|
||||
xdsClientWrapperForServerSds.start();
|
||||
EnvoyServerProtoData.Listener listener = new EnvoyServerProtoData.Listener(
|
||||
"listener1", "0.0.0.0", Arrays.<EnvoyServerProtoData.FilterChain>asList(), null);
|
||||
XdsServerTestHelper.generateListenerUpdate(
|
||||
xdsClientWrapperForServerSds.getListenerWatcher(), listener);
|
||||
|
||||
SdsProtocolNegotiators.HandlerPickerHandler handlerPickerHandler =
|
||||
new SdsProtocolNegotiators.HandlerPickerHandler(grpcHandler, xdsClientWrapperForServerSds,
|
||||
InternalProtocolNegotiators.serverPlaintext());
|
||||
pipeline.addLast(handlerPickerHandler);
|
||||
channelHandlerCtx = pipeline.context(handlerPickerHandler);
|
||||
assertThat(channelHandlerCtx).isNotNull(); // should find HandlerPickerHandler
|
||||
|
||||
// kick off protocol negotiation
|
||||
pipeline.fireUserEventTriggered(InternalProtocolNegotiationEvent.getDefault());
|
||||
channelHandlerCtx = pipeline.context(handlerPickerHandler);
|
||||
assertThat(channelHandlerCtx).isNotNull(); // HandlerPickerHandler still there
|
||||
try {
|
||||
channel.checkException();
|
||||
fail("exception expected!");
|
||||
} catch (Exception e) {
|
||||
assertThat(e).hasMessageThat().contains("no matching filter chain");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientSdsProtocolNegotiatorNewHandler_fireProtocolNegotiationEvent()
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
|
|
|
|||
Loading…
Reference in New Issue