use of io.grpc.xds.Filter.NamedFilterConfig in project grpc-java by grpc.
the class ClientXdsClient method parseHttpConnectionManager.
@VisibleForTesting
static io.grpc.xds.HttpConnectionManager parseHttpConnectionManager(HttpConnectionManager proto, Set<String> rdsResources, FilterRegistry filterRegistry, boolean parseHttpFilter, boolean isForClient) throws ResourceInvalidException {
if (enableRbac && proto.getXffNumTrustedHops() != 0) {
throw new ResourceInvalidException("HttpConnectionManager with xff_num_trusted_hops unsupported");
}
if (enableRbac && !proto.getOriginalIpDetectionExtensionsList().isEmpty()) {
throw new ResourceInvalidException("HttpConnectionManager with " + "original_ip_detection_extensions unsupported");
}
// Obtain max_stream_duration from Http Protocol Options.
long maxStreamDuration = 0;
if (proto.hasCommonHttpProtocolOptions()) {
HttpProtocolOptions options = proto.getCommonHttpProtocolOptions();
if (options.hasMaxStreamDuration()) {
maxStreamDuration = Durations.toNanos(options.getMaxStreamDuration());
}
}
// Parse http filters.
List<NamedFilterConfig> filterConfigs = null;
if (parseHttpFilter) {
if (proto.getHttpFiltersList().isEmpty()) {
throw new ResourceInvalidException("Missing HttpFilter in HttpConnectionManager.");
}
filterConfigs = new ArrayList<>();
Set<String> names = new HashSet<>();
for (int i = 0; i < proto.getHttpFiltersCount(); i++) {
io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter httpFilter = proto.getHttpFiltersList().get(i);
String filterName = httpFilter.getName();
if (!names.add(filterName)) {
throw new ResourceInvalidException("HttpConnectionManager contains duplicate HttpFilter: " + filterName);
}
StructOrError<FilterConfig> filterConfig = parseHttpFilter(httpFilter, filterRegistry, isForClient);
if ((i == proto.getHttpFiltersCount() - 1) && (filterConfig == null || !isTerminalFilter(filterConfig.struct))) {
throw new ResourceInvalidException("The last HttpFilter must be a terminal filter: " + filterName);
}
if (filterConfig == null) {
continue;
}
if (filterConfig.getErrorDetail() != null) {
throw new ResourceInvalidException("HttpConnectionManager contains invalid HttpFilter: " + filterConfig.getErrorDetail());
}
if ((i < proto.getHttpFiltersCount() - 1) && isTerminalFilter(filterConfig.getStruct())) {
throw new ResourceInvalidException("A terminal HttpFilter must be the last filter: " + filterName);
}
filterConfigs.add(new NamedFilterConfig(filterName, filterConfig.struct));
}
}
// Parse inlined RouteConfiguration or RDS.
if (proto.hasRouteConfig()) {
List<VirtualHost> virtualHosts = extractVirtualHosts(proto.getRouteConfig(), filterRegistry, parseHttpFilter);
return io.grpc.xds.HttpConnectionManager.forVirtualHosts(maxStreamDuration, virtualHosts, filterConfigs);
}
if (proto.hasRds()) {
Rds rds = proto.getRds();
if (!rds.hasConfigSource()) {
throw new ResourceInvalidException("HttpConnectionManager contains invalid RDS: missing config_source");
}
if (!rds.getConfigSource().hasAds() && !rds.getConfigSource().hasSelf()) {
throw new ResourceInvalidException("HttpConnectionManager contains invalid RDS: must specify ADS or self ConfigSource");
}
// Collect the RDS resource referenced by this HttpConnectionManager.
rdsResources.add(rds.getRouteConfigName());
return io.grpc.xds.HttpConnectionManager.forRdsName(maxStreamDuration, rds.getRouteConfigName(), filterConfigs);
}
throw new ResourceInvalidException("HttpConnectionManager neither has inlined route_config nor RDS");
}
use of io.grpc.xds.Filter.NamedFilterConfig in project grpc-java by grpc.
the class XdsServerWrapperTest method discoverState_rds_onError_and_resourceNotExist.
@Test
public void discoverState_rds_onError_and_resourceNotExist() 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);
}
}
});
String ldsWatched = xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
assertThat(ldsWatched).isEqualTo("grpc/server?udpa.resource.listening_address=0.0.0.0:1");
VirtualHost virtualHost = createVirtualHost("virtual-host-0");
HttpConnectionManager hcmVirtual = HttpConnectionManager.forVirtualHosts(0L, Collections.singletonList(virtualHost), new ArrayList<NamedFilterConfig>());
EnvoyServerProtoData.FilterChain f0 = createFilterChain("filter-chain-0", hcmVirtual);
EnvoyServerProtoData.FilterChain f1 = createFilterChain("filter-chain-1", createRds("r0"));
xdsClient.deliverLdsUpdate(Arrays.asList(f0, f1), null);
xdsClient.rdsCount.await();
xdsClient.rdsWatchers.get("r0").onError(Status.CANCELLED);
start.get(5000, TimeUnit.MILLISECONDS);
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size()).isEqualTo(2);
ServerRoutingConfig realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1).get();
assertThat(realConfig.virtualHosts()).isEmpty();
assertThat(realConfig.interceptors()).isEmpty();
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f0).get();
assertThat(realConfig.virtualHosts()).isEqualTo(hcmVirtual.virtualHosts());
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
xdsClient.deliverRdsUpdate("r0", Collections.singletonList(createVirtualHost("virtual-host-1")));
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1).get();
assertThat(realConfig.virtualHosts()).isEqualTo(Collections.singletonList(createVirtualHost("virtual-host-1")));
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
xdsClient.rdsWatchers.get("r0").onError(Status.CANCELLED);
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1).get();
assertThat(realConfig.virtualHosts()).isEqualTo(Collections.singletonList(createVirtualHost("virtual-host-1")));
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
xdsClient.rdsWatchers.get("r0").onResourceDoesNotExist("r0");
realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(f1).get();
assertThat(realConfig.virtualHosts()).isEmpty();
assertThat(realConfig.interceptors()).isEmpty();
}
use of io.grpc.xds.Filter.NamedFilterConfig in project grpc-java by grpc.
the class XdsServerWrapperTest method buildInterceptor_rds.
@Test
@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)).thenReturn(interceptor0);
when(((ServerInterceptorBuilder) filter).buildServerInterceptor(f0, f0Override)).thenReturn(interceptor1);
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));
xdsClient.rdsWatchers.get("r0").onResourceDoesNotExist("r0");
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(filterChain).get()).isEqualTo(noopConfig);
}
use of io.grpc.xds.Filter.NamedFilterConfig in project grpc-java by grpc.
the class XdsServerWrapperTest method discoverState_virtualhost.
@Test
public void discoverState_virtualhost() 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);
}
}
});
String ldsWatched = xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
assertThat(ldsWatched).isEqualTo("grpc/server?udpa.resource.listening_address=0.0.0.0:1");
VirtualHost virtualHost = VirtualHost.create("virtual-host", Collections.singletonList("auth"), new ArrayList<Route>(), ImmutableMap.<String, FilterConfig>of());
HttpConnectionManager httpConnectionManager = HttpConnectionManager.forVirtualHosts(0L, Collections.singletonList(virtualHost), new ArrayList<NamedFilterConfig>());
EnvoyServerProtoData.FilterChain filterChain = EnvoyServerProtoData.FilterChain.create("filter-chain-foo", createMatch(), httpConnectionManager, createTls(), mock(TlsContextManager.class));
xdsClient.deliverLdsUpdate(Collections.singletonList(filterChain), null);
start.get(5000, TimeUnit.MILLISECONDS);
assertThat(ldsWatched).isEqualTo("grpc/server?udpa.resource.listening_address=0.0.0.0:1");
assertThat(selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().size()).isEqualTo(1);
ServerRoutingConfig realConfig = selectorManager.getSelectorToUpdateSelector().getRoutingConfigs().get(filterChain).get();
assertThat(realConfig.virtualHosts()).isEqualTo(httpConnectionManager.virtualHosts());
assertThat(realConfig.interceptors()).isEqualTo(ImmutableMap.of());
verify(listener).onServing();
verify(mockServer).start();
}
use of io.grpc.xds.Filter.NamedFilterConfig in project grpc-java by grpc.
the class XdsServerWrapperTest method shutdown.
@Test
public void shutdown() 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);
}
}
});
String ldsWatched = xdsClient.ldsResource.get(5, TimeUnit.SECONDS);
assertThat(ldsWatched).isEqualTo("grpc/server?udpa.resource.listening_address=0.0.0.0:1");
HttpConnectionManager hcm_virtual = HttpConnectionManager.forVirtualHosts(0L, Collections.singletonList(createVirtualHost("virtual-host-0")), new ArrayList<NamedFilterConfig>());
FilterChain f0 = createFilterChain("filter-chain-0", hcm_virtual);
FilterChain f1 = createFilterChain("filter-chain-1", createRds("rds"));
xdsClient.deliverLdsUpdate(Collections.singletonList(f0), f1);
xdsClient.rdsCount.await(5, TimeUnit.SECONDS);
xdsClient.deliverRdsUpdate("rds", Collections.singletonList(createVirtualHost("virtual-host-1")));
start.get(5000, TimeUnit.MILLISECONDS);
verify(mockServer).start();
xdsServerWrapper.shutdown();
assertThat(xdsServerWrapper.isShutdown()).isTrue();
assertThat(xdsClient.ldsResource).isNull();
assertThat(xdsClient.shutdown).isTrue();
verify(mockServer).shutdown();
assertThat(f0.sslContextProviderSupplier().isShutdown()).isTrue();
assertThat(f1.sslContextProviderSupplier().isShutdown()).isTrue();
when(mockServer.isTerminated()).thenReturn(true);
when(mockServer.awaitTermination(anyLong(), any(TimeUnit.class))).thenReturn(true);
assertThat(xdsServerWrapper.awaitTermination(5, TimeUnit.SECONDS)).isTrue();
xdsServerWrapper.awaitTermination();
assertThat(xdsServerWrapper.isTerminated()).isTrue();
assertThat(start.get()).isSameInstanceAs(xdsServerWrapper);
}
Aggregations