• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

grpc / grpc-java / #19702

18 Feb 2025 06:47PM UTC coverage: 88.587% (-0.005%) from 88.592%
#19702

push

github

web-flow
xds: Change how xDS filters are created by introducing Filter.Provider (#11883)

This is the first step towards supporting filter state retention in
Java. The mechanism will be similar to the one described in [A83]
(https://github.com/grpc/proposal/blob/master/A83-xds-gcp-authn-filter.md#filter-call-credentials-cache)
for C-core, and will serve the same purpose. However, the
implementation details are very different due to the different nature
of xDS HTTP filter support in C-core and Java.

In Java, xDS HTTP filters are backed by classes implementing
`io.grpc.xds.Filter`, from here just called "Filters". To support
Filter state retention (next PR), Java's xDS implementation must be
able to create unique Filter instances per:
- Per HCM
  `envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager`
- Per filter name as specified in
  `envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter.name`

This PR **does not** implements Filter state retention, but lays the
groundwork for it by changing how filters are registered and
instantiated. To achieve this, all existing Filter classes had to be
updated to the new instantiation mechanism described below.

Prior to these this PR, Filters had no livecycle. FilterRegistry
provided singleton instances for a given typeUrl. This PR introduces
a new interface `Filter.Provider`, which instantiates Filter classes.
All functionality that doesn't need an instance of a Filter is moved
to the Filter.Provider. This includes parsing filter config proto
into FilterConfig and determining the filter kind
(client-side, server-side, or both).

This PR is limited to refactoring, and there's no changes to the
existing behavior. Note that all Filter Providers still return
singleton Filter instances. However, with this PR, it is now possible
to create Providers that return a new Filter instance each time
`newInstance` is called.

34252 of 38665 relevant lines covered (88.59%)

0.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

47.62
/../core/src/main/java/io/grpc/internal/PickSubchannelArgsImpl.java
1
/*
2
 * Copyright 2016 The gRPC Authors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package io.grpc.internal;
18

19
import static com.google.common.base.Preconditions.checkNotNull;
20

21
import com.google.common.base.Objects;
22
import io.grpc.CallOptions;
23
import io.grpc.LoadBalancer.PickDetailsConsumer;
24
import io.grpc.LoadBalancer.PickSubchannelArgs;
25
import io.grpc.Metadata;
26
import io.grpc.MethodDescriptor;
27

28
/** Implementation of {@link PickSubchannelArgs}. */
29
public final class PickSubchannelArgsImpl extends PickSubchannelArgs {
30
  private final CallOptions callOptions;
31
  private final Metadata headers;
32
  private final MethodDescriptor<?, ?> method;
33
  private final PickDetailsConsumer pickDetailsConsumer;
34

35
  /**
36
   * Creates call args object for given method with its call options, metadata.
37
   */
38
  public PickSubchannelArgsImpl(
39
      MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
40
      PickDetailsConsumer pickDetailsConsumer) {
1✔
41
    this.method = checkNotNull(method, "method");
1✔
42
    this.headers = checkNotNull(headers, "headers");
1✔
43
    this.callOptions = checkNotNull(callOptions, "callOptions");
1✔
44
    this.pickDetailsConsumer = checkNotNull(pickDetailsConsumer, "pickDetailsConsumer");
1✔
45
  }
1✔
46

47
  @Override
48
  public Metadata getHeaders() {
49
    return headers;
1✔
50
  }
51

52
  @Override
53
  public CallOptions getCallOptions() {
54
    return callOptions;
1✔
55
  }
56

57
  @Override
58
  public MethodDescriptor<?, ?> getMethodDescriptor() {
59
    return method;
1✔
60
  }
61

62
  @Override
63
  public PickDetailsConsumer getPickDetailsConsumer() {
64
    return pickDetailsConsumer;
1✔
65
  }
66

67
  @Override
68
  public boolean equals(Object o) {
69
    if (this == o) {
×
70
      return true;
×
71
    }
72
    if (o == null || getClass() != o.getClass()) {
×
73
      return false;
×
74
    }
75
    PickSubchannelArgsImpl that = (PickSubchannelArgsImpl) o;
×
76
    return Objects.equal(callOptions, that.callOptions)
×
77
        && Objects.equal(headers, that.headers)
×
78
        && Objects.equal(method, that.method)
×
79
        && Objects.equal(pickDetailsConsumer, that.pickDetailsConsumer);
×
80
  }
81

82
  @Override
83
  public int hashCode() {
84
    return Objects.hashCode(callOptions, headers, method, pickDetailsConsumer);
×
85
  }
86

87
  @Override
88
  public final String toString() {
89
    return "[method=" + method + " headers=" + headers + " callOptions=" + callOptions + "]";
×
90
  }
91
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc