mirror of https://github.com/grpc/grpc-java.git
Make channelz work with proto lite (#11685)
Allows android apps to expose internal grpc state for debugging.
This commit is contained in:
parent
921f88ae30
commit
b1703345f7
|
|
@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
import com.google.protobuf.Any;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.Int64Value;
|
||||
import com.google.protobuf.MessageLite;
|
||||
import com.google.protobuf.util.Durations;
|
||||
import com.google.protobuf.util.Timestamps;
|
||||
import io.grpc.ConnectivityState;
|
||||
|
|
@ -79,6 +80,8 @@ import java.util.logging.Logger;
|
|||
|
||||
/**
|
||||
* A static utility class for turning internal data structures into protos.
|
||||
*
|
||||
* <p>Works with both regular and lite protos.
|
||||
*/
|
||||
final class ChannelzProtoUtil {
|
||||
private static final Logger logger = Logger.getLogger(ChannelzProtoUtil.class.getName());
|
||||
|
|
@ -254,22 +257,20 @@ final class ChannelzProtoUtil {
|
|||
} else {
|
||||
lingerOpt = SocketOptionLinger.getDefaultInstance();
|
||||
}
|
||||
return SocketOption
|
||||
.newBuilder()
|
||||
return SocketOption.newBuilder()
|
||||
.setName(SO_LINGER)
|
||||
.setAdditional(Any.pack(lingerOpt))
|
||||
.setAdditional(packToAny("SocketOptionLinger", lingerOpt))
|
||||
.build();
|
||||
}
|
||||
|
||||
static SocketOption toSocketOptionTimeout(String name, int timeoutMillis) {
|
||||
Preconditions.checkNotNull(name);
|
||||
return SocketOption
|
||||
.newBuilder()
|
||||
return SocketOption.newBuilder()
|
||||
.setName(name)
|
||||
.setAdditional(
|
||||
Any.pack(
|
||||
SocketOptionTimeout
|
||||
.newBuilder()
|
||||
packToAny(
|
||||
"SocketOptionTimeout",
|
||||
SocketOptionTimeout.newBuilder()
|
||||
.setDuration(Durations.fromMillis(timeoutMillis))
|
||||
.build()))
|
||||
.build();
|
||||
|
|
@ -307,10 +308,9 @@ final class ChannelzProtoUtil {
|
|||
.setTcpiAdvmss(i.advmss)
|
||||
.setTcpiReordering(i.reordering)
|
||||
.build();
|
||||
return SocketOption
|
||||
.newBuilder()
|
||||
return SocketOption.newBuilder()
|
||||
.setName(TCP_INFO)
|
||||
.setAdditional(Any.pack(tcpInfo))
|
||||
.setAdditional(packToAny("SocketOptionTcpInfo", tcpInfo))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
@ -380,10 +380,11 @@ final class ChannelzProtoUtil {
|
|||
private static List<ChannelTraceEvent> toChannelTraceEvents(List<Event> events) {
|
||||
List<ChannelTraceEvent> channelTraceEvents = new ArrayList<>();
|
||||
for (Event event : events) {
|
||||
ChannelTraceEvent.Builder builder = ChannelTraceEvent.newBuilder()
|
||||
.setDescription(event.description)
|
||||
.setSeverity(Severity.valueOf(event.severity.name()))
|
||||
.setTimestamp(Timestamps.fromNanos(event.timestampNanos));
|
||||
ChannelTraceEvent.Builder builder =
|
||||
ChannelTraceEvent.newBuilder()
|
||||
.setDescription(event.description)
|
||||
.setSeverity(toSeverity(event.severity))
|
||||
.setTimestamp(Timestamps.fromNanos(event.timestampNanos));
|
||||
if (event.channelRef != null) {
|
||||
builder.setChannelRef(toChannelRef(event.channelRef));
|
||||
}
|
||||
|
|
@ -395,14 +396,39 @@ final class ChannelzProtoUtil {
|
|||
return Collections.unmodifiableList(channelTraceEvents);
|
||||
}
|
||||
|
||||
static Severity toSeverity(Event.Severity severity) {
|
||||
if (severity == null) {
|
||||
return Severity.CT_UNKNOWN;
|
||||
}
|
||||
switch (severity) {
|
||||
case CT_INFO:
|
||||
return Severity.CT_INFO;
|
||||
case CT_ERROR:
|
||||
return Severity.CT_ERROR;
|
||||
case CT_WARNING:
|
||||
return Severity.CT_WARNING;
|
||||
default:
|
||||
return Severity.CT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static State toState(ConnectivityState state) {
|
||||
if (state == null) {
|
||||
return State.UNKNOWN;
|
||||
}
|
||||
try {
|
||||
return Enum.valueOf(State.class, state.name());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return State.UNKNOWN;
|
||||
switch (state) {
|
||||
case IDLE:
|
||||
return State.IDLE;
|
||||
case READY:
|
||||
return State.READY;
|
||||
case CONNECTING:
|
||||
return State.CONNECTING;
|
||||
case SHUTDOWN:
|
||||
return State.SHUTDOWN;
|
||||
case TRANSIENT_FAILURE:
|
||||
return State.TRANSIENT_FAILURE;
|
||||
default:
|
||||
return State.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -468,4 +494,12 @@ final class ChannelzProtoUtil {
|
|||
throw Status.INTERNAL.withCause(e).asRuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
// A version of Any.pack() that works with protolite.
|
||||
private static Any packToAny(String typeName, MessageLite value) {
|
||||
return Any.newBuilder()
|
||||
.setTypeUrl("type.googleapis.com/grpc.channelz.v1." + typeName)
|
||||
.setValue(value.toByteString())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import com.google.common.collect.ImmutableMap;
|
|||
import com.google.protobuf.Any;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.Int64Value;
|
||||
import com.google.protobuf.Message;
|
||||
import com.google.protobuf.MessageLite;
|
||||
import com.google.protobuf.util.Durations;
|
||||
import com.google.protobuf.util.Timestamps;
|
||||
import io.grpc.ConnectivityState;
|
||||
|
|
@ -154,33 +154,44 @@ public final class ChannelzProtoUtilTest {
|
|||
.setData(serverData)
|
||||
.build();
|
||||
|
||||
private final SocketOption sockOptLingerDisabled = SocketOption
|
||||
.newBuilder()
|
||||
.setName("SO_LINGER")
|
||||
.setAdditional(
|
||||
Any.pack(SocketOptionLinger.getDefaultInstance()))
|
||||
.build();
|
||||
private final SocketOption sockOptLingerDisabled =
|
||||
SocketOption.newBuilder()
|
||||
.setName("SO_LINGER")
|
||||
.setAdditional(
|
||||
Any.newBuilder()
|
||||
.setTypeUrl("type.googleapis.com/grpc.channelz.v1.SocketOptionLinger")
|
||||
.setValue(SocketOptionLinger.getDefaultInstance().toByteString())
|
||||
.build())
|
||||
.build();
|
||||
|
||||
private final SocketOption sockOptlinger10s = SocketOption
|
||||
.newBuilder()
|
||||
.setName("SO_LINGER")
|
||||
.setAdditional(
|
||||
Any.pack(SocketOptionLinger
|
||||
.newBuilder()
|
||||
.setActive(true)
|
||||
.setDuration(Durations.fromSeconds(10))
|
||||
.build()))
|
||||
.build();
|
||||
private final SocketOption sockOptlinger10s =
|
||||
SocketOption.newBuilder()
|
||||
.setName("SO_LINGER")
|
||||
.setAdditional(
|
||||
Any.newBuilder()
|
||||
.setTypeUrl("type.googleapis.com/grpc.channelz.v1.SocketOptionLinger")
|
||||
.setValue(
|
||||
SocketOptionLinger.newBuilder()
|
||||
.setActive(true)
|
||||
.setDuration(Durations.fromSeconds(10))
|
||||
.build()
|
||||
.toByteString())
|
||||
.build())
|
||||
.build();
|
||||
|
||||
private final SocketOption sockOptTimeout200ms = SocketOption
|
||||
.newBuilder()
|
||||
.setName("SO_TIMEOUT")
|
||||
.setAdditional(
|
||||
Any.pack(SocketOptionTimeout
|
||||
.newBuilder()
|
||||
.setDuration(Durations.fromMillis(200))
|
||||
.build())
|
||||
).build();
|
||||
private final SocketOption sockOptTimeout200ms =
|
||||
SocketOption.newBuilder()
|
||||
.setName("SO_TIMEOUT")
|
||||
.setAdditional(
|
||||
Any.newBuilder()
|
||||
.setTypeUrl("type.googleapis.com/grpc.channelz.v1.SocketOptionTimeout")
|
||||
.setValue(
|
||||
SocketOptionTimeout.newBuilder()
|
||||
.setDuration(Durations.fromMillis(200))
|
||||
.build()
|
||||
.toByteString())
|
||||
.build())
|
||||
.build();
|
||||
|
||||
private final SocketOption sockOptAdditional = SocketOption
|
||||
.newBuilder()
|
||||
|
|
@ -221,43 +232,46 @@ public final class ChannelzProtoUtilTest {
|
|||
.setReordering(728)
|
||||
.build();
|
||||
|
||||
private final SocketOption socketOptionTcpInfo = SocketOption
|
||||
.newBuilder()
|
||||
.setName("TCP_INFO")
|
||||
.setAdditional(
|
||||
Any.pack(
|
||||
SocketOptionTcpInfo.newBuilder()
|
||||
.setTcpiState(70)
|
||||
.setTcpiCaState(71)
|
||||
.setTcpiRetransmits(72)
|
||||
.setTcpiProbes(73)
|
||||
.setTcpiBackoff(74)
|
||||
.setTcpiOptions(75)
|
||||
.setTcpiSndWscale(76)
|
||||
.setTcpiRcvWscale(77)
|
||||
.setTcpiRto(78)
|
||||
.setTcpiAto(79)
|
||||
.setTcpiSndMss(710)
|
||||
.setTcpiRcvMss(711)
|
||||
.setTcpiUnacked(712)
|
||||
.setTcpiSacked(713)
|
||||
.setTcpiLost(714)
|
||||
.setTcpiRetrans(715)
|
||||
.setTcpiFackets(716)
|
||||
.setTcpiLastDataSent(717)
|
||||
.setTcpiLastAckSent(718)
|
||||
.setTcpiLastDataRecv(719)
|
||||
.setTcpiLastAckRecv(720)
|
||||
.setTcpiPmtu(721)
|
||||
.setTcpiRcvSsthresh(722)
|
||||
.setTcpiRtt(723)
|
||||
.setTcpiRttvar(724)
|
||||
.setTcpiSndSsthresh(725)
|
||||
.setTcpiSndCwnd(726)
|
||||
.setTcpiAdvmss(727)
|
||||
.setTcpiReordering(728)
|
||||
.build()))
|
||||
.build();
|
||||
private final SocketOption socketOptionTcpInfo =
|
||||
SocketOption.newBuilder()
|
||||
.setName("TCP_INFO")
|
||||
.setAdditional(
|
||||
Any.newBuilder()
|
||||
.setTypeUrl("type.googleapis.com/grpc.channelz.v1.SocketOptionTcpInfo")
|
||||
.setValue(
|
||||
SocketOptionTcpInfo.newBuilder()
|
||||
.setTcpiState(70)
|
||||
.setTcpiCaState(71)
|
||||
.setTcpiRetransmits(72)
|
||||
.setTcpiProbes(73)
|
||||
.setTcpiBackoff(74)
|
||||
.setTcpiOptions(75)
|
||||
.setTcpiSndWscale(76)
|
||||
.setTcpiRcvWscale(77)
|
||||
.setTcpiRto(78)
|
||||
.setTcpiAto(79)
|
||||
.setTcpiSndMss(710)
|
||||
.setTcpiRcvMss(711)
|
||||
.setTcpiUnacked(712)
|
||||
.setTcpiSacked(713)
|
||||
.setTcpiLost(714)
|
||||
.setTcpiRetrans(715)
|
||||
.setTcpiFackets(716)
|
||||
.setTcpiLastDataSent(717)
|
||||
.setTcpiLastAckSent(718)
|
||||
.setTcpiLastDataRecv(719)
|
||||
.setTcpiLastAckRecv(720)
|
||||
.setTcpiPmtu(721)
|
||||
.setTcpiRcvSsthresh(722)
|
||||
.setTcpiRtt(723)
|
||||
.setTcpiRttvar(724)
|
||||
.setTcpiSndSsthresh(725)
|
||||
.setTcpiSndCwnd(726)
|
||||
.setTcpiAdvmss(727)
|
||||
.setTcpiReordering(728)
|
||||
.build()
|
||||
.toByteString()))
|
||||
.build();
|
||||
|
||||
private final TestListenSocket listenSocket = new TestListenSocket();
|
||||
private final SocketRef listenSocketRef = SocketRef
|
||||
|
|
@ -336,6 +350,16 @@ public final class ChannelzProtoUtilTest {
|
|||
assertEquals(serverRef, ChannelzProtoUtil.toServerRef(server));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toSeverity() {
|
||||
for (Severity severity : Severity.values()) {
|
||||
assertEquals(
|
||||
severity.name(),
|
||||
ChannelzProtoUtil.toSeverity(severity).name()); // OK because test isn't proguarded.
|
||||
}
|
||||
assertEquals(ChannelTraceEvent.Severity.CT_UNKNOWN, ChannelzProtoUtil.toSeverity(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toSocketRef() {
|
||||
assertEquals(socketRef, ChannelzProtoUtil.toSocketRef(socket));
|
||||
|
|
@ -346,7 +370,7 @@ public final class ChannelzProtoUtilTest {
|
|||
for (ConnectivityState connectivityState : ConnectivityState.values()) {
|
||||
assertEquals(
|
||||
connectivityState.name(),
|
||||
ChannelzProtoUtil.toState(connectivityState).getValueDescriptor().getName());
|
||||
ChannelzProtoUtil.toState(connectivityState).name()); // OK because test isn't proguarded.
|
||||
}
|
||||
assertEquals(State.UNKNOWN, ChannelzProtoUtil.toState(null));
|
||||
}
|
||||
|
|
@ -475,8 +499,12 @@ public final class ChannelzProtoUtilTest {
|
|||
@Test
|
||||
public void socketSecurityOther() throws Exception {
|
||||
// what is packed here is not important, just pick some proto message
|
||||
Message contents = GetChannelRequest.newBuilder().setChannelId(1).build();
|
||||
Any packed = Any.pack(contents);
|
||||
MessageLite contents = GetChannelRequest.newBuilder().setChannelId(1).build();
|
||||
Any packed =
|
||||
Any.newBuilder()
|
||||
.setTypeUrl("type.googleapis.com/grpc.channelz.v1.GetChannelRequest")
|
||||
.setValue(contents.toByteString())
|
||||
.build();
|
||||
socket.security
|
||||
= new InternalChannelz.Security(
|
||||
new InternalChannelz.OtherSecurity("other_security", packed));
|
||||
|
|
|
|||
Loading…
Reference in New Issue