Skip to content

xds: RLQS Prototype v2 #12014

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
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
5 changes: 4 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -29,11 +29,14 @@ commons-math3 = "org.apache.commons:commons-math3:3.6.1"
conscrypt = "org.conscrypt:conscrypt-openjdk-uber:2.5.2"
cronet-api = "org.chromium.net:cronet-api:119.6045.31"
cronet-embedded = "org.chromium.net:cronet-embedded:119.6045.31"
dev-cel-compiler = "dev.cel:compiler:0.9.1-proto3"
dev-cel-protobuf = "dev.cel:protobuf:0.9.1-proto3"
dev-cel-runtime = "dev.cel:runtime:0.9.1-proto3"
# error-prone 2.31.0+ blocked on https://github.com/grpc/grpc-java/issues/10152
# It breaks Bazel (ArrayIndexOutOfBoundsException in turbine) and Dexing ("D8:
# java.lang.NullPointerException"). We can trivially upgrade the Bazel CI to
# 6.3.0+ (https://github.com/bazelbuild/bazel/issues/18743).
errorprone-annotations = "com.google.errorprone:error_prone_annotations:2.30.0"
errorprone-annotations = "com.google.errorprone:error_prone_annotations:2.36.0"
# error-prone 2.32.0+ require Java 17+
errorprone-core = "com.google.errorprone:error_prone_core:2.31.0"
google-api-protos = "com.google.api.grpc:proto-google-common-protos:2.51.0"
5 changes: 4 additions & 1 deletion xds/build.gradle
Original file line number Diff line number Diff line change
@@ -53,6 +53,8 @@ dependencies {
project(':grpc-services'),
project(':grpc-auth'),
project(path: ':grpc-alts', configuration: 'shadow'),
libraries.dev.cel.runtime,
libraries.dev.cel.protobuf,
libraries.guava,
libraries.gson,
libraries.re2j,
@@ -72,7 +74,8 @@ dependencies {
compileOnly libraries.netty.transport.epoll

testImplementation project(':grpc-testing'),
project(':grpc-testing-proto')
project(':grpc-testing-proto'),
libraries.dev.cel.compiler
testImplementation (libraries.netty.transport.epoll) {
artifact {
classifier = "linux-x86_64"
3 changes: 2 additions & 1 deletion xds/src/main/java/io/grpc/xds/FilterRegistry.java
Original file line number Diff line number Diff line change
@@ -37,7 +37,8 @@ static synchronized FilterRegistry getDefaultRegistry() {
instance = newRegistry().register(
new FaultFilter.Provider(),
new RouterFilter.Provider(),
new RbacFilter.Provider());
new RbacFilter.Provider(),
new RlqsFilter.Provider());
}
return instance;
}
9 changes: 9 additions & 0 deletions xds/src/main/java/io/grpc/xds/MessagePrinter.java
Original file line number Diff line number Diff line change
@@ -16,6 +16,8 @@

package io.grpc.xds;

import com.github.xds.type.matcher.v3.CelMatcher;
import com.github.xds.type.matcher.v3.HttpAttributesCelMatchInput;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
@@ -28,6 +30,8 @@
import io.envoyproxy.envoy.config.route.v3.RouteConfiguration;
import io.envoyproxy.envoy.extensions.clusters.aggregate.v3.ClusterConfig;
import io.envoyproxy.envoy.extensions.filters.http.fault.v3.HTTPFault;
import io.envoyproxy.envoy.extensions.filters.http.rate_limit_quota.v3.RateLimitQuotaFilterConfig;
import io.envoyproxy.envoy.extensions.filters.http.rate_limit_quota.v3.RateLimitQuotaOverride;
import io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBAC;
import io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBACPerRoute;
import io.envoyproxy.envoy.extensions.filters.http.router.v3.Router;
@@ -58,6 +62,11 @@ private static JsonFormat.Printer newPrinter() {
.add(RBAC.getDescriptor())
.add(RBACPerRoute.getDescriptor())
.add(Router.getDescriptor())
// RLQS
.add(RateLimitQuotaFilterConfig.getDescriptor())
.add(RateLimitQuotaOverride.getDescriptor())
.add(HttpAttributesCelMatchInput.getDescriptor())
.add(CelMatcher.getDescriptor())
// UpstreamTlsContext and DownstreamTlsContext in v3 are not transitively imported
// by top-level resource types.
.add(UpstreamTlsContext.getDescriptor())
284 changes: 284 additions & 0 deletions xds/src/main/java/io/grpc/xds/RlqsFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.grpc.xds;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.grpc.xds.client.XdsResourceType.ResourceInvalidException;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.protobuf.Any;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import io.envoyproxy.envoy.extensions.filters.http.rate_limit_quota.v3.RateLimitQuotaBucketSettings;
import io.envoyproxy.envoy.extensions.filters.http.rate_limit_quota.v3.RateLimitQuotaFilterConfig;
import io.envoyproxy.envoy.extensions.filters.http.rate_limit_quota.v3.RateLimitQuotaOverride;
import io.grpc.InternalLogId;
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.ServerCall.Listener;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.internal.GrpcUtil;
import io.grpc.internal.SharedResourceHolder;
import io.grpc.xds.client.XdsLogger;
import io.grpc.xds.client.XdsLogger.XdsLogLevel;
import io.grpc.xds.internal.datatype.GrpcService;
import io.grpc.xds.internal.matchers.HttpMatchInput;
import io.grpc.xds.internal.matchers.Matcher;
import io.grpc.xds.internal.matchers.MatcherList;
import io.grpc.xds.internal.matchers.OnMatch;
import io.grpc.xds.internal.rlqs.RlqsBucketSettings;
import io.grpc.xds.internal.rlqs.RlqsCache;
import io.grpc.xds.internal.rlqs.RlqsFilterState;
import io.grpc.xds.internal.rlqs.RlqsRateLimitResult;
import java.util.ConcurrentModificationException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;
import javax.annotation.Nullable;

/** RBAC Http filter implementation. */
// TODO(sergiitk): introduce a layer between the filter and interceptor.
// lds has filter names and the names are unique - even for server instances.
final class RlqsFilter implements Filter {
private final XdsLogger logger;

static final boolean enabled = GrpcUtil.getFlag("GRPC_EXPERIMENTAL_XDS_ENABLE_RLQS", false);

Check warning on line 62 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L62

Added line #L62 was not covered by tests

// TODO(sergiitk): [IMPL] remove
// Do do not fail on parsing errors, only log requests.
static final boolean dryRun = GrpcUtil.getFlag("GRPC_EXPERIMENTAL_RLQS_DRY_RUN", false);

Check warning on line 66 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L66

Added line #L66 was not covered by tests

static final String TYPE_URL = "type.googleapis.com/"
+ "envoy.extensions.filters.http.rate_limit_quota.v3.RateLimitQuotaFilterConfig";
static final String TYPE_URL_OVERRIDE_CONFIG = "type.googleapis.com/"
+ "envoy.extensions.filters.http.rate_limit_quota.v3.RateLimitQuotaOverride";

private final AtomicBoolean shutdown = new AtomicBoolean();
private final AtomicReference<RlqsCache> rlqsCache = new AtomicReference<>();

Check warning on line 74 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L73-L74

Added lines #L73 - L74 were not covered by tests

// TODO(sergiitk): [IMPL] figure out what to use here.
private final ScheduledExecutorService scheduler =
SharedResourceHolder.get(GrpcUtil.TIMER_SERVICE);

Check warning on line 78 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L77-L78

Added lines #L77 - L78 were not covered by tests

public RlqsFilter(String name) {
logger = XdsLogger.withLogId(InternalLogId.allocate(this.getClass(), null));
logger.log(XdsLogLevel.DEBUG,
"Created RLQS Filter name='%s' with enabled=%s, dryRun=%s", name, enabled, dryRun);
}

Check warning on line 84 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L80-L84

Added lines #L80 - L84 were not covered by tests

static final class Provider implements Filter.Provider {
private static final Logger logger = Logger.getLogger(Provider.class.getName());

@Override
public String[] typeUrls() {
return new String[]{TYPE_URL, TYPE_URL_OVERRIDE_CONFIG};
}

@Override
public boolean isServerFilter() {
return true;

Check warning on line 96 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L96

Added line #L96 was not covered by tests
}

@Override
public RlqsFilter newInstance(String name) {
return new RlqsFilter(name);

Check warning on line 101 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L101

Added line #L101 was not covered by tests
}

@Override
public ConfigOrError<RlqsFilterConfig> parseFilterConfig(Message rawProtoMessage) {
try {
RlqsFilterConfig rlqsFilterConfig =
parseRlqsFilter(unpackAny(rawProtoMessage, RateLimitQuotaFilterConfig.class));
return ConfigOrError.fromConfig(rlqsFilterConfig);
} catch (InvalidProtocolBufferException e) {
return ConfigOrError.fromError("Can't unpack RateLimitQuotaFilterConfig proto: " + e);
} catch (ResourceInvalidException e) {
return ConfigOrError.fromError(e.getMessage());

Check warning on line 113 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L107-L113

Added lines #L107 - L113 were not covered by tests
}
}

@Override
public ConfigOrError<RlqsFilterConfig> parseFilterConfigOverride(Message rawProtoMessage) {
try {
RlqsFilterConfig rlqsFilterConfig =
parseRlqsFilterOverride(unpackAny(rawProtoMessage, RateLimitQuotaOverride.class));
return ConfigOrError.fromConfig(rlqsFilterConfig);
} catch (InvalidProtocolBufferException e) {
return ConfigOrError.fromError("Can't unpack RateLimitQuotaOverride proto: " + e);
} catch (ResourceInvalidException e) {
return ConfigOrError.fromError(e.getMessage());

Check warning on line 126 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L120-L126

Added lines #L120 - L126 were not covered by tests
}
}

@VisibleForTesting
RlqsFilterConfig parseRlqsFilter(RateLimitQuotaFilterConfig rlqsFilterProto)
throws ResourceInvalidException, InvalidProtocolBufferException {
RlqsFilterConfig.Builder builder = RlqsFilterConfig.builder();

Check warning on line 133 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L133

Added line #L133 was not covered by tests
if (rlqsFilterProto.getDomain().isEmpty()) {
throw new ResourceInvalidException("RateLimitQuotaFilterConfig domain is required");

Check warning on line 135 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L135

Added line #L135 was not covered by tests
}
builder.domain(rlqsFilterProto.getDomain())
.rlqsService(GrpcService.fromEnvoyProto(rlqsFilterProto.getRlqsServer()));

Check warning on line 138 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L137-L138

Added lines #L137 - L138 were not covered by tests

// TODO(sergiitk): [IMPL] Remove
if (dryRun) {
logger.finest("RLQS DRY RUN: not parsing matchers");
return builder.build();

Check warning on line 143 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L142-L143

Added lines #L142 - L143 were not covered by tests
}

// TODO(sergiitk): [IMPL] actually parse, move to RlqsBucketSettings.fromProto()
RateLimitQuotaBucketSettings fallbackBucketSettingsProto = unpackAny(
rlqsFilterProto.getBucketMatchers().getOnNoMatch().getAction().getTypedConfig(),

Check warning on line 148 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L147-L148

Added lines #L147 - L148 were not covered by tests
RateLimitQuotaBucketSettings.class);
RlqsBucketSettings fallbackBucket = RlqsBucketSettings.create(
ImmutableMap.of("bucket_id", headers -> "hello"),
fallbackBucketSettingsProto.getReportingInterval());

Check warning on line 152 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L150-L152

Added lines #L150 - L152 were not covered by tests

// TODO(sergiitk): [IMPL] actually parse, move to Matcher.fromProto()
Matcher<HttpMatchInput, RlqsBucketSettings> bucketMatchers = new RlqsMatcher(fallbackBucket);

Check warning on line 155 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L155

Added line #L155 was not covered by tests

return builder.bucketMatchers(bucketMatchers).build();

Check warning on line 157 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L157

Added line #L157 was not covered by tests
}
}

@Override
public void close() {
// TODO(sergiitk): [DESIGN] besides shutting down everything, should there
// be per-route interceptor destructors?
if (!shutdown.compareAndSet(false, true)) {
throw new ConcurrentModificationException(

Check warning on line 166 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L166

Added line #L166 was not covered by tests
"Unexpected: RlqsFilter#close called multiple times");
}
RlqsCache oldCache = rlqsCache.getAndUpdate(unused -> null);

Check warning on line 169 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L169

Added line #L169 was not covered by tests
if (oldCache != null) {
oldCache.shutdown();

Check warning on line 171 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L171

Added line #L171 was not covered by tests
}
}

Check warning on line 173 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L173

Added line #L173 was not covered by tests

// @Override
public boolean isEnabled() {
return enabled;

Check warning on line 177 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L177

Added line #L177 was not covered by tests
}

@Nullable
@Override
public ServerInterceptor buildServerInterceptor(
FilterConfig config, @Nullable FilterConfig overrideConfig) {
// ScheduledExecutorService scheduler

// Called when we get an xds update - when the LRS or RLS changes.
RlqsFilterConfig rlqsFilterConfig = (RlqsFilterConfig) checkNotNull(config, "config");

Check warning on line 187 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L187

Added line #L187 was not covered by tests

// Per-route and per-host configuration overrides.
if (overrideConfig != null) {
RlqsFilterConfig rlqsFilterOverride = (RlqsFilterConfig) overrideConfig;

Check warning on line 191 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L191

Added line #L191 was not covered by tests
// All fields are inherited from the main config, unless overridden.
RlqsFilterConfig.Builder overrideBuilder = rlqsFilterConfig.toBuilder();

Check warning on line 193 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L193

Added line #L193 was not covered by tests
if (!rlqsFilterOverride.domain().isEmpty()) {
overrideBuilder.domain(rlqsFilterOverride.domain());

Check warning on line 195 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L195

Added line #L195 was not covered by tests
}
if (rlqsFilterOverride.bucketMatchers() != null) {
overrideBuilder.bucketMatchers(rlqsFilterOverride.bucketMatchers());

Check warning on line 198 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L198

Added line #L198 was not covered by tests
}
// Override bucket matchers if not null.
rlqsFilterConfig = overrideBuilder.build();

Check warning on line 201 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L201

Added line #L201 was not covered by tests
}

rlqsCache.compareAndSet(null, RlqsCache.newInstance(scheduler));
return generateRlqsInterceptor(rlqsFilterConfig);

Check warning on line 205 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L204-L205

Added lines #L204 - L205 were not covered by tests
}

@Nullable
private ServerInterceptor generateRlqsInterceptor(RlqsFilterConfig config) {
checkNotNull(config, "config");
checkNotNull(config.rlqsService(), "config.rlqsService");
RlqsCache rlqsCache = this.rlqsCache.get();

Check warning on line 212 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L210-L212

Added lines #L210 - L212 were not covered by tests
if (rlqsCache == null) {
// Being shut down, return no interceptor.
return null;

Check warning on line 215 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L215

Added line #L215 was not covered by tests
}

final RlqsFilterState rlqsFilterState = rlqsCache.getOrCreateFilterState(config);

Check warning on line 218 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L218

Added line #L218 was not covered by tests

return new ServerInterceptor() {

Check warning on line 220 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L220

Added line #L220 was not covered by tests
@Override
public <ReqT, RespT> Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
HttpMatchInput httpMatchInput = HttpMatchInput.create(headers, call);

Check warning on line 224 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L224

Added line #L224 was not covered by tests

// TODO(sergiitk): [IMPL] Remove
if (dryRun) {
// logger.log(XdsLogLevel.INFO, "RLQS DRY RUN: request <<" + httpMatchInput + ">>");
return next.startCall(call, headers);

Check warning on line 229 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L229

Added line #L229 was not covered by tests
}

RlqsRateLimitResult result = rlqsFilterState.rateLimit(httpMatchInput);

Check warning on line 232 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L232

Added line #L232 was not covered by tests
if (result.isAllowed()) {
return next.startCall(call, headers);

Check warning on line 234 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L234

Added line #L234 was not covered by tests
}
RlqsRateLimitResult.DenyResponse denyResponse = result.denyResponse().get();
call.close(denyResponse.status(), denyResponse.headersToAdd());
return new ServerCall.Listener<ReqT>(){};

Check warning on line 238 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L236-L238

Added lines #L236 - L238 were not covered by tests
}
};
}

static class RlqsMatcher extends Matcher<HttpMatchInput, RlqsBucketSettings> {
private final RlqsBucketSettings fallbackBucket;

RlqsMatcher(RlqsBucketSettings fallbackBucket) {
this.fallbackBucket = fallbackBucket;
}

Check warning on line 248 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L246-L248

Added lines #L246 - L248 were not covered by tests

@Nullable
@Override
public MatcherList<HttpMatchInput, RlqsBucketSettings> matcherList() {
return null;

Check warning on line 253 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L253

Added line #L253 was not covered by tests
}

@Override
public OnMatch<HttpMatchInput, RlqsBucketSettings> onNoMatch() {
return OnMatch.ofAction(fallbackBucket);

Check warning on line 258 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L258

Added line #L258 was not covered by tests
}

@Override
public RlqsBucketSettings match(HttpMatchInput input) {
return null;

Check warning on line 263 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L263

Added line #L263 was not covered by tests
}
}

@VisibleForTesting
static RlqsFilterConfig parseRlqsFilterOverride(RateLimitQuotaOverride rlqsFilterProtoOverride)
throws ResourceInvalidException {
RlqsFilterConfig.Builder builder = RlqsFilterConfig.builder();

Check warning on line 270 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L270

Added line #L270 was not covered by tests
// TODO(sergiitk): [IMPL] bucket_matchers.

return builder.domain(rlqsFilterProtoOverride.getDomain()).build();

Check warning on line 273 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L273

Added line #L273 was not covered by tests
}

private static <T extends com.google.protobuf.Message> T unpackAny(
Message message, Class<T> clazz) throws InvalidProtocolBufferException {
if (!(message instanceof Any)) {
throw new InvalidProtocolBufferException(
"Invalid config type: " + message.getClass().getCanonicalName());

Check warning on line 280 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L279-L280

Added lines #L279 - L280 were not covered by tests
}
return ((Any) message).unpack(clazz);

Check warning on line 282 in xds/src/main/java/io/grpc/xds/RlqsFilter.java

Codecov / codecov/patch

xds/src/main/java/io/grpc/xds/RlqsFilter.java#L282

Added line #L282 was not covered by tests
}
}
Loading