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

grpc / grpc-java / #19671

30 Jan 2025 08:43PM UTC coverage: 88.581% (-0.01%) from 88.595%
#19671

push

github

web-flow
xds: Reuse filter interceptors across RPCs

This moves the interceptor creation from the ConfigSelector to the
resource update handling.

The code structure changes will make adding support for filter
lifecycles (for RLQS) a bit easier. The filter lifecycles will allow
filters to share state across interceptors, and constructing all the
interceptors on a single thread will mean filters wouldn't need to be
thread-safe (but their interceptors would be thread-safe).

33760 of 38112 relevant lines covered (88.58%)

0.89 hits per line

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

87.5
/../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
import com.google.common.base.MoreObjects;
20
import com.google.protobuf.Message;
21
import io.grpc.ClientInterceptor;
22
import io.grpc.ServerInterceptor;
23
import java.util.Objects;
24
import java.util.concurrent.ScheduledExecutorService;
25
import javax.annotation.Nullable;
26

27
/**
28
 * Defines the parsing functionality of an HTTP filter. A Filter may optionally implement either
29
 * {@link ClientInterceptorBuilder} or {@link ServerInterceptorBuilder} or both, indicating it is
30
 * capable of working on the client side or server side or both, respectively.
31
 */
32
interface Filter {
33

34
  /**
35
   * The proto message types supported by this filter. A filter will be registered by each of its
36
   * supported message types.
37
   */
38
  String[] typeUrls();
39

40
  /**
41
   * Parses the top-level filter config from raw proto message. The message may be either a {@link
42
   * com.google.protobuf.Any} or a {@link com.google.protobuf.Struct}.
43
   */
44
  ConfigOrError<? extends FilterConfig> parseFilterConfig(Message rawProtoMessage);
45

46
  /**
47
   * Parses the per-filter override filter config from raw proto message. The message may be either
48
   * a {@link com.google.protobuf.Any} or a {@link com.google.protobuf.Struct}.
49
   */
50
  ConfigOrError<? extends FilterConfig> parseFilterConfigOverride(Message rawProtoMessage);
51

52
  /** Represents an opaque data structure holding configuration for a filter. */
53
  interface FilterConfig {
54
    String typeUrl();
55
  }
56

57
  /** Uses the FilterConfigs produced above to produce an HTTP filter interceptor for clients. */
58
  interface ClientInterceptorBuilder {
59
    @Nullable
60
    ClientInterceptor buildClientInterceptor(
61
        FilterConfig config, @Nullable FilterConfig overrideConfig,
62
        ScheduledExecutorService scheduler);
63
  }
64

65
  /** Uses the FilterConfigs produced above to produce an HTTP filter interceptor for the server. */
66
  interface ServerInterceptorBuilder {
67
    @Nullable
68
    ServerInterceptor buildServerInterceptor(
69
        FilterConfig config, @Nullable FilterConfig overrideConfig);
70
  }
71

72
  /** Filter config with instance name. */
73
  final class NamedFilterConfig {
74
    // filter instance name
75
    final String name;
76
    final FilterConfig filterConfig;
77

78
    NamedFilterConfig(String name, FilterConfig filterConfig) {
1✔
79
      this.name = name;
1✔
80
      this.filterConfig = filterConfig;
1✔
81
    }
1✔
82

83
    @Override
84
    public boolean equals(Object o) {
85
      if (this == o) {
1✔
86
        return true;
×
87
      }
88
      if (o == null || getClass() != o.getClass()) {
1✔
89
        return false;
×
90
      }
91
      NamedFilterConfig that = (NamedFilterConfig) o;
1✔
92
      return Objects.equals(name, that.name)
1✔
93
          && Objects.equals(filterConfig, that.filterConfig);
1✔
94
    }
95

96
    @Override
97
    public int hashCode() {
98
      return Objects.hash(name, filterConfig);
1✔
99
    }
100

101
    @Override
102
    public String toString() {
103
      return MoreObjects.toStringHelper(this)
1✔
104
          .add("name", name)
1✔
105
          .add("filterConfig", filterConfig)
1✔
106
          .toString();
1✔
107
    }
108
  }
109
}
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