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

grpc / grpc-java / #20490

24 Sep 2026 01:27PM UTC coverage: 89.306% (+0.002%) from 89.304%
#20490

push

github

web-flow
api: move ATTR_ADDRESS_NAME to EquivalentAddressGroup (#13072)

Correction to the implementation of [gRFC
A81](https://github.com/grpc/proposal/blob/master/A81-xds-authority-rewriting.md)-xds-authority-rewriting.
The proposal says:
> Note that the resolver attribute used here should be a general-purpose
one, not something specific to EDS;

The endpoint hostname attribute from gRFC A81 is currently defined in
`XdsInternalAttributes`, which makes it unreachable from other modules.

Move the key to `EquivalentAddressGroup` alongside the other endpoint
attributes and re-export it via `InternalEquivalentAddressGroup`.
`XdsInternalAttributes` held nothing else, so it is removed and its
callers now reference the key directly.

This is needed by the autosharding LB policy [gRFC
A119](https://github.com/grpc/proposal/pull/551), which keys its
endpoint map on the A81 hostname. `autosharding` cannot depend on `xds`
because `xds` will depend on autosharding.

39143 of 43830 relevant lines covered (89.31%)

0.89 hits per line

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

94.87
/../api/src/main/java/io/grpc/EquivalentAddressGroup.java
1
/*
2
 * Copyright 2015 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;
18

19
import com.google.common.base.Preconditions;
20
import java.lang.annotation.Documented;
21
import java.lang.annotation.Retention;
22
import java.lang.annotation.RetentionPolicy;
23
import java.net.SocketAddress;
24
import java.util.ArrayList;
25
import java.util.Collections;
26
import java.util.List;
27

28
/**
29
 * A group of {@link SocketAddress}es that are considered equivalent when channel makes connections.
30
 *
31
 * <p>Usually the addresses are addresses resolved from the same host name, and connecting to any of
32
 * them is equally sufficient. They do have order. An address appears earlier on the list is likely
33
 * to be tried earlier.
34
 */
35
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1770")
36
public final class EquivalentAddressGroup {
37

38
  /**
39
   * The authority to be used when constructing Subchannels for this EquivalentAddressGroup.
40
   * However, if the channel has overridden authority via
41
   * {@link ManagedChannelBuilder#overrideAuthority(String)}, the transport will use the channel's
42
   * authority override.
43
   *
44
   * <p>The authority <strong>must</strong> be from a trusted source, because if the authority is
45
   * tampered with, RPCs may be sent to attackers which may leak sensitive user data. If the
46
   * authority was acquired by doing I/O, the communication must be authenticated (e.g., via TLS).
47
   * Recognize that the server that provided the authority can trivially impersonate the service.
48
   */
49
  @Attr
50
  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/6138")
51
  public static final Attributes.Key<String> ATTR_AUTHORITY_OVERRIDE =
1 ✔
52
      Attributes.Key.create("io.grpc.EquivalentAddressGroup.ATTR_AUTHORITY_OVERRIDE");
1 ✔
53
  /**
54
   * The name of the locality that this EquivalentAddressGroup is in.
55
   */
56
  public static final Attributes.Key<String> ATTR_LOCALITY_NAME =
1 ✔
57
      Attributes.Key.create("io.grpc.EquivalentAddressGroup.LOCALITY");
1 ✔
58
  /**
59
   * The backend service associated with this EquivalentAddressGroup.
60
   */
61
  @Attr
62
  static final Attributes.Key<String> ATTR_BACKEND_SERVICE =
1 ✔
63
      Attributes.Key.create("io.grpc.EquivalentAddressGroup.BACKEND_SERVICE");
1 ✔
64
  /**
65
   * Endpoint weight for load balancing purposes. While the type is Long, it must be a valid uint32.
66
   * Must not be zero. The weight is proportional to the other endpoints; if an endpoint's weight is
67
   * twice that of another endpoint, it is intended to receive twice the load.
68
   */
69
  @Attr
70
  static final Attributes.Key<Long> ATTR_WEIGHT =
1 ✔
71
      Attributes.Key.create("io.grpc.EquivalentAddressGroup.ATTR_WEIGHT");
1 ✔
72
  /**
73
   * Name associated with individual address, if available (e.g., DNS name).
74
   */
75
  @Attr
76
  static final Attributes.Key<String> ATTR_ADDRESS_NAME =
1 ✔
77
      Attributes.Key.create("io.grpc.EquivalentAddressGroup.ATTR_ADDRESS_NAME");
1 ✔
78

79
  private final List<SocketAddress> addrs;
80
  private final Attributes attrs;
81

82
  /**
83
   * {@link SocketAddress} docs say that the addresses are immutable, so we cache the hashCode.
84
   */
85
  private final int hashCode;
86

87
  /**
88
   * List constructor without {@link Attributes}.
89
   */
90
  public EquivalentAddressGroup(List<SocketAddress> addrs) {
91
    this(addrs, Attributes.EMPTY);
1 ✔
92
  }
1 ✔
93

94
  /**
95
   * List constructor with {@link Attributes}.
96
   */
97
  public EquivalentAddressGroup(List<SocketAddress> addrs, @Attr Attributes attrs) {
1 ✔
98
    Preconditions.checkArgument(!addrs.isEmpty(), "addrs is empty");
1 ✔
99
    this.addrs = Collections.unmodifiableList(new ArrayList<>(addrs));
1 ✔
100
    this.attrs = Preconditions.checkNotNull(attrs, "attrs");
1 ✔
101
    // Attributes may contain mutable objects, which means Attributes' hashCode may change over
102
    // time, thus we don't cache Attributes' hashCode.
103
    hashCode = this.addrs.hashCode();
1 ✔
104
  }
1 ✔
105

106
  /**
107
   * Singleton constructor without Attributes.
108
   */
109
  public EquivalentAddressGroup(SocketAddress addr) {
110
    this(addr, Attributes.EMPTY);
1 ✔
111
  }
1 ✔
112

113
  /**
114
   * Singleton constructor with Attributes.
115
   */
116
  public EquivalentAddressGroup(SocketAddress addr, @Attr Attributes attrs) {
117
    this(Collections.singletonList(addr), attrs);
1 ✔
118
  }
1 ✔
119

120
  /**
121
   * Returns an immutable list of the addresses.
122
   */
123
  public List<SocketAddress> getAddresses() {
124
    return addrs;
1 ✔
125
  }
126

127
  /**
128
   * Returns the attributes.
129
   */
130
  @Attr
131
  public Attributes getAttributes() {
132
    return attrs;
1 ✔
133
  }
134

135
  @Override
136
  public String toString() {
137
    // EquivalentAddressGroup is intended to contain a small number of addresses for the same
138
    // endpoint(e.g., IPv4/IPv6). Aggregating many groups into a single EquivalentAddressGroup
139
    // is no longer done, so this no longer needs summarization.
140
    return "[" + addrs + "/" + attrs + "]";
1 ✔
141
  }
142

143
  @Override
144
  public int hashCode() {
145
    // Avoids creating an iterator on the underlying array list.
146
    return hashCode;
1 ✔
147
  }
148

149
  /**
150
   * Returns true if the given object is also an {@link EquivalentAddressGroup} with an equal
151
   * address list and equal attribute values.
152
   *
153
   * <p>Note that if the attributes include mutable values, it is possible for two objects to be
154
   * considered equal at one point in time and not equal at another (due to concurrent mutation of
155
   * attribute values).
156
   */
157
  @Override
158
  public boolean equals(Object other) {
159
    if (this == other) {
1 ✔
160
      return true;
1 ✔
161
    }
162
    if (!(other instanceof EquivalentAddressGroup)) {
1 ✔
163
      return false;
×
164
    }
165
    EquivalentAddressGroup that = (EquivalentAddressGroup) other;
1 ✔
166
    if (addrs.size() != that.addrs.size()) {
1 ✔
167
      return false;
×
168
    }
169
    // Avoids creating an iterator on the underlying array list.
170
    for (int i = 0; i < addrs.size(); i++) {
1 ✔
171
      if (!addrs.get(i).equals(that.addrs.get(i))) {
1 ✔
172
        return false;
1 ✔
173
      }
174
    }
175
    if (!attrs.equals(that.attrs)) {
1 ✔
176
      return false;
1 ✔
177
    }
178
    return true;
1 ✔
179
  }
180

181
  /**
182
   * Annotation for {@link EquivalentAddressGroup}'s attributes. It follows the annotation semantics
183
   * defined by {@link Attributes}.
184
   */
185
  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4972")
186
  @Retention(RetentionPolicy.SOURCE)
187
  @Documented
188
  public @interface Attr {}
189
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc