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

grpc / grpc-java / #20306

08 Jun 2026 01:54PM UTC coverage: 88.869% (-0.04%) from 88.908%
#20306

push

github

ejona86
xds: Remove newlines from XdsConfig.toString()

The newlines can make logs really hard to read, as many log handling
systems will split up each log statement by line. With the newlines,
those singular log entries get split between multiple log entries which
can make reading/processing it pretty ugly.

When logging XdsConfig by itself, it isn't necessarily _that_ bad when
XdsConfig is what you're actually trying to look at, but when XdsConfig
is in the attributes of ResolvedAddresses it gets very distracting.

36485 of 41055 relevant lines covered (88.87%)

0.89 hits per line

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

92.68
/../xds/src/main/java/io/grpc/xds/XdsConfig.java
1
/*
2
 * Copyright 2024 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 static com.google.common.base.Preconditions.checkNotNull;
20

21
import com.google.common.base.MoreObjects;
22
import com.google.common.collect.ImmutableList;
23
import com.google.common.collect.ImmutableMap;
24
import io.grpc.StatusOr;
25
import io.grpc.xds.XdsClusterResource.CdsUpdate;
26
import io.grpc.xds.XdsEndpointResource.EdsUpdate;
27
import io.grpc.xds.XdsListenerResource.LdsUpdate;
28
import io.grpc.xds.XdsRouteConfigureResource.RdsUpdate;
29
import java.io.Closeable;
30
import java.util.HashMap;
31
import java.util.List;
32
import java.util.Map;
33
import java.util.Objects;
34

35
/**
36
 * Represents the xDS configuration tree for a specified Listener.
37
 */
38
final class XdsConfig {
39
  private final LdsUpdate listener;
40
  private final RdsUpdate route;
41
  private final VirtualHost virtualHost;
42
  private final ImmutableMap<String, StatusOr<XdsClusterConfig>> clusters;
43
  private final int hashCode;
44

45
  XdsConfig(LdsUpdate listener, RdsUpdate route, Map<String, StatusOr<XdsClusterConfig>> clusters,
46
            VirtualHost virtualHost) {
47
    this(listener, route, virtualHost, ImmutableMap.copyOf(clusters));
1✔
48
  }
1✔
49

50
  public XdsConfig(LdsUpdate listener, RdsUpdate route, VirtualHost virtualHost,
51
                   ImmutableMap<String, StatusOr<XdsClusterConfig>> clusters) {
1✔
52
    this.listener = listener;
1✔
53
    this.route = route;
1✔
54
    this.virtualHost = virtualHost;
1✔
55
    this.clusters = clusters;
1✔
56

57
    hashCode = Objects.hash(listener, route, virtualHost, clusters);
1✔
58
  }
1✔
59

60
  @Override
61
  public boolean equals(Object obj) {
62
    if (!(obj instanceof XdsConfig)) {
1✔
63
      return false;
×
64
    }
65

66
    XdsConfig o = (XdsConfig) obj;
1✔
67

68
    return hashCode() == o.hashCode() && Objects.equals(listener, o.listener)
1✔
69
        && Objects.equals(route, o.route) && Objects.equals(virtualHost, o.virtualHost)
1✔
70
        && Objects.equals(clusters, o.clusters);
1✔
71
  }
72

73
  @Override
74
  public int hashCode() {
75
    return hashCode;
1✔
76
  }
77

78
  @Override
79
  public String toString() {
80
    return MoreObjects.toStringHelper(this)
1✔
81
        .add("listener", listener)
1✔
82
        .add("route", route)
1✔
83
        .add("virtualHost", virtualHost)
1✔
84
        .add("clusters", clusters)
1✔
85
        .toString();
1✔
86
  }
87

88
  public LdsUpdate getListener() {
89
    return listener;
1✔
90
  }
91

92
  public RdsUpdate getRoute() {
93
    return route;
×
94
  }
95

96
  public VirtualHost getVirtualHost() {
97
    return virtualHost;
1✔
98
  }
99

100
  public ImmutableMap<String, StatusOr<XdsClusterConfig>> getClusters() {
101
    return clusters;
1✔
102
  }
103

104
  static final class XdsClusterConfig {
105
    private final String clusterName;
106
    private final CdsUpdate clusterResource;
107
    private final ClusterChild children; // holds details
108

109
    XdsClusterConfig(String clusterName, CdsUpdate clusterResource, ClusterChild details) {
1✔
110
      this.clusterName = checkNotNull(clusterName, "clusterName");
1✔
111
      this.clusterResource = checkNotNull(clusterResource, "clusterResource");
1✔
112
      this.children = checkNotNull(details, "details");
1✔
113
    }
1✔
114

115
    @Override
116
    public int hashCode() {
117
      return clusterName.hashCode() + clusterResource.hashCode() + children.hashCode();
1✔
118
    }
119

120
    @Override
121
    public boolean equals(Object obj) {
122
      if (!(obj instanceof XdsClusterConfig)) {
1✔
123
        return false;
×
124
      }
125
      XdsClusterConfig o = (XdsClusterConfig) obj;
1✔
126
      return Objects.equals(clusterName, o.clusterName)
1✔
127
          && Objects.equals(clusterResource, o.clusterResource)
1✔
128
          && Objects.equals(children, o.children);
1✔
129
    }
130

131
    @Override
132
    public String toString() {
133
      StringBuilder builder = new StringBuilder();
1✔
134
      builder.append("XdsClusterConfig{clusterName=").append(clusterName)
1✔
135
          .append(", clusterResource=").append(clusterResource)
1✔
136
          .append(", children={").append(children)
1✔
137
          .append("}");
1✔
138
      return builder.toString();
1✔
139
    }
140

141
    public String getClusterName() {
142
      return clusterName;
×
143
    }
144

145
    public CdsUpdate getClusterResource() {
146
      return clusterResource;
1✔
147
    }
148

149
    public ClusterChild getChildren() {
150
      return children;
1✔
151
    }
152

153
    interface ClusterChild {}
154

155
    /** Endpoint info for EDS and LOGICAL_DNS clusters.  If there was an
156
     * error, endpoints will be null and resolution_note will be set.
157
     */
158
    static final class EndpointConfig implements ClusterChild {
159
      private final StatusOr<EdsUpdate> endpoint;
160

161
      public EndpointConfig(StatusOr<EdsUpdate> endpoint) {
1✔
162
        this.endpoint = checkNotNull(endpoint, "endpoint");
1✔
163
      }
1✔
164

165
      @Override
166
      public int hashCode() {
167
        return endpoint.hashCode();
1✔
168
      }
169

170
      @Override
171
      public boolean equals(Object obj) {
172
        if (!(obj instanceof EndpointConfig)) {
1✔
173
          return false;
×
174
        }
175
        return Objects.equals(endpoint, ((EndpointConfig)obj).endpoint);
1✔
176
      }
177

178
      public StatusOr<EdsUpdate> getEndpoint() {
179
        return endpoint;
1✔
180
      }
181

182
      @Override
183
      public String toString() {
184
        if (endpoint.hasValue()) {
1✔
185
          return "EndpointConfig{endpoint=" + endpoint.getValue() + "}";
1✔
186
        } else {
187
          return "EndpointConfig{error=" + endpoint.getStatus() + "}";
1✔
188
        }
189
      }
190
    }
191

192
    // The list of leaf clusters for an aggregate cluster.
193
    static final class AggregateConfig implements ClusterChild {
194
      private final List<String> leafNames;
195

196
      public AggregateConfig(List<String> leafNames) {
1✔
197
        this.leafNames = ImmutableList.copyOf(checkNotNull(leafNames, "leafNames"));
1✔
198
      }
1✔
199

200
      public List<String> getLeafNames() {
201
        return leafNames;
1✔
202
      }
203

204
      @Override
205
      public int hashCode() {
206
        return leafNames.hashCode();
1✔
207
      }
208

209
      @Override
210
      public boolean equals(Object obj) {
211
        if (!(obj instanceof AggregateConfig)) {
1✔
212
          return false;
×
213
        }
214
        return Objects.equals(leafNames, ((AggregateConfig) obj).leafNames);
1✔
215
      }
216
    }
217
  }
218

219
  static final class XdsConfigBuilder {
1✔
220
    private LdsUpdate listener;
221
    private RdsUpdate route;
222
    private Map<String, StatusOr<XdsClusterConfig>> clusters = new HashMap<>();
1✔
223
    private VirtualHost virtualHost;
224

225
    XdsConfigBuilder setListener(LdsUpdate listener) {
226
      this.listener = checkNotNull(listener, "listener");
1✔
227
      return this;
1✔
228
    }
229

230
    XdsConfigBuilder setRoute(RdsUpdate route) {
231
      this.route = checkNotNull(route, "route");
1✔
232
      return this;
1✔
233
    }
234

235
    XdsConfigBuilder addCluster(String name, StatusOr<XdsClusterConfig> clusterConfig) {
236
      checkNotNull(name, "name");
1✔
237
      checkNotNull(clusterConfig, "clusterConfig");
1✔
238
      clusters.put(name, clusterConfig);
1✔
239
      return this;
1✔
240
    }
241

242
    XdsConfigBuilder setVirtualHost(VirtualHost virtualHost) {
243
      this.virtualHost = checkNotNull(virtualHost, "virtualHost");
1✔
244
      return this;
1✔
245
    }
246

247
    XdsConfig build() {
248
      checkNotNull(listener, "listener");
1✔
249
      checkNotNull(route, "route");
1✔
250
      checkNotNull(virtualHost, "virtualHost");
1✔
251
      return new XdsConfig(listener, route, clusters, virtualHost);
1✔
252
    }
253
  }
254

255
  public interface XdsClusterSubscriptionRegistry {
256
    Subscription subscribeToCluster(String clusterName);
257
  }
258

259
  public interface Subscription extends Closeable {
260
    /** Release resources without throwing exceptions. */
261
    @Override
262
    void close();
263
  }
264
}
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