Skip to content

Commit be05900

Browse files
committed
fix: skip filter
1 parent af9a9ce commit be05900

3 files changed

Lines changed: 80 additions & 0 deletions

File tree

xds/src/main/java/io/grpc/xds/CompositeFilter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ private static FilterDelegate createFilterDelegate(
246246
delegates.add(new DelegateEntry(provider, parsed.config, childFilterConfig.getName()));
247247
}
248248
return new FilterDelegate(delegates, samplePercent);
249+
} else if (actionAny.getTypeUrl().equals(
250+
"type.googleapis.com/envoy.extensions.filters.common.matcher.action.v3.SkipFilter")) {
251+
return new FilterDelegate(Collections.emptyList(), null);
249252
}
250253
} catch (InvalidProtocolBufferException e) {
251254
throw new RuntimeException(e);

xds/src/main/java/io/grpc/xds/internal/MatcherParser.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ public static Matchers.StringMatcher parseStringMatcher(
123123
"Unknown StringMatcher match pattern: " + proto.getMatchPatternCase());
124124
}
125125
}
126+
126127
/** Translates envoy proto FractionalPercent to internal FractionMatcher. */
127128
public static Matchers.FractionMatcher parseFractionMatcher(
128129
io.envoyproxy.envoy.type.v3.FractionalPercent proto) {

xds/src/test/java/io/grpc/xds/CompositeFilterTest.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,4 +1029,80 @@ public ConfigOrError answer(
10291029

10301030
assertThat(result.errorDetail).contains("Maximum recursion depth of 8 exceeded");
10311031
}
1032+
1033+
@Test
1034+
public void clientInterceptorSkipsOnSkipFilter() {
1035+
// Setup Config with a matcher that MATCHES, but action is SkipFilter
1036+
1037+
Any skipActionAny = Any.newBuilder()
1038+
.setTypeUrl("type.googleapis.com/envoy.extensions.filters.common.matcher.action"
1039+
+ ".v3.SkipFilter")
1040+
.setValue(com.google.protobuf.ByteString.EMPTY)
1041+
.build();
1042+
1043+
Matcher.OnMatch matchAction = Matcher.OnMatch.newBuilder()
1044+
.setAction(com.github.xds.core.v3.TypedExtensionConfig.newBuilder()
1045+
.setName("action")
1046+
.setTypedConfig(skipActionAny)
1047+
.build())
1048+
.build();
1049+
1050+
Matcher matcher = Matcher.newBuilder()
1051+
.setMatcherList(Matcher.MatcherList.newBuilder()
1052+
.addMatchers(Matcher.MatcherList.FieldMatcher.newBuilder()
1053+
.setPredicate(Matcher.MatcherList.Predicate.newBuilder()
1054+
.setSinglePredicate(Matcher.MatcherList.Predicate.SinglePredicate.newBuilder()
1055+
.setInput(com.github.xds.core.v3.TypedExtensionConfig.newBuilder()
1056+
.setName("request_headers")
1057+
.setTypedConfig(Any.pack(
1058+
HttpRequestHeaderMatchInput.newBuilder()
1059+
.setHeaderName("foo")
1060+
.build()))
1061+
.build())
1062+
.setValueMatch(StringMatcher.newBuilder().setExact("bar").build())
1063+
.build())
1064+
.build())
1065+
.setOnMatch(matchAction)
1066+
.build())
1067+
.build())
1068+
.build();
1069+
1070+
ExtensionWithMatcher proto = ExtensionWithMatcher.newBuilder()
1071+
.setExtensionConfig(TypedExtensionConfig.newBuilder().setName("composite").build())
1072+
.setXdsMatcher(matcher)
1073+
.build();
1074+
1075+
ConfigOrError<CompositeFilter.CompositeFilterConfig> result = provider
1076+
.parseFilterConfig(Any.pack(proto));
1077+
1078+
assertThat(result.errorDetail).isNull();
1079+
1080+
CompositeFilter filter = (CompositeFilter) provider.newInstance("composite");
1081+
ClientInterceptor interceptor = filter.buildClientInterceptor(result.config, null,
1082+
mock(ScheduledExecutorService.class));
1083+
1084+
Channel next = mock(Channel.class);
1085+
ClientCall nextCall = mock(ClientCall.class);
1086+
when(next.newCall(any(), any())).thenReturn(nextCall);
1087+
1088+
MethodDescriptor.Marshaller<Void> marshaller = mock(MethodDescriptor.Marshaller.class);
1089+
MethodDescriptor<Void, Void> method = MethodDescriptor.<Void, Void>newBuilder()
1090+
.setType(MethodDescriptor.MethodType.UNARY)
1091+
.setFullMethodName("service/method")
1092+
.setRequestMarshaller(marshaller)
1093+
.setResponseMarshaller(marshaller)
1094+
.build();
1095+
1096+
ClientCall<Void, Void> call = interceptor.interceptCall(method, CallOptions.DEFAULT, next);
1097+
1098+
Metadata headers = new Metadata();
1099+
headers.put(Metadata.Key.of("foo", Metadata.ASCII_STRING_MARSHALLER), "bar"); // This matches
1100+
1101+
call.start(mock(ClientCall.Listener.class), headers);
1102+
1103+
// Verify it SKIPS (calls next directly, never calls fakeClientInterceptor)
1104+
verify(fakeClientInterceptor, org.mockito.Mockito.never()).interceptCall(any(), any(), any());
1105+
verify(next).newCall(any(), any());
1106+
verify(nextCall).start(any(), eq(headers));
1107+
}
10321108
}

0 commit comments

Comments
 (0)