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

grpc / grpc-java / #20338

26 Jun 2026 11:37AM UTC coverage: 89.043% (+0.2%) from 88.876%
#20338

push

github

web-flow
Ext_proc filter and client interceptor (#12792)

Implements ext_proc filter from [grfc A93](https://github.com/grpc/proposal/pull/484)  (internal [design doc](http://go/ext-proc-design-java)).

37578 of 42202 relevant lines covered (89.04%)

0.89 hits per line

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

92.59
/../xds/src/main/java/io/grpc/xds/Filter.java
1
/*
2
 * Copyright 2021 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.xds;
18

19

20
import com.google.auto.value.AutoValue;
21
import com.google.common.base.MoreObjects;
22
import com.google.protobuf.Message;
23
import io.grpc.ClientInterceptor;
24
import io.grpc.MetricRecorder;
25
import io.grpc.ServerInterceptor;
26
import io.grpc.xds.client.Bootstrapper.BootstrapInfo;
27
import io.grpc.xds.client.Bootstrapper.ServerInfo;
28
import java.io.Closeable;
29
import java.util.Objects;
30
import java.util.concurrent.ScheduledExecutorService;
31
import javax.annotation.Nullable;
32

33
/**
34
 * Defines the parsing functionality of an HTTP filter.
35
 *
36
 * <p>A Filter may optionally implement either {@link Filter#buildClientInterceptor} or
37
 * {@link Filter#buildServerInterceptor} or both, and return true from corresponding
38
 * {@link Provider#isClientFilter()}, {@link Provider#isServerFilter()} to indicate that the filter
39
 * is capable of working on the client side or server side or both, respectively.
40
 */
41
interface Filter extends Closeable {
42

43
  /** Represents an opaque data structure holding configuration for a filter. */
44
  interface FilterConfig {
45
    String typeUrl();
46
  }
47

48
  /**
49
   * Common interface for filter providers.
50
   */
51
  interface Provider {
52
    /**
53
     * The proto message types supported by this filter. A filter will be registered by each of its
54
     * supported message types.
55
     */
56
    String[] typeUrls();
57

58
    /**
59
     * Whether the filter can be installed on the client side.
60
     *
61
     * <p>Returns true if the filter implements {@link Filter#buildClientInterceptor}.
62
     */
63
    default boolean isClientFilter() {
64
      return false;
1✔
65
    }
66

67
    /**
68
     * Whether the filter can be installed into xDS-enabled servers.
69
     *
70
     * <p>Returns true if the filter implements {@link Filter#buildServerInterceptor}.
71
     */
72
    default boolean isServerFilter() {
73
      return false;
1✔
74
    }
75

76
    /**
77
     * Creates a new instance of the filter.
78
     *
79
     * <p>Returns a filter instance registered with the same typeUrls as the provider,
80
     * capable of working with the same FilterConfig type returned by provider's parse functions.
81
     *
82
     * <p>For xDS gRPC clients, new filter instances are created per combination of:
83
     * <ol>
84
     *   <li><code>XdsNameResolver</code> instance,</li>
85
     *   <li>Filter name+typeUrl in HttpConnectionManager (HCM) http_filters.</li>
86
     * </ol>
87
     *
88
     * <p>For xDS-enabled gRPC servers, new filter instances are created per combination of:
89
     * <ol>
90
     *   <li>Server instance,</li>
91
     *   <li>FilterChain name,</li>
92
     *   <li>Filter name+typeUrl in FilterChain's HCM.http_filters.</li>
93
     * </ol>
94
     */
95
    Filter newInstance(FilterContext context);
96

97
    /**
98
     * Parses the top-level filter config from raw proto message. The message may be either a {@link
99
     * com.google.protobuf.Any} or a {@link com.google.protobuf.Struct}.
100
     */
101
    ConfigOrError<? extends FilterConfig> parseFilterConfig(
102
        Message rawProtoMessage, FilterConfigParseContext context);
103

104
    /**
105
     * Parses the per-filter override filter config from raw proto message. The message may be
106
     * either a {@link com.google.protobuf.Any} or a {@link com.google.protobuf.Struct}.
107
     */
108
    ConfigOrError<? extends FilterConfig> parseFilterConfigOverride(
109
        Message rawProtoMessage, FilterConfigParseContext context);
110
  }
111

112
  /** Uses the FilterConfigs produced above to produce an HTTP filter interceptor for clients. */
113
  @Nullable
114
  default ClientInterceptor buildClientInterceptor(
115
      FilterConfig config, @Nullable FilterConfig overrideConfig,
116
      ScheduledExecutorService scheduler) {
117
    return null;
1✔
118
  }
119

120
  /** Uses the FilterConfigs produced above to produce an HTTP filter interceptor for the server. */
121
  @Nullable
122
  default ServerInterceptor buildServerInterceptor(
123
      FilterConfig config, @Nullable FilterConfig overrideConfig) {
124
    return null;
1✔
125
  }
126

127
  /**
128
   * Releases filter resources like shared resources and remote connections.
129
   *
130
   * <p>See {@link Provider#newInstance()} for details on filter instance creation.
131
   */
132
  @Override
133
  default void close() {}
1✔
134

135
  /** Context carrying dynamic metadata for a filter. */
136
  @AutoValue
137
  abstract static class FilterConfigParseContext {
1✔
138
    abstract BootstrapInfo bootstrapInfo();
139

140
    abstract ServerInfo serverInfo();
141

142
    static Builder builder() {
143
      return new AutoValue_Filter_FilterConfigParseContext.Builder();
1✔
144
    }
145

146
    @AutoValue.Builder
147
    abstract static class Builder {
1✔
148
      abstract Builder bootstrapInfo(BootstrapInfo info);
149

150
      abstract Builder serverInfo(ServerInfo info);
151

152
      abstract FilterConfigParseContext build();
153
    }
154
  }
155

156
  /** Context containing naming and metrics reporting objects for a filter instance. */
157
  @AutoValue
158
  abstract static class FilterContext {
1✔
159
    abstract String filterName();
160

161
    abstract MetricRecorder metricsRecorder();
162

163
    static FilterContext create(String filterName, MetricRecorder metricsRecorder) {
164
      return new AutoValue_Filter_FilterContext(filterName, metricsRecorder);
1✔
165
    }
166
  }
167

168
  /** Filter config with instance name. */
169
  final class NamedFilterConfig {
170
    // filter instance name
171
    final String name;
172
    final FilterConfig filterConfig;
173

174
    NamedFilterConfig(String name, FilterConfig filterConfig) {
1✔
175
      this.name = name;
1✔
176
      this.filterConfig = filterConfig;
1✔
177
    }
1✔
178

179
    String filterStateKey() {
180
      return name + "_" + filterConfig.typeUrl();
1✔
181
    }
182

183
    @Override
184
    public boolean equals(Object o) {
185
      if (this == o) {
1✔
186
        return true;
×
187
      }
188
      if (o == null || getClass() != o.getClass()) {
1✔
189
        return false;
×
190
      }
191
      NamedFilterConfig that = (NamedFilterConfig) o;
1✔
192
      return Objects.equals(name, that.name)
1✔
193
          && Objects.equals(filterConfig, that.filterConfig);
1✔
194
    }
195

196
    @Override
197
    public int hashCode() {
198
      return Objects.hash(name, filterConfig);
1✔
199
    }
200

201
    @Override
202
    public String toString() {
203
      return MoreObjects.toStringHelper(this)
1✔
204
          .add("name", name)
1✔
205
          .add("filterConfig", filterConfig)
1✔
206
          .toString();
1✔
207
    }
208
  }
209
}
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