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}.
|
* 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.
|
// Unique name for the FilterChain.
|
||||||
private final String name;
|
private final String name;
|
||||||
// TODO(sanjaypujare): flatten structure by moving FilterChainMatch class members here.
|
// 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
|
* Corresponds to Envoy proto message {@link io.envoyproxy.envoy.api.v2.Listener} & related
|
||||||
* classes.
|
* classes.
|
||||||
*/
|
*/
|
||||||
static final class Listener {
|
public static final class Listener {
|
||||||
private final String name;
|
private final String name;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final String address;
|
private final String address;
|
||||||
|
|
@ -399,7 +399,8 @@ public final class EnvoyServerProtoData {
|
||||||
@Nullable
|
@Nullable
|
||||||
private final FilterChain defaultFilterChain;
|
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) {
|
List<FilterChain> filterChains, @Nullable FilterChain defaultFilterChain) {
|
||||||
this.name = checkNotNull(name, "name");
|
this.name = checkNotNull(name, "name");
|
||||||
this.address = address;
|
this.address = address;
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,11 @@ public final class XdsClientWrapperForServerSds {
|
||||||
} else if (filterChains.size() == 1) {
|
} else if (filterChains.size() == 1) {
|
||||||
return filterChains.get(0).getSslContextProviderSupplier();
|
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();
|
return listener.getDefaultFilterChain().getSslContextProviderSupplier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -428,7 +433,7 @@ public final class XdsClientWrapperForServerSds {
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
XdsClient.LdsResourceWatcher getListenerWatcher() {
|
public XdsClient.LdsResourceWatcher getListenerWatcher() {
|
||||||
return listenerWatcher;
|
return listenerWatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import org.mockito.ArgumentCaptor;
|
||||||
/**
|
/**
|
||||||
* Helper methods related to {@link XdsServerBuilder} and related classes.
|
* 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 SERVER_URI = "trafficdirector.googleapis.com";
|
||||||
private static final String NODE_ID =
|
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) {
|
TlsContextManager tlsContextManager) {
|
||||||
FakeXdsClientPoolFactory fakeXdsClientPoolFactory = new FakeXdsClientPoolFactory(
|
FakeXdsClientPoolFactory fakeXdsClientPoolFactory = new FakeXdsClientPoolFactory(
|
||||||
buildMockXdsClient(tlsContextManager));
|
buildMockXdsClient(tlsContextManager));
|
||||||
|
|
@ -139,6 +140,11 @@ class XdsServerTestHelper {
|
||||||
registeredWatcher.onChanged(listenerUpdate);
|
registeredWatcher.onChanged(listenerUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void generateListenerUpdate(
|
||||||
|
XdsClient.LdsResourceWatcher registeredWatcher, EnvoyServerProtoData.Listener listener) {
|
||||||
|
registeredWatcher.onChanged(LdsUpdate.forTcpListener(listener));
|
||||||
|
}
|
||||||
|
|
||||||
static int findFreePort() throws IOException {
|
static int findFreePort() throws IOException {
|
||||||
try (ServerSocket socket = new ServerSocket(0)) {
|
try (ServerSocket socket = new ServerSocket(0)) {
|
||||||
socket.setReuseAddress(true);
|
socket.setReuseAddress(true);
|
||||||
|
|
|
||||||
|
|
@ -44,12 +44,14 @@ import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator;
|
||||||
import io.grpc.netty.InternalProtocolNegotiators;
|
import io.grpc.netty.InternalProtocolNegotiators;
|
||||||
import io.grpc.xds.Bootstrapper;
|
import io.grpc.xds.Bootstrapper;
|
||||||
import io.grpc.xds.CommonBootstrapperTestUtils;
|
import io.grpc.xds.CommonBootstrapperTestUtils;
|
||||||
|
import io.grpc.xds.EnvoyServerProtoData;
|
||||||
import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
|
import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
|
||||||
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
|
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
|
||||||
import io.grpc.xds.InternalXdsAttributes;
|
import io.grpc.xds.InternalXdsAttributes;
|
||||||
import io.grpc.xds.TlsContextManager;
|
import io.grpc.xds.TlsContextManager;
|
||||||
import io.grpc.xds.XdsClientWrapperForServerSds;
|
import io.grpc.xds.XdsClientWrapperForServerSds;
|
||||||
import io.grpc.xds.XdsClientWrapperForServerSdsTestMisc;
|
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.ClientSdsHandler;
|
||||||
import io.grpc.xds.internal.sds.SdsProtocolNegotiators.ClientSdsProtocolNegotiator;
|
import io.grpc.xds.internal.sds.SdsProtocolNegotiators.ClientSdsProtocolNegotiator;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
|
|
@ -72,6 +74,7 @@ import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.security.cert.CertStoreException;
|
import java.security.cert.CertStoreException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
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
|
@Test
|
||||||
public void clientSdsProtocolNegotiatorNewHandler_fireProtocolNegotiationEvent()
|
public void clientSdsProtocolNegotiatorNewHandler_fireProtocolNegotiationEvent()
|
||||||
throws InterruptedException, TimeoutException, ExecutionException {
|
throws InterruptedException, TimeoutException, ExecutionException {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue