mirror of https://github.com/grpc/grpc-java.git
xds, rbac: build per route serverInterceptor for httpConfig (#8524)
This commit is contained in:
parent
9d9d8ec66b
commit
fcf13952bb
|
|
@ -59,6 +59,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
@ -135,28 +136,29 @@ final class FilterChainMatchingProtocolNegotiators {
|
||||||
|
|
||||||
static final class FilterChainSelector {
|
static final class FilterChainSelector {
|
||||||
public static final FilterChainSelector NO_FILTER_CHAIN = new FilterChainSelector(
|
public static final FilterChainSelector NO_FILTER_CHAIN = new FilterChainSelector(
|
||||||
Collections.<FilterChain, ServerRoutingConfig>emptyMap(), null, null);
|
Collections.<FilterChain, AtomicReference<ServerRoutingConfig>>emptyMap(),
|
||||||
private final Map<FilterChain, ServerRoutingConfig> routingConfigs;
|
null, new AtomicReference<ServerRoutingConfig>());
|
||||||
|
private final Map<FilterChain, AtomicReference<ServerRoutingConfig>> routingConfigs;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final SslContextProviderSupplier defaultSslContextProviderSupplier;
|
private final SslContextProviderSupplier defaultSslContextProviderSupplier;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final ServerRoutingConfig defaultRoutingConfig;
|
private final AtomicReference<ServerRoutingConfig> defaultRoutingConfig;
|
||||||
|
|
||||||
FilterChainSelector(Map<FilterChain, ServerRoutingConfig> routingConfigs,
|
FilterChainSelector(Map<FilterChain, AtomicReference<ServerRoutingConfig>> routingConfigs,
|
||||||
@Nullable SslContextProviderSupplier defaultSslContextProviderSupplier,
|
@Nullable SslContextProviderSupplier defaultSslContextProviderSupplier,
|
||||||
@Nullable ServerRoutingConfig defaultRoutingConfig) {
|
@Nullable AtomicReference<ServerRoutingConfig> defaultRoutingConfig) {
|
||||||
this.routingConfigs = checkNotNull(routingConfigs, "routingConfigs");
|
this.routingConfigs = checkNotNull(routingConfigs, "routingConfigs");
|
||||||
this.defaultSslContextProviderSupplier = defaultSslContextProviderSupplier;
|
this.defaultSslContextProviderSupplier = defaultSslContextProviderSupplier;
|
||||||
this.defaultRoutingConfig = defaultRoutingConfig;
|
this.defaultRoutingConfig = checkNotNull(defaultRoutingConfig, "defaultRoutingConfig");
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Map<FilterChain, ServerRoutingConfig> getRoutingConfigs() {
|
Map<FilterChain, AtomicReference<ServerRoutingConfig>> getRoutingConfigs() {
|
||||||
return routingConfigs;
|
return routingConfigs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
ServerRoutingConfig getDefaultRoutingConfig() {
|
AtomicReference<ServerRoutingConfig> getDefaultRoutingConfig() {
|
||||||
return defaultRoutingConfig;
|
return defaultRoutingConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,7 +191,7 @@ final class FilterChainMatchingProtocolNegotiators {
|
||||||
return new SelectedConfig(
|
return new SelectedConfig(
|
||||||
routingConfigs.get(selected), selected.getSslContextProviderSupplier());
|
routingConfigs.get(selected), selected.getSslContextProviderSupplier());
|
||||||
}
|
}
|
||||||
if (defaultRoutingConfig != null) {
|
if (defaultRoutingConfig.get() != null) {
|
||||||
return new SelectedConfig(defaultRoutingConfig, defaultSslContextProviderSupplier);
|
return new SelectedConfig(defaultRoutingConfig, defaultSslContextProviderSupplier);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -393,11 +395,11 @@ final class FilterChainMatchingProtocolNegotiators {
|
||||||
* The FilterChain level configuration.
|
* The FilterChain level configuration.
|
||||||
*/
|
*/
|
||||||
private static final class SelectedConfig {
|
private static final class SelectedConfig {
|
||||||
private final ServerRoutingConfig routingConfig;
|
private final AtomicReference<ServerRoutingConfig> routingConfig;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final SslContextProviderSupplier sslContextProviderSupplier;
|
private final SslContextProviderSupplier sslContextProviderSupplier;
|
||||||
|
|
||||||
private SelectedConfig(ServerRoutingConfig routingConfig,
|
private SelectedConfig(AtomicReference<ServerRoutingConfig> routingConfig,
|
||||||
@Nullable SslContextProviderSupplier sslContextProviderSupplier) {
|
@Nullable SslContextProviderSupplier sslContextProviderSupplier) {
|
||||||
this.routingConfig = checkNotNull(routingConfig, "routingConfig");
|
this.routingConfig = checkNotNull(routingConfig, "routingConfig");
|
||||||
this.sslContextProviderSupplier = sslContextProviderSupplier;
|
this.sslContextProviderSupplier = sslContextProviderSupplier;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkState;
|
||||||
import com.google.auto.value.AutoValue;
|
import com.google.auto.value.AutoValue;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.InternalServerInterceptors;
|
import io.grpc.InternalServerInterceptors;
|
||||||
|
|
@ -87,8 +88,9 @@ final class XdsServerWrapper extends Server {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
public static final Attributes.Key<ServerRoutingConfig> ATTR_SERVER_ROUTING_CONFIG =
|
public static final Attributes.Key<AtomicReference<ServerRoutingConfig>>
|
||||||
Attributes.Key.create("io.grpc.xds.ServerWrapper.serverRoutingConfig");
|
ATTR_SERVER_ROUTING_CONFIG =
|
||||||
|
Attributes.Key.create("io.grpc.xds.ServerWrapper.serverRoutingConfig");
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final long RETRY_DELAY_NANOS = TimeUnit.MINUTES.toNanos(1);
|
static final long RETRY_DELAY_NANOS = TimeUnit.MINUTES.toNanos(1);
|
||||||
|
|
@ -346,6 +348,15 @@ final class XdsServerWrapper extends Server {
|
||||||
@Nullable
|
@Nullable
|
||||||
private FilterChain defaultFilterChain;
|
private FilterChain defaultFilterChain;
|
||||||
private boolean stopped;
|
private boolean stopped;
|
||||||
|
private final Map<FilterChain, AtomicReference<ServerRoutingConfig>> savedRdsRoutingConfigRef
|
||||||
|
= new HashMap<>();
|
||||||
|
private final ServerInterceptor noopInterceptor = new ServerInterceptor() {
|
||||||
|
@Override
|
||||||
|
public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
||||||
|
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||||
|
return next.startCall(call, headers);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private DiscoveryState(String resourceName) {
|
private DiscoveryState(String resourceName) {
|
||||||
this.resourceName = checkNotNull(resourceName, "resourceName");
|
this.resourceName = checkNotNull(resourceName, "resourceName");
|
||||||
|
|
@ -452,14 +463,16 @@ final class XdsServerWrapper extends Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSelector() {
|
private void updateSelector() {
|
||||||
Map<FilterChain, ServerRoutingConfig> filterChainRouting = new HashMap<>();
|
Map<FilterChain, AtomicReference<ServerRoutingConfig>> filterChainRouting = new HashMap<>();
|
||||||
|
savedRdsRoutingConfigRef.clear();
|
||||||
for (FilterChain filterChain: filterChains) {
|
for (FilterChain filterChain: filterChains) {
|
||||||
filterChainRouting.put(filterChain, generateRoutingConfig(filterChain));
|
filterChainRouting.put(filterChain, generateRoutingConfig(filterChain));
|
||||||
}
|
}
|
||||||
FilterChainSelector selector = new FilterChainSelector(
|
FilterChainSelector selector = new FilterChainSelector(
|
||||||
Collections.unmodifiableMap(filterChainRouting),
|
Collections.unmodifiableMap(filterChainRouting),
|
||||||
defaultFilterChain == null ? null : defaultFilterChain.getSslContextProviderSupplier(),
|
defaultFilterChain == null ? null : defaultFilterChain.getSslContextProviderSupplier(),
|
||||||
defaultFilterChain == null ? null : generateRoutingConfig(defaultFilterChain));
|
defaultFilterChain == null ? new AtomicReference<ServerRoutingConfig>() :
|
||||||
|
generateRoutingConfig(defaultFilterChain));
|
||||||
List<SslContextProviderSupplier> toRelease = getSuppliersInUse();
|
List<SslContextProviderSupplier> toRelease = getSuppliersInUse();
|
||||||
filterChainSelectorManager.updateSelector(selector);
|
filterChainSelectorManager.updateSelector(selector);
|
||||||
for (SslContextProviderSupplier e: toRelease) {
|
for (SslContextProviderSupplier e: toRelease) {
|
||||||
|
|
@ -468,18 +481,84 @@ final class XdsServerWrapper extends Server {
|
||||||
startDelegateServer();
|
startDelegateServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServerRoutingConfig generateRoutingConfig(FilterChain filterChain) {
|
private AtomicReference<ServerRoutingConfig> generateRoutingConfig(FilterChain filterChain) {
|
||||||
HttpConnectionManager hcm = filterChain.getHttpConnectionManager();
|
HttpConnectionManager hcm = filterChain.getHttpConnectionManager();
|
||||||
if (hcm.virtualHosts() != null) {
|
if (hcm.virtualHosts() != null) {
|
||||||
return ServerRoutingConfig.create(hcm.httpFilterConfigs(),
|
ImmutableMap<Route, ServerInterceptor> interceptors = generatePerRouteInterceptors(
|
||||||
new AtomicReference<>(hcm.virtualHosts()));
|
hcm.httpFilterConfigs(), hcm.virtualHosts());
|
||||||
|
return new AtomicReference<>(ServerRoutingConfig.create(hcm.virtualHosts(),interceptors));
|
||||||
} else {
|
} else {
|
||||||
RouteDiscoveryState rds = routeDiscoveryStates.get(hcm.rdsName());
|
RouteDiscoveryState rds = routeDiscoveryStates.get(hcm.rdsName());
|
||||||
checkNotNull(rds, "rds");
|
checkNotNull(rds, "rds");
|
||||||
return ServerRoutingConfig.create(hcm.httpFilterConfigs(), rds.savedVirtualHosts);
|
AtomicReference<ServerRoutingConfig> serverRoutingConfigRef = new AtomicReference<>();
|
||||||
|
if (rds.savedVirtualHosts != null) {
|
||||||
|
ImmutableMap<Route, ServerInterceptor> interceptors = generatePerRouteInterceptors(
|
||||||
|
hcm.httpFilterConfigs(), rds.savedVirtualHosts);
|
||||||
|
ServerRoutingConfig serverRoutingConfig =
|
||||||
|
ServerRoutingConfig.create(rds.savedVirtualHosts, interceptors);
|
||||||
|
serverRoutingConfigRef.set(serverRoutingConfig);
|
||||||
|
} else {
|
||||||
|
serverRoutingConfigRef.set(ServerRoutingConfig.FAILING_ROUTING_CONFIG);
|
||||||
|
}
|
||||||
|
savedRdsRoutingConfigRef.put(filterChain, serverRoutingConfigRef);
|
||||||
|
return serverRoutingConfigRef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ImmutableMap<Route, ServerInterceptor> generatePerRouteInterceptors(
|
||||||
|
List<NamedFilterConfig> namedFilterConfigs, List<VirtualHost> virtualHosts) {
|
||||||
|
ImmutableMap.Builder<Route, ServerInterceptor> perRouteInterceptors =
|
||||||
|
new ImmutableMap.Builder<>();
|
||||||
|
for (VirtualHost virtualHost : virtualHosts) {
|
||||||
|
for (Route route : virtualHost.routes()) {
|
||||||
|
List<ServerInterceptor> filterInterceptors = new ArrayList<>();
|
||||||
|
Map<String, FilterConfig> selectedOverrideConfigs =
|
||||||
|
new HashMap<>(virtualHost.filterConfigOverrides());
|
||||||
|
selectedOverrideConfigs.putAll(route.filterConfigOverrides());
|
||||||
|
for (NamedFilterConfig namedFilterConfig : namedFilterConfigs) {
|
||||||
|
FilterConfig filterConfig = namedFilterConfig.filterConfig;
|
||||||
|
Filter filter = filterRegistry.get(filterConfig.typeUrl());
|
||||||
|
if (filter instanceof ServerInterceptorBuilder) {
|
||||||
|
ServerInterceptor interceptor =
|
||||||
|
((ServerInterceptorBuilder) filter).buildServerInterceptor(
|
||||||
|
filterConfig, selectedOverrideConfigs.get(namedFilterConfig.name));
|
||||||
|
if (interceptor != null) {
|
||||||
|
filterInterceptors.add(interceptor);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.log(Level.WARNING, "HttpFilterConfig(type URL: "
|
||||||
|
+ filterConfig.typeUrl() + ") is not supported on server-side. "
|
||||||
|
+ "Probably a bug at ClientXdsClient verification.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ServerInterceptor interceptor = combineInterceptors(filterInterceptors);
|
||||||
|
perRouteInterceptors.put(route, interceptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return perRouteInterceptors.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServerInterceptor combineInterceptors(final List<ServerInterceptor> interceptors) {
|
||||||
|
if (interceptors.isEmpty()) {
|
||||||
|
return noopInterceptor;
|
||||||
|
}
|
||||||
|
if (interceptors.size() == 1) {
|
||||||
|
return interceptors.get(0);
|
||||||
|
}
|
||||||
|
return new ServerInterceptor() {
|
||||||
|
@Override
|
||||||
|
public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
||||||
|
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||||
|
// intercept forward
|
||||||
|
for (int i = interceptors.size() - 1; i >= 0; i--) {
|
||||||
|
next = InternalServerInterceptors.interceptCallHandlerCreate(
|
||||||
|
interceptors.get(i), next);
|
||||||
|
}
|
||||||
|
return next.startCall(call, headers);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void handleConfigNotFound(StatusException exception) {
|
private void handleConfigNotFound(StatusException exception) {
|
||||||
cleanUpRouteDiscoveryStates();
|
cleanUpRouteDiscoveryStates();
|
||||||
List<SslContextProviderSupplier> toRelease = getSuppliersInUse();
|
List<SslContextProviderSupplier> toRelease = getSuppliersInUse();
|
||||||
|
|
@ -508,6 +587,7 @@ final class XdsServerWrapper extends Server {
|
||||||
xdsClient.cancelRdsResourceWatch(rdsName, rdsState);
|
xdsClient.cancelRdsResourceWatch(rdsName, rdsState);
|
||||||
}
|
}
|
||||||
routeDiscoveryStates.clear();
|
routeDiscoveryStates.clear();
|
||||||
|
savedRdsRoutingConfigRef.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SslContextProviderSupplier> getSuppliersInUse() {
|
private List<SslContextProviderSupplier> getSuppliersInUse() {
|
||||||
|
|
@ -544,8 +624,7 @@ final class XdsServerWrapper extends Server {
|
||||||
|
|
||||||
private final class RouteDiscoveryState implements RdsResourceWatcher {
|
private final class RouteDiscoveryState implements RdsResourceWatcher {
|
||||||
private final String resourceName;
|
private final String resourceName;
|
||||||
private AtomicReference<ImmutableList<VirtualHost>> savedVirtualHosts =
|
private ImmutableList<VirtualHost> savedVirtualHosts;
|
||||||
new AtomicReference<>();
|
|
||||||
private boolean isPending = true;
|
private boolean isPending = true;
|
||||||
|
|
||||||
private RouteDiscoveryState(String resourceName) {
|
private RouteDiscoveryState(String resourceName) {
|
||||||
|
|
@ -560,7 +639,8 @@ final class XdsServerWrapper extends Server {
|
||||||
if (!routeDiscoveryStates.containsKey(resourceName)) {
|
if (!routeDiscoveryStates.containsKey(resourceName)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
savedVirtualHosts.set(ImmutableList.copyOf(update.virtualHosts));
|
savedVirtualHosts = ImmutableList.copyOf(update.virtualHosts);
|
||||||
|
updateRdsRoutingConfig();
|
||||||
maybeUpdateSelector();
|
maybeUpdateSelector();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -575,7 +655,8 @@ final class XdsServerWrapper extends Server {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.log(Level.WARNING, "Rds {0} unavailable", resourceName);
|
logger.log(Level.WARNING, "Rds {0} unavailable", resourceName);
|
||||||
savedVirtualHosts.set(null);
|
savedVirtualHosts = null;
|
||||||
|
updateRdsRoutingConfig();
|
||||||
maybeUpdateSelector();
|
maybeUpdateSelector();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -596,6 +677,25 @@ final class XdsServerWrapper extends Server {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateRdsRoutingConfig() {
|
||||||
|
for (FilterChain filterChain : savedRdsRoutingConfigRef.keySet()) {
|
||||||
|
if (resourceName.equals(filterChain.getHttpConnectionManager().rdsName())) {
|
||||||
|
ServerRoutingConfig updatedRoutingConfig;
|
||||||
|
if (savedVirtualHosts == null) {
|
||||||
|
updatedRoutingConfig = ServerRoutingConfig.FAILING_ROUTING_CONFIG;
|
||||||
|
} else {
|
||||||
|
ImmutableMap<Route, ServerInterceptor> updatedInterceptors =
|
||||||
|
generatePerRouteInterceptors(
|
||||||
|
filterChain.getHttpConnectionManager().httpFilterConfigs(),
|
||||||
|
savedVirtualHosts);
|
||||||
|
updatedRoutingConfig = ServerRoutingConfig.create(savedVirtualHosts,
|
||||||
|
updatedInterceptors);
|
||||||
|
}
|
||||||
|
savedRdsRoutingConfigRef.get(filterChain).set(updatedRoutingConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the selector to use the most recently updated configs only after all rds have been
|
// Update the selector to use the most recently updated configs only after all rds have been
|
||||||
// discovered for the first time. Later changes on rds will be applied through virtual host
|
// discovered for the first time. Later changes on rds will be applied through virtual host
|
||||||
// list atomic ref.
|
// list atomic ref.
|
||||||
|
|
@ -632,18 +732,16 @@ final class XdsServerWrapper extends Server {
|
||||||
@Override
|
@Override
|
||||||
public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
||||||
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||||
ServerRoutingConfig routingConfig = call.getAttributes().get(ATTR_SERVER_ROUTING_CONFIG);
|
AtomicReference<ServerRoutingConfig> routingConfigRef =
|
||||||
if (routingConfig == null) {
|
call.getAttributes().get(ATTR_SERVER_ROUTING_CONFIG);
|
||||||
String errorMsg = "Missing xDS routing config.";
|
ServerRoutingConfig routingConfig = routingConfigRef == null ? null :
|
||||||
call.close(Status.UNAVAILABLE.withDescription(errorMsg), new Metadata());
|
routingConfigRef.get();
|
||||||
return new Listener<ReqT>() {};
|
if (routingConfig == null || routingConfig == ServerRoutingConfig.FAILING_ROUTING_CONFIG) {
|
||||||
}
|
String errorMsg = "Missing or broken xDS routing config: RDS config unavailable.";
|
||||||
List<VirtualHost> virtualHosts = routingConfig.virtualHosts().get();
|
|
||||||
if (virtualHosts == null) {
|
|
||||||
String errorMsg = "Missing xDS routing config VirtualHosts due to RDS config unavailable.";
|
|
||||||
call.close(Status.UNAVAILABLE.withDescription(errorMsg), new Metadata());
|
call.close(Status.UNAVAILABLE.withDescription(errorMsg), new Metadata());
|
||||||
return new Listener<ReqT>() {};
|
return new Listener<ReqT>() {};
|
||||||
}
|
}
|
||||||
|
List<VirtualHost> virtualHosts = routingConfig.virtualHosts();
|
||||||
VirtualHost virtualHost = RoutingUtils.findVirtualHostForHostName(
|
VirtualHost virtualHost = RoutingUtils.findVirtualHostForHostName(
|
||||||
virtualHosts, call.getAuthority());
|
virtualHosts, call.getAuthority());
|
||||||
if (virtualHost == null) {
|
if (virtualHost == null) {
|
||||||
|
|
@ -653,14 +751,11 @@ final class XdsServerWrapper extends Server {
|
||||||
return new Listener<ReqT>() {};
|
return new Listener<ReqT>() {};
|
||||||
}
|
}
|
||||||
Route selectedRoute = null;
|
Route selectedRoute = null;
|
||||||
Map<String, FilterConfig> selectedOverrideConfigs =
|
|
||||||
new HashMap<>(virtualHost.filterConfigOverrides());
|
|
||||||
MethodDescriptor<ReqT, RespT> method = call.getMethodDescriptor();
|
MethodDescriptor<ReqT, RespT> method = call.getMethodDescriptor();
|
||||||
for (Route route : virtualHost.routes()) {
|
for (Route route : virtualHost.routes()) {
|
||||||
if (RoutingUtils.matchRoute(
|
if (RoutingUtils.matchRoute(
|
||||||
route.routeMatch(), "/" + method.getFullMethodName(), headers, random)) {
|
route.routeMatch(), "/" + method.getFullMethodName(), headers, random)) {
|
||||||
selectedRoute = route;
|
selectedRoute = route;
|
||||||
selectedOverrideConfigs.putAll(route.filterConfigOverrides());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -670,48 +765,12 @@ final class XdsServerWrapper extends Server {
|
||||||
new Metadata());
|
new Metadata());
|
||||||
return new ServerCall.Listener<ReqT>() {};
|
return new ServerCall.Listener<ReqT>() {};
|
||||||
}
|
}
|
||||||
List<ServerInterceptor> filterInterceptors = new ArrayList<>();
|
ServerInterceptor routeInterceptor = noopInterceptor;
|
||||||
for (NamedFilterConfig namedFilterConfig : routingConfig.httpFilterConfigs()) {
|
Map<Route, ServerInterceptor> perRouteInterceptors = routingConfig.interceptors();
|
||||||
FilterConfig filterConfig = namedFilterConfig.filterConfig;
|
if (perRouteInterceptors != null && perRouteInterceptors.get(selectedRoute) != null) {
|
||||||
Filter filter = filterRegistry.get(filterConfig.typeUrl());
|
routeInterceptor = perRouteInterceptors.get(selectedRoute);
|
||||||
if (filter instanceof ServerInterceptorBuilder) {
|
|
||||||
ServerInterceptor interceptor =
|
|
||||||
((ServerInterceptorBuilder) filter).buildServerInterceptor(
|
|
||||||
filterConfig, selectedOverrideConfigs.get(namedFilterConfig.name));
|
|
||||||
if (interceptor != null) {
|
|
||||||
filterInterceptors.add(interceptor);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
call.close(
|
|
||||||
Status.UNAVAILABLE.withDescription("HttpFilterConfig(type URL: "
|
|
||||||
+ filterConfig.typeUrl() + ") is not supported on server-side."),
|
|
||||||
new Metadata());
|
|
||||||
return new Listener<ReqT>() {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ServerInterceptor interceptor = combineInterceptors(filterInterceptors);
|
return routeInterceptor.interceptCall(call, headers, next);
|
||||||
return interceptor.interceptCall(call, headers, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ServerInterceptor combineInterceptors(final List<ServerInterceptor> interceptors) {
|
|
||||||
if (interceptors.isEmpty()) {
|
|
||||||
return noopInterceptor;
|
|
||||||
}
|
|
||||||
if (interceptors.size() == 1) {
|
|
||||||
return interceptors.get(0);
|
|
||||||
}
|
|
||||||
return new ServerInterceptor() {
|
|
||||||
@Override
|
|
||||||
public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
|
||||||
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
|
||||||
// intercept forward
|
|
||||||
for (int i = interceptors.size() - 1; i >= 0; i--) {
|
|
||||||
next = InternalServerInterceptors.interceptCallHandlerCreate(
|
|
||||||
interceptors.get(i), next);
|
|
||||||
}
|
|
||||||
return next.startCall(call, headers);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -720,20 +779,24 @@ final class XdsServerWrapper extends Server {
|
||||||
*/
|
*/
|
||||||
@AutoValue
|
@AutoValue
|
||||||
abstract static class ServerRoutingConfig {
|
abstract static class ServerRoutingConfig {
|
||||||
// Top level http filter configs.
|
@VisibleForTesting
|
||||||
abstract ImmutableList<NamedFilterConfig> httpFilterConfigs();
|
static final ServerRoutingConfig FAILING_ROUTING_CONFIG = ServerRoutingConfig.create(
|
||||||
|
ImmutableList.<VirtualHost>of(), ImmutableMap.<Route, ServerInterceptor>of());
|
||||||
|
|
||||||
abstract AtomicReference<ImmutableList<VirtualHost>> virtualHosts();
|
abstract ImmutableList<VirtualHost> virtualHosts();
|
||||||
|
|
||||||
|
// Prebuilt per route server interceptors from http filter configs.
|
||||||
|
abstract ImmutableMap<Route, ServerInterceptor> interceptors();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server routing configuration.
|
* Server routing configuration.
|
||||||
* */
|
* */
|
||||||
public static ServerRoutingConfig create(List<NamedFilterConfig> httpFilterConfigs,
|
public static ServerRoutingConfig create(
|
||||||
AtomicReference<ImmutableList<VirtualHost>> virtualHosts) {
|
ImmutableList<VirtualHost> virtualHosts,
|
||||||
checkNotNull(httpFilterConfigs, "httpFilterConfigs");
|
ImmutableMap<Route, ServerInterceptor> interceptors) {
|
||||||
checkNotNull(virtualHosts, "virtualHosts");
|
checkNotNull(virtualHosts, "virtualHosts");
|
||||||
return new AutoValue_XdsServerWrapper_ServerRoutingConfig(
|
checkNotNull(interceptors, "interceptors");
|
||||||
ImmutableList.copyOf(httpFilterConfigs), virtualHosts);
|
return new AutoValue_XdsServerWrapper_ServerRoutingConfig(virtualHosts, interceptors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import static org.mockito.Mockito.when;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
|
import io.grpc.ServerInterceptor;
|
||||||
import io.grpc.internal.TestUtils.NoopChannelLogger;
|
import io.grpc.internal.TestUtils.NoopChannelLogger;
|
||||||
import io.grpc.netty.GrpcHttp2ConnectionHandler;
|
import io.grpc.netty.GrpcHttp2ConnectionHandler;
|
||||||
import io.grpc.netty.InternalProtocolNegotiationEvent;
|
import io.grpc.netty.InternalProtocolNegotiationEvent;
|
||||||
|
|
@ -93,8 +94,12 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
private static final String LOCAL_IP = "10.1.2.3"; // dest
|
private static final String LOCAL_IP = "10.1.2.3"; // dest
|
||||||
private static final String REMOTE_IP = "10.4.2.3"; // source
|
private static final String REMOTE_IP = "10.4.2.3"; // source
|
||||||
private static final int PORT = 7000;
|
private static final int PORT = 7000;
|
||||||
private final ServerRoutingConfig noopConfig = ServerRoutingConfig.create(
|
private final AtomicReference<ServerRoutingConfig> noopConfig = new AtomicReference<>(
|
||||||
new ArrayList<NamedFilterConfig>(), new AtomicReference<ImmutableList<VirtualHost>>());
|
ServerRoutingConfig.create(ImmutableList.<VirtualHost>of(),
|
||||||
|
ImmutableMap.<Route, ServerInterceptor>of()));
|
||||||
|
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
||||||
|
final SettableFuture<AtomicReference<ServerRoutingConfig>> routingSettable =
|
||||||
|
SettableFuture.create();
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@SuppressWarnings("FutureReturnValueIgnored")
|
@SuppressWarnings("FutureReturnValueIgnored")
|
||||||
|
|
@ -108,15 +113,14 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nofilterChainMatch_defaultSslContext() throws Exception {
|
public void nofilterChainMatch_defaultSslContext() throws Exception {
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
|
|
||||||
SslContextProviderSupplier defaultSsl = new SslContextProviderSupplier(createTls(),
|
SslContextProviderSupplier defaultSsl = new SslContextProviderSupplier(createTls(),
|
||||||
tlsContextManager);
|
tlsContextManager);
|
||||||
selectorManager.updateSelector(new FilterChainSelector(
|
selectorManager.updateSelector(new FilterChainSelector(
|
||||||
new HashMap<FilterChain, ServerRoutingConfig>(), defaultSsl, noopConfig));
|
new HashMap<FilterChain, AtomicReference<ServerRoutingConfig>>(),
|
||||||
|
defaultSsl, noopConfig));
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
setupChannel("172.168.1.1", "172.168.1.2", 80, filterChainMatchingHandler);
|
setupChannel("172.168.1.1", "172.168.1.2", 80, filterChainMatchingHandler);
|
||||||
|
|
@ -138,7 +142,8 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
@Test
|
@Test
|
||||||
public void noFilterChainMatch_noDefaultSslContext() {
|
public void noFilterChainMatch_noDefaultSslContext() {
|
||||||
selectorManager.updateSelector(new FilterChainSelector(
|
selectorManager.updateSelector(new FilterChainSelector(
|
||||||
new HashMap<FilterChain, ServerRoutingConfig>(), null, null));
|
new HashMap<FilterChain, AtomicReference<ServerRoutingConfig>>(),
|
||||||
|
null, new AtomicReference<ServerRoutingConfig>()));
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
setupChannel("172.168.1.1", "172.168.2.2", 90, filterChainMatchingHandler);
|
setupChannel("172.168.1.1", "172.168.2.2", 90, filterChainMatchingHandler);
|
||||||
|
|
@ -156,7 +161,7 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
ChannelHandler next = new ChannelInboundHandlerAdapter();
|
ChannelHandler next = new ChannelInboundHandlerAdapter();
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
selectorManager.updateSelector(new FilterChainSelector(
|
selectorManager.updateSelector(new FilterChainSelector(
|
||||||
new HashMap<FilterChain, ServerRoutingConfig>(), null, noopConfig));
|
new HashMap<FilterChain, AtomicReference<ServerRoutingConfig>>(), null, noopConfig));
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
setupChannel("172.168.1.1", "172.168.2.2", 90, filterChainMatchingHandler);
|
setupChannel("172.168.1.1", "172.168.2.2", 90, filterChainMatchingHandler);
|
||||||
|
|
@ -175,7 +180,7 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
assertThat(msg).isNull();
|
assertThat(msg).isNull();
|
||||||
|
|
||||||
selectorManager.updateSelector(new FilterChainSelector(
|
selectorManager.updateSelector(new FilterChainSelector(
|
||||||
new HashMap<FilterChain, ServerRoutingConfig>(), null, noopConfig));
|
new HashMap<FilterChain, AtomicReference<ServerRoutingConfig>>(), null, noopConfig));
|
||||||
assertThat(channel.readOutbound().getClass().getName())
|
assertThat(channel.readOutbound().getClass().getName())
|
||||||
.isEqualTo("io.grpc.netty.GracefulServerCloseCommand");
|
.isEqualTo("io.grpc.netty.GracefulServerCloseCommand");
|
||||||
}
|
}
|
||||||
|
|
@ -199,11 +204,9 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
tlsContextManager);
|
tlsContextManager);
|
||||||
|
|
||||||
selectorManager.updateSelector(new FilterChainSelector(ImmutableMap.of(filterChain, noopConfig),
|
selectorManager.updateSelector(new FilterChainSelector(ImmutableMap.of(filterChain, noopConfig),
|
||||||
null, null));
|
null, new AtomicReference<ServerRoutingConfig>()));
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -243,8 +246,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -281,17 +282,16 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
tlsContextForDefaultFilterChain, tlsContextManager);
|
tlsContextForDefaultFilterChain, tlsContextManager);
|
||||||
|
|
||||||
ServerRoutingConfig routingConfig = ServerRoutingConfig.create(
|
ServerRoutingConfig routingConfig = ServerRoutingConfig.create(
|
||||||
new ArrayList<NamedFilterConfig>(), new AtomicReference<>(
|
ImmutableList.of(createVirtualHost("virtual")),
|
||||||
ImmutableList.of(createVirtualHost("virtual"))));
|
ImmutableMap.<Route, ServerInterceptor>of());
|
||||||
selectorManager.updateSelector(new FilterChainSelector(
|
selectorManager.updateSelector(new FilterChainSelector(
|
||||||
ImmutableMap.of(filterChainWithDestPort, routingConfig),
|
ImmutableMap.of(filterChainWithDestPort,
|
||||||
|
new AtomicReference<ServerRoutingConfig>(routingConfig)),
|
||||||
defaultFilterChain.getSslContextProviderSupplier(), noopConfig));
|
defaultFilterChain.getSslContextProviderSupplier(), noopConfig));
|
||||||
|
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -333,8 +333,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -377,8 +375,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -417,12 +413,11 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
|
|
||||||
selectorManager.updateSelector(new FilterChainSelector(
|
selectorManager.updateSelector(new FilterChainSelector(
|
||||||
ImmutableMap.of(filterChain0Length, noopConfig),
|
ImmutableMap.of(filterChain0Length, noopConfig),
|
||||||
defaultFilterChain.getSslContextProviderSupplier(), null));
|
defaultFilterChain.getSslContextProviderSupplier(),
|
||||||
|
new AtomicReference<ServerRoutingConfig>()));
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -480,8 +475,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -538,8 +531,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -596,8 +587,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
|
|
||||||
|
|
@ -658,8 +647,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -700,8 +687,7 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -714,8 +700,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sourceTypeLocal() throws Exception {
|
public void sourceTypeLocal() throws Exception {
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
EnvoyServerProtoData.DownstreamTlsContext tlsContextMatch =
|
EnvoyServerProtoData.DownstreamTlsContext tlsContextMatch =
|
||||||
|
|
@ -755,8 +739,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
@Test
|
@Test
|
||||||
public void sourcePrefixRange_moreSpecificWith2Wins()
|
public void sourcePrefixRange_moreSpecificWith2Wins()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
|
|
||||||
|
|
@ -817,7 +799,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
@Test
|
@Test
|
||||||
public void sourcePrefixRange_2Matchers_expectException()
|
public void sourcePrefixRange_2Matchers_expectException()
|
||||||
throws UnknownHostException {
|
throws UnknownHostException {
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
ChannelHandler next = new ChannelInboundHandlerAdapter() {
|
ChannelHandler next = new ChannelInboundHandlerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
|
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
|
||||||
|
|
@ -932,8 +913,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
|
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -1074,7 +1053,7 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
EnvoyServerProtoData.FilterChain defaultFilterChain = new EnvoyServerProtoData.FilterChain(
|
EnvoyServerProtoData.FilterChain defaultFilterChain = new EnvoyServerProtoData.FilterChain(
|
||||||
"filter-chain-7", null, HTTP_CONNECTION_MANAGER, null, tlsContextManager);
|
"filter-chain-7", null, HTTP_CONNECTION_MANAGER, null, tlsContextManager);
|
||||||
|
|
||||||
Map<FilterChain, ServerRoutingConfig> map = new HashMap<>();
|
Map<FilterChain, AtomicReference<ServerRoutingConfig>> map = new HashMap<>();
|
||||||
map.put(filterChain1, randomConfig("1"));
|
map.put(filterChain1, randomConfig("1"));
|
||||||
map.put(filterChain2, randomConfig("2"));
|
map.put(filterChain2, randomConfig("2"));
|
||||||
map.put(filterChain3, randomConfig("3"));
|
map.put(filterChain3, randomConfig("3"));
|
||||||
|
|
@ -1087,8 +1066,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
|
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -1161,8 +1138,6 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
|
|
||||||
FilterChainMatchingHandler filterChainMatchingHandler =
|
FilterChainMatchingHandler filterChainMatchingHandler =
|
||||||
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
new FilterChainMatchingHandler(grpcHandler, selectorManager, mockDelegate);
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet = SettableFuture.create();
|
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable = SettableFuture.create();
|
|
||||||
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
ChannelHandler next = captureAttrHandler(sslSet, routingSettable);
|
||||||
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
when(mockDelegate.newHandler(grpcHandler)).thenReturn(next);
|
||||||
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
setupChannel(LOCAL_IP, REMOTE_IP, 15000, filterChainMatchingHandler);
|
||||||
|
|
@ -1186,10 +1161,11 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
ImmutableMap.<String, FilterConfig>of());
|
ImmutableMap.<String, FilterConfig>of());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ServerRoutingConfig randomConfig(String domain) {
|
private static AtomicReference<ServerRoutingConfig> randomConfig(String domain) {
|
||||||
return ServerRoutingConfig.create(
|
return new AtomicReference<>(
|
||||||
new ArrayList<NamedFilterConfig>(), new AtomicReference<>(
|
ServerRoutingConfig.create(ImmutableList.of(createVirtualHost(domain)),
|
||||||
ImmutableList.of(createVirtualHost(domain))));
|
ImmutableMap.<Route, ServerInterceptor>of())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EnvoyServerProtoData.DownstreamTlsContext createTls() {
|
private EnvoyServerProtoData.DownstreamTlsContext createTls() {
|
||||||
|
|
@ -1218,7 +1194,7 @@ public class FilterChainMatchingProtocolNegotiatorsTest {
|
||||||
|
|
||||||
private static ChannelHandler captureAttrHandler(
|
private static ChannelHandler captureAttrHandler(
|
||||||
final SettableFuture<SslContextProviderSupplier> sslSet,
|
final SettableFuture<SslContextProviderSupplier> sslSet,
|
||||||
final SettableFuture<ServerRoutingConfig> routingSettable) {
|
final SettableFuture<AtomicReference<ServerRoutingConfig>> routingSettable) {
|
||||||
return new ChannelInboundHandlerAdapter() {
|
return new ChannelInboundHandlerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
|
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,9 @@ package io.grpc.xds;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import io.grpc.ServerInterceptor;
|
||||||
import io.grpc.xds.EnvoyServerProtoData.FilterChain;
|
import io.grpc.xds.EnvoyServerProtoData.FilterChain;
|
||||||
import io.grpc.xds.Filter.NamedFilterConfig;
|
|
||||||
import io.grpc.xds.FilterChainMatchingProtocolNegotiators.FilterChainMatchingHandler.FilterChainSelector;
|
import io.grpc.xds.FilterChainMatchingProtocolNegotiators.FilterChainMatchingHandler.FilterChainSelector;
|
||||||
import io.grpc.xds.FilterChainSelectorManager.Closer;
|
import io.grpc.xds.FilterChainSelectorManager.Closer;
|
||||||
import io.grpc.xds.XdsServerWrapper.ServerRoutingConfig;
|
import io.grpc.xds.XdsServerWrapper.ServerRoutingConfig;
|
||||||
|
|
@ -33,13 +34,15 @@ import org.junit.runners.JUnit4;
|
||||||
@RunWith(JUnit4.class)
|
@RunWith(JUnit4.class)
|
||||||
public final class FilterChainSelectorManagerTest {
|
public final class FilterChainSelectorManagerTest {
|
||||||
private FilterChainSelectorManager manager = new FilterChainSelectorManager();
|
private FilterChainSelectorManager manager = new FilterChainSelectorManager();
|
||||||
private ServerRoutingConfig noopConfig = ServerRoutingConfig.create(
|
private AtomicReference<ServerRoutingConfig> noopConfig = new AtomicReference<>(
|
||||||
Collections.<NamedFilterConfig>emptyList(),
|
ServerRoutingConfig.create(ImmutableList.<VirtualHost>of(),
|
||||||
new AtomicReference<ImmutableList<VirtualHost>>());
|
ImmutableMap.<VirtualHost.Route, ServerInterceptor>of()));
|
||||||
private FilterChainSelector selector1 = new FilterChainSelector(
|
private FilterChainSelector selector1 = new FilterChainSelector(
|
||||||
Collections.<FilterChain,ServerRoutingConfig>emptyMap(), null, null);
|
Collections.<FilterChain,AtomicReference<ServerRoutingConfig>>emptyMap(),
|
||||||
|
null, new AtomicReference<ServerRoutingConfig>());
|
||||||
private FilterChainSelector selector2 = new FilterChainSelector(
|
private FilterChainSelector selector2 = new FilterChainSelector(
|
||||||
Collections.<FilterChain,ServerRoutingConfig>emptyMap(), null, noopConfig);
|
Collections.<FilterChain,AtomicReference<ServerRoutingConfig>>emptyMap(),
|
||||||
|
null, noopConfig);
|
||||||
private CounterRunnable runnable1 = new CounterRunnable();
|
private CounterRunnable runnable1 = new CounterRunnable();
|
||||||
private CounterRunnable runnable2 = new CounterRunnable();
|
private CounterRunnable runnable2 = new CounterRunnable();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,8 @@ public class XdsServerWrapperTest {
|
||||||
private FakeXdsClient xdsClient = new FakeXdsClient();
|
private FakeXdsClient xdsClient = new FakeXdsClient();
|
||||||
private FilterRegistry filterRegistry = FilterRegistry.getDefaultRegistry();
|
private FilterRegistry filterRegistry = FilterRegistry.getDefaultRegistry();
|
||||||
private XdsServerWrapper xdsServerWrapper;
|
private XdsServerWrapper xdsServerWrapper;
|
||||||
|
private ServerRoutingConfig noopConfig = ServerRoutingConfig.create(
|
||||||
|
ImmutableList.<VirtualHost>of(), ImmutableMap.<Route, ServerInterceptor>of());
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
|
@ -380,9 +382,9 @@ public class XdsServerWrapperTest {
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
||||||
.isEqualTo(1);
|
.isEqualTo(1);
|
||||||
ServerRoutingConfig realConfig =
|
ServerRoutingConfig realConfig =
|
||||||
selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(filterChain);
|
selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(filterChain).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(httpConnectionManager.virtualHosts());
|
assertThat(realConfig.virtualHosts()).isEqualTo(httpConnectionManager.virtualHosts());
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(httpConnectionManager.httpFilterConfigs());
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
verify(listener).onServing();
|
verify(listener).onServing();
|
||||||
verify(mockServer).start();
|
verify(mockServer).start();
|
||||||
}
|
}
|
||||||
|
|
@ -429,26 +431,21 @@ public class XdsServerWrapperTest {
|
||||||
start.get(5000, TimeUnit.MILLISECONDS);
|
start.get(5000, TimeUnit.MILLISECONDS);
|
||||||
verify(mockServer).start();
|
verify(mockServer).start();
|
||||||
ServerRoutingConfig realConfig =
|
ServerRoutingConfig realConfig =
|
||||||
selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f0);
|
selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f0).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-0")));
|
Collections.singletonList(createVirtualHost("virtual-host-0")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
f0.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
||||||
.isEqualTo(2);
|
.isEqualTo(2);
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f2);
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f2).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
f2.getHttpConnectionManager().httpFilterConfigs());
|
realConfig = selectorManager.getSelectorToUpdateSelector().getDefaultRoutingConfig().get();
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getDefaultRoutingConfig();
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-2")));
|
Collections.singletonList(createVirtualHost("virtual-host-2")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
|
||||||
f3.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getDefaultSslContextProviderSupplier())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getDefaultSslContextProviderSupplier())
|
||||||
.isEqualTo(
|
.isEqualTo(f3.getSslContextProviderSupplier());
|
||||||
f3.getSslContextProviderSupplier());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -481,22 +478,20 @@ public class XdsServerWrapperTest {
|
||||||
start.get(5000, TimeUnit.MILLISECONDS);
|
start.get(5000, TimeUnit.MILLISECONDS);
|
||||||
verify(mockServer, times(1)).start();
|
verify(mockServer, times(1)).start();
|
||||||
ServerRoutingConfig realConfig =
|
ServerRoutingConfig realConfig =
|
||||||
selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f0);
|
selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f0).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-0")));
|
Collections.singletonList(createVirtualHost("virtual-host-0")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
f0.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1);
|
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-0")));
|
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
|
||||||
f1.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
|
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getDefaultRoutingConfig();
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-0")));
|
Collections.singletonList(createVirtualHost("virtual-host-0")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
f2.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
|
realConfig = selectorManager.getSelectorToUpdateSelector().getDefaultRoutingConfig().get();
|
||||||
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
|
Collections.singletonList(createVirtualHost("virtual-host-0")));
|
||||||
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getDefaultSslContextProviderSupplier())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getDefaultSslContextProviderSupplier())
|
||||||
.isSameInstanceAs(f2.getSslContextProviderSupplier());
|
.isSameInstanceAs(f2.getSslContextProviderSupplier());
|
||||||
|
|
||||||
|
|
@ -513,25 +508,22 @@ public class XdsServerWrapperTest {
|
||||||
|
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
||||||
.isEqualTo(2);
|
.isEqualTo(2);
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f5);
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f5).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
f5.getHttpConnectionManager().httpFilterConfigs());
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f3).get();
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f3);
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-0")));
|
Collections.singletonList(createVirtualHost("virtual-host-0")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
f3.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
|
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getDefaultRoutingConfig();
|
realConfig = selectorManager.getSelectorToUpdateSelector().getDefaultRoutingConfig().get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
f4.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getDefaultSslContextProviderSupplier())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getDefaultSslContextProviderSupplier())
|
||||||
.isSameInstanceAs(
|
.isSameInstanceAs(f4.getSslContextProviderSupplier());
|
||||||
f4.getSslContextProviderSupplier());
|
|
||||||
verify(mockServer, times(1)).start();
|
verify(mockServer, times(1)).start();
|
||||||
xdsServerWrapper.shutdown();
|
xdsServerWrapper.shutdown();
|
||||||
verify(mockServer, times(1)).shutdown();
|
verify(mockServer, times(1)).shutdown();
|
||||||
|
|
@ -567,35 +559,31 @@ public class XdsServerWrapperTest {
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
||||||
.isEqualTo(2);
|
.isEqualTo(2);
|
||||||
ServerRoutingConfig realConfig =
|
ServerRoutingConfig realConfig =
|
||||||
selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1);
|
selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isNull();
|
assertThat(realConfig.virtualHosts()).isEmpty();
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEmpty();
|
||||||
f1.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f0);
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f0).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(hcmVirtual.virtualHosts());
|
assertThat(realConfig.virtualHosts()).isEqualTo(hcmVirtual.virtualHosts());
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
f0.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
|
|
||||||
xdsClient.deliverRdsUpdate("r0",
|
xdsClient.deliverRdsUpdate("r0",
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1);
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
f1.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
|
|
||||||
xdsClient.rdsWatchers.get("r0").onError(Status.CANCELLED);
|
xdsClient.rdsWatchers.get("r0").onError(Status.CANCELLED);
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1);
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
f1.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
|
|
||||||
xdsClient.rdsWatchers.get("r0").onResourceDoesNotExist("r0");
|
xdsClient.rdsWatchers.get("r0").onResourceDoesNotExist("r0");
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1);
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isNull();
|
assertThat(realConfig.virtualHosts()).isEmpty();
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEmpty();
|
||||||
f1.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -648,11 +636,11 @@ public class XdsServerWrapperTest {
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
||||||
.isEqualTo(1);
|
.isEqualTo(1);
|
||||||
ServerRoutingConfig realConfig =
|
ServerRoutingConfig realConfig =
|
||||||
selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(filterChain1);
|
selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(filterChain1).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
filterChain1.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
// xds update after start
|
// xds update after start
|
||||||
xdsClient.deliverRdsUpdate("rds",
|
xdsClient.deliverRdsUpdate("rds",
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-2")));
|
Collections.singletonList(createVirtualHost("virtual-host-2")));
|
||||||
|
|
@ -664,11 +652,11 @@ public class XdsServerWrapperTest {
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
||||||
.isEqualTo(1);
|
.isEqualTo(1);
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs()
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs()
|
||||||
.get(filterChain1);
|
.get(filterChain1).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-2")));
|
Collections.singletonList(createVirtualHost("virtual-host-2")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
filterChain1.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
assertThat(sslSupplier1.isShutdown()).isFalse();
|
assertThat(sslSupplier1.isShutdown()).isFalse();
|
||||||
|
|
||||||
// not serving after serving
|
// not serving after serving
|
||||||
|
|
@ -705,11 +693,11 @@ public class XdsServerWrapperTest {
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
||||||
.isEqualTo(1);
|
.isEqualTo(1);
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs()
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs()
|
||||||
.get(filterChain2);
|
.get(filterChain2).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
filterChain2.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
assertThat(executor.numPendingTasks()).isEqualTo(1);
|
assertThat(executor.numPendingTasks()).isEqualTo(1);
|
||||||
xdsClient.ldsWatcher.onResourceDoesNotExist(ldsResource);
|
xdsClient.ldsWatcher.onResourceDoesNotExist(ldsResource);
|
||||||
verify(mockServer, times(4)).shutdown();
|
verify(mockServer, times(4)).shutdown();
|
||||||
|
|
@ -733,11 +721,11 @@ public class XdsServerWrapperTest {
|
||||||
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
||||||
.isEqualTo(1);
|
.isEqualTo(1);
|
||||||
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs()
|
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs()
|
||||||
.get(filterChain3);
|
.get(filterChain3).get();
|
||||||
assertThat(realConfig.virtualHosts().get()).isEqualTo(
|
assertThat(realConfig.virtualHosts()).isEqualTo(
|
||||||
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
Collections.singletonList(createVirtualHost("virtual-host-1")));
|
||||||
assertThat(realConfig.httpFilterConfigs()).isEqualTo(
|
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
|
||||||
filterChain3.getHttpConnectionManager().httpFilterConfigs());
|
|
||||||
xdsServerWrapper.shutdown();
|
xdsServerWrapper.shutdown();
|
||||||
verify(mockServer, times(5)).shutdown();
|
verify(mockServer, times(5)).shutdown();
|
||||||
assertThat(sslSupplier3.isShutdown()).isTrue();
|
assertThat(sslSupplier3.isShutdown()).isTrue();
|
||||||
|
|
@ -747,9 +735,9 @@ public class XdsServerWrapperTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void interceptor_notServerInterceptor() throws Exception {
|
public void interceptor_success() throws Exception {
|
||||||
ArgumentCaptor<ConfigApplyingInterceptor> interceptorCaptor =
|
ArgumentCaptor<ConfigApplyingInterceptor> interceptorCaptor =
|
||||||
ArgumentCaptor.forClass(ConfigApplyingInterceptor.class);
|
ArgumentCaptor.forClass(ConfigApplyingInterceptor.class);
|
||||||
final SettableFuture<Server> start = SettableFuture.create();
|
final SettableFuture<Server> start = SettableFuture.create();
|
||||||
Executors.newSingleThreadExecutor().execute(new Runnable() {
|
Executors.newSingleThreadExecutor().execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -764,26 +752,36 @@ public class XdsServerWrapperTest {
|
||||||
xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
|
xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
|
||||||
verify(mockBuilder).intercept(interceptorCaptor.capture());
|
verify(mockBuilder).intercept(interceptorCaptor.capture());
|
||||||
ConfigApplyingInterceptor interceptor = interceptorCaptor.getValue();
|
ConfigApplyingInterceptor interceptor = interceptorCaptor.getValue();
|
||||||
ServerRoutingConfig routingConfig = createRoutingConfig("/FooService/barMethod",
|
RouteMatch routeMatch =
|
||||||
"foo.google.com", "filter-type-url");
|
RouteMatch.create(
|
||||||
|
PathMatcher.fromPath("/FooService/barMethod", true),
|
||||||
|
Collections.<HeaderMatcher>emptyList(), null);
|
||||||
|
Route route = Route.forAction(routeMatch, null,
|
||||||
|
ImmutableMap.<String, FilterConfig>of());
|
||||||
|
VirtualHost virtualHost = VirtualHost.create(
|
||||||
|
"v1", Collections.singletonList("foo.google.com"), Arrays.asList(route),
|
||||||
|
ImmutableMap.<String, FilterConfig>of());
|
||||||
|
final List<Integer> interceptorTrace = new ArrayList<>();
|
||||||
|
ServerInterceptor interceptor0 = new ServerInterceptor() {
|
||||||
|
@Override
|
||||||
|
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
||||||
|
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||||
|
interceptorTrace.add(0);
|
||||||
|
return next.startCall(call, headers);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ServerRoutingConfig realConfig = ServerRoutingConfig.create(
|
||||||
|
ImmutableList.of(virtualHost), ImmutableMap.of(route, interceptor0));
|
||||||
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
||||||
when(serverCall.getAttributes()).thenReturn(
|
|
||||||
Attributes.newBuilder().set(ATTR_SERVER_ROUTING_CONFIG, routingConfig).build());
|
|
||||||
when(serverCall.getMethodDescriptor()).thenReturn(createMethod("FooService/barMethod"));
|
when(serverCall.getMethodDescriptor()).thenReturn(createMethod("FooService/barMethod"));
|
||||||
|
when(serverCall.getAttributes()).thenReturn(
|
||||||
|
Attributes.newBuilder().set(ATTR_SERVER_ROUTING_CONFIG,
|
||||||
|
new AtomicReference<>(realConfig)).build());
|
||||||
when(serverCall.getAuthority()).thenReturn("foo.google.com");
|
when(serverCall.getAuthority()).thenReturn("foo.google.com");
|
||||||
|
|
||||||
Filter filter = mock(Filter.class);
|
|
||||||
when(filter.typeUrls()).thenReturn(new String[]{"filter-type-url"});
|
|
||||||
filterRegistry.register(filter);
|
|
||||||
ServerCallHandler<Void, Void> next = mock(ServerCallHandler.class);
|
ServerCallHandler<Void, Void> next = mock(ServerCallHandler.class);
|
||||||
interceptor.interceptCall(serverCall, new Metadata(), next);
|
interceptor.interceptCall(serverCall, new Metadata(), next);
|
||||||
verify(next, never()).startCall(any(ServerCall.class), any(Metadata.class));
|
verify(next).startCall(eq(serverCall), any(Metadata.class));
|
||||||
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
|
assertThat(interceptorTrace).isEqualTo(Arrays.asList(0));
|
||||||
verify(serverCall).close(statusCaptor.capture(), any(Metadata.class));
|
|
||||||
Status status = statusCaptor.getValue();
|
|
||||||
assertThat(status.getCode()).isEqualTo(Status.UNAVAILABLE.getCode());
|
|
||||||
assertThat(status.getDescription()).isEqualTo(
|
|
||||||
"HttpFilterConfig(type URL: filter-type-url) is not supported on server-side.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -809,7 +807,8 @@ public class XdsServerWrapperTest {
|
||||||
"foo.google.com", "filter-type-url");
|
"foo.google.com", "filter-type-url");
|
||||||
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
||||||
when(serverCall.getAttributes()).thenReturn(
|
when(serverCall.getAttributes()).thenReturn(
|
||||||
Attributes.newBuilder().set(ATTR_SERVER_ROUTING_CONFIG, routingConfig).build());
|
Attributes.newBuilder().set(ATTR_SERVER_ROUTING_CONFIG,
|
||||||
|
new AtomicReference<>(routingConfig)).build());
|
||||||
when(serverCall.getAuthority()).thenReturn("not-match.google.com");
|
when(serverCall.getAuthority()).thenReturn("not-match.google.com");
|
||||||
|
|
||||||
Filter filter = mock(Filter.class);
|
Filter filter = mock(Filter.class);
|
||||||
|
|
@ -848,7 +847,8 @@ public class XdsServerWrapperTest {
|
||||||
"foo.google.com", "filter-type-url");
|
"foo.google.com", "filter-type-url");
|
||||||
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
||||||
when(serverCall.getAttributes()).thenReturn(
|
when(serverCall.getAttributes()).thenReturn(
|
||||||
Attributes.newBuilder().set(ATTR_SERVER_ROUTING_CONFIG, routingConfig).build());
|
Attributes.newBuilder()
|
||||||
|
.set(ATTR_SERVER_ROUTING_CONFIG, new AtomicReference<>(routingConfig)).build());
|
||||||
when(serverCall.getMethodDescriptor()).thenReturn(createMethod("NotMatchMethod"));
|
when(serverCall.getMethodDescriptor()).thenReturn(createMethod("NotMatchMethod"));
|
||||||
when(serverCall.getAuthority()).thenReturn("foo.google.com");
|
when(serverCall.getAuthority()).thenReturn("foo.google.com");
|
||||||
|
|
||||||
|
|
@ -884,12 +884,11 @@ public class XdsServerWrapperTest {
|
||||||
xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
|
xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
|
||||||
verify(mockBuilder).intercept(interceptorCaptor.capture());
|
verify(mockBuilder).intercept(interceptorCaptor.capture());
|
||||||
ConfigApplyingInterceptor interceptor = interceptorCaptor.getValue();
|
ConfigApplyingInterceptor interceptor = interceptorCaptor.getValue();
|
||||||
ServerRoutingConfig failingConfig = ServerRoutingConfig.create(
|
|
||||||
ImmutableList.<NamedFilterConfig>of(), new AtomicReference<ImmutableList<VirtualHost>>()
|
|
||||||
);
|
|
||||||
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
||||||
|
|
||||||
when(serverCall.getAttributes()).thenReturn(
|
when(serverCall.getAttributes()).thenReturn(
|
||||||
Attributes.newBuilder().set(ATTR_SERVER_ROUTING_CONFIG, failingConfig).build());
|
Attributes.newBuilder().set(ATTR_SERVER_ROUTING_CONFIG,
|
||||||
|
new AtomicReference<>(ServerRoutingConfig.FAILING_ROUTING_CONFIG)).build());
|
||||||
|
|
||||||
ServerCallHandler<Void, Void> next = mock(ServerCallHandler.class);
|
ServerCallHandler<Void, Void> next = mock(ServerCallHandler.class);
|
||||||
interceptor.interceptCall(serverCall, new Metadata(), next);
|
interceptor.interceptCall(serverCall, new Metadata(), next);
|
||||||
|
|
@ -899,14 +898,12 @@ public class XdsServerWrapperTest {
|
||||||
Status status = statusCaptor.getValue();
|
Status status = statusCaptor.getValue();
|
||||||
assertThat(status.getCode()).isEqualTo(Status.UNAVAILABLE.getCode());
|
assertThat(status.getCode()).isEqualTo(Status.UNAVAILABLE.getCode());
|
||||||
assertThat(status.getDescription()).isEqualTo(
|
assertThat(status.getDescription()).isEqualTo(
|
||||||
"Missing xDS routing config VirtualHosts due to RDS config unavailable.");
|
"Missing or broken xDS routing config: RDS config unavailable.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void interceptors() throws Exception {
|
public void buildInterceptor_inline() throws Exception {
|
||||||
ArgumentCaptor<ConfigApplyingInterceptor> interceptorCaptor =
|
|
||||||
ArgumentCaptor.forClass(ConfigApplyingInterceptor.class);
|
|
||||||
final SettableFuture<Server> start = SettableFuture.create();
|
final SettableFuture<Server> start = SettableFuture.create();
|
||||||
Executors.newSingleThreadExecutor().execute(new Runnable() {
|
Executors.newSingleThreadExecutor().execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -919,14 +916,12 @@ public class XdsServerWrapperTest {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
|
xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
|
||||||
verify(mockBuilder).intercept(interceptorCaptor.capture());
|
|
||||||
final ConfigApplyingInterceptor interceptor = interceptorCaptor.getValue();
|
|
||||||
RouteMatch routeMatch =
|
RouteMatch routeMatch =
|
||||||
RouteMatch.create(
|
RouteMatch.create(
|
||||||
PathMatcher.fromPath("/FooService/barMethod", true),
|
PathMatcher.fromPath("/FooService/barMethod", true),
|
||||||
Collections.<HeaderMatcher>emptyList(), null);
|
Collections.<HeaderMatcher>emptyList(), null);
|
||||||
Filter filter = mock(Filter.class, withSettings()
|
Filter filter = mock(Filter.class, withSettings()
|
||||||
.extraInterfaces(ServerInterceptorBuilder.class));
|
.extraInterfaces(ServerInterceptorBuilder.class));
|
||||||
when(filter.typeUrls()).thenReturn(new String[]{"filter-type-url"});
|
when(filter.typeUrls()).thenReturn(new String[]{"filter-type-url"});
|
||||||
filterRegistry.register(filter);
|
filterRegistry.register(filter);
|
||||||
FilterConfig f0 = mock(FilterConfig.class);
|
FilterConfig f0 = mock(FilterConfig.class);
|
||||||
|
|
@ -936,7 +931,7 @@ public class XdsServerWrapperTest {
|
||||||
ServerInterceptor interceptor0 = new ServerInterceptor() {
|
ServerInterceptor interceptor0 = new ServerInterceptor() {
|
||||||
@Override
|
@Override
|
||||||
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
||||||
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||||
interceptorTrace.add(0);
|
interceptorTrace.add(0);
|
||||||
return next.startCall(call, headers);
|
return next.startCall(call, headers);
|
||||||
}
|
}
|
||||||
|
|
@ -949,55 +944,130 @@ public class XdsServerWrapperTest {
|
||||||
return next.startCall(call, headers);
|
return next.startCall(call, headers);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
when(((ServerInterceptorBuilder)filter).buildServerInterceptor(f0, null))
|
||||||
|
.thenReturn(interceptor0);
|
||||||
|
when(((ServerInterceptorBuilder)filter).buildServerInterceptor(f0, f0Override))
|
||||||
|
.thenReturn(interceptor1);
|
||||||
|
Route route = Route.forAction(routeMatch, null,
|
||||||
|
ImmutableMap.<String, FilterConfig>of());
|
||||||
VirtualHost virtualHost = VirtualHost.create(
|
VirtualHost virtualHost = VirtualHost.create(
|
||||||
"v1", Collections.singletonList("foo.google.com"),
|
"v1", Collections.singletonList("foo.google.com"), Arrays.asList(route),
|
||||||
Arrays.asList(Route.forAction(routeMatch, null,
|
ImmutableMap.of("filter-config-name-0", f0Override));
|
||||||
ImmutableMap.<String, FilterConfig>of())),
|
HttpConnectionManager hcmVirtual = HttpConnectionManager.forVirtualHosts(
|
||||||
ImmutableMap.of("filter-config-name-0", f0Override));
|
0L, Collections.singletonList(virtualHost),
|
||||||
ServerRoutingConfig routingConfig = ServerRoutingConfig.create(
|
Arrays.asList(new NamedFilterConfig("filter-config-name-0", f0),
|
||||||
Arrays.asList(new NamedFilterConfig("filter-config-name-0", f0),
|
new NamedFilterConfig("filter-config-name-1", f0)));
|
||||||
new NamedFilterConfig("filter-config-name-1", f0)),
|
EnvoyServerProtoData.FilterChain filterChain = createFilterChain("filter-chain-0", hcmVirtual);
|
||||||
new AtomicReference<>(ImmutableList.<VirtualHost>of(virtualHost))
|
xdsClient.deliverLdsUpdate(Collections.singletonList(filterChain), null);
|
||||||
);
|
start.get(5000, TimeUnit.MILLISECONDS);
|
||||||
|
verify(mockServer).start();
|
||||||
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
||||||
|
.isEqualTo(1);
|
||||||
|
ServerInterceptor realInterceptor = selectorManager.getSelectorToUpdateSelector()
|
||||||
|
.getRoutingConfigs().get(filterChain).get().interceptors().get(route);
|
||||||
|
assertThat(realInterceptor).isNotNull();
|
||||||
|
|
||||||
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
||||||
ServerCallHandler<Void, Void> mockNext = mock(ServerCallHandler.class);
|
ServerCallHandler<Void, Void> mockNext = mock(ServerCallHandler.class);
|
||||||
final ServerCall.Listener<Void> listener = new ServerCall.Listener<Void>() {};
|
final ServerCall.Listener<Void> listener = new ServerCall.Listener<Void>() {};
|
||||||
when(mockNext.startCall(any(ServerCall.class), any(Metadata.class))).thenReturn(listener);
|
when(mockNext.startCall(any(ServerCall.class), any(Metadata.class))).thenReturn(listener);
|
||||||
when(serverCall.getAttributes()).thenReturn(
|
realInterceptor.interceptCall(serverCall, new Metadata(), mockNext);
|
||||||
Attributes.newBuilder().set(ATTR_SERVER_ROUTING_CONFIG, routingConfig).build());
|
assertThat(interceptorTrace).isEqualTo(Arrays.asList(1, 0));
|
||||||
when(serverCall.getMethodDescriptor()).thenReturn(createMethod("FooService/barMethod"));
|
|
||||||
when(serverCall.getAuthority()).thenReturn("foo.google.com");
|
|
||||||
|
|
||||||
when(((ServerInterceptorBuilder)filter).buildServerInterceptor(f0, f0Override))
|
|
||||||
.thenReturn(null);
|
|
||||||
when(((ServerInterceptorBuilder)filter).buildServerInterceptor(f0, null))
|
|
||||||
.thenReturn(null);
|
|
||||||
ServerCall.Listener<Void> configApplyingInterceptorListener =
|
|
||||||
interceptor.interceptCall(serverCall, new Metadata(), mockNext);
|
|
||||||
assertThat(configApplyingInterceptorListener).isSameInstanceAs(listener);
|
|
||||||
verify(mockNext).startCall(eq(serverCall), any(Metadata.class));
|
verify(mockNext).startCall(eq(serverCall), any(Metadata.class));
|
||||||
assertThat(interceptorTrace).isEqualTo(Arrays.asList());
|
}
|
||||||
|
|
||||||
when(((ServerInterceptorBuilder)filter).buildServerInterceptor(f0, f0Override))
|
@Test
|
||||||
.thenReturn(null);
|
@SuppressWarnings("unchecked")
|
||||||
|
public void buildInterceptor_rds() throws Exception {
|
||||||
|
final SettableFuture<Server> start = SettableFuture.create();
|
||||||
|
Executors.newSingleThreadExecutor().execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
start.set(xdsServerWrapper.start());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
start.setException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
Filter filter = mock(Filter.class, withSettings()
|
||||||
|
.extraInterfaces(ServerInterceptorBuilder.class));
|
||||||
|
when(filter.typeUrls()).thenReturn(new String[]{"filter-type-url"});
|
||||||
|
filterRegistry.register(filter);
|
||||||
|
FilterConfig f0 = mock(FilterConfig.class);
|
||||||
|
FilterConfig f0Override = mock(FilterConfig.class);
|
||||||
|
when(f0.typeUrl()).thenReturn("filter-type-url");
|
||||||
|
final List<Integer> interceptorTrace = new ArrayList<>();
|
||||||
|
ServerInterceptor interceptor0 = new ServerInterceptor() {
|
||||||
|
@Override
|
||||||
|
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
||||||
|
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||||
|
interceptorTrace.add(0);
|
||||||
|
return next.startCall(call, headers);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ServerInterceptor interceptor1 = new ServerInterceptor() {
|
||||||
|
@Override
|
||||||
|
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
||||||
|
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||||
|
interceptorTrace.add(1);
|
||||||
|
return next.startCall(call, headers);
|
||||||
|
}
|
||||||
|
};
|
||||||
when(((ServerInterceptorBuilder)filter).buildServerInterceptor(f0, null))
|
when(((ServerInterceptorBuilder)filter).buildServerInterceptor(f0, null))
|
||||||
.thenReturn(interceptor0);
|
.thenReturn(interceptor0);
|
||||||
configApplyingInterceptorListener = interceptor.interceptCall(
|
when(((ServerInterceptorBuilder)filter).buildServerInterceptor(f0, f0Override))
|
||||||
serverCall, new Metadata(), mockNext);
|
.thenReturn(interceptor1);
|
||||||
assertThat(configApplyingInterceptorListener).isSameInstanceAs(listener);
|
RouteMatch routeMatch =
|
||||||
|
RouteMatch.create(
|
||||||
|
PathMatcher.fromPath("/FooService/barMethod", true),
|
||||||
|
Collections.<HeaderMatcher>emptyList(), null);
|
||||||
|
|
||||||
|
HttpConnectionManager rdsHcm = HttpConnectionManager.forRdsName(0L, "r0",
|
||||||
|
Arrays.asList(new NamedFilterConfig("filter-config-name-0", f0),
|
||||||
|
new NamedFilterConfig("filter-config-name-1", f0)));
|
||||||
|
EnvoyServerProtoData.FilterChain filterChain = createFilterChain("filter-chain-0", rdsHcm);
|
||||||
|
xdsClient.deliverLdsUpdate(Collections.singletonList(filterChain), null);
|
||||||
|
Route route = Route.forAction(routeMatch, null,
|
||||||
|
ImmutableMap.<String, FilterConfig>of());
|
||||||
|
VirtualHost virtualHost = VirtualHost.create(
|
||||||
|
"v1", Collections.singletonList("foo.google.com"), Arrays.asList(route),
|
||||||
|
ImmutableMap.of("filter-config-name-0", f0Override));
|
||||||
|
xdsClient.rdsCount.await(5, TimeUnit.SECONDS);
|
||||||
|
xdsClient.deliverRdsUpdate("r0", Collections.singletonList(virtualHost));
|
||||||
|
start.get(5000, TimeUnit.MILLISECONDS);
|
||||||
|
verify(mockServer).start();
|
||||||
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size())
|
||||||
|
.isEqualTo(1);
|
||||||
|
ServerInterceptor realInterceptor = selectorManager.getSelectorToUpdateSelector()
|
||||||
|
.getRoutingConfigs().get(filterChain).get().interceptors().get(route);
|
||||||
|
assertThat(realInterceptor).isNotNull();
|
||||||
|
|
||||||
|
ServerCall<Void, Void> serverCall = mock(ServerCall.class);
|
||||||
|
ServerCallHandler<Void, Void> mockNext = mock(ServerCallHandler.class);
|
||||||
|
final ServerCall.Listener<Void> listener = new ServerCall.Listener<Void>() {};
|
||||||
|
when(mockNext.startCall(any(ServerCall.class), any(Metadata.class))).thenReturn(listener);
|
||||||
|
realInterceptor.interceptCall(serverCall, new Metadata(), mockNext);
|
||||||
|
assertThat(interceptorTrace).isEqualTo(Arrays.asList(1, 0));
|
||||||
|
verify(mockNext).startCall(eq(serverCall), any(Metadata.class));
|
||||||
|
|
||||||
|
virtualHost = VirtualHost.create(
|
||||||
|
"v1", Collections.singletonList("foo.google.com"), Arrays.asList(route),
|
||||||
|
ImmutableMap.<String, FilterConfig>of());
|
||||||
|
xdsClient.deliverRdsUpdate("r0", Collections.singletonList(virtualHost));
|
||||||
|
realInterceptor = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs()
|
||||||
|
.get(filterChain).get().interceptors().get(route);
|
||||||
|
assertThat(realInterceptor).isNotNull();
|
||||||
|
interceptorTrace.clear();
|
||||||
|
realInterceptor.interceptCall(serverCall, new Metadata(), mockNext);
|
||||||
|
assertThat(interceptorTrace).isEqualTo(Arrays.asList(0, 0));
|
||||||
verify(mockNext, times(2)).startCall(eq(serverCall), any(Metadata.class));
|
verify(mockNext, times(2)).startCall(eq(serverCall), any(Metadata.class));
|
||||||
assertThat(interceptorTrace).isEqualTo(Arrays.asList(0));
|
|
||||||
|
|
||||||
when(((ServerInterceptorBuilder)filter).buildServerInterceptor(f0, f0Override))
|
xdsClient.rdsWatchers.get("r0").onResourceDoesNotExist("r0");
|
||||||
.thenReturn(interceptor0);
|
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs()
|
||||||
when(((ServerInterceptorBuilder)filter).buildServerInterceptor(f0, null))
|
.get(filterChain).get()).isEqualTo(noopConfig);
|
||||||
.thenReturn(interceptor1);
|
|
||||||
configApplyingInterceptorListener = interceptor.interceptCall(
|
|
||||||
serverCall, new Metadata(), mockNext);
|
|
||||||
assertThat(configApplyingInterceptorListener).isSameInstanceAs(listener);
|
|
||||||
verify(mockNext, times(3)).startCall(eq(serverCall), any(Metadata.class));
|
|
||||||
assertThat(interceptorTrace).isEqualTo(Arrays.asList(0, 0, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FilterChain createFilterChain(String name, HttpConnectionManager hcm) {
|
private static FilterChain createFilterChain(String name, HttpConnectionManager hcm) {
|
||||||
|
|
@ -1012,8 +1082,12 @@ public class XdsServerWrapperTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HttpConnectionManager createRds(String name) {
|
private static HttpConnectionManager createRds(String name) {
|
||||||
|
return createRds(name, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HttpConnectionManager createRds(String name, FilterConfig filterConfig) {
|
||||||
return HttpConnectionManager.forRdsName(0L, name,
|
return HttpConnectionManager.forRdsName(0L, name,
|
||||||
Arrays.asList(new NamedFilterConfig("named-config-" + name, null)));
|
Arrays.asList(new NamedFilterConfig("named-config-" + name, filterConfig)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EnvoyServerProtoData.FilterChainMatch createMatch() {
|
private static EnvoyServerProtoData.FilterChainMatch createMatch() {
|
||||||
|
|
@ -1041,9 +1115,8 @@ public class XdsServerWrapperTest {
|
||||||
Collections.<String, FilterConfig>emptyMap());
|
Collections.<String, FilterConfig>emptyMap());
|
||||||
FilterConfig f0 = mock(FilterConfig.class);
|
FilterConfig f0 = mock(FilterConfig.class);
|
||||||
when(f0.typeUrl()).thenReturn(filterType);
|
when(f0.typeUrl()).thenReturn(filterType);
|
||||||
return ServerRoutingConfig.create(
|
return ServerRoutingConfig.create(ImmutableList.<VirtualHost>of(virtualHost),
|
||||||
Arrays.asList(new NamedFilterConfig("filter-config-name-0", f0)),
|
ImmutableMap.<Route, ServerInterceptor>of()
|
||||||
new AtomicReference<>(ImmutableList.<VirtualHost>of(virtualHost))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue