Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
616 changes: 616 additions & 0 deletions xds/src/main/java/io/grpc/xds/CompositeFilter.java

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions xds/src/main/java/io/grpc/xds/FilterRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ private FilterRegistry() {}
static synchronized FilterRegistry getDefaultRegistry() {
if (instance == null) {
instance = newRegistry().register(
new FaultFilter.Provider(),
new RouterFilter.Provider(),
new RbacFilter.Provider(),
new GcpAuthenticationFilter.Provider());
new FaultFilter.Provider(),
new RouterFilter.Provider(),
new RbacFilter.Provider(),
new GcpAuthenticationFilter.Provider(),
new CompositeFilter.Provider());
}
return instance;
}
Expand All @@ -58,6 +59,13 @@ FilterRegistry register(Filter.Provider... filters) {
return this;
}

@VisibleForTesting
void deregister(Filter.Provider provider) {
for (String typeUrl : provider.typeUrls()) {
supportedFilters.remove(typeUrl);
}
}

@Nullable
Filter.Provider get(String typeUrl) {
return supportedFilters.get(typeUrl);
Expand Down
25 changes: 21 additions & 4 deletions xds/src/main/java/io/grpc/xds/VirtualHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,38 @@ abstract static class Route {

abstract ImmutableMap<String, FilterConfig> filterConfigOverrides();

@Nullable
abstract ImmutableMap<String, com.google.protobuf.Struct> filterMetadata();

static Route forAction(RouteMatch routeMatch, RouteAction routeAction,
Map<String, FilterConfig> filterConfigOverrides) {
return create(routeMatch, routeAction, filterConfigOverrides);
return create(routeMatch, routeAction, filterConfigOverrides, null);
}

static Route forAction(RouteMatch routeMatch, RouteAction routeAction,
Map<String, FilterConfig> filterConfigOverrides,
@Nullable Map<String, com.google.protobuf.Struct> filterMetadata) {
return create(routeMatch, routeAction, filterConfigOverrides, filterMetadata);
}

static Route forNonForwardingAction(RouteMatch routeMatch,
Map<String, FilterConfig> filterConfigOverrides) {
return create(routeMatch, null, filterConfigOverrides);
return create(routeMatch, null, filterConfigOverrides, null);
}

static Route forNonForwardingAction(RouteMatch routeMatch,
Map<String, FilterConfig> filterConfigOverrides,
@Nullable Map<String, com.google.protobuf.Struct> filterMetadata) {
return create(routeMatch, null, filterConfigOverrides, filterMetadata);
}

private static Route create(
RouteMatch routeMatch, @Nullable RouteAction routeAction,
Map<String, FilterConfig> filterConfigOverrides) {
Map<String, FilterConfig> filterConfigOverrides,
@Nullable Map<String, com.google.protobuf.Struct> filterMetadata) {
return new AutoValue_VirtualHost_Route(
routeMatch, routeAction, ImmutableMap.copyOf(filterConfigOverrides));
routeMatch, routeAction, ImmutableMap.copyOf(filterConfigOverrides),
filterMetadata == null ? null : ImmutableMap.copyOf(filterMetadata));
}

@AutoValue
Expand Down
15 changes: 15 additions & 0 deletions xds/src/main/java/io/grpc/xds/XdsAttributes.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@

package io.grpc.xds;

import com.google.protobuf.Struct;
import io.grpc.Attributes;
import io.grpc.EquivalentAddressGroup;
import io.grpc.Grpc;
import io.grpc.NameResolver;
import io.grpc.xds.XdsNameResolverProvider.CallCounterProvider;
import io.grpc.xds.client.Locality;
import io.grpc.xds.client.XdsClient;
import java.util.Map;

/**
* Attributes used for xDS implementation.
Expand Down Expand Up @@ -100,5 +102,18 @@ final class XdsAttributes {
static final Attributes.Key<Long> ATTR_DRAIN_GRACE_NANOS =
Attributes.Key.create("io.grpc.xds.XdsAttributes.drainGraceTime");

/**
* Attribute key for xDS route metadata used in filter matching.
*/
@NameResolver.ResolutionResultAttr
public static final Attributes.Key<Map<String, Struct>> ATTR_FILTER_METADATA = Attributes.Key
.create("io.grpc.xds.XdsAttributes.filterMetadata");

/**
* CallOptions key for xDS route metadata used in filter matching.
*/
public static final io.grpc.CallOptions.Key<Map<String, Struct>> CALL_OPTIONS_FILTER_METADATA =
io.grpc.CallOptions.Key.create("io.grpc.xds.XdsAttributes.filterMetadata");

private XdsAttributes() {}
}
2 changes: 1 addition & 1 deletion xds/src/main/java/io/grpc/xds/XdsListenerResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ static FilterChain parseFilterChain(
// FilterChain contains L4 filters, so we ensure it contains only HCM.
if (proto.getFiltersCount() != 1) {
throw new ResourceInvalidException("FilterChain " + filterChainName
+ " should contain exact one HttpConnectionManager filter");
+ " should contain exactly one HttpConnectionManager filter");
}
io.envoyproxy.envoy.config.listener.v3.Filter l4Filter = proto.getFiltersList().get(0);
if (!l4Filter.hasTypedConfig()) {
Expand Down
3 changes: 3 additions & 0 deletions xds/src/main/java/io/grpc/xds/XdsNameResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ private void updateResolutionResult(XdsConfig xdsConfig) {
.setAttributes(attrs)
.setServiceConfig(parsedServiceConfig)
.build();
// todo: abhishek probably the filters are getting applied here ??
if (!listener.onResult2(result).isOk()) {
resolveState.xdsDependencyManager.requestReresolution();
}
Expand Down Expand Up @@ -404,6 +405,7 @@ static boolean matchHostName(String hostName, String pattern) {
private final class ConfigSelector extends InternalConfigSelector {
@Override
public Result selectConfig(PickSubchannelArgs args) {
// todo: AgraVator probably the filters are getting populated here
RoutingConfig routingCfg;
RouteData selectedRoute;
String cluster;
Expand Down Expand Up @@ -716,6 +718,7 @@ public void onUpdate(StatusOr<XdsConfig> updateOrStatus) {
}

VirtualHost virtualHost = update.getVirtualHost();
// filters and there configurations
ImmutableList<NamedFilterConfig> filterConfigs = httpConnectionManager.httpFilterConfigs();
long streamDurationNano = httpConnectionManager.httpMaxStreamDurationNano();

Expand Down
11 changes: 9 additions & 2 deletions xds/src/main/java/io/grpc/xds/XdsRouteConfigureResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.google.protobuf.Duration;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.Struct;
import com.google.protobuf.util.Durations;
import com.google.re2j.Pattern;
import com.google.re2j.PatternSyntaxException;
Expand Down Expand Up @@ -289,6 +290,11 @@ static StructOrError<Route> parseRoute(
}
Map<String, FilterConfig> overrideConfigs = overrideConfigsOrError.getStruct();

Map<String, Struct> filterMetadata = null;
if (proto.hasMetadata()) {
filterMetadata = proto.getMetadata().getFilterMetadataMap();
}

switch (proto.getActionCase()) {
case ROUTE:
StructOrError<RouteAction> routeAction =
Expand All @@ -303,10 +309,11 @@ static StructOrError<Route> parseRoute(
+ routeAction.getErrorDetail());
}
return StructOrError.fromStruct(
Route.forAction(routeMatch.getStruct(), routeAction.getStruct(), overrideConfigs));
Route.forAction(routeMatch.getStruct(), routeAction.getStruct(), overrideConfigs,
filterMetadata));
case NON_FORWARDING_ACTION:
return StructOrError.fromStruct(
Route.forNonForwardingAction(routeMatch.getStruct(), overrideConfigs));
Route.forNonForwardingAction(routeMatch.getStruct(), overrideConfigs, filterMetadata));
case REDIRECT:
case DIRECT_RESPONSE:
case FILTER_ACTION:
Expand Down
26 changes: 26 additions & 0 deletions xds/src/main/java/io/grpc/xds/internal/MatcherParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,36 @@ public static Matchers.StringMatcher parseStringMatcher(
Pattern.compile(proto.getSafeRegex().getRegex()));
case CONTAINS:
return Matchers.StringMatcher.forContains(proto.getContains());
case CUSTOM:
throw new IllegalArgumentException("custom string matcher is not supported");
case MATCHPATTERN_NOT_SET:
default:
throw new IllegalArgumentException(
"Unknown StringMatcher match pattern: " + proto.getMatchPatternCase());
}
}

/** Translate StringMatcher xDS proto to internal StringMatcher. */
public static Matchers.StringMatcher parseStringMatcher(
com.github.xds.type.matcher.v3.StringMatcher proto) {
switch (proto.getMatchPatternCase()) {
case EXACT:
return Matchers.StringMatcher.forExact(proto.getExact(), proto.getIgnoreCase());
case PREFIX:
return Matchers.StringMatcher.forPrefix(proto.getPrefix(), proto.getIgnoreCase());
case SUFFIX:
return Matchers.StringMatcher.forSuffix(proto.getSuffix(), proto.getIgnoreCase());
case SAFE_REGEX:
return Matchers.StringMatcher.forSafeRegEx(
Pattern.compile(proto.getSafeRegex().getRegex()));
case CONTAINS:
return Matchers.StringMatcher.forContains(proto.getContains());
case CUSTOM:
throw new IllegalArgumentException("custom string matcher is not supported");
case MATCHPATTERN_NOT_SET:
default:
throw new IllegalArgumentException(
"Unknown StringMatcher match pattern: " + proto.getMatchPatternCase());
}
}
}
Loading
Loading