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

grpc / grpc-java / #19550

14 Nov 2024 12:50AM UTC coverage: 84.607% (-0.03%) from 84.632%
#19550

push

github

web-flow
Make channelz work with proto lite (#11685)

Allows android apps to expose internal grpc state for debugging.

34100 of 40304 relevant lines covered (84.61%)

0.85 hits per line

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

96.31
/../services/src/main/java/io/grpc/protobuf/services/ChannelzProtoUtil.java
1
/*
2
 * Copyright 2018 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.protobuf.services;
18

19
import com.google.common.base.Preconditions;
20
import com.google.common.util.concurrent.ListenableFuture;
21
import com.google.protobuf.Any;
22
import com.google.protobuf.ByteString;
23
import com.google.protobuf.Int64Value;
24
import com.google.protobuf.MessageLite;
25
import com.google.protobuf.util.Durations;
26
import com.google.protobuf.util.Timestamps;
27
import io.grpc.ConnectivityState;
28
import io.grpc.InternalChannelz;
29
import io.grpc.InternalChannelz.ChannelStats;
30
import io.grpc.InternalChannelz.ChannelTrace.Event;
31
import io.grpc.InternalChannelz.RootChannelList;
32
import io.grpc.InternalChannelz.ServerList;
33
import io.grpc.InternalChannelz.ServerSocketsList;
34
import io.grpc.InternalChannelz.ServerStats;
35
import io.grpc.InternalChannelz.SocketStats;
36
import io.grpc.InternalChannelz.TransportStats;
37
import io.grpc.InternalInstrumented;
38
import io.grpc.InternalWithLogId;
39
import io.grpc.Status;
40
import io.grpc.channelz.v1.Address;
41
import io.grpc.channelz.v1.Address.OtherAddress;
42
import io.grpc.channelz.v1.Address.TcpIpAddress;
43
import io.grpc.channelz.v1.Address.UdsAddress;
44
import io.grpc.channelz.v1.Channel;
45
import io.grpc.channelz.v1.ChannelConnectivityState;
46
import io.grpc.channelz.v1.ChannelConnectivityState.State;
47
import io.grpc.channelz.v1.ChannelData;
48
import io.grpc.channelz.v1.ChannelRef;
49
import io.grpc.channelz.v1.ChannelTrace;
50
import io.grpc.channelz.v1.ChannelTraceEvent;
51
import io.grpc.channelz.v1.ChannelTraceEvent.Severity;
52
import io.grpc.channelz.v1.GetServerSocketsResponse;
53
import io.grpc.channelz.v1.GetServersResponse;
54
import io.grpc.channelz.v1.GetTopChannelsResponse;
55
import io.grpc.channelz.v1.Security;
56
import io.grpc.channelz.v1.Security.OtherSecurity;
57
import io.grpc.channelz.v1.Security.Tls;
58
import io.grpc.channelz.v1.Server;
59
import io.grpc.channelz.v1.ServerData;
60
import io.grpc.channelz.v1.ServerRef;
61
import io.grpc.channelz.v1.Socket;
62
import io.grpc.channelz.v1.SocketData;
63
import io.grpc.channelz.v1.SocketOption;
64
import io.grpc.channelz.v1.SocketOptionLinger;
65
import io.grpc.channelz.v1.SocketOptionTcpInfo;
66
import io.grpc.channelz.v1.SocketOptionTimeout;
67
import io.grpc.channelz.v1.SocketRef;
68
import io.grpc.channelz.v1.Subchannel;
69
import io.grpc.channelz.v1.SubchannelRef;
70
import java.net.InetSocketAddress;
71
import java.net.SocketAddress;
72
import java.security.cert.CertificateEncodingException;
73
import java.util.ArrayList;
74
import java.util.Collections;
75
import java.util.List;
76
import java.util.Map;
77
import java.util.concurrent.ExecutionException;
78
import java.util.logging.Level;
79
import java.util.logging.Logger;
80

81
/**
82
 * A static utility class for turning internal data structures into protos.
83
 *
84
 * <p>Works with both regular and lite protos.
85
 */
86
final class ChannelzProtoUtil {
87
  private static final Logger logger = Logger.getLogger(ChannelzProtoUtil.class.getName());
1✔
88

89
  private ChannelzProtoUtil() {
90
    // do not instantiate.
91
  }
92

93
  static ChannelRef toChannelRef(InternalWithLogId obj) {
94
    return ChannelRef
1✔
95
        .newBuilder()
1✔
96
        .setChannelId(obj.getLogId().getId())
1✔
97
        .setName(obj.toString())
1✔
98
        .build();
1✔
99
  }
100

101
  static SubchannelRef toSubchannelRef(InternalWithLogId obj) {
102
    return SubchannelRef
1✔
103
        .newBuilder()
1✔
104
        .setSubchannelId(obj.getLogId().getId())
1✔
105
        .setName(obj.toString())
1✔
106
        .build();
1✔
107
  }
108

109
  static ServerRef toServerRef(InternalWithLogId obj) {
110
    return ServerRef
1✔
111
        .newBuilder()
1✔
112
        .setServerId(obj.getLogId().getId())
1✔
113
        .setName(obj.toString())
1✔
114
        .build();
1✔
115
  }
116

117
  static SocketRef toSocketRef(InternalWithLogId obj) {
118
    return SocketRef
1✔
119
        .newBuilder()
1✔
120
        .setSocketId(obj.getLogId().getId())
1✔
121
        .setName(obj.toString())
1✔
122
        .build();
1✔
123
  }
124

125
  static Server toServer(InternalInstrumented<ServerStats> obj) {
126
    ServerStats stats = getFuture(obj.getStats());
1✔
127
    Server.Builder builder = Server
128
        .newBuilder()
1✔
129
        .setRef(toServerRef(obj))
1✔
130
        .setData(toServerData(stats));
1✔
131
    for (InternalInstrumented<SocketStats> listenSocket : stats.listenSockets) {
1✔
132
      builder.addListenSocket(toSocketRef(listenSocket));
1✔
133
    }
1✔
134
    return builder.build();
1✔
135
  }
136

137
  static ServerData toServerData(ServerStats stats) {
138
    return ServerData
1✔
139
        .newBuilder()
1✔
140
        .setCallsStarted(stats.callsStarted)
1✔
141
        .setCallsSucceeded(stats.callsSucceeded)
1✔
142
        .setCallsFailed(stats.callsFailed)
1✔
143
        .setLastCallStartedTimestamp(Timestamps.fromNanos(stats.lastCallStartedNanos))
1✔
144
        .build();
1✔
145
  }
146

147
  static Security toSecurity(InternalChannelz.Security security) {
148
    Preconditions.checkNotNull(security);
1✔
149
    Preconditions.checkState(
1✔
150
        security.tls != null ^ security.other != null,
151
        "one of tls or othersecurity must be non null");
152
    if (security.tls != null) {
1✔
153
      Tls.Builder tlsBuilder
154
          = Tls.newBuilder().setStandardName(security.tls.cipherSuiteStandardName);
1✔
155
      try {
156
        if (security.tls.localCert != null) {
1✔
157
          tlsBuilder.setLocalCertificate(ByteString.copyFrom(
1✔
158
              security.tls.localCert.getEncoded()));
1✔
159
        }
160
        if (security.tls.remoteCert != null) {
1✔
161
          tlsBuilder.setRemoteCertificate(ByteString.copyFrom(
1✔
162
              security.tls.remoteCert.getEncoded()));
1✔
163
        }
164
      } catch (CertificateEncodingException e) {
×
165
        logger.log(Level.FINE, "Caught exception", e);
×
166
      }
1✔
167
      return Security.newBuilder().setTls(tlsBuilder).build();
1✔
168
    } else {
169
      OtherSecurity.Builder builder = OtherSecurity.newBuilder().setName(security.other.name);
1✔
170
      if (security.other.any != null) {
1✔
171
        builder.setValue((Any) security.other.any);
1✔
172
      }
173
      return Security.newBuilder().setOther(builder).build();
1✔
174
    }
175
  }
176

177
  static Socket toSocket(InternalInstrumented<SocketStats> obj) {
178
    SocketStats socketStats = getFuture(obj.getStats());
1✔
179
    Socket.Builder builder = Socket.newBuilder()
1✔
180
        .setRef(toSocketRef(obj))
1✔
181
        .setLocal(toAddress(socketStats.local));
1✔
182
    if (socketStats.security != null) {
1✔
183
      builder.setSecurity(toSecurity(socketStats.security));
1✔
184
    }
185
    // listen sockets do not have remote nor data
186
    if (socketStats.remote != null) {
1✔
187
      builder.setRemote(toAddress(socketStats.remote));
1✔
188
    }
189
    builder.setData(extractSocketData(socketStats));
1✔
190
    return builder.build();
1✔
191
  }
192

193
  static Address toAddress(SocketAddress address) {
194
    Preconditions.checkNotNull(address);
1✔
195
    Address.Builder builder = Address.newBuilder();
1✔
196
    if (address instanceof InetSocketAddress) {
1✔
197
      InetSocketAddress inetAddress = (InetSocketAddress) address;
1✔
198
      builder.setTcpipAddress(
1✔
199
          TcpIpAddress
200
              .newBuilder()
1✔
201
              .setIpAddress(
1✔
202
                  ByteString.copyFrom(inetAddress.getAddress().getAddress()))
1✔
203
              .setPort(inetAddress.getPort())
1✔
204
              .build());
1✔
205
    } else if (address.getClass().getName().endsWith("io.netty.channel.unix.DomainSocketAddress")) {
1✔
206
      builder.setUdsAddress(
1✔
207
          UdsAddress
208
              .newBuilder()
1✔
209
              .setFilename(address.toString()) // DomainSocketAddress.toString returns filename
1✔
210
              .build());
1✔
211
    } else {
212
      builder.setOtherAddress(OtherAddress.newBuilder().setName(address.toString()).build());
1✔
213
    }
214
    return builder.build();
1✔
215
  }
216

217
  static SocketData extractSocketData(SocketStats socketStats) {
218
    SocketData.Builder builder = SocketData.newBuilder();
1✔
219
    if (socketStats.data != null) {
1✔
220
      TransportStats s = socketStats.data;
1✔
221
      builder
1✔
222
          .setStreamsStarted(s.streamsStarted)
1✔
223
          .setStreamsSucceeded(s.streamsSucceeded)
1✔
224
          .setStreamsFailed(s.streamsFailed)
1✔
225
          .setMessagesSent(s.messagesSent)
1✔
226
          .setMessagesReceived(s.messagesReceived)
1✔
227
          .setKeepAlivesSent(s.keepAlivesSent)
1✔
228
          .setLastLocalStreamCreatedTimestamp(
1✔
229
              Timestamps.fromNanos(s.lastLocalStreamCreatedTimeNanos))
1✔
230
          .setLastRemoteStreamCreatedTimestamp(
1✔
231
              Timestamps.fromNanos(s.lastRemoteStreamCreatedTimeNanos))
1✔
232
          .setLastMessageSentTimestamp(
1✔
233
              Timestamps.fromNanos(s.lastMessageSentTimeNanos))
1✔
234
          .setLastMessageReceivedTimestamp(
1✔
235
              Timestamps.fromNanos(s.lastMessageReceivedTimeNanos))
1✔
236
          .setLocalFlowControlWindow(
1✔
237
              Int64Value.of(s.localFlowControlWindow))
1✔
238
          .setRemoteFlowControlWindow(
1✔
239
              Int64Value.of(s.remoteFlowControlWindow));
1✔
240
    }
241
    builder.addAllOption(toSocketOptionsList(socketStats.socketOptions));
1✔
242
    return builder.build();
1✔
243
  }
244

245
  public static final String SO_LINGER = "SO_LINGER";
246
  public static final String SO_TIMEOUT = "SO_TIMEOUT";
247
  public static final String TCP_INFO = "TCP_INFO";
248

249
  static SocketOption toSocketOptionLinger(int lingerSeconds) {
250
    final SocketOptionLinger lingerOpt;
251
    if (lingerSeconds >= 0) {
1✔
252
      lingerOpt = SocketOptionLinger
253
          .newBuilder()
1✔
254
          .setActive(true)
1✔
255
          .setDuration(Durations.fromSeconds(lingerSeconds))
1✔
256
          .build();
1✔
257
    } else {
258
      lingerOpt = SocketOptionLinger.getDefaultInstance();
1✔
259
    }
260
    return SocketOption.newBuilder()
1✔
261
        .setName(SO_LINGER)
1✔
262
        .setAdditional(packToAny("SocketOptionLinger", lingerOpt))
1✔
263
        .build();
1✔
264
  }
265

266
  static SocketOption toSocketOptionTimeout(String name, int timeoutMillis) {
267
    Preconditions.checkNotNull(name);
1✔
268
    return SocketOption.newBuilder()
1✔
269
        .setName(name)
1✔
270
        .setAdditional(
1✔
271
            packToAny(
1✔
272
                "SocketOptionTimeout",
273
                SocketOptionTimeout.newBuilder()
1✔
274
                    .setDuration(Durations.fromMillis(timeoutMillis))
1✔
275
                    .build()))
1✔
276
        .build();
1✔
277
  }
278

279
  static SocketOption toSocketOptionTcpInfo(InternalChannelz.TcpInfo i) {
280
    SocketOptionTcpInfo tcpInfo = SocketOptionTcpInfo.newBuilder()
1✔
281
        .setTcpiState(i.state)
1✔
282
        .setTcpiCaState(i.caState)
1✔
283
        .setTcpiRetransmits(i.retransmits)
1✔
284
        .setTcpiProbes(i.probes)
1✔
285
        .setTcpiBackoff(i.backoff)
1✔
286
        .setTcpiOptions(i.options)
1✔
287
        .setTcpiSndWscale(i.sndWscale)
1✔
288
        .setTcpiRcvWscale(i.rcvWscale)
1✔
289
        .setTcpiRto(i.rto)
1✔
290
        .setTcpiAto(i.ato)
1✔
291
        .setTcpiSndMss(i.sndMss)
1✔
292
        .setTcpiRcvMss(i.rcvMss)
1✔
293
        .setTcpiUnacked(i.unacked)
1✔
294
        .setTcpiSacked(i.sacked)
1✔
295
        .setTcpiLost(i.lost)
1✔
296
        .setTcpiRetrans(i.retrans)
1✔
297
        .setTcpiFackets(i.fackets)
1✔
298
        .setTcpiLastDataSent(i.lastDataSent)
1✔
299
        .setTcpiLastAckSent(i.lastAckSent)
1✔
300
        .setTcpiLastDataRecv(i.lastDataRecv)
1✔
301
        .setTcpiLastAckRecv(i.lastAckRecv)
1✔
302
        .setTcpiPmtu(i.pmtu)
1✔
303
        .setTcpiRcvSsthresh(i.rcvSsthresh)
1✔
304
        .setTcpiRtt(i.rtt)
1✔
305
        .setTcpiRttvar(i.rttvar)
1✔
306
        .setTcpiSndSsthresh(i.sndSsthresh)
1✔
307
        .setTcpiSndCwnd(i.sndCwnd)
1✔
308
        .setTcpiAdvmss(i.advmss)
1✔
309
        .setTcpiReordering(i.reordering)
1✔
310
        .build();
1✔
311
    return SocketOption.newBuilder()
1✔
312
        .setName(TCP_INFO)
1✔
313
        .setAdditional(packToAny("SocketOptionTcpInfo", tcpInfo))
1✔
314
        .build();
1✔
315
  }
316

317
  static SocketOption toSocketOptionAdditional(String name, String value) {
318
    Preconditions.checkNotNull(name);
1✔
319
    Preconditions.checkNotNull(value);
1✔
320
    return SocketOption.newBuilder().setName(name).setValue(value).build();
1✔
321
  }
322

323
  static List<SocketOption> toSocketOptionsList(InternalChannelz.SocketOptions options) {
324
    Preconditions.checkNotNull(options);
1✔
325
    List<SocketOption> ret = new ArrayList<>();
1✔
326
    if (options.lingerSeconds != null) {
1✔
327
      ret.add(toSocketOptionLinger(options.lingerSeconds));
1✔
328
    }
329
    if (options.soTimeoutMillis != null) {
1✔
330
      ret.add(toSocketOptionTimeout(SO_TIMEOUT, options.soTimeoutMillis));
1✔
331
    }
332
    if (options.tcpInfo != null) {
1✔
333
      ret.add(toSocketOptionTcpInfo(options.tcpInfo));
1✔
334
    }
335
    for (Map.Entry<String, String> entry : options.others.entrySet()) {
1✔
336
      ret.add(toSocketOptionAdditional(entry.getKey(), entry.getValue()));
1✔
337
    }
1✔
338
    return ret;
1✔
339
  }
340

341
  static Channel toChannel(InternalInstrumented<ChannelStats> channel) {
342
    ChannelStats stats = getFuture(channel.getStats());
1✔
343
    Channel.Builder channelBuilder = Channel
344
        .newBuilder()
1✔
345
        .setRef(toChannelRef(channel))
1✔
346
        .setData(extractChannelData(stats));
1✔
347
    for (InternalWithLogId subchannel : stats.subchannels) {
1✔
348
      channelBuilder.addSubchannelRef(toSubchannelRef(subchannel));
1✔
349
    }
1✔
350

351
    return channelBuilder.build();
1✔
352
  }
353

354
  static ChannelData extractChannelData(InternalChannelz.ChannelStats stats) {
355
    ChannelData.Builder builder = ChannelData.newBuilder();
1✔
356
    builder.setTarget(stats.target)
1✔
357
        .setState(toChannelConnectivityState(stats.state))
1✔
358
        .setCallsStarted(stats.callsStarted)
1✔
359
        .setCallsSucceeded(stats.callsSucceeded)
1✔
360
        .setCallsFailed(stats.callsFailed)
1✔
361
        .setLastCallStartedTimestamp(Timestamps.fromNanos(stats.lastCallStartedNanos));
1✔
362
    if (stats.channelTrace != null) {
1✔
363
      builder.setTrace(toChannelTrace(stats.channelTrace));
1✔
364
    }
365
    return builder.build();
1✔
366
  }
367

368
  static ChannelConnectivityState toChannelConnectivityState(ConnectivityState s) {
369
    return ChannelConnectivityState.newBuilder().setState(toState(s)).build();
1✔
370
  }
371

372
  private static ChannelTrace toChannelTrace(InternalChannelz.ChannelTrace channelTrace) {
373
    return ChannelTrace.newBuilder()
1✔
374
        .setNumEventsLogged(channelTrace.numEventsLogged)
1✔
375
        .setCreationTimestamp(Timestamps.fromNanos(channelTrace.creationTimeNanos))
1✔
376
        .addAllEvents(toChannelTraceEvents(channelTrace.events))
1✔
377
        .build();
1✔
378
  }
379

380
  private static List<ChannelTraceEvent> toChannelTraceEvents(List<Event> events) {
381
    List<ChannelTraceEvent> channelTraceEvents = new ArrayList<>();
1✔
382
    for (Event event : events) {
1✔
383
      ChannelTraceEvent.Builder builder =
384
          ChannelTraceEvent.newBuilder()
1✔
385
              .setDescription(event.description)
1✔
386
              .setSeverity(toSeverity(event.severity))
1✔
387
              .setTimestamp(Timestamps.fromNanos(event.timestampNanos));
1✔
388
      if (event.channelRef != null) {
1✔
389
        builder.setChannelRef(toChannelRef(event.channelRef));
1✔
390
      }
391
      if (event.subchannelRef != null) {
1✔
392
        builder.setSubchannelRef(toSubchannelRef(event.subchannelRef));
1✔
393
      }
394
      channelTraceEvents.add(builder.build());
1✔
395
    }
1✔
396
    return Collections.unmodifiableList(channelTraceEvents);
1✔
397
  }
398

399
  static Severity toSeverity(Event.Severity severity) {
400
    if (severity == null) {
1✔
401
      return Severity.CT_UNKNOWN;
1✔
402
    }
403
    switch (severity) {
1✔
404
      case CT_INFO:
405
        return Severity.CT_INFO;
1✔
406
      case CT_ERROR:
407
        return Severity.CT_ERROR;
1✔
408
      case CT_WARNING:
409
        return Severity.CT_WARNING;
1✔
410
      default:
411
        return Severity.CT_UNKNOWN;
1✔
412
    }
413
  }
414

415
  static State toState(ConnectivityState state) {
416
    if (state == null) {
1✔
417
      return State.UNKNOWN;
1✔
418
    }
419
    switch (state) {
1✔
420
      case IDLE:
421
        return State.IDLE;
1✔
422
      case READY:
423
        return State.READY;
1✔
424
      case CONNECTING:
425
        return State.CONNECTING;
1✔
426
      case SHUTDOWN:
427
        return State.SHUTDOWN;
1✔
428
      case TRANSIENT_FAILURE:
429
        return State.TRANSIENT_FAILURE;
1✔
430
      default:
431
        return State.UNKNOWN;
×
432
    }
433
  }
434

435
  static Subchannel toSubchannel(InternalInstrumented<ChannelStats> subchannel) {
436
    ChannelStats stats = getFuture(subchannel.getStats());
1✔
437
    Subchannel.Builder subchannelBuilder = Subchannel
438
        .newBuilder()
1✔
439
        .setRef(toSubchannelRef(subchannel))
1✔
440
        .setData(extractChannelData(stats));
1✔
441
    Preconditions.checkState(stats.sockets.isEmpty() || stats.subchannels.isEmpty());
1✔
442
    for (InternalWithLogId childSocket : stats.sockets) {
1✔
443
      subchannelBuilder.addSocketRef(toSocketRef(childSocket));
1✔
444
    }
1✔
445
    for (InternalWithLogId childSubchannel : stats.subchannels) {
1✔
446
      subchannelBuilder.addSubchannelRef(toSubchannelRef(childSubchannel));
1✔
447
    }
1✔
448
    return subchannelBuilder.build();
1✔
449
  }
450

451
  static GetTopChannelsResponse toGetTopChannelResponse(RootChannelList rootChannels) {
452
    GetTopChannelsResponse.Builder responseBuilder = GetTopChannelsResponse
453
        .newBuilder()
1✔
454
        .setEnd(rootChannels.end);
1✔
455
    for (InternalInstrumented<ChannelStats> c : rootChannels.channels) {
1✔
456
      responseBuilder.addChannel(ChannelzProtoUtil.toChannel(c));
1✔
457
    }
1✔
458
    return responseBuilder.build();
1✔
459
  }
460

461
  static GetServersResponse toGetServersResponse(ServerList servers) {
462
    GetServersResponse.Builder responseBuilder = GetServersResponse
463
        .newBuilder()
1✔
464
        .setEnd(servers.end);
1✔
465
    for (InternalInstrumented<ServerStats> s : servers.servers) {
1✔
466
      responseBuilder.addServer(ChannelzProtoUtil.toServer(s));
1✔
467
    }
1✔
468
    return responseBuilder.build();
1✔
469
  }
470

471
  static GetServerSocketsResponse toGetServerSocketsResponse(ServerSocketsList serverSockets) {
472
    GetServerSocketsResponse.Builder responseBuilder = GetServerSocketsResponse
473
        .newBuilder()
1✔
474
        .setEnd(serverSockets.end);
1✔
475
    for (InternalWithLogId s : serverSockets.sockets) {
1✔
476
      responseBuilder.addSocketRef(ChannelzProtoUtil.toSocketRef(s));
1✔
477
    }
1✔
478
    return responseBuilder.build();
1✔
479
  }
480

481
  private static <T> T getFuture(ListenableFuture<T> future) {
482
    try {
483
      T ret = future.get();
1✔
484
      if (ret == null) {
1✔
485
        throw Status.UNIMPLEMENTED
×
486
            .withDescription("The entity's stats can not be retrieved. "
×
487
                + "If this is an InProcessTransport this is expected.")
488
            .asRuntimeException();
×
489
      }
490
      return ret;
1✔
491
    } catch (InterruptedException e) {
×
492
      throw Status.INTERNAL.withCause(e).asRuntimeException();
×
493
    } catch (ExecutionException e) {
×
494
      throw Status.INTERNAL.withCause(e).asRuntimeException();
×
495
    }
496
  }
497

498
  // A version of Any.pack() that works with protolite.
499
  private static Any packToAny(String typeName, MessageLite value) {
500
    return Any.newBuilder()
1✔
501
        .setTypeUrl("type.googleapis.com/grpc.channelz.v1." + typeName)
1✔
502
        .setValue(value.toByteString())
1✔
503
        .build();
1✔
504
  }
505
}
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