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

grpc / grpc-java / #19975

08 Sep 2025 09:55PM UTC coverage: 88.547% (+0.01%) from 88.535%
#19975

push

github

web-flow
otel: subchannel metrics A94 (#12202)

Implements [A94](https://github.com/grpc/proposal/pull/485/files) except for the exact reason for disconnect_error

34806 of 39308 relevant lines covered (88.55%)

0.89 hits per line

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

93.94
/../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
  private final List<SocketAddress> addrs;
59
  private final Attributes attrs;
60

61
  /**
62
   * {@link SocketAddress} docs say that the addresses are immutable, so we cache the hashCode.
63
   */
64
  private final int hashCode;
65

66
  /**
67
   * List constructor without {@link Attributes}.
68
   */
69
  public EquivalentAddressGroup(List<SocketAddress> addrs) {
70
    this(addrs, Attributes.EMPTY);
1✔
71
  }
1✔
72

73
  /**
74
   * List constructor with {@link Attributes}.
75
   */
76
  public EquivalentAddressGroup(List<SocketAddress> addrs, @Attr Attributes attrs) {
1✔
77
    Preconditions.checkArgument(!addrs.isEmpty(), "addrs is empty");
1✔
78
    this.addrs = Collections.unmodifiableList(new ArrayList<>(addrs));
1✔
79
    this.attrs = Preconditions.checkNotNull(attrs, "attrs");
1✔
80
    // Attributes may contain mutable objects, which means Attributes' hashCode may change over
81
    // time, thus we don't cache Attributes' hashCode.
82
    hashCode = this.addrs.hashCode();
1✔
83
  }
1✔
84

85
  /**
86
   * Singleton constructor without Attributes.
87
   */
88
  public EquivalentAddressGroup(SocketAddress addr) {
89
    this(addr, Attributes.EMPTY);
1✔
90
  }
1✔
91

92
  /**
93
   * Singleton constructor with Attributes.
94
   */
95
  public EquivalentAddressGroup(SocketAddress addr, @Attr Attributes attrs) {
96
    this(Collections.singletonList(addr), attrs);
1✔
97
  }
1✔
98

99
  /**
100
   * Returns an immutable list of the addresses.
101
   */
102
  public List<SocketAddress> getAddresses() {
103
    return addrs;
1✔
104
  }
105

106
  /**
107
   * Returns the attributes.
108
   */
109
  @Attr
110
  public Attributes getAttributes() {
111
    return attrs;
1✔
112
  }
113

114
  @Override
115
  public String toString() {
116
    // TODO(zpencer): Summarize return value if addr is very large
117
    return "[" + addrs + "/" + attrs + "]";
1✔
118
  }
119

120
  @Override
121
  public int hashCode() {
122
    // Avoids creating an iterator on the underlying array list.
123
    return hashCode;
1✔
124
  }
125

126
  /**
127
   * Returns true if the given object is also an {@link EquivalentAddressGroup} with an equal
128
   * address list and equal attribute values.
129
   *
130
   * <p>Note that if the attributes include mutable values, it is possible for two objects to be
131
   * considered equal at one point in time and not equal at another (due to concurrent mutation of
132
   * attribute values).
133
   */
134
  @Override
135
  public boolean equals(Object other) {
136
    if (this == other) {
1✔
137
      return true;
1✔
138
    }
139
    if (!(other instanceof EquivalentAddressGroup)) {
1✔
140
      return false;
×
141
    }
142
    EquivalentAddressGroup that = (EquivalentAddressGroup) other;
1✔
143
    if (addrs.size() != that.addrs.size()) {
1✔
144
      return false;
×
145
    }
146
    // Avoids creating an iterator on the underlying array list.
147
    for (int i = 0; i < addrs.size(); i++) {
1✔
148
      if (!addrs.get(i).equals(that.addrs.get(i))) {
1✔
149
        return false;
1✔
150
      }
151
    }
152
    if (!attrs.equals(that.attrs)) {
1✔
153
      return false;
1✔
154
    }
155
    return true;
1✔
156
  }
157

158
  /**
159
   * Annotation for {@link EquivalentAddressGroup}'s attributes. It follows the annotation semantics
160
   * defined by {@link Attributes}.
161
   */
162
  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4972")
163
  @Retention(RetentionPolicy.SOURCE)
164
  @Documented
165
  public @interface Attr {}
166
}
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

© 2025 Coveralls, Inc