mirror of https://github.com/grpc/grpc-java.git
xds: remove path matcher format requirements and default route requirement for routing enabled (v1.30.x backport) (#7063) (#7070)
Remove requirement for formats of path matchers. Only require the last route to be the default route for the case when routing is disabled.
This commit is contained in:
parent
bd1c256ef5
commit
d71161432a
|
|
@ -444,6 +444,7 @@ final class EnvoyProtoData {
|
|||
return routeAction;
|
||||
}
|
||||
|
||||
// TODO(chengyuanzhang): delete and do not use after routing feature is always ON.
|
||||
boolean isDefaultRoute() {
|
||||
return routeMatch.isMatchAll();
|
||||
}
|
||||
|
|
@ -553,16 +554,10 @@ final class EnvoyProtoData {
|
|||
return pathExactMatch;
|
||||
}
|
||||
|
||||
boolean isMatchAll() {
|
||||
if (pathSafeRegExMatch != null || fractionMatch != null) {
|
||||
return false;
|
||||
}
|
||||
if (!headerMatchers.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (pathExactMatch != null) {
|
||||
return false;
|
||||
}
|
||||
// TODO(chengyuanzhang): delete and do not use after routing feature is always ON.
|
||||
private boolean isMatchAll() {
|
||||
// For backward compatibility, all the other matchers are ignored. When routing is enabled,
|
||||
// we should never care if a matcher matches all requests.
|
||||
if (pathPrefixMatch != null) {
|
||||
return pathPrefixMatch.isEmpty() || pathPrefixMatch.equals("/");
|
||||
}
|
||||
|
|
@ -655,27 +650,9 @@ final class EnvoyProtoData {
|
|||
switch (proto.getPathSpecifierCase()) {
|
||||
case PREFIX:
|
||||
prefixPathMatch = proto.getPrefix();
|
||||
// Supported prefix match format:
|
||||
// "", "/" (default)
|
||||
// "/service/"
|
||||
if (!prefixPathMatch.isEmpty() && !prefixPathMatch.equals("/")) {
|
||||
if (!prefixPathMatch.startsWith("/") || !prefixPathMatch.endsWith("/")
|
||||
|| prefixPathMatch.length() < 3) {
|
||||
return StructOrError.fromError(
|
||||
"Invalid format of prefix path match: " + prefixPathMatch);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PATH:
|
||||
exactPathMatch = proto.getPath();
|
||||
int lastSlash = exactPathMatch.lastIndexOf('/');
|
||||
// Supported exact match format:
|
||||
// "/service/method"
|
||||
if (!exactPathMatch.startsWith("/") || lastSlash == 0
|
||||
|| lastSlash == exactPathMatch.length() - 1) {
|
||||
return StructOrError.fromError(
|
||||
"Invalid format of exact path match: " + exactPathMatch);
|
||||
}
|
||||
break;
|
||||
case REGEX:
|
||||
return StructOrError.fromError("Unsupported path match type: regex");
|
||||
|
|
|
|||
|
|
@ -858,14 +858,14 @@ final class XdsClientImpl extends XdsClient {
|
|||
throw new InvalidProtoDataException(
|
||||
"Virtual host [" + virtualHost.getName() + "] contains no usable route");
|
||||
}
|
||||
// The last route must be a default route.
|
||||
if (!Iterables.getLast(routes).isDefaultRoute()) {
|
||||
throw new InvalidProtoDataException(
|
||||
"Virtual host [" + virtualHost.getName()
|
||||
+ "] contains non-default route as the last route");
|
||||
}
|
||||
|
||||
if (!enableExperimentalRouting) {
|
||||
EnvoyProtoData.Route defaultRoute = Iterables.getLast(routes);
|
||||
if (!defaultRoute.isDefaultRoute()) {
|
||||
throw new InvalidProtoDataException(
|
||||
"Virtual host [" + virtualHost.getName()
|
||||
+ "] contains non-default route as the last route");
|
||||
}
|
||||
return Collections.singletonList(defaultRoute);
|
||||
}
|
||||
return Collections.unmodifiableList(routes);
|
||||
|
|
|
|||
|
|
@ -246,51 +246,6 @@ public class EnvoyProtoDataTest {
|
|||
assertThat(unsetStruct.getStruct()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertRouteMatch_pathMatchFormat() {
|
||||
StructOrError<RouteMatch> struct1 =
|
||||
RouteMatch.fromEnvoyProtoRouteMatch(buildSimpleRouteMatchProto("", null));
|
||||
StructOrError<RouteMatch> struct2 =
|
||||
RouteMatch.fromEnvoyProtoRouteMatch(buildSimpleRouteMatchProto("/", null));
|
||||
StructOrError<RouteMatch> struct3 =
|
||||
RouteMatch.fromEnvoyProtoRouteMatch(buildSimpleRouteMatchProto("/service", null));
|
||||
StructOrError<RouteMatch> struct4 =
|
||||
RouteMatch.fromEnvoyProtoRouteMatch(buildSimpleRouteMatchProto("/service/", null));
|
||||
StructOrError<RouteMatch> struct5 =
|
||||
RouteMatch.fromEnvoyProtoRouteMatch(buildSimpleRouteMatchProto(null, ""));
|
||||
StructOrError<RouteMatch> struct6 =
|
||||
RouteMatch.fromEnvoyProtoRouteMatch(buildSimpleRouteMatchProto(null, "/service/method"));
|
||||
StructOrError<RouteMatch> struct7 =
|
||||
RouteMatch.fromEnvoyProtoRouteMatch(buildSimpleRouteMatchProto(null, "/service/method/"));
|
||||
StructOrError<RouteMatch> struct8 =
|
||||
RouteMatch.fromEnvoyProtoRouteMatch(
|
||||
io.envoyproxy.envoy.api.v2.route.RouteMatch.newBuilder()
|
||||
.setSafeRegex(
|
||||
io.envoyproxy.envoy.type.matcher.RegexMatcher.newBuilder().setRegex("["))
|
||||
.build());
|
||||
|
||||
assertThat(struct1.getStruct()).isNotNull();
|
||||
assertThat(struct2.getStruct()).isNotNull();
|
||||
assertThat(struct3.getStruct()).isNull();
|
||||
assertThat(struct4.getStruct()).isNotNull();
|
||||
assertThat(struct5.getStruct()).isNull();
|
||||
assertThat(struct6.getStruct()).isNotNull();
|
||||
assertThat(struct7.getStruct()).isNull();
|
||||
assertThat(struct8.getStruct()).isNull();
|
||||
}
|
||||
|
||||
private static io.envoyproxy.envoy.api.v2.route.RouteMatch buildSimpleRouteMatchProto(
|
||||
@Nullable String pathPrefix, @Nullable String path) {
|
||||
io.envoyproxy.envoy.api.v2.route.RouteMatch.Builder builder =
|
||||
io.envoyproxy.envoy.api.v2.route.RouteMatch.newBuilder();
|
||||
if (pathPrefix != null) {
|
||||
builder.setPrefix(pathPrefix);
|
||||
} else if (path != null) {
|
||||
builder.setPath(path);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertRouteMatch_withHeaderMatching() {
|
||||
io.envoyproxy.envoy.api.v2.route.RouteMatch proto =
|
||||
|
|
|
|||
Loading…
Reference in New Issue