mirror of https://github.com/grpc/grpc-java.git
all: API refactoring in preparation to support retry stats (#8355)
Rebased PR #8343 into the first commit of this PR, then (the 2nd commit) reverted the part for metric recording of retry attempts. The PR as a whole is mechanical refactoring. No behavior change (except that some of the old code path when tracer is created is moved into the new method `streamCreated()`). The API change is documented in go/grpc-stats-api-change-for-retry-java
This commit is contained in:
parent
b2764595e6
commit
860e97d12a
|
|
@ -19,7 +19,6 @@ package io.grpc;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import io.grpc.Grpc;
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -28,6 +27,18 @@ import javax.annotation.concurrent.ThreadSafe;
|
||||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861")
|
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861")
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
public abstract class ClientStreamTracer extends StreamTracer {
|
public abstract class ClientStreamTracer extends StreamTracer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The stream is being created on a ready transport.
|
||||||
|
*
|
||||||
|
* @param headers the mutable initial metadata. Modifications to it will be sent to the socket but
|
||||||
|
* not be seen by client interceptors and the application.
|
||||||
|
*
|
||||||
|
* @since 1.40.0
|
||||||
|
*/
|
||||||
|
public void streamCreated(@Grpc.TransportAttr Attributes transportAttrs, Metadata headers) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Headers has been sent to the socket.
|
* Headers has been sent to the socket.
|
||||||
*/
|
*/
|
||||||
|
|
@ -54,22 +65,6 @@ public abstract class ClientStreamTracer extends StreamTracer {
|
||||||
* Factory class for {@link ClientStreamTracer}.
|
* Factory class for {@link ClientStreamTracer}.
|
||||||
*/
|
*/
|
||||||
public abstract static class Factory {
|
public abstract static class Factory {
|
||||||
/**
|
|
||||||
* Creates a {@link ClientStreamTracer} for a new client stream.
|
|
||||||
*
|
|
||||||
* @param callOptions the effective CallOptions of the call
|
|
||||||
* @param headers the mutable headers of the stream. It can be safely mutated within this
|
|
||||||
* method. It should not be saved because it is not safe for read or write after the
|
|
||||||
* method returns.
|
|
||||||
*
|
|
||||||
* @deprecated use {@link
|
|
||||||
* #newClientStreamTracer(io.grpc.ClientStreamTracer.StreamInfo, io.grpc.Metadata)} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public ClientStreamTracer newClientStreamTracer(CallOptions callOptions, Metadata headers) {
|
|
||||||
throw new UnsupportedOperationException("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link ClientStreamTracer} for a new client stream. This is called inside the
|
* Creates a {@link ClientStreamTracer} for a new client stream. This is called inside the
|
||||||
* transport when it's creating the stream.
|
* transport when it's creating the stream.
|
||||||
|
|
@ -81,12 +76,15 @@ public abstract class ClientStreamTracer extends StreamTracer {
|
||||||
*
|
*
|
||||||
* @since 1.20.0
|
* @since 1.20.0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
|
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
|
||||||
return newClientStreamTracer(info.getCallOptions(), headers);
|
throw new UnsupportedOperationException("Not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** An abstract class for internal use only. */
|
||||||
|
@Internal
|
||||||
|
public abstract static class InternalLimitedInfoFactory extends Factory {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about a stream.
|
* Information about a stream.
|
||||||
*
|
*
|
||||||
|
|
@ -99,15 +97,21 @@ public abstract class ClientStreamTracer extends StreamTracer {
|
||||||
public static final class StreamInfo {
|
public static final class StreamInfo {
|
||||||
private final Attributes transportAttrs;
|
private final Attributes transportAttrs;
|
||||||
private final CallOptions callOptions;
|
private final CallOptions callOptions;
|
||||||
|
private final boolean isTransparentRetry;
|
||||||
|
|
||||||
StreamInfo(Attributes transportAttrs, CallOptions callOptions) {
|
StreamInfo(Attributes transportAttrs, CallOptions callOptions, boolean isTransparentRetry) {
|
||||||
this.transportAttrs = checkNotNull(transportAttrs, "transportAttrs");
|
this.transportAttrs = checkNotNull(transportAttrs, "transportAttrs");
|
||||||
this.callOptions = checkNotNull(callOptions, "callOptions");
|
this.callOptions = checkNotNull(callOptions, "callOptions");
|
||||||
|
this.isTransparentRetry = isTransparentRetry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the attributes of the transport that this stream was created on.
|
* Returns the attributes of the transport that this stream was created on.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link ClientStreamTracer#streamCreated(Attributes, Metadata)} to handle
|
||||||
|
* the transport Attributes instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@Grpc.TransportAttr
|
@Grpc.TransportAttr
|
||||||
public Attributes getTransportAttrs() {
|
public Attributes getTransportAttrs() {
|
||||||
return transportAttrs;
|
return transportAttrs;
|
||||||
|
|
@ -120,16 +124,25 @@ public abstract class ClientStreamTracer extends StreamTracer {
|
||||||
return callOptions;
|
return callOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the stream is a transparent retry.
|
||||||
|
*
|
||||||
|
* @since 1.40.0
|
||||||
|
*/
|
||||||
|
public boolean isTransparentRetry() {
|
||||||
|
return isTransparentRetry;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts this StreamInfo into a new Builder.
|
* Converts this StreamInfo into a new Builder.
|
||||||
*
|
*
|
||||||
* @since 1.21.0
|
* @since 1.21.0
|
||||||
*/
|
*/
|
||||||
public Builder toBuilder() {
|
public Builder toBuilder() {
|
||||||
Builder builder = new Builder();
|
return new Builder()
|
||||||
builder.setTransportAttrs(transportAttrs);
|
.setCallOptions(callOptions)
|
||||||
builder.setCallOptions(callOptions);
|
.setTransportAttrs(transportAttrs)
|
||||||
return builder;
|
.setIsTransparentRetry(isTransparentRetry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -146,6 +159,7 @@ public abstract class ClientStreamTracer extends StreamTracer {
|
||||||
return MoreObjects.toStringHelper(this)
|
return MoreObjects.toStringHelper(this)
|
||||||
.add("transportAttrs", transportAttrs)
|
.add("transportAttrs", transportAttrs)
|
||||||
.add("callOptions", callOptions)
|
.add("callOptions", callOptions)
|
||||||
|
.add("isTransparentRetry", isTransparentRetry)
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,6 +171,7 @@ public abstract class ClientStreamTracer extends StreamTracer {
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
private Attributes transportAttrs = Attributes.EMPTY;
|
private Attributes transportAttrs = Attributes.EMPTY;
|
||||||
private CallOptions callOptions = CallOptions.DEFAULT;
|
private CallOptions callOptions = CallOptions.DEFAULT;
|
||||||
|
private boolean isTransparentRetry;
|
||||||
|
|
||||||
Builder() {
|
Builder() {
|
||||||
}
|
}
|
||||||
|
|
@ -164,9 +179,12 @@ public abstract class ClientStreamTracer extends StreamTracer {
|
||||||
/**
|
/**
|
||||||
* Sets the attributes of the transport that this stream was created on. This field is
|
* Sets the attributes of the transport that this stream was created on. This field is
|
||||||
* optional.
|
* optional.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link ClientStreamTracer#streamCreated(Attributes, Metadata)} to handle
|
||||||
|
* the transport Attributes instead.
|
||||||
*/
|
*/
|
||||||
@Grpc.TransportAttr
|
@Deprecated
|
||||||
public Builder setTransportAttrs(Attributes transportAttrs) {
|
public Builder setTransportAttrs(@Grpc.TransportAttr Attributes transportAttrs) {
|
||||||
this.transportAttrs = checkNotNull(transportAttrs, "transportAttrs cannot be null");
|
this.transportAttrs = checkNotNull(transportAttrs, "transportAttrs cannot be null");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -179,11 +197,21 @@ public abstract class ClientStreamTracer extends StreamTracer {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the stream is a transparent retry.
|
||||||
|
*
|
||||||
|
* @since 1.40.0
|
||||||
|
*/
|
||||||
|
public Builder setIsTransparentRetry(boolean isTransparentRetry) {
|
||||||
|
this.isTransparentRetry = isTransparentRetry;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a new StreamInfo.
|
* Builds a new StreamInfo.
|
||||||
*/
|
*/
|
||||||
public StreamInfo build() {
|
public StreamInfo build() {
|
||||||
return new StreamInfo(transportAttrs, callOptions);
|
return new StreamInfo(transportAttrs, callOptions, isTransparentRetry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
import io.grpc.ClientStreamTracer.StreamInfo;
|
||||||
import io.grpc.internal.SerializingExecutor;
|
import io.grpc.internal.SerializingExecutor;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
@ -271,7 +272,7 @@ public class CallOptionsTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FakeTracerFactory extends ClientStreamTracer.Factory {
|
private static class FakeTracerFactory extends ClientStreamTracer.InternalLimitedInfoFactory {
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
FakeTracerFactory(String name) {
|
FakeTracerFactory(String name) {
|
||||||
|
|
@ -279,8 +280,7 @@ public class CallOptionsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientStreamTracer newClientStreamTracer(
|
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
|
||||||
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
|
||||||
return new ClientStreamTracer() {};
|
return new ClientStreamTracer() {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Grpc;
|
import io.grpc.Grpc;
|
||||||
import io.grpc.Internal;
|
import io.grpc.Internal;
|
||||||
import io.grpc.InternalChannelz.SocketStats;
|
import io.grpc.InternalChannelz.SocketStats;
|
||||||
|
|
@ -632,28 +633,28 @@ public abstract class BinderTransport
|
||||||
public synchronized ClientStream newStream(
|
public synchronized ClientStream newStream(
|
||||||
final MethodDescriptor<?, ?> method,
|
final MethodDescriptor<?, ?> method,
|
||||||
final Metadata headers,
|
final Metadata headers,
|
||||||
final CallOptions callOptions) {
|
final CallOptions callOptions,
|
||||||
|
ClientStreamTracer[] tracers) {
|
||||||
if (isShutdown()) {
|
if (isShutdown()) {
|
||||||
return newFailingClientStream(shutdownStatus, callOptions, attributes, headers);
|
return newFailingClientStream(shutdownStatus, attributes, headers, tracers);
|
||||||
} else {
|
} else {
|
||||||
int callId = latestCallId++;
|
int callId = latestCallId++;
|
||||||
if (latestCallId == LAST_CALL_ID) {
|
if (latestCallId == LAST_CALL_ID) {
|
||||||
latestCallId = FIRST_CALL_ID;
|
latestCallId = FIRST_CALL_ID;
|
||||||
}
|
}
|
||||||
|
StatsTraceContext statsTraceContext =
|
||||||
|
StatsTraceContext.newClientContext(tracers, attributes, headers);
|
||||||
Inbound.ClientInbound inbound =
|
Inbound.ClientInbound inbound =
|
||||||
new Inbound.ClientInbound(
|
new Inbound.ClientInbound(
|
||||||
this, attributes, callId, GrpcUtil.shouldBeCountedForInUse(callOptions));
|
this, attributes, callId, GrpcUtil.shouldBeCountedForInUse(callOptions));
|
||||||
if (ongoingCalls.putIfAbsent(callId, inbound) != null) {
|
if (ongoingCalls.putIfAbsent(callId, inbound) != null) {
|
||||||
Status failure = Status.INTERNAL.withDescription("Clashing call IDs");
|
Status failure = Status.INTERNAL.withDescription("Clashing call IDs");
|
||||||
shutdownInternal(failure, true);
|
shutdownInternal(failure, true);
|
||||||
return newFailingClientStream(failure, callOptions, attributes, headers);
|
return newFailingClientStream(failure, attributes, headers, tracers);
|
||||||
} else {
|
} else {
|
||||||
if (inbound.countsForInUse() && numInUseStreams.getAndIncrement() == 0) {
|
if (inbound.countsForInUse() && numInUseStreams.getAndIncrement() == 0) {
|
||||||
clientTransportListener.transportInUse(true);
|
clientTransportListener.transportInUse(true);
|
||||||
}
|
}
|
||||||
StatsTraceContext statsTraceContext =
|
|
||||||
StatsTraceContext.newClientContext(callOptions, attributes, headers);
|
|
||||||
|
|
||||||
Outbound.ClientOutbound outbound =
|
Outbound.ClientOutbound outbound =
|
||||||
new Outbound.ClientOutbound(this, callId, method, headers, statsTraceContext);
|
new Outbound.ClientOutbound(this, callId, method, headers, statsTraceContext);
|
||||||
if (method.getType().clientSendsOneMessage()) {
|
if (method.getType().clientSendsOneMessage()) {
|
||||||
|
|
@ -763,12 +764,12 @@ public abstract class BinderTransport
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ClientStream newFailingClientStream(
|
private static ClientStream newFailingClientStream(
|
||||||
Status failure, CallOptions callOptions, Attributes attributes, Metadata headers) {
|
Status failure, Attributes attributes, Metadata headers,
|
||||||
|
ClientStreamTracer[] tracers) {
|
||||||
StatsTraceContext statsTraceContext =
|
StatsTraceContext statsTraceContext =
|
||||||
StatsTraceContext.newClientContext(callOptions, attributes, headers);
|
StatsTraceContext.newClientContext(tracers, attributes, headers);
|
||||||
statsTraceContext.clientOutboundHeaders();
|
statsTraceContext.clientOutboundHeaders();
|
||||||
statsTraceContext.streamClosed(failure);
|
return new FailingClientStream(failure, tracers);
|
||||||
return new FailingClientStream(failure);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InternalLogId buildLogId(
|
private static InternalLogId buildLogId(
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkState;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.Channel;
|
import io.grpc.Channel;
|
||||||
import io.grpc.ClientCall;
|
import io.grpc.ClientCall;
|
||||||
|
|
@ -138,15 +139,6 @@ final class CensusStatsModule {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a {@link ClientCallTracer} for a new call.
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
ClientCallTracer newClientCallTracer(
|
|
||||||
TagContext parentCtx, String fullMethodName) {
|
|
||||||
return new ClientCallTracer(this, parentCtx, fullMethodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the server tracer factory.
|
* Returns the server tracer factory.
|
||||||
*/
|
*/
|
||||||
|
|
@ -231,6 +223,7 @@ final class CensusStatsModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
private final CensusStatsModule module;
|
private final CensusStatsModule module;
|
||||||
|
final TagContext parentCtx;
|
||||||
private final TagContext startCtx;
|
private final TagContext startCtx;
|
||||||
|
|
||||||
volatile long outboundMessageCount;
|
volatile long outboundMessageCount;
|
||||||
|
|
@ -240,11 +233,22 @@ final class CensusStatsModule {
|
||||||
volatile long outboundUncompressedSize;
|
volatile long outboundUncompressedSize;
|
||||||
volatile long inboundUncompressedSize;
|
volatile long inboundUncompressedSize;
|
||||||
|
|
||||||
ClientTracer(CensusStatsModule module, TagContext startCtx) {
|
ClientTracer(CensusStatsModule module, TagContext parentCtx, TagContext startCtx) {
|
||||||
this.module = checkNotNull(module, "module");
|
this.module = checkNotNull(module, "module");
|
||||||
|
this.parentCtx = parentCtx;
|
||||||
this.startCtx = checkNotNull(startCtx, "startCtx");
|
this.startCtx = checkNotNull(startCtx, "startCtx");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamCreated(Attributes transportAttrs, Metadata headers) {
|
||||||
|
if (module.propagateTags) {
|
||||||
|
headers.discardAll(module.statsHeader);
|
||||||
|
if (!module.tagger.empty().equals(parentCtx)) {
|
||||||
|
headers.put(module.statsHeader, parentCtx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("NonAtomicVolatileUpdate")
|
@SuppressWarnings("NonAtomicVolatileUpdate")
|
||||||
public void outboundWireSize(long bytes) {
|
public void outboundWireSize(long bytes) {
|
||||||
|
|
@ -315,12 +319,14 @@ final class CensusStatsModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final class ClientCallTracer extends ClientStreamTracer.Factory {
|
static final class CallAttemptsTracerFactory extends
|
||||||
|
ClientStreamTracer.InternalLimitedInfoFactory {
|
||||||
@Nullable
|
@Nullable
|
||||||
private static final AtomicReferenceFieldUpdater<ClientCallTracer, ClientTracer>
|
private static final AtomicReferenceFieldUpdater<CallAttemptsTracerFactory, ClientTracer>
|
||||||
streamTracerUpdater;
|
streamTracerUpdater;
|
||||||
|
|
||||||
@Nullable private static final AtomicIntegerFieldUpdater<ClientCallTracer> callEndedUpdater;
|
@Nullable
|
||||||
|
private static final AtomicIntegerFieldUpdater<CallAttemptsTracerFactory> callEndedUpdater;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When using Atomic*FieldUpdater, some Samsung Android 5.0.x devices encounter a bug in their
|
* When using Atomic*FieldUpdater, some Samsung Android 5.0.x devices encounter a bug in their
|
||||||
|
|
@ -328,14 +334,14 @@ final class CensusStatsModule {
|
||||||
* (potentially racy) direct updates of the volatile variables.
|
* (potentially racy) direct updates of the volatile variables.
|
||||||
*/
|
*/
|
||||||
static {
|
static {
|
||||||
AtomicReferenceFieldUpdater<ClientCallTracer, ClientTracer> tmpStreamTracerUpdater;
|
AtomicReferenceFieldUpdater<CallAttemptsTracerFactory, ClientTracer> tmpStreamTracerUpdater;
|
||||||
AtomicIntegerFieldUpdater<ClientCallTracer> tmpCallEndedUpdater;
|
AtomicIntegerFieldUpdater<CallAttemptsTracerFactory> tmpCallEndedUpdater;
|
||||||
try {
|
try {
|
||||||
tmpStreamTracerUpdater =
|
tmpStreamTracerUpdater =
|
||||||
AtomicReferenceFieldUpdater.newUpdater(
|
AtomicReferenceFieldUpdater.newUpdater(
|
||||||
ClientCallTracer.class, ClientTracer.class, "streamTracer");
|
CallAttemptsTracerFactory.class, ClientTracer.class, "streamTracer");
|
||||||
tmpCallEndedUpdater =
|
tmpCallEndedUpdater =
|
||||||
AtomicIntegerFieldUpdater.newUpdater(ClientCallTracer.class, "callEnded");
|
AtomicIntegerFieldUpdater.newUpdater(CallAttemptsTracerFactory.class, "callEnded");
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
logger.log(Level.SEVERE, "Creating atomic field updaters failed", t);
|
logger.log(Level.SEVERE, "Creating atomic field updaters failed", t);
|
||||||
tmpStreamTracerUpdater = null;
|
tmpStreamTracerUpdater = null;
|
||||||
|
|
@ -352,7 +358,8 @@ final class CensusStatsModule {
|
||||||
private final TagContext parentCtx;
|
private final TagContext parentCtx;
|
||||||
private final TagContext startCtx;
|
private final TagContext startCtx;
|
||||||
|
|
||||||
ClientCallTracer(CensusStatsModule module, TagContext parentCtx, String fullMethodName) {
|
CallAttemptsTracerFactory(
|
||||||
|
CensusStatsModule module, TagContext parentCtx, String fullMethodName) {
|
||||||
this.module = checkNotNull(module);
|
this.module = checkNotNull(module);
|
||||||
this.parentCtx = checkNotNull(parentCtx);
|
this.parentCtx = checkNotNull(parentCtx);
|
||||||
TagValue methodTag = TagValue.create(fullMethodName);
|
TagValue methodTag = TagValue.create(fullMethodName);
|
||||||
|
|
@ -370,7 +377,7 @@ final class CensusStatsModule {
|
||||||
@Override
|
@Override
|
||||||
public ClientStreamTracer newClientStreamTracer(
|
public ClientStreamTracer newClientStreamTracer(
|
||||||
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
||||||
ClientTracer tracer = new ClientTracer(module, startCtx);
|
ClientTracer tracer = new ClientTracer(module, parentCtx, startCtx);
|
||||||
// TODO(zhangkun83): Once retry or hedging is implemented, a ClientCall may start more than
|
// TODO(zhangkun83): Once retry or hedging is implemented, a ClientCall may start more than
|
||||||
// one streams. We will need to update this file to support them.
|
// one streams. We will need to update this file to support them.
|
||||||
if (streamTracerUpdater != null) {
|
if (streamTracerUpdater != null) {
|
||||||
|
|
@ -383,12 +390,6 @@ final class CensusStatsModule {
|
||||||
"Are you creating multiple streams per call? This class doesn't yet support this case");
|
"Are you creating multiple streams per call? This class doesn't yet support this case");
|
||||||
streamTracer = tracer;
|
streamTracer = tracer;
|
||||||
}
|
}
|
||||||
if (module.propagateTags) {
|
|
||||||
headers.discardAll(module.statsHeader);
|
|
||||||
if (!module.tagger.empty().equals(parentCtx)) {
|
|
||||||
headers.put(module.statsHeader, parentCtx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tracer;
|
return tracer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -416,7 +417,7 @@ final class CensusStatsModule {
|
||||||
long roundtripNanos = stopwatch.elapsed(TimeUnit.NANOSECONDS);
|
long roundtripNanos = stopwatch.elapsed(TimeUnit.NANOSECONDS);
|
||||||
ClientTracer tracer = streamTracer;
|
ClientTracer tracer = streamTracer;
|
||||||
if (tracer == null) {
|
if (tracer == null) {
|
||||||
tracer = new ClientTracer(module, startCtx);
|
tracer = new ClientTracer(module, parentCtx, startCtx);
|
||||||
}
|
}
|
||||||
MeasureMap measureMap = module.statsRecorder.newMeasureMap()
|
MeasureMap measureMap = module.statsRecorder.newMeasureMap()
|
||||||
// TODO(songya): remove the deprecated measure constants once they are completed removed.
|
// TODO(songya): remove the deprecated measure constants once they are completed removed.
|
||||||
|
|
@ -686,8 +687,8 @@ final class CensusStatsModule {
|
||||||
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
|
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
|
||||||
// New RPCs on client-side inherit the tag context from the current Context.
|
// New RPCs on client-side inherit the tag context from the current Context.
|
||||||
TagContext parentCtx = tagger.getCurrentTagContext();
|
TagContext parentCtx = tagger.getCurrentTagContext();
|
||||||
final ClientCallTracer tracerFactory =
|
final CallAttemptsTracerFactory tracerFactory = new CallAttemptsTracerFactory(
|
||||||
newClientCallTracer(parentCtx, method.getFullMethodName());
|
CensusStatsModule.this, parentCtx, method.getFullMethodName());
|
||||||
ClientCall<ReqT, RespT> call =
|
ClientCall<ReqT, RespT> call =
|
||||||
next.newCall(method, callOptions.withStreamTracerFactory(tracerFactory));
|
next.newCall(method, callOptions.withStreamTracerFactory(tracerFactory));
|
||||||
return new SimpleForwardingClientCall<ReqT, RespT>(call) {
|
return new SimpleForwardingClientCall<ReqT, RespT>(call) {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package io.grpc.census;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.Channel;
|
import io.grpc.Channel;
|
||||||
import io.grpc.ClientCall;
|
import io.grpc.ClientCall;
|
||||||
|
|
@ -222,7 +223,7 @@ final class CensusTracingModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final class ClientCallTracer extends ClientStreamTracer.Factory {
|
final class ClientCallTracer extends ClientStreamTracer.InternalLimitedInfoFactory {
|
||||||
volatile int callEnded;
|
volatile int callEnded;
|
||||||
|
|
||||||
private final boolean isSampledToLocalTracing;
|
private final boolean isSampledToLocalTracing;
|
||||||
|
|
@ -243,11 +244,7 @@ final class CensusTracingModule {
|
||||||
@Override
|
@Override
|
||||||
public ClientStreamTracer newClientStreamTracer(
|
public ClientStreamTracer newClientStreamTracer(
|
||||||
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
||||||
if (span != BlankSpan.INSTANCE) {
|
return new ClientTracer(span, tracingHeader);
|
||||||
headers.discardAll(tracingHeader);
|
|
||||||
headers.put(tracingHeader, span.getContext());
|
|
||||||
}
|
|
||||||
return new ClientTracer(span);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -273,9 +270,19 @@ final class CensusTracingModule {
|
||||||
|
|
||||||
private static final class ClientTracer extends ClientStreamTracer {
|
private static final class ClientTracer extends ClientStreamTracer {
|
||||||
private final Span span;
|
private final Span span;
|
||||||
|
final Metadata.Key<SpanContext> tracingHeader;
|
||||||
|
|
||||||
ClientTracer(Span span) {
|
ClientTracer(Span span, Metadata.Key<SpanContext> tracingHeader) {
|
||||||
this.span = checkNotNull(span, "span");
|
this.span = checkNotNull(span, "span");
|
||||||
|
this.tracingHeader = tracingHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamCreated(Attributes transportAtts, Metadata headers) {
|
||||||
|
if (span != BlankSpan.INSTANCE) {
|
||||||
|
headers.discardAll(tracingHeader);
|
||||||
|
headers.put(tracingHeader, span.getContext());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -295,7 +295,7 @@ public class CensusModulesTest {
|
||||||
instanceof CensusTracingModule.ClientCallTracer);
|
instanceof CensusTracingModule.ClientCallTracer);
|
||||||
assertTrue(
|
assertTrue(
|
||||||
capturedCallOptions.get().getStreamTracerFactories().get(1)
|
capturedCallOptions.get().getStreamTracerFactories().get(1)
|
||||||
instanceof CensusStatsModule.ClientCallTracer);
|
instanceof CensusStatsModule.CallAttemptsTracerFactory);
|
||||||
|
|
||||||
// Make the call
|
// Make the call
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
|
|
@ -388,11 +388,12 @@ public class CensusModulesTest {
|
||||||
new CensusStatsModule(
|
new CensusStatsModule(
|
||||||
tagger, tagCtxSerializer, statsRecorder, fakeClock.getStopwatchSupplier(),
|
tagger, tagCtxSerializer, statsRecorder, fakeClock.getStopwatchSupplier(),
|
||||||
true, recordStarts, recordFinishes, recordRealTime);
|
true, recordStarts, recordFinishes, recordRealTime);
|
||||||
CensusStatsModule.ClientCallTracer callTracer =
|
CensusStatsModule.CallAttemptsTracerFactory callAttemptsTracerFactory =
|
||||||
localCensusStats.newClientCallTracer(
|
new CensusStatsModule.CallAttemptsTracerFactory(
|
||||||
tagger.empty(), method.getFullMethodName());
|
localCensusStats, tagger.empty(), method.getFullMethodName());
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
ClientStreamTracer tracer = callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
ClientStreamTracer tracer =
|
||||||
|
callAttemptsTracerFactory.newClientStreamTracer(STREAM_INFO, headers);
|
||||||
|
|
||||||
if (recordStarts) {
|
if (recordStarts) {
|
||||||
StatsTestUtils.MetricsRecord record = statsRecorder.pollRecord();
|
StatsTestUtils.MetricsRecord record = statsRecorder.pollRecord();
|
||||||
|
|
@ -455,7 +456,7 @@ public class CensusModulesTest {
|
||||||
|
|
||||||
tracer.inboundUncompressedSize(552);
|
tracer.inboundUncompressedSize(552);
|
||||||
tracer.streamClosed(Status.OK);
|
tracer.streamClosed(Status.OK);
|
||||||
callTracer.callEnded(Status.OK);
|
callAttemptsTracerFactory.callEnded(Status.OK);
|
||||||
|
|
||||||
if (recordFinishes) {
|
if (recordFinishes) {
|
||||||
StatsTestUtils.MetricsRecord record = statsRecorder.pollRecord();
|
StatsTestUtils.MetricsRecord record = statsRecorder.pollRecord();
|
||||||
|
|
@ -522,6 +523,7 @@ public class CensusModulesTest {
|
||||||
censusTracing.newClientCallTracer(null, method);
|
censusTracing.newClientCallTracer(null, method);
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
ClientStreamTracer clientStreamTracer = callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
ClientStreamTracer clientStreamTracer = callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
||||||
|
clientStreamTracer.streamCreated(Attributes.EMPTY, headers);
|
||||||
verify(tracer).spanBuilderWithExplicitParent(
|
verify(tracer).spanBuilderWithExplicitParent(
|
||||||
eq("Sent.package1.service2.method3"), ArgumentMatchers.<Span>isNull());
|
eq("Sent.package1.service2.method3"), ArgumentMatchers.<Span>isNull());
|
||||||
verify(spyClientSpan, never()).end(any(EndSpanOptions.class));
|
verify(spyClientSpan, never()).end(any(EndSpanOptions.class));
|
||||||
|
|
@ -575,11 +577,15 @@ public class CensusModulesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void clientStreamNeverCreatedStillRecordStats() {
|
public void clientStreamNeverCreatedStillRecordStats() {
|
||||||
CensusStatsModule.ClientCallTracer callTracer =
|
CensusStatsModule.CallAttemptsTracerFactory callAttemptsTracerFactory =
|
||||||
censusStats.newClientCallTracer(tagger.empty(), method.getFullMethodName());
|
new CensusStatsModule.CallAttemptsTracerFactory(
|
||||||
|
censusStats, tagger.empty(), method.getFullMethodName());
|
||||||
|
ClientStreamTracer streamTracer =
|
||||||
|
callAttemptsTracerFactory.newClientStreamTracer(STREAM_INFO, new Metadata());
|
||||||
fakeClock.forwardTime(3000, MILLISECONDS);
|
fakeClock.forwardTime(3000, MILLISECONDS);
|
||||||
callTracer.callEnded(Status.DEADLINE_EXCEEDED.withDescription("3 seconds"));
|
Status status = Status.DEADLINE_EXCEEDED.withDescription("3 seconds");
|
||||||
|
streamTracer.streamClosed(status);
|
||||||
|
callAttemptsTracerFactory.callEnded(status);
|
||||||
|
|
||||||
// Upstart record
|
// Upstart record
|
||||||
StatsTestUtils.MetricsRecord record = statsRecorder.pollRecord();
|
StatsTestUtils.MetricsRecord record = statsRecorder.pollRecord();
|
||||||
|
|
@ -680,10 +686,13 @@ public class CensusModulesTest {
|
||||||
fakeClock.getStopwatchSupplier(),
|
fakeClock.getStopwatchSupplier(),
|
||||||
propagate, recordStats, recordStats, recordStats);
|
propagate, recordStats, recordStats, recordStats);
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
CensusStatsModule.ClientCallTracer callTracer =
|
CensusStatsModule.CallAttemptsTracerFactory callAttemptsTracerFactory =
|
||||||
census.newClientCallTracer(clientCtx, method.getFullMethodName());
|
new CensusStatsModule.CallAttemptsTracerFactory(
|
||||||
|
census, clientCtx, method.getFullMethodName());
|
||||||
// This propagates clientCtx to headers if propagates==true
|
// This propagates clientCtx to headers if propagates==true
|
||||||
callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
ClientStreamTracer streamTracer =
|
||||||
|
callAttemptsTracerFactory.newClientStreamTracer(STREAM_INFO, headers);
|
||||||
|
streamTracer.streamCreated(Attributes.EMPTY, headers);
|
||||||
if (recordStats) {
|
if (recordStats) {
|
||||||
// Client upstart record
|
// Client upstart record
|
||||||
StatsTestUtils.MetricsRecord clientRecord = statsRecorder.pollRecord();
|
StatsTestUtils.MetricsRecord clientRecord = statsRecorder.pollRecord();
|
||||||
|
|
@ -746,7 +755,8 @@ public class CensusModulesTest {
|
||||||
|
|
||||||
// Verifies that the client tracer factory uses clientCtx, which includes the custom tags, to
|
// Verifies that the client tracer factory uses clientCtx, which includes the custom tags, to
|
||||||
// record stats.
|
// record stats.
|
||||||
callTracer.callEnded(Status.OK);
|
streamTracer.streamClosed(Status.OK);
|
||||||
|
callAttemptsTracerFactory.callEnded(Status.OK);
|
||||||
|
|
||||||
if (recordStats) {
|
if (recordStats) {
|
||||||
// Client completion record
|
// Client completion record
|
||||||
|
|
@ -769,10 +779,12 @@ public class CensusModulesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void statsHeadersNotPropagateDefaultContext() {
|
public void statsHeadersNotPropagateDefaultContext() {
|
||||||
CensusStatsModule.ClientCallTracer callTracer =
|
CensusStatsModule.CallAttemptsTracerFactory callAttemptsTracerFactory =
|
||||||
censusStats.newClientCallTracer(tagger.empty(), method.getFullMethodName());
|
new CensusStatsModule.CallAttemptsTracerFactory(
|
||||||
|
censusStats, tagger.empty(), method.getFullMethodName());
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
callAttemptsTracerFactory.newClientStreamTracer(STREAM_INFO, headers)
|
||||||
|
.streamCreated(Attributes.EMPTY, headers);
|
||||||
assertFalse(headers.containsKey(censusStats.statsHeader));
|
assertFalse(headers.containsKey(censusStats.statsHeader));
|
||||||
// Clear recorded stats to satisfy the assertions in wrapUp()
|
// Clear recorded stats to satisfy the assertions in wrapUp()
|
||||||
statsRecorder.rolloverRecords();
|
statsRecorder.rolloverRecords();
|
||||||
|
|
@ -803,7 +815,8 @@ public class CensusModulesTest {
|
||||||
CensusTracingModule.ClientCallTracer callTracer =
|
CensusTracingModule.ClientCallTracer callTracer =
|
||||||
censusTracing.newClientCallTracer(fakeClientParentSpan, method);
|
censusTracing.newClientCallTracer(fakeClientParentSpan, method);
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
ClientStreamTracer streamTracer = callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
||||||
|
streamTracer.streamCreated(Attributes.EMPTY, headers);
|
||||||
|
|
||||||
verify(mockTracingPropagationHandler).toByteArray(same(fakeClientSpanContext));
|
verify(mockTracingPropagationHandler).toByteArray(same(fakeClientSpanContext));
|
||||||
verifyNoMoreInteractions(mockTracingPropagationHandler);
|
verifyNoMoreInteractions(mockTracingPropagationHandler);
|
||||||
|
|
@ -831,7 +844,8 @@ public class CensusModulesTest {
|
||||||
censusTracing.newClientCallTracer(fakeClientParentSpan, method);
|
censusTracing.newClientCallTracer(fakeClientParentSpan, method);
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
|
|
||||||
callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
ClientStreamTracer streamTracer = callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
||||||
|
streamTracer.streamCreated(Attributes.EMPTY, headers);
|
||||||
|
|
||||||
assertThat(headers.keys()).isNotEmpty();
|
assertThat(headers.keys()).isNotEmpty();
|
||||||
}
|
}
|
||||||
|
|
@ -845,7 +859,7 @@ public class CensusModulesTest {
|
||||||
|
|
||||||
CensusTracingModule.ClientCallTracer callTracer =
|
CensusTracingModule.ClientCallTracer callTracer =
|
||||||
censusTracing.newClientCallTracer(BlankSpan.INSTANCE, method);
|
censusTracing.newClientCallTracer(BlankSpan.INSTANCE, method);
|
||||||
callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
callTracer.newClientStreamTracer(STREAM_INFO, headers).streamCreated(Attributes.EMPTY, headers);
|
||||||
|
|
||||||
assertThat(headers.keys()).isEmpty();
|
assertThat(headers.keys()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
@ -862,7 +876,7 @@ public class CensusModulesTest {
|
||||||
|
|
||||||
CensusTracingModule.ClientCallTracer callTracer =
|
CensusTracingModule.ClientCallTracer callTracer =
|
||||||
censusTracing.newClientCallTracer(BlankSpan.INSTANCE, method);
|
censusTracing.newClientCallTracer(BlankSpan.INSTANCE, method);
|
||||||
callTracer.newClientStreamTracer(STREAM_INFO, headers);
|
callTracer.newClientStreamTracer(STREAM_INFO, headers).streamCreated(Attributes.EMPTY, headers);
|
||||||
|
|
||||||
assertThat(headers.keys()).containsExactlyElementsIn(originalHeaderKeys);
|
assertThat(headers.keys()).containsExactlyElementsIn(originalHeaderKeys);
|
||||||
}
|
}
|
||||||
|
|
@ -1186,13 +1200,18 @@ public class CensusModulesTest {
|
||||||
tagger, tagCtxSerializer, localStats.getStatsRecorder(), fakeClock.getStopwatchSupplier(),
|
tagger, tagCtxSerializer, localStats.getStatsRecorder(), fakeClock.getStopwatchSupplier(),
|
||||||
false, false, true, false /* real-time */);
|
false, false, true, false /* real-time */);
|
||||||
|
|
||||||
CensusStatsModule.ClientCallTracer callTracer =
|
CensusStatsModule.CallAttemptsTracerFactory callAttemptsTracerFactory =
|
||||||
localCensusStats.newClientCallTracer(
|
new CensusStatsModule.CallAttemptsTracerFactory(
|
||||||
tagger.empty(), method.getFullMethodName());
|
localCensusStats, tagger.empty(), method.getFullMethodName());
|
||||||
|
|
||||||
callTracer.newClientStreamTracer(STREAM_INFO, new Metadata());
|
Metadata headers = new Metadata();
|
||||||
|
ClientStreamTracer tracer =
|
||||||
|
callAttemptsTracerFactory.newClientStreamTracer(STREAM_INFO, headers);
|
||||||
|
tracer.streamCreated(Attributes.EMPTY, headers);
|
||||||
fakeClock.forwardTime(30, MILLISECONDS);
|
fakeClock.forwardTime(30, MILLISECONDS);
|
||||||
callTracer.callEnded(Status.PERMISSION_DENIED.withDescription("No you don't"));
|
Status status = Status.PERMISSION_DENIED.withDescription("No you don't");
|
||||||
|
tracer.streamClosed(status);
|
||||||
|
callAttemptsTracerFactory.callEnded(status);
|
||||||
|
|
||||||
// Give OpenCensus a chance to update the views asynchronously.
|
// Give OpenCensus a chance to update the views asynchronously.
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
package io.grpc.internal;
|
package io.grpc.internal;
|
||||||
|
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.MethodDescriptor;
|
import io.grpc.MethodDescriptor;
|
||||||
import io.grpc.ServerStreamTracer;
|
import io.grpc.ServerStreamTracer;
|
||||||
|
|
@ -50,7 +50,8 @@ public class StatsTraceContextBenchmark {
|
||||||
@BenchmarkMode(Mode.SampleTime)
|
@BenchmarkMode(Mode.SampleTime)
|
||||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
public StatsTraceContext newClientContext() {
|
public StatsTraceContext newClientContext() {
|
||||||
return StatsTraceContext.newClientContext(CallOptions.DEFAULT, Attributes.EMPTY, emptyMetadata);
|
return StatsTraceContext.newClientContext(
|
||||||
|
new ClientStreamTracer[] { new ClientStreamTracer() {} }, Attributes.EMPTY, emptyMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Compressor;
|
import io.grpc.Compressor;
|
||||||
import io.grpc.Deadline;
|
import io.grpc.Deadline;
|
||||||
import io.grpc.Decompressor;
|
import io.grpc.Decompressor;
|
||||||
|
|
@ -205,10 +206,12 @@ final class InProcessTransport implements ServerTransport, ConnectionClientTrans
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized ClientStream newStream(
|
public synchronized ClientStream newStream(
|
||||||
final MethodDescriptor<?, ?> method, final Metadata headers, final CallOptions callOptions) {
|
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
||||||
|
ClientStreamTracer[] tracers) {
|
||||||
|
StatsTraceContext statsTraceContext =
|
||||||
|
StatsTraceContext.newClientContext(tracers, getAttributes(), headers);
|
||||||
if (shutdownStatus != null) {
|
if (shutdownStatus != null) {
|
||||||
return failedClientStream(
|
return failedClientStream(statsTraceContext, shutdownStatus);
|
||||||
StatsTraceContext.newClientContext(callOptions, attributes, headers), shutdownStatus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
headers.put(GrpcUtil.USER_AGENT_KEY, userAgent);
|
headers.put(GrpcUtil.USER_AGENT_KEY, userAgent);
|
||||||
|
|
@ -226,12 +229,12 @@ final class InProcessTransport implements ServerTransport, ConnectionClientTrans
|
||||||
"Request metadata larger than %d: %d",
|
"Request metadata larger than %d: %d",
|
||||||
serverMaxInboundMetadataSize,
|
serverMaxInboundMetadataSize,
|
||||||
metadataSize));
|
metadataSize));
|
||||||
return failedClientStream(
|
return failedClientStream(statsTraceContext, status);
|
||||||
StatsTraceContext.newClientContext(callOptions, attributes, headers), status);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new InProcessStream(method, headers, callOptions, authority).clientStream;
|
return new InProcessStream(method, headers, callOptions, authority, statsTraceContext)
|
||||||
|
.clientStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientStream failedClientStream(
|
private ClientStream failedClientStream(
|
||||||
|
|
@ -377,12 +380,12 @@ final class InProcessTransport implements ServerTransport, ConnectionClientTrans
|
||||||
|
|
||||||
private InProcessStream(
|
private InProcessStream(
|
||||||
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
||||||
String authority) {
|
String authority , StatsTraceContext statsTraceContext) {
|
||||||
this.method = checkNotNull(method, "method");
|
this.method = checkNotNull(method, "method");
|
||||||
this.headers = checkNotNull(headers, "headers");
|
this.headers = checkNotNull(headers, "headers");
|
||||||
this.callOptions = checkNotNull(callOptions, "callOptions");
|
this.callOptions = checkNotNull(callOptions, "callOptions");
|
||||||
this.authority = authority;
|
this.authority = authority;
|
||||||
this.clientStream = new InProcessClientStream(callOptions, headers);
|
this.clientStream = new InProcessClientStream(callOptions, statsTraceContext);
|
||||||
this.serverStream = new InProcessServerStream(method, headers);
|
this.serverStream = new InProcessServerStream(method, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -673,9 +676,10 @@ final class InProcessTransport implements ServerTransport, ConnectionClientTrans
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private int outboundSeqNo;
|
private int outboundSeqNo;
|
||||||
|
|
||||||
InProcessClientStream(CallOptions callOptions, Metadata headers) {
|
InProcessClientStream(
|
||||||
|
CallOptions callOptions, StatsTraceContext statsTraceContext) {
|
||||||
this.callOptions = callOptions;
|
this.callOptions = callOptions;
|
||||||
statsTraceCtx = StatsTraceContext.newClientContext(callOptions, attributes, headers);
|
statsTraceCtx = statsTraceContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void setListener(ServerStreamListener listener) {
|
private synchronized void setListener(ServerStreamListener listener) {
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import io.grpc.CallCredentials.RequestInfo;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ChannelCredentials;
|
import io.grpc.ChannelCredentials;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.CompositeCallCredentials;
|
import io.grpc.CompositeCallCredentials;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.MethodDescriptor;
|
import io.grpc.MethodDescriptor;
|
||||||
|
|
@ -104,7 +105,8 @@ final class CallCredentialsApplyingTransportFactory implements ClientTransportFa
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public ClientStream newStream(
|
public ClientStream newStream(
|
||||||
final MethodDescriptor<?, ?> method, Metadata headers, final CallOptions callOptions) {
|
final MethodDescriptor<?, ?> method, Metadata headers, final CallOptions callOptions,
|
||||||
|
ClientStreamTracer[] tracers) {
|
||||||
CallCredentials creds = callOptions.getCredentials();
|
CallCredentials creds = callOptions.getCredentials();
|
||||||
if (creds == null) {
|
if (creds == null) {
|
||||||
creds = channelCallCredentials;
|
creds = channelCallCredentials;
|
||||||
|
|
@ -113,10 +115,10 @@ final class CallCredentialsApplyingTransportFactory implements ClientTransportFa
|
||||||
}
|
}
|
||||||
if (creds != null) {
|
if (creds != null) {
|
||||||
MetadataApplierImpl applier = new MetadataApplierImpl(
|
MetadataApplierImpl applier = new MetadataApplierImpl(
|
||||||
delegate, method, headers, callOptions, applierListener);
|
delegate, method, headers, callOptions, applierListener, tracers);
|
||||||
if (pendingApplier.incrementAndGet() > 0) {
|
if (pendingApplier.incrementAndGet() > 0) {
|
||||||
applierListener.onComplete();
|
applierListener.onComplete();
|
||||||
return new FailingClientStream(shutdownStatus);
|
return new FailingClientStream(shutdownStatus, tracers);
|
||||||
}
|
}
|
||||||
RequestInfo requestInfo = new RequestInfo() {
|
RequestInfo requestInfo = new RequestInfo() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -152,9 +154,9 @@ final class CallCredentialsApplyingTransportFactory implements ClientTransportFa
|
||||||
return applier.returnStream();
|
return applier.returnStream();
|
||||||
} else {
|
} else {
|
||||||
if (pendingApplier.get() >= 0) {
|
if (pendingApplier.get() >= 0) {
|
||||||
return new FailingClientStream(shutdownStatus);
|
return new FailingClientStream(shutdownStatus, tracers);
|
||||||
}
|
}
|
||||||
return delegate.newStream(method, headers, callOptions);
|
return delegate.newStream(method, headers, callOptions, tracers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import com.google.common.base.MoreObjects;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ClientCall;
|
import io.grpc.ClientCall;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Codec;
|
import io.grpc.Codec;
|
||||||
import io.grpc.Compressor;
|
import io.grpc.Compressor;
|
||||||
import io.grpc.CompressorRegistry;
|
import io.grpc.CompressorRegistry;
|
||||||
|
|
@ -254,9 +255,11 @@ final class ClientCallImpl<ReqT, RespT> extends ClientCall<ReqT, RespT> {
|
||||||
effectiveDeadline, context.getDeadline(), callOptions.getDeadline());
|
effectiveDeadline, context.getDeadline(), callOptions.getDeadline());
|
||||||
stream = clientStreamProvider.newStream(method, callOptions, headers, context);
|
stream = clientStreamProvider.newStream(method, callOptions, headers, context);
|
||||||
} else {
|
} else {
|
||||||
|
ClientStreamTracer[] tracers = GrpcUtil.getClientStreamTracers(callOptions, headers, false);
|
||||||
stream = new FailingClientStream(
|
stream = new FailingClientStream(
|
||||||
DEADLINE_EXCEEDED.withDescription(
|
DEADLINE_EXCEEDED.withDescription(
|
||||||
"ClientCall started after deadline exceeded: " + effectiveDeadline));
|
"ClientCall started after deadline exceeded: " + effectiveDeadline),
|
||||||
|
tracers);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callExecutorIsDirect) {
|
if (callExecutorIsDirect) {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package io.grpc.internal;
|
package io.grpc.internal;
|
||||||
|
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.InternalChannelz.SocketStats;
|
import io.grpc.InternalChannelz.SocketStats;
|
||||||
import io.grpc.InternalInstrumented;
|
import io.grpc.InternalInstrumented;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
|
@ -46,10 +47,15 @@ public interface ClientTransport extends InternalInstrumented<SocketStats> {
|
||||||
* @param method the descriptor of the remote method to be called for this stream.
|
* @param method the descriptor of the remote method to be called for this stream.
|
||||||
* @param headers to send at the beginning of the call
|
* @param headers to send at the beginning of the call
|
||||||
* @param callOptions runtime options of the call
|
* @param callOptions runtime options of the call
|
||||||
|
* @param tracers a non-empty array of tracers. The last element in it is reserved to be set by
|
||||||
|
* the load balancer's pick result and otherwise is a no-op tracer.
|
||||||
* @return the newly created stream.
|
* @return the newly created stream.
|
||||||
*/
|
*/
|
||||||
// TODO(nmittler): Consider also throwing for stopping.
|
// TODO(nmittler): Consider also throwing for stopping.
|
||||||
ClientStream newStream(MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions);
|
ClientStream newStream(
|
||||||
|
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
||||||
|
// Using array for tracers instead of a list or composition for better performance.
|
||||||
|
ClientStreamTracer[] tracers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pings a remote endpoint. When an acknowledgement is received, the given callback will be
|
* Pings a remote endpoint. When an acknowledgement is received, the given callback will be
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Context;
|
import io.grpc.Context;
|
||||||
import io.grpc.InternalChannelz.SocketStats;
|
import io.grpc.InternalChannelz.SocketStats;
|
||||||
import io.grpc.InternalLogId;
|
import io.grpc.InternalLogId;
|
||||||
|
|
@ -133,7 +134,8 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final ClientStream newStream(
|
public final ClientStream newStream(
|
||||||
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions) {
|
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
||||||
|
ClientStreamTracer[] tracers) {
|
||||||
try {
|
try {
|
||||||
PickSubchannelArgs args = new PickSubchannelArgsImpl(method, headers, callOptions);
|
PickSubchannelArgs args = new PickSubchannelArgsImpl(method, headers, callOptions);
|
||||||
SubchannelPicker picker = null;
|
SubchannelPicker picker = null;
|
||||||
|
|
@ -141,14 +143,14 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
while (true) {
|
while (true) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (shutdownStatus != null) {
|
if (shutdownStatus != null) {
|
||||||
return new FailingClientStream(shutdownStatus);
|
return new FailingClientStream(shutdownStatus, tracers);
|
||||||
}
|
}
|
||||||
if (lastPicker == null) {
|
if (lastPicker == null) {
|
||||||
return createPendingStream(args);
|
return createPendingStream(args, tracers);
|
||||||
}
|
}
|
||||||
// Check for second time through the loop, and whether anything changed
|
// Check for second time through the loop, and whether anything changed
|
||||||
if (picker != null && pickerVersion == lastPickerVersion) {
|
if (picker != null && pickerVersion == lastPickerVersion) {
|
||||||
return createPendingStream(args);
|
return createPendingStream(args, tracers);
|
||||||
}
|
}
|
||||||
picker = lastPicker;
|
picker = lastPicker;
|
||||||
pickerVersion = lastPickerVersion;
|
pickerVersion = lastPickerVersion;
|
||||||
|
|
@ -158,7 +160,8 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
callOptions.isWaitForReady());
|
callOptions.isWaitForReady());
|
||||||
if (transport != null) {
|
if (transport != null) {
|
||||||
return transport.newStream(
|
return transport.newStream(
|
||||||
args.getMethodDescriptor(), args.getHeaders(), args.getCallOptions());
|
args.getMethodDescriptor(), args.getHeaders(), args.getCallOptions(),
|
||||||
|
tracers);
|
||||||
}
|
}
|
||||||
// This picker's conclusion is "buffer". If there hasn't been a newer picker set (possible
|
// This picker's conclusion is "buffer". If there hasn't been a newer picker set (possible
|
||||||
// race with reprocess()), we will buffer it. Otherwise, will try with the new picker.
|
// race with reprocess()), we will buffer it. Otherwise, will try with the new picker.
|
||||||
|
|
@ -173,8 +176,9 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
* schedule tasks on syncContext.
|
* schedule tasks on syncContext.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
private PendingStream createPendingStream(PickSubchannelArgs args) {
|
private PendingStream createPendingStream(
|
||||||
PendingStream pendingStream = new PendingStream(args);
|
PickSubchannelArgs args, ClientStreamTracer[] tracers) {
|
||||||
|
PendingStream pendingStream = new PendingStream(args, tracers);
|
||||||
pendingStreams.add(pendingStream);
|
pendingStreams.add(pendingStream);
|
||||||
if (getPendingStreamsCount() == 1) {
|
if (getPendingStreamsCount() == 1) {
|
||||||
syncContext.executeLater(reportTransportInUse);
|
syncContext.executeLater(reportTransportInUse);
|
||||||
|
|
@ -239,7 +243,8 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
}
|
}
|
||||||
if (savedReportTransportTerminated != null) {
|
if (savedReportTransportTerminated != null) {
|
||||||
for (PendingStream stream : savedPendingStreams) {
|
for (PendingStream stream : savedPendingStreams) {
|
||||||
Runnable runnable = stream.setStream(new FailingClientStream(status, RpcProgress.REFUSED));
|
Runnable runnable = stream.setStream(
|
||||||
|
new FailingClientStream(status, RpcProgress.REFUSED, stream.tracers));
|
||||||
if (runnable != null) {
|
if (runnable != null) {
|
||||||
// Drain in-line instead of using an executor as failing stream just throws everything
|
// Drain in-line instead of using an executor as failing stream just throws everything
|
||||||
// away. This is essentially the same behavior as DelayedStream.cancel() but can be done
|
// away. This is essentially the same behavior as DelayedStream.cancel() but can be done
|
||||||
|
|
@ -346,9 +351,11 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
private class PendingStream extends DelayedStream {
|
private class PendingStream extends DelayedStream {
|
||||||
private final PickSubchannelArgs args;
|
private final PickSubchannelArgs args;
|
||||||
private final Context context = Context.current();
|
private final Context context = Context.current();
|
||||||
|
private final ClientStreamTracer[] tracers;
|
||||||
|
|
||||||
private PendingStream(PickSubchannelArgs args) {
|
private PendingStream(PickSubchannelArgs args, ClientStreamTracer[] tracers) {
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
this.tracers = tracers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Runnable may be null. */
|
/** Runnable may be null. */
|
||||||
|
|
@ -357,7 +364,8 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
Context origContext = context.attach();
|
Context origContext = context.attach();
|
||||||
try {
|
try {
|
||||||
realStream = transport.newStream(
|
realStream = transport.newStream(
|
||||||
args.getMethodDescriptor(), args.getHeaders(), args.getCallOptions());
|
args.getMethodDescriptor(), args.getHeaders(), args.getCallOptions(),
|
||||||
|
tracers);
|
||||||
} finally {
|
} finally {
|
||||||
context.detach(origContext);
|
context.detach(origContext);
|
||||||
}
|
}
|
||||||
|
|
@ -382,6 +390,13 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
syncContext.drain();
|
syncContext.drain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onEarlyCancellation(Status reason) {
|
||||||
|
for (ClientStreamTracer tracer : tracers) {
|
||||||
|
tracer.streamClosed(reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void appendTimeoutInsight(InsightBuilder insight) {
|
public void appendTimeoutInsight(InsightBuilder insight) {
|
||||||
if (args.getCallOptions().isWaitForReady()) {
|
if (args.getCallOptions().isWaitForReady()) {
|
||||||
|
|
|
||||||
|
|
@ -324,11 +324,15 @@ class DelayedStream implements ClientStream {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
drainPendingCalls();
|
drainPendingCalls();
|
||||||
|
onEarlyCancellation(reason);
|
||||||
// Note that listener is a DelayedStreamListener
|
// Note that listener is a DelayedStreamListener
|
||||||
listener.closed(reason, RpcProgress.PROCESSED, new Metadata());
|
listener.closed(reason, RpcProgress.PROCESSED, new Metadata());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void onEarlyCancellation(Status reason) {
|
||||||
|
}
|
||||||
|
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private void setRealStream(ClientStream realStream) {
|
private void setRealStream(ClientStream realStream) {
|
||||||
checkState(this.realStream == null, "realStream already set to %s", this.realStream);
|
checkState(this.realStream == null, "realStream already set to %s", this.realStream);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package io.grpc.internal;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.Status;
|
import io.grpc.Status;
|
||||||
import io.grpc.internal.ClientStreamListener.RpcProgress;
|
import io.grpc.internal.ClientStreamListener.RpcProgress;
|
||||||
|
|
@ -30,27 +31,33 @@ public final class FailingClientStream extends NoopClientStream {
|
||||||
private boolean started;
|
private boolean started;
|
||||||
private final Status error;
|
private final Status error;
|
||||||
private final RpcProgress rpcProgress;
|
private final RpcProgress rpcProgress;
|
||||||
|
private final ClientStreamTracer[] tracers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code FailingClientStream} that would fail with the given error.
|
* Creates a {@code FailingClientStream} that would fail with the given error.
|
||||||
*/
|
*/
|
||||||
public FailingClientStream(Status error) {
|
public FailingClientStream(Status error, ClientStreamTracer[] tracers) {
|
||||||
this(error, RpcProgress.PROCESSED);
|
this(error, RpcProgress.PROCESSED, tracers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code FailingClientStream} that would fail with the given error.
|
* Creates a {@code FailingClientStream} that would fail with the given error.
|
||||||
*/
|
*/
|
||||||
public FailingClientStream(Status error, RpcProgress rpcProgress) {
|
public FailingClientStream(
|
||||||
|
Status error, RpcProgress rpcProgress, ClientStreamTracer[] tracers) {
|
||||||
Preconditions.checkArgument(!error.isOk(), "error must not be OK");
|
Preconditions.checkArgument(!error.isOk(), "error must not be OK");
|
||||||
this.error = error;
|
this.error = error;
|
||||||
this.rpcProgress = rpcProgress;
|
this.rpcProgress = rpcProgress;
|
||||||
|
this.tracers = tracers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(ClientStreamListener listener) {
|
public void start(ClientStreamListener listener) {
|
||||||
Preconditions.checkState(!started, "already started");
|
Preconditions.checkState(!started, "already started");
|
||||||
started = true;
|
started = true;
|
||||||
|
for (ClientStreamTracer tracer : tracers) {
|
||||||
|
tracer.streamClosed(error);
|
||||||
|
}
|
||||||
listener.closed(error, rpcProgress, new Metadata());
|
listener.closed(error, rpcProgress, new Metadata());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import com.google.common.base.Preconditions;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.InternalChannelz.SocketStats;
|
import io.grpc.InternalChannelz.SocketStats;
|
||||||
import io.grpc.InternalLogId;
|
import io.grpc.InternalLogId;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
|
@ -45,8 +46,9 @@ class FailingClientTransport implements ClientTransport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientStream newStream(
|
public ClientStream newStream(
|
||||||
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions) {
|
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
||||||
return new FailingClientStream(error, rpcProgress);
|
ClientStreamTracer[] tracers) {
|
||||||
|
return new FailingClientStream(error, rpcProgress, tracers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 The gRPC Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.grpc.internal;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import io.grpc.Attributes;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
|
import io.grpc.Metadata;
|
||||||
|
import io.grpc.Status;
|
||||||
|
|
||||||
|
public abstract class ForwardingClientStreamTracer extends ClientStreamTracer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the underlying {@code ClientStreamTracer}.
|
||||||
|
*/
|
||||||
|
protected abstract ClientStreamTracer delegate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamCreated(Attributes transportAttrs, Metadata headers) {
|
||||||
|
delegate().streamCreated(transportAttrs, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void outboundHeaders() {
|
||||||
|
delegate().outboundHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inboundHeaders() {
|
||||||
|
delegate().inboundHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inboundTrailers(Metadata trailers) {
|
||||||
|
delegate().inboundTrailers(trailers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamClosed(Status status) {
|
||||||
|
delegate().streamClosed(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void outboundMessage(int seqNo) {
|
||||||
|
delegate().outboundMessage(seqNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inboundMessage(int seqNo) {
|
||||||
|
delegate().inboundMessage(seqNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void outboundMessageSent(int seqNo, long optionalWireSize, long optionalUncompressedSize) {
|
||||||
|
delegate().outboundMessageSent(seqNo, optionalWireSize, optionalUncompressedSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inboundMessageRead(int seqNo, long optionalWireSize, long optionalUncompressedSize) {
|
||||||
|
delegate().inboundMessageRead(seqNo, optionalWireSize, optionalUncompressedSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void outboundWireSize(long bytes) {
|
||||||
|
delegate().outboundWireSize(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void outboundUncompressedSize(long bytes) {
|
||||||
|
delegate().outboundUncompressedSize(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inboundWireSize(long bytes) {
|
||||||
|
delegate().inboundWireSize(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inboundUncompressedSize(long bytes) {
|
||||||
|
delegate().inboundUncompressedSize(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this).add("delegate", delegate()).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,7 @@ import com.google.common.base.MoreObjects;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.InternalChannelz.SocketStats;
|
import io.grpc.InternalChannelz.SocketStats;
|
||||||
import io.grpc.InternalLogId;
|
import io.grpc.InternalLogId;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
|
@ -45,8 +46,9 @@ abstract class ForwardingConnectionClientTransport implements ConnectionClientTr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientStream newStream(
|
public ClientStream newStream(
|
||||||
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions) {
|
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
||||||
return delegate().newStream(method, headers, callOptions);
|
ClientStreamTracer[] tracers) {
|
||||||
|
return delegate().newStream(method, headers, callOptions, tracers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package io.grpc.internal;
|
package io.grpc.internal;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
|
@ -26,8 +27,11 @@ import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ClientStreamTracer;
|
import io.grpc.ClientStreamTracer;
|
||||||
|
import io.grpc.ClientStreamTracer.InternalLimitedInfoFactory;
|
||||||
|
import io.grpc.ClientStreamTracer.StreamInfo;
|
||||||
import io.grpc.InternalChannelz.SocketStats;
|
import io.grpc.InternalChannelz.SocketStats;
|
||||||
import io.grpc.InternalLogId;
|
import io.grpc.InternalLogId;
|
||||||
import io.grpc.InternalMetadata;
|
import io.grpc.InternalMetadata;
|
||||||
|
|
@ -54,12 +58,14 @@ import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
@ -253,6 +259,8 @@ public final class GrpcUtil {
|
||||||
public static final CallOptions.Key<Boolean> CALL_OPTIONS_RPC_OWNED_BY_BALANCER =
|
public static final CallOptions.Key<Boolean> CALL_OPTIONS_RPC_OWNED_BY_BALANCER =
|
||||||
CallOptions.Key.create("io.grpc.internal.CALL_OPTIONS_RPC_OWNED_BY_BALANCER");
|
CallOptions.Key.create("io.grpc.internal.CALL_OPTIONS_RPC_OWNED_BY_BALANCER");
|
||||||
|
|
||||||
|
private static final ClientStreamTracer NOOP_TRACER = new ClientStreamTracer() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if an RPC with the given properties should be counted when calculating the
|
* Returns true if an RPC with the given properties should be counted when calculating the
|
||||||
* in-use state of a transport.
|
* in-use state of a transport.
|
||||||
|
|
@ -711,9 +719,14 @@ public final class GrpcUtil {
|
||||||
return new ClientTransport() {
|
return new ClientTransport() {
|
||||||
@Override
|
@Override
|
||||||
public ClientStream newStream(
|
public ClientStream newStream(
|
||||||
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions) {
|
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
||||||
return transport.newStream(
|
ClientStreamTracer[] tracers) {
|
||||||
method, headers, callOptions.withStreamTracerFactory(streamTracerFactory));
|
StreamInfo info = StreamInfo.newBuilder().setCallOptions(callOptions).build();
|
||||||
|
ClientStreamTracer streamTracer =
|
||||||
|
newClientStreamTracer(streamTracerFactory, info, headers);
|
||||||
|
checkState(tracers[tracers.length - 1] == NOOP_TRACER, "lb tracer already assigned");
|
||||||
|
tracers[tracers.length - 1] = streamTracer;
|
||||||
|
return transport.newStream(method, headers, callOptions, tracers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -743,6 +756,64 @@ public final class GrpcUtil {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets stream tracers based on CallOptions. */
|
||||||
|
public static ClientStreamTracer[] getClientStreamTracers(
|
||||||
|
CallOptions callOptions, Metadata headers, boolean isTransparentRetry) {
|
||||||
|
List<ClientStreamTracer.Factory> factories = callOptions.getStreamTracerFactories();
|
||||||
|
ClientStreamTracer[] tracers = new ClientStreamTracer[factories.size() + 1];
|
||||||
|
StreamInfo streamInfo = StreamInfo.newBuilder()
|
||||||
|
.setCallOptions(callOptions)
|
||||||
|
.setIsTransparentRetry(isTransparentRetry)
|
||||||
|
.build();
|
||||||
|
for (int i = 0; i < factories.size(); i++) {
|
||||||
|
tracers[i] = newClientStreamTracer(factories.get(i), streamInfo, headers);
|
||||||
|
}
|
||||||
|
// Reserved to be set later by the lb as per the API contract of ClientTransport.newStream().
|
||||||
|
// See also GrpcUtil.getTransportFromPickResult()
|
||||||
|
tracers[tracers.length - 1] = NOOP_TRACER;
|
||||||
|
return tracers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A util function for backward compatibility to support deprecated StreamInfo.getAttributes().
|
||||||
|
@VisibleForTesting
|
||||||
|
static ClientStreamTracer newClientStreamTracer(
|
||||||
|
final ClientStreamTracer.Factory streamTracerFactory, final StreamInfo info,
|
||||||
|
final Metadata headers) {
|
||||||
|
ClientStreamTracer streamTracer;
|
||||||
|
if (streamTracerFactory instanceof InternalLimitedInfoFactory) {
|
||||||
|
streamTracer = streamTracerFactory.newClientStreamTracer(info, headers);
|
||||||
|
} else {
|
||||||
|
streamTracer = new ForwardingClientStreamTracer() {
|
||||||
|
final ClientStreamTracer noop = new ClientStreamTracer() {};
|
||||||
|
AtomicReference<ClientStreamTracer> delegate = new AtomicReference<>(noop);
|
||||||
|
|
||||||
|
void maybeInit(StreamInfo info, Metadata headers) {
|
||||||
|
delegate.compareAndSet(noop, streamTracerFactory.newClientStreamTracer(info, headers));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClientStreamTracer delegate() {
|
||||||
|
return delegate.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public void streamCreated(Attributes transportAttrs, Metadata headers) {
|
||||||
|
StreamInfo streamInfo = info.toBuilder().setTransportAttrs(transportAttrs).build();
|
||||||
|
maybeInit(streamInfo, headers);
|
||||||
|
delegate().streamCreated(transportAttrs, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamClosed(Status status) {
|
||||||
|
maybeInit(info, headers);
|
||||||
|
delegate().streamClosed(status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return streamTracer;
|
||||||
|
}
|
||||||
|
|
||||||
/** Quietly closes all messages in MessageProducer. */
|
/** Quietly closes all messages in MessageProducer. */
|
||||||
static void closeQuietly(MessageProducer producer) {
|
static void closeQuietly(MessageProducer producer) {
|
||||||
InputStream message;
|
InputStream message;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
import io.grpc.ChannelLogger.ChannelLogLevel;
|
import io.grpc.ChannelLogger.ChannelLogLevel;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.ConnectivityState;
|
import io.grpc.ConnectivityState;
|
||||||
import io.grpc.ConnectivityStateInfo;
|
import io.grpc.ConnectivityStateInfo;
|
||||||
import io.grpc.EquivalentAddressGroup;
|
import io.grpc.EquivalentAddressGroup;
|
||||||
|
|
@ -667,8 +668,9 @@ final class InternalSubchannel implements InternalInstrumented<ChannelStats>, Tr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientStream newStream(
|
public ClientStream newStream(
|
||||||
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions) {
|
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
||||||
final ClientStream streamDelegate = super.newStream(method, headers, callOptions);
|
ClientStreamTracer[] tracers) {
|
||||||
|
final ClientStream streamDelegate = super.newStream(method, headers, callOptions, tracers);
|
||||||
return new ForwardingClientStream() {
|
return new ForwardingClientStream() {
|
||||||
@Override
|
@Override
|
||||||
protected ClientStream delegate() {
|
protected ClientStream delegate() {
|
||||||
|
|
|
||||||
|
|
@ -532,8 +532,10 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
||||||
ClientTransport transport =
|
ClientTransport transport =
|
||||||
getTransport(new PickSubchannelArgsImpl(method, headers, callOptions));
|
getTransport(new PickSubchannelArgsImpl(method, headers, callOptions));
|
||||||
Context origContext = context.attach();
|
Context origContext = context.attach();
|
||||||
|
ClientStreamTracer[] tracers = GrpcUtil.getClientStreamTracers(
|
||||||
|
callOptions, headers, /* isTransparentRetry= */ false);
|
||||||
try {
|
try {
|
||||||
return transport.newStream(method, headers, callOptions);
|
return transport.newStream(method, headers, callOptions, tracers);
|
||||||
} finally {
|
} finally {
|
||||||
context.detach(origContext);
|
context.detach(origContext);
|
||||||
}
|
}
|
||||||
|
|
@ -569,13 +571,16 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ClientStream newSubstream(ClientStreamTracer.Factory tracerFactory, Metadata newHeaders) {
|
ClientStream newSubstream(
|
||||||
CallOptions newOptions = callOptions.withStreamTracerFactory(tracerFactory);
|
Metadata newHeaders, ClientStreamTracer.Factory factory, boolean isTransparentRetry) {
|
||||||
|
CallOptions newOptions = callOptions.withStreamTracerFactory(factory);
|
||||||
|
ClientStreamTracer[] tracers =
|
||||||
|
GrpcUtil.getClientStreamTracers(newOptions, newHeaders, isTransparentRetry);
|
||||||
ClientTransport transport =
|
ClientTransport transport =
|
||||||
getTransport(new PickSubchannelArgsImpl(method, newHeaders, newOptions));
|
getTransport(new PickSubchannelArgsImpl(method, newHeaders, newOptions));
|
||||||
Context origContext = context.attach();
|
Context origContext = context.attach();
|
||||||
try {
|
try {
|
||||||
return transport.newStream(method, newHeaders, newOptions);
|
return transport.newStream(method, newHeaders, newOptions, tracers);
|
||||||
} finally {
|
} finally {
|
||||||
context.detach(origContext);
|
context.detach(origContext);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
import io.grpc.CallCredentials.MetadataApplier;
|
import io.grpc.CallCredentials.MetadataApplier;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Context;
|
import io.grpc.Context;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.MethodDescriptor;
|
import io.grpc.MethodDescriptor;
|
||||||
|
|
@ -36,7 +37,7 @@ final class MetadataApplierImpl extends MetadataApplier {
|
||||||
private final CallOptions callOptions;
|
private final CallOptions callOptions;
|
||||||
private final Context ctx;
|
private final Context ctx;
|
||||||
private final MetadataApplierListener listener;
|
private final MetadataApplierListener listener;
|
||||||
|
private final ClientStreamTracer[] tracers;
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
|
|
||||||
// null if neither apply() or returnStream() are called.
|
// null if neither apply() or returnStream() are called.
|
||||||
|
|
@ -52,13 +53,14 @@ final class MetadataApplierImpl extends MetadataApplier {
|
||||||
|
|
||||||
MetadataApplierImpl(
|
MetadataApplierImpl(
|
||||||
ClientTransport transport, MethodDescriptor<?, ?> method, Metadata origHeaders,
|
ClientTransport transport, MethodDescriptor<?, ?> method, Metadata origHeaders,
|
||||||
CallOptions callOptions, MetadataApplierListener listener) {
|
CallOptions callOptions, MetadataApplierListener listener, ClientStreamTracer[] tracers) {
|
||||||
this.transport = transport;
|
this.transport = transport;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.origHeaders = origHeaders;
|
this.origHeaders = origHeaders;
|
||||||
this.callOptions = callOptions;
|
this.callOptions = callOptions;
|
||||||
this.ctx = Context.current();
|
this.ctx = Context.current();
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
|
this.tracers = tracers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -69,7 +71,7 @@ final class MetadataApplierImpl extends MetadataApplier {
|
||||||
ClientStream realStream;
|
ClientStream realStream;
|
||||||
Context origCtx = ctx.attach();
|
Context origCtx = ctx.attach();
|
||||||
try {
|
try {
|
||||||
realStream = transport.newStream(method, origHeaders, callOptions);
|
realStream = transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
} finally {
|
} finally {
|
||||||
ctx.detach(origCtx);
|
ctx.detach(origCtx);
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +82,7 @@ final class MetadataApplierImpl extends MetadataApplier {
|
||||||
public void fail(Status status) {
|
public void fail(Status status) {
|
||||||
checkArgument(!status.isOk(), "Cannot fail with OK status");
|
checkArgument(!status.isOk(), "Cannot fail with OK status");
|
||||||
checkState(!finalized, "apply() or fail() already called");
|
checkState(!finalized, "apply() or fail() already called");
|
||||||
finalizeWith(new FailingClientStream(status));
|
finalizeWith(new FailingClientStream(status, tracers));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finalizeWith(ClientStream stream) {
|
private void finalizeWith(ClientStream stream) {
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import com.google.common.util.concurrent.SettableFuture;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ClientCall;
|
import io.grpc.ClientCall;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.ConnectivityState;
|
import io.grpc.ConnectivityState;
|
||||||
import io.grpc.ConnectivityStateInfo;
|
import io.grpc.ConnectivityStateInfo;
|
||||||
import io.grpc.Context;
|
import io.grpc.Context;
|
||||||
|
|
@ -86,12 +87,14 @@ final class OobChannel extends ManagedChannel implements InternalInstrumented<Ch
|
||||||
@Override
|
@Override
|
||||||
public ClientStream newStream(MethodDescriptor<?, ?> method,
|
public ClientStream newStream(MethodDescriptor<?, ?> method,
|
||||||
CallOptions callOptions, Metadata headers, Context context) {
|
CallOptions callOptions, Metadata headers, Context context) {
|
||||||
|
ClientStreamTracer[] tracers = GrpcUtil.getClientStreamTracers(
|
||||||
|
callOptions, headers, /* isTransparentRetry= */ false);
|
||||||
Context origContext = context.attach();
|
Context origContext = context.attach();
|
||||||
// delayed transport's newStream() always acquires a lock, but concurrent performance doesn't
|
// delayed transport's newStream() always acquires a lock, but concurrent performance doesn't
|
||||||
// matter here because OOB communication should be sparse, and it's not on application RPC's
|
// matter here because OOB communication should be sparse, and it's not on application RPC's
|
||||||
// critical path.
|
// critical path.
|
||||||
try {
|
try {
|
||||||
return delayedTransport.newStream(method, headers, callOptions);
|
return delayedTransport.newStream(method, headers, callOptions, tracers);
|
||||||
} finally {
|
} finally {
|
||||||
context.detach(origContext);
|
context.detach(origContext);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -203,11 +203,11 @@ abstract class RetriableStream<ReqT> implements ClientStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Substream createSubstream(int previousAttemptCount) {
|
private Substream createSubstream(int previousAttemptCount, boolean isTransparentRetry) {
|
||||||
Substream sub = new Substream(previousAttemptCount);
|
Substream sub = new Substream(previousAttemptCount);
|
||||||
// one tracer per substream
|
// one tracer per substream
|
||||||
final ClientStreamTracer bufferSizeTracer = new BufferSizeTracer(sub);
|
final ClientStreamTracer bufferSizeTracer = new BufferSizeTracer(sub);
|
||||||
ClientStreamTracer.Factory tracerFactory = new ClientStreamTracer.Factory() {
|
ClientStreamTracer.Factory tracerFactory = new ClientStreamTracer.InternalLimitedInfoFactory() {
|
||||||
@Override
|
@Override
|
||||||
public ClientStreamTracer newClientStreamTracer(
|
public ClientStreamTracer newClientStreamTracer(
|
||||||
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
||||||
|
|
@ -217,7 +217,7 @@ abstract class RetriableStream<ReqT> implements ClientStream {
|
||||||
|
|
||||||
Metadata newHeaders = updateHeaders(headers, previousAttemptCount);
|
Metadata newHeaders = updateHeaders(headers, previousAttemptCount);
|
||||||
// NOTICE: This set _must_ be done before stream.start() and it actually is.
|
// NOTICE: This set _must_ be done before stream.start() and it actually is.
|
||||||
sub.stream = newSubstream(tracerFactory, newHeaders);
|
sub.stream = newSubstream(newHeaders, tracerFactory, isTransparentRetry);
|
||||||
return sub;
|
return sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,7 +226,7 @@ abstract class RetriableStream<ReqT> implements ClientStream {
|
||||||
* Client stream is not yet started.
|
* Client stream is not yet started.
|
||||||
*/
|
*/
|
||||||
abstract ClientStream newSubstream(
|
abstract ClientStream newSubstream(
|
||||||
ClientStreamTracer.Factory tracerFactory, Metadata headers);
|
Metadata headers, ClientStreamTracer.Factory tracerFactory, boolean isTransparentRetry);
|
||||||
|
|
||||||
/** Adds grpc-previous-rpc-attempts in the headers of a retry/hedging RPC. */
|
/** Adds grpc-previous-rpc-attempts in the headers of a retry/hedging RPC. */
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
|
@ -322,7 +322,7 @@ abstract class RetriableStream<ReqT> implements ClientStream {
|
||||||
state.buffer.add(new StartEntry());
|
state.buffer.add(new StartEntry());
|
||||||
}
|
}
|
||||||
|
|
||||||
Substream substream = createSubstream(0);
|
Substream substream = createSubstream(0, false);
|
||||||
if (isHedging) {
|
if (isHedging) {
|
||||||
FutureCanceller scheduledHedgingRef = null;
|
FutureCanceller scheduledHedgingRef = null;
|
||||||
|
|
||||||
|
|
@ -399,7 +399,7 @@ abstract class RetriableStream<ReqT> implements ClientStream {
|
||||||
// If this run is not cancelled, the value of state.hedgingAttemptCount won't change
|
// If this run is not cancelled, the value of state.hedgingAttemptCount won't change
|
||||||
// until state.addActiveHedge() is called subsequently, even the state could possibly
|
// until state.addActiveHedge() is called subsequently, even the state could possibly
|
||||||
// change.
|
// change.
|
||||||
Substream newSubstream = createSubstream(state.hedgingAttemptCount);
|
Substream newSubstream = createSubstream(state.hedgingAttemptCount, false);
|
||||||
boolean cancelled = false;
|
boolean cancelled = false;
|
||||||
FutureCanceller future = null;
|
FutureCanceller future = null;
|
||||||
|
|
||||||
|
|
@ -784,8 +784,7 @@ abstract class RetriableStream<ReqT> implements ClientStream {
|
||||||
if (rpcProgress == RpcProgress.REFUSED
|
if (rpcProgress == RpcProgress.REFUSED
|
||||||
&& noMoreTransparentRetry.compareAndSet(false, true)) {
|
&& noMoreTransparentRetry.compareAndSet(false, true)) {
|
||||||
// transparent retry
|
// transparent retry
|
||||||
final Substream newSubstream = createSubstream(
|
final Substream newSubstream = createSubstream(substream.previousAttemptCount, true);
|
||||||
substream.previousAttemptCount);
|
|
||||||
if (isHedging) {
|
if (isHedging) {
|
||||||
boolean commit = false;
|
boolean commit = false;
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
|
|
@ -863,8 +862,9 @@ abstract class RetriableStream<ReqT> implements ClientStream {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// retry
|
// retry
|
||||||
Substream newSubstream =
|
Substream newSubstream = createSubstream(
|
||||||
createSubstream(substream.previousAttemptCount + 1);
|
substream.previousAttemptCount + 1,
|
||||||
|
false);
|
||||||
drain(newSubstream);
|
drain(newSubstream);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
|
||||||
import io.grpc.ClientStreamTracer;
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Context;
|
import io.grpc.Context;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
|
@ -48,21 +47,12 @@ public final class StatsTraceContext {
|
||||||
* Factory method for the client-side.
|
* Factory method for the client-side.
|
||||||
*/
|
*/
|
||||||
public static StatsTraceContext newClientContext(
|
public static StatsTraceContext newClientContext(
|
||||||
final CallOptions callOptions, final Attributes transportAttrs, Metadata headers) {
|
ClientStreamTracer[] tracers, Attributes transportAtts, Metadata headers) {
|
||||||
List<ClientStreamTracer.Factory> factories = callOptions.getStreamTracerFactories();
|
StatsTraceContext ctx = new StatsTraceContext(tracers);
|
||||||
if (factories.isEmpty()) {
|
for (ClientStreamTracer tracer : tracers) {
|
||||||
return NOOP;
|
tracer.streamCreated(transportAtts, headers);
|
||||||
}
|
}
|
||||||
ClientStreamTracer.StreamInfo info =
|
return ctx;
|
||||||
ClientStreamTracer.StreamInfo.newBuilder()
|
|
||||||
.setTransportAttrs(transportAttrs).setCallOptions(callOptions).build();
|
|
||||||
// This array will be iterated multiple times per RPC. Use primitive array instead of Collection
|
|
||||||
// so that for-each doesn't create an Iterator every time.
|
|
||||||
StreamTracer[] tracers = new StreamTracer[factories.size()];
|
|
||||||
for (int i = 0; i < tracers.length; i++) {
|
|
||||||
tracers[i] = factories.get(i).newClientStreamTracer(info, headers);
|
|
||||||
}
|
|
||||||
return new StatsTraceContext(tracers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.Channel;
|
import io.grpc.Channel;
|
||||||
import io.grpc.ClientCall;
|
import io.grpc.ClientCall;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Context;
|
import io.grpc.Context;
|
||||||
import io.grpc.InternalConfigSelector;
|
import io.grpc.InternalConfigSelector;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
|
@ -57,9 +58,11 @@ final class SubchannelChannel extends Channel {
|
||||||
if (transport == null) {
|
if (transport == null) {
|
||||||
transport = notReadyTransport;
|
transport = notReadyTransport;
|
||||||
}
|
}
|
||||||
|
ClientStreamTracer[] tracers = GrpcUtil.getClientStreamTracers(
|
||||||
|
callOptions, headers, /* isTransparentRetry= */ false);
|
||||||
Context origContext = context.attach();
|
Context origContext = context.attach();
|
||||||
try {
|
try {
|
||||||
return transport.newStream(method, headers, callOptions);
|
return transport.newStream(method, headers, callOptions, tracers);
|
||||||
} finally {
|
} finally {
|
||||||
context.detach(origContext);
|
context.detach(origContext);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package io.grpc.util;
|
package io.grpc.util;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
|
import io.grpc.Attributes;
|
||||||
import io.grpc.ClientStreamTracer;
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.ExperimentalApi;
|
import io.grpc.ExperimentalApi;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
|
@ -27,6 +28,11 @@ public abstract class ForwardingClientStreamTracer extends ClientStreamTracer {
|
||||||
/** Returns the underlying {@code ClientStreamTracer}. */
|
/** Returns the underlying {@code ClientStreamTracer}. */
|
||||||
protected abstract ClientStreamTracer delegate();
|
protected abstract ClientStreamTracer delegate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamCreated(Attributes transportAttrs, Metadata headers) {
|
||||||
|
delegate().streamCreated(transportAttrs, headers);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outboundHeaders() {
|
public void outboundHeaders() {
|
||||||
delegate().outboundHeaders();
|
delegate().outboundHeaders();
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ public class ClientStreamTracerTest {
|
||||||
Attributes.newBuilder().set(TRANSPORT_ATTR_KEY, "value").build();
|
Attributes.newBuilder().set(TRANSPORT_ATTR_KEY, "value").build();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SuppressWarnings("deprecation") // info.getTransportAttrs()
|
||||||
public void streamInfo_empty() {
|
public void streamInfo_empty() {
|
||||||
StreamInfo info = StreamInfo.newBuilder().build();
|
StreamInfo info = StreamInfo.newBuilder().build();
|
||||||
assertThat(info.getCallOptions()).isSameInstanceAs(CallOptions.DEFAULT);
|
assertThat(info.getCallOptions()).isSameInstanceAs(CallOptions.DEFAULT);
|
||||||
|
|
@ -41,6 +42,7 @@ public class ClientStreamTracerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SuppressWarnings("deprecation") // info.getTransportAttrs()
|
||||||
public void streamInfo_withInfo() {
|
public void streamInfo_withInfo() {
|
||||||
StreamInfo info = StreamInfo.newBuilder()
|
StreamInfo info = StreamInfo.newBuilder()
|
||||||
.setCallOptions(callOptions).setTransportAttrs(transportAttrs).build();
|
.setCallOptions(callOptions).setTransportAttrs(transportAttrs).build();
|
||||||
|
|
@ -49,6 +51,7 @@ public class ClientStreamTracerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SuppressWarnings("deprecation") // info.setTransportAttrs()
|
||||||
public void streamInfo_noEquality() {
|
public void streamInfo_noEquality() {
|
||||||
StreamInfo info1 = StreamInfo.newBuilder()
|
StreamInfo info1 = StreamInfo.newBuilder()
|
||||||
.setCallOptions(callOptions).setTransportAttrs(transportAttrs).build();
|
.setCallOptions(callOptions).setTransportAttrs(transportAttrs).build();
|
||||||
|
|
@ -60,6 +63,7 @@ public class ClientStreamTracerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SuppressWarnings("deprecation") // info.getTransportAttrs()
|
||||||
public void streamInfo_toBuilder() {
|
public void streamInfo_toBuilder() {
|
||||||
StreamInfo info1 = StreamInfo.newBuilder()
|
StreamInfo info1 = StreamInfo.newBuilder()
|
||||||
.setCallOptions(callOptions).setTransportAttrs(transportAttrs).build();
|
.setCallOptions(callOptions).setTransportAttrs(transportAttrs).build();
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
import io.grpc.ClientStreamTracer;
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.ClientStreamTracer.StreamInfo;
|
|
||||||
import io.grpc.Grpc;
|
import io.grpc.Grpc;
|
||||||
import io.grpc.InternalChannelz.SocketStats;
|
import io.grpc.InternalChannelz.SocketStats;
|
||||||
import io.grpc.InternalChannelz.TransportStats;
|
import io.grpc.InternalChannelz.TransportStats;
|
||||||
|
|
@ -172,7 +171,7 @@ public abstract class AbstractTransportTest {
|
||||||
.setRequestMarshaller(StringMarshaller.INSTANCE)
|
.setRequestMarshaller(StringMarshaller.INSTANCE)
|
||||||
.setResponseMarshaller(StringMarshaller.INSTANCE)
|
.setResponseMarshaller(StringMarshaller.INSTANCE)
|
||||||
.build();
|
.build();
|
||||||
private CallOptions callOptions;
|
private final CallOptions callOptions = CallOptions.DEFAULT;
|
||||||
|
|
||||||
private Metadata.Key<String> asciiKey = Metadata.Key.of(
|
private Metadata.Key<String> asciiKey = Metadata.Key.of(
|
||||||
"ascii-key", Metadata.ASCII_STRING_MARSHALLER);
|
"ascii-key", Metadata.ASCII_STRING_MARSHALLER);
|
||||||
|
|
@ -186,24 +185,14 @@ public abstract class AbstractTransportTest {
|
||||||
= mock(ManagedClientTransport.Listener.class);
|
= mock(ManagedClientTransport.Listener.class);
|
||||||
private MockServerListener serverListener = new MockServerListener();
|
private MockServerListener serverListener = new MockServerListener();
|
||||||
private ArgumentCaptor<Throwable> throwableCaptor = ArgumentCaptor.forClass(Throwable.class);
|
private ArgumentCaptor<Throwable> throwableCaptor = ArgumentCaptor.forClass(Throwable.class);
|
||||||
private final TestClientStreamTracer clientStreamTracer1 = new TestClientStreamTracer();
|
private final TestClientStreamTracer clientStreamTracer1 = new TestHeaderClientStreamTracer();
|
||||||
private final TestClientStreamTracer clientStreamTracer2 = new TestClientStreamTracer();
|
private final TestClientStreamTracer clientStreamTracer2 = new TestHeaderClientStreamTracer();
|
||||||
private final ClientStreamTracer.Factory clientStreamTracerFactory = mock(
|
private final ClientStreamTracer[] tracers = new ClientStreamTracer[] {
|
||||||
ClientStreamTracer.Factory.class,
|
clientStreamTracer1, clientStreamTracer2
|
||||||
delegatesTo(new ClientStreamTracer.Factory() {
|
};
|
||||||
final ArrayDeque<TestClientStreamTracer> tracers =
|
private final ClientStreamTracer[] noopTracers = new ClientStreamTracer[] {
|
||||||
new ArrayDeque<>(Arrays.asList(clientStreamTracer1, clientStreamTracer2));
|
new ClientStreamTracer() {}
|
||||||
|
};
|
||||||
@Override
|
|
||||||
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata metadata) {
|
|
||||||
metadata.put(tracerHeaderKey, tracerKeyValue);
|
|
||||||
TestClientStreamTracer tracer = tracers.poll();
|
|
||||||
if (tracer != null) {
|
|
||||||
return tracer;
|
|
||||||
}
|
|
||||||
return new TestClientStreamTracer();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
private final TestServerStreamTracer serverStreamTracer1 = new TestServerStreamTracer();
|
private final TestServerStreamTracer serverStreamTracer1 = new TestServerStreamTracer();
|
||||||
private final TestServerStreamTracer serverStreamTracer2 = new TestServerStreamTracer();
|
private final TestServerStreamTracer serverStreamTracer2 = new TestServerStreamTracer();
|
||||||
|
|
@ -230,7 +219,6 @@ public abstract class AbstractTransportTest {
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
server = newServer(Arrays.asList(serverStreamTracerFactory));
|
server = newServer(Arrays.asList(serverStreamTracerFactory));
|
||||||
callOptions = CallOptions.DEFAULT.withStreamTracerFactory(clientStreamTracerFactory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
@ -291,7 +279,8 @@ public abstract class AbstractTransportTest {
|
||||||
// after having sent a RST_STREAM to the server. Previously, this would have broken the
|
// after having sent a RST_STREAM to the server. Previously, this would have broken the
|
||||||
// Netty channel.
|
// Netty channel.
|
||||||
|
|
||||||
ClientStream stream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream stream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, noopTracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
stream.start(clientStreamListener);
|
stream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation
|
StreamCreation serverStreamCreation
|
||||||
|
|
@ -314,7 +303,8 @@ public abstract class AbstractTransportTest {
|
||||||
|
|
||||||
// Test that the channel is still usable i.e. we can receive headers from the server on a
|
// Test that the channel is still usable i.e. we can receive headers from the server on a
|
||||||
// new stream.
|
// new stream.
|
||||||
stream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
stream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, noopTracers);
|
||||||
stream.start(mockClientStreamListener2);
|
stream.start(mockClientStreamListener2);
|
||||||
serverStreamCreation
|
serverStreamCreation
|
||||||
= serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
|
|
@ -449,7 +439,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
||||||
|
|
@ -501,7 +492,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
||||||
|
|
@ -539,7 +531,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
||||||
|
|
@ -594,7 +587,8 @@ public abstract class AbstractTransportTest {
|
||||||
client = newClientTransport(server);
|
client = newClientTransport(server);
|
||||||
startTransport(client, mockClientTransportListener);
|
startTransport(client, mockClientTransportListener);
|
||||||
// Stream prevents termination
|
// Stream prevents termination
|
||||||
ClientStream stream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream stream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
stream.start(clientStreamListener);
|
stream.start(clientStreamListener);
|
||||||
client.shutdown(Status.UNAVAILABLE);
|
client.shutdown(Status.UNAVAILABLE);
|
||||||
|
|
@ -633,22 +627,19 @@ public abstract class AbstractTransportTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void newStream_duringShutdown() throws Exception {
|
public void newStream_duringShutdown() throws Exception {
|
||||||
InOrder inOrder = inOrder(clientStreamTracerFactory);
|
|
||||||
server.start(serverListener);
|
server.start(serverListener);
|
||||||
client = newClientTransport(server);
|
client = newClientTransport(server);
|
||||||
startTransport(client, mockClientTransportListener);
|
startTransport(client, mockClientTransportListener);
|
||||||
// Stream prevents termination
|
// Stream prevents termination
|
||||||
ClientStream stream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream stream = client.newStream(
|
||||||
inOrder.verify(clientStreamTracerFactory).newClientStreamTracer(
|
methodDescriptor, new Metadata(), callOptions, noopTracers);
|
||||||
any(ClientStreamTracer.StreamInfo.class), any(Metadata.class));
|
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
stream.start(clientStreamListener);
|
stream.start(clientStreamListener);
|
||||||
client.shutdown(Status.UNAVAILABLE);
|
client.shutdown(Status.UNAVAILABLE);
|
||||||
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportShutdown(any(Status.class));
|
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportShutdown(any(Status.class));
|
||||||
|
|
||||||
ClientStream stream2 = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream stream2 = client.newStream(
|
||||||
inOrder.verify(clientStreamTracerFactory).newClientStreamTracer(
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
any(ClientStreamTracer.StreamInfo.class), any(Metadata.class));
|
|
||||||
ClientStreamListenerBase clientStreamListener2 = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener2 = new ClientStreamListenerBase();
|
||||||
stream2.start(clientStreamListener2);
|
stream2.start(clientStreamListener2);
|
||||||
Status clientStreamStatus2 =
|
Status clientStreamStatus2 =
|
||||||
|
|
@ -683,15 +674,14 @@ public abstract class AbstractTransportTest {
|
||||||
client.shutdown(shutdownReason);
|
client.shutdown(shutdownReason);
|
||||||
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportTerminated();
|
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportTerminated();
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
ClientStream stream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream stream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
stream.start(clientStreamListener);
|
stream.start(clientStreamListener);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
shutdownReason, clientStreamListener.status.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
shutdownReason, clientStreamListener.status.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||||
assertNotNull(clientStreamListener.trailers.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
assertNotNull(clientStreamListener.trailers.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||||
verify(mockClientTransportListener, never()).transportInUse(anyBoolean());
|
verify(mockClientTransportListener, never()).transportInUse(anyBoolean());
|
||||||
verify(clientStreamTracerFactory).newClientStreamTracer(
|
|
||||||
any(ClientStreamTracer.StreamInfo.class), any(Metadata.class));
|
|
||||||
assertNull(clientStreamTracer1.getInboundTrailers());
|
assertNull(clientStreamTracer1.getInboundTrailers());
|
||||||
assertSame(shutdownReason, clientStreamTracer1.getStatus());
|
assertSame(shutdownReason, clientStreamTracer1.getStatus());
|
||||||
// Assert no interactions
|
// Assert no interactions
|
||||||
|
|
@ -708,7 +698,8 @@ public abstract class AbstractTransportTest {
|
||||||
// CALL_OPTIONS_RPC_OWNED_BY_BALANCER in CallOptions. It won't be counted for in-use signal.
|
// CALL_OPTIONS_RPC_OWNED_BY_BALANCER in CallOptions. It won't be counted for in-use signal.
|
||||||
ClientStream stream1 = client.newStream(
|
ClientStream stream1 = client.newStream(
|
||||||
methodDescriptor, new Metadata(),
|
methodDescriptor, new Metadata(),
|
||||||
callOptions.withOption(GrpcUtil.CALL_OPTIONS_RPC_OWNED_BY_BALANCER, Boolean.TRUE));
|
callOptions.withOption(GrpcUtil.CALL_OPTIONS_RPC_OWNED_BY_BALANCER, Boolean.TRUE),
|
||||||
|
noopTracers);
|
||||||
ClientStreamListenerBase clientStreamListener1 = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener1 = new ClientStreamListenerBase();
|
||||||
stream1.start(clientStreamListener1);
|
stream1.start(clientStreamListener1);
|
||||||
MockServerTransportListener serverTransportListener
|
MockServerTransportListener serverTransportListener
|
||||||
|
|
@ -717,7 +708,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
// stream2 is the normal RPC, and will be counted for in-use
|
// stream2 is the normal RPC, and will be counted for in-use
|
||||||
ClientStream stream2 = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream stream2 = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, noopTracers);
|
||||||
ClientStreamListenerBase clientStreamListener2 = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener2 = new ClientStreamListenerBase();
|
||||||
stream2.start(clientStreamListener2);
|
stream2.start(clientStreamListener2);
|
||||||
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
||||||
|
|
@ -743,7 +735,8 @@ public abstract class AbstractTransportTest {
|
||||||
server.start(serverListener);
|
server.start(serverListener);
|
||||||
client = newClientTransport(server);
|
client = newClientTransport(server);
|
||||||
startTransport(client, mockClientTransportListener);
|
startTransport(client, mockClientTransportListener);
|
||||||
ClientStream stream1 = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream stream1 = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, noopTracers);
|
||||||
ClientStreamListenerBase clientStreamListener1 = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener1 = new ClientStreamListenerBase();
|
||||||
stream1.start(clientStreamListener1);
|
stream1.start(clientStreamListener1);
|
||||||
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
||||||
|
|
@ -751,7 +744,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
StreamCreation serverStreamCreation1
|
StreamCreation serverStreamCreation1
|
||||||
= serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
ClientStream stream2 = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream stream2 = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, noopTracers);
|
||||||
ClientStreamListenerBase clientStreamListener2 = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener2 = new ClientStreamListenerBase();
|
||||||
stream2.start(clientStreamListener2);
|
stream2.start(clientStreamListener2);
|
||||||
StreamCreation serverStreamCreation2
|
StreamCreation serverStreamCreation2
|
||||||
|
|
@ -773,11 +767,13 @@ public abstract class AbstractTransportTest {
|
||||||
server.start(serverListener);
|
server.start(serverListener);
|
||||||
client = newClientTransport(server);
|
client = newClientTransport(server);
|
||||||
startTransport(client, mockClientTransportListener);
|
startTransport(client, mockClientTransportListener);
|
||||||
ClientStream stream1 = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream stream1 = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, noopTracers);
|
||||||
ClientStreamListenerBase clientStreamListener1 = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener1 = new ClientStreamListenerBase();
|
||||||
stream1.start(clientStreamListener1);
|
stream1.start(clientStreamListener1);
|
||||||
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportInUse(true);
|
||||||
ClientStream stream2 = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream stream2 = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, noopTracers);
|
||||||
ClientStreamListenerBase clientStreamListener2 = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener2 = new ClientStreamListenerBase();
|
||||||
stream2.start(clientStreamListener2);
|
stream2.start(clientStreamListener2);
|
||||||
|
|
||||||
|
|
@ -792,7 +788,6 @@ public abstract class AbstractTransportTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void basicStream() throws Exception {
|
public void basicStream() throws Exception {
|
||||||
InOrder clientInOrder = inOrder(clientStreamTracerFactory);
|
|
||||||
InOrder serverInOrder = inOrder(serverStreamTracerFactory);
|
InOrder serverInOrder = inOrder(serverStreamTracerFactory);
|
||||||
server.start(serverListener);
|
server.start(serverListener);
|
||||||
client = newClientTransport(server);
|
client = newClientTransport(server);
|
||||||
|
|
@ -816,14 +811,10 @@ public abstract class AbstractTransportTest {
|
||||||
Metadata clientHeadersCopy = new Metadata();
|
Metadata clientHeadersCopy = new Metadata();
|
||||||
|
|
||||||
clientHeadersCopy.merge(clientHeaders);
|
clientHeadersCopy.merge(clientHeaders);
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, clientHeaders, callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
ArgumentCaptor<ClientStreamTracer.StreamInfo> streamInfoCaptor = ArgumentCaptor.forClass(null);
|
methodDescriptor, clientHeaders, callOptions, tracers);
|
||||||
clientInOrder.verify(clientStreamTracerFactory).newClientStreamTracer(
|
assertThat(((TestHeaderClientStreamTracer) clientStreamTracer1).transportAttrs)
|
||||||
streamInfoCaptor.capture(), same(clientHeaders));
|
.isSameInstanceAs(((ConnectionClientTransport) client).getAttributes());
|
||||||
ClientStreamTracer.StreamInfo streamInfo = streamInfoCaptor.getValue();
|
|
||||||
assertThat(streamInfo.getTransportAttrs()).isSameInstanceAs(
|
|
||||||
((ConnectionClientTransport) client).getAttributes());
|
|
||||||
assertThat(streamInfo.getCallOptions()).isSameInstanceAs(callOptions);
|
|
||||||
|
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
|
|
@ -974,7 +965,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
Metadata clientHeaders = new Metadata();
|
Metadata clientHeaders = new Metadata();
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, clientHeaders, callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, clientHeaders, callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation
|
StreamCreation serverStreamCreation
|
||||||
|
|
@ -1005,7 +997,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation
|
StreamCreation serverStreamCreation
|
||||||
|
|
@ -1044,7 +1037,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation
|
StreamCreation serverStreamCreation
|
||||||
|
|
@ -1080,7 +1074,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation
|
StreamCreation serverStreamCreation
|
||||||
|
|
@ -1122,7 +1117,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation
|
StreamCreation serverStreamCreation
|
||||||
|
|
@ -1155,7 +1151,8 @@ public abstract class AbstractTransportTest {
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
final ClientStream clientStream =
|
final ClientStream clientStream =
|
||||||
client.newStream(methodDescriptor, new Metadata(), callOptions);
|
client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase() {
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -1196,7 +1193,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation
|
StreamCreation serverStreamCreation
|
||||||
|
|
@ -1230,7 +1228,8 @@ public abstract class AbstractTransportTest {
|
||||||
|
|
||||||
final SettableFuture<Boolean> closedCalled = SettableFuture.create();
|
final SettableFuture<Boolean> closedCalled = SettableFuture.create();
|
||||||
final ClientStream clientStream =
|
final ClientStream clientStream =
|
||||||
client.newStream(methodDescriptor, new Metadata(), callOptions);
|
client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
final Status status = Status.CANCELLED.withDescription("nevermind");
|
final Status status = Status.CANCELLED.withDescription("nevermind");
|
||||||
clientStream.start(new ClientStreamListener() {
|
clientStream.start(new ClientStreamListener() {
|
||||||
private boolean messageReceived = false;
|
private boolean messageReceived = false;
|
||||||
|
|
@ -1311,7 +1310,8 @@ public abstract class AbstractTransportTest {
|
||||||
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation
|
StreamCreation serverStreamCreation
|
||||||
|
|
@ -1331,8 +1331,6 @@ public abstract class AbstractTransportTest {
|
||||||
// Cause should not be transmitted between server and client
|
// Cause should not be transmitted between server and client
|
||||||
assertNull(clientStreamStatus.getCause());
|
assertNull(clientStreamStatus.getCause());
|
||||||
|
|
||||||
verify(clientStreamTracerFactory).newClientStreamTracer(
|
|
||||||
any(ClientStreamTracer.StreamInfo.class), any(Metadata.class));
|
|
||||||
assertTrue(clientStreamTracer1.getOutboundHeaders());
|
assertTrue(clientStreamTracer1.getOutboundHeaders());
|
||||||
assertNull(clientStreamTracer1.getInboundTrailers());
|
assertNull(clientStreamTracer1.getInboundTrailers());
|
||||||
assertSame(clientStreamStatus, clientStreamTracer1.getStatus());
|
assertSame(clientStreamStatus, clientStreamTracer1.getStatus());
|
||||||
|
|
@ -1353,7 +1351,8 @@ public abstract class AbstractTransportTest {
|
||||||
serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
serverTransport = serverTransportListener.transport;
|
serverTransport = serverTransportListener.transport;
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation =
|
StreamCreation serverStreamCreation =
|
||||||
|
|
@ -1515,7 +1514,8 @@ public abstract class AbstractTransportTest {
|
||||||
|
|
||||||
// boilerplate
|
// boilerplate
|
||||||
ClientStream clientStream =
|
ClientStream clientStream =
|
||||||
client.newStream(methodDescriptor, new Metadata(), callOptions);
|
client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation server
|
StreamCreation server
|
||||||
|
|
@ -1547,7 +1547,8 @@ public abstract class AbstractTransportTest {
|
||||||
|
|
||||||
// boilerplate
|
// boilerplate
|
||||||
ClientStream clientStream =
|
ClientStream clientStream =
|
||||||
client.newStream(methodDescriptor, new Metadata(), callOptions);
|
client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListener clientListener = mock(ClientStreamListener.class);
|
ClientStreamListener clientListener = mock(ClientStreamListener.class);
|
||||||
clientStream.start(clientListener);
|
clientStream.start(clientListener);
|
||||||
StreamCreation server
|
StreamCreation server
|
||||||
|
|
@ -1594,7 +1595,8 @@ public abstract class AbstractTransportTest {
|
||||||
assertEquals(0, clientBefore.streamsStarted);
|
assertEquals(0, clientBefore.streamsStarted);
|
||||||
assertEquals(0, clientBefore.lastRemoteStreamCreatedTimeNanos);
|
assertEquals(0, clientBefore.lastRemoteStreamCreatedTimeNanos);
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation = serverTransportListener
|
StreamCreation serverStreamCreation = serverTransportListener
|
||||||
|
|
@ -1624,7 +1626,8 @@ public abstract class AbstractTransportTest {
|
||||||
TransportStats clientBefore = getTransportStats(client);
|
TransportStats clientBefore = getTransportStats(client);
|
||||||
assertEquals(1, clientBefore.streamsStarted);
|
assertEquals(1, clientBefore.streamsStarted);
|
||||||
|
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, noopTracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
StreamCreation serverStreamCreation = serverTransportListener
|
StreamCreation serverStreamCreation = serverTransportListener
|
||||||
|
|
@ -1654,7 +1657,8 @@ public abstract class AbstractTransportTest {
|
||||||
server.start(serverListener);
|
server.start(serverListener);
|
||||||
client = newClientTransport(server);
|
client = newClientTransport(server);
|
||||||
startTransport(client, mockClientTransportListener);
|
startTransport(client, mockClientTransportListener);
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
MockServerTransportListener serverTransportListener
|
MockServerTransportListener serverTransportListener
|
||||||
|
|
@ -1693,7 +1697,8 @@ public abstract class AbstractTransportTest {
|
||||||
server.start(serverListener);
|
server.start(serverListener);
|
||||||
client = newClientTransport(server);
|
client = newClientTransport(server);
|
||||||
startTransport(client, mockClientTransportListener);
|
startTransport(client, mockClientTransportListener);
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
MockServerTransportListener serverTransportListener
|
MockServerTransportListener serverTransportListener
|
||||||
|
|
@ -1733,7 +1738,8 @@ public abstract class AbstractTransportTest {
|
||||||
server.start(serverListener);
|
server.start(serverListener);
|
||||||
client = newClientTransport(server);
|
client = newClientTransport(server);
|
||||||
startTransport(client, mockClientTransportListener);
|
startTransport(client, mockClientTransportListener);
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
MockServerTransportListener serverTransportListener =
|
MockServerTransportListener serverTransportListener =
|
||||||
|
|
@ -1768,7 +1774,8 @@ public abstract class AbstractTransportTest {
|
||||||
server.start(serverListener);
|
server.start(serverListener);
|
||||||
client = newClientTransport(server);
|
client = newClientTransport(server);
|
||||||
startTransport(client, mockClientTransportListener);
|
startTransport(client, mockClientTransportListener);
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
MockServerTransportListener serverTransportListener
|
MockServerTransportListener serverTransportListener
|
||||||
|
|
@ -1809,7 +1816,8 @@ public abstract class AbstractTransportTest {
|
||||||
server.start(serverListener);
|
server.start(serverListener);
|
||||||
client = newClientTransport(server);
|
client = newClientTransport(server);
|
||||||
startTransport(client, mockClientTransportListener);
|
startTransport(client, mockClientTransportListener);
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
MockServerTransportListener serverTransportListener
|
MockServerTransportListener serverTransportListener
|
||||||
|
|
@ -1849,7 +1857,8 @@ public abstract class AbstractTransportTest {
|
||||||
server.start(serverListener);
|
server.start(serverListener);
|
||||||
ManagedClientTransport client = newClientTransport(server);
|
ManagedClientTransport client = newClientTransport(server);
|
||||||
startTransport(client, mockClientTransportListener);
|
startTransport(client, mockClientTransportListener);
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
|
|
||||||
|
|
@ -1896,8 +1905,8 @@ public abstract class AbstractTransportTest {
|
||||||
Metadata.Key.of("foo-bin", Metadata.BINARY_BYTE_MARSHALLER),
|
Metadata.Key.of("foo-bin", Metadata.BINARY_BYTE_MARSHALLER),
|
||||||
new byte[GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE]);
|
new byte[GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE]);
|
||||||
|
|
||||||
ClientStream clientStream =
|
ClientStream clientStream = client.newStream(
|
||||||
client.newStream(methodDescriptor, tooLargeMetadata, callOptions);
|
methodDescriptor, tooLargeMetadata, callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
|
|
||||||
|
|
@ -1931,7 +1940,8 @@ public abstract class AbstractTransportTest {
|
||||||
new byte[GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE]);
|
new byte[GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE]);
|
||||||
|
|
||||||
ClientStream clientStream =
|
ClientStream clientStream =
|
||||||
client.newStream(methodDescriptor, new Metadata(), callOptions);
|
client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
|
|
||||||
|
|
@ -1975,7 +1985,8 @@ public abstract class AbstractTransportTest {
|
||||||
new byte[GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE]);
|
new byte[GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE]);
|
||||||
|
|
||||||
ClientStream clientStream =
|
ClientStream clientStream =
|
||||||
client.newStream(methodDescriptor, new Metadata(), callOptions);
|
client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions, tracers);
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
|
|
||||||
|
|
@ -2011,7 +2022,9 @@ public abstract class AbstractTransportTest {
|
||||||
ManagedClientTransport client = newClientTransport(server);
|
ManagedClientTransport client = newClientTransport(server);
|
||||||
ManagedClientTransport.Listener listener = mock(ManagedClientTransport.Listener.class);
|
ManagedClientTransport.Listener listener = mock(ManagedClientTransport.Listener.class);
|
||||||
startTransport(client, listener);
|
startTransport(client, listener);
|
||||||
ClientStream clientStream = client.newStream(methodDescriptor, new Metadata(), callOptions);
|
ClientStream clientStream = client.newStream(
|
||||||
|
methodDescriptor, new Metadata(), callOptions,
|
||||||
|
new ClientStreamTracer[] { new ClientStreamTracer() {} });
|
||||||
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
|
||||||
clientStream.start(clientStreamListener);
|
clientStream.start(clientStreamListener);
|
||||||
|
|
||||||
|
|
@ -2092,6 +2105,16 @@ public abstract class AbstractTransportTest {
|
||||||
verify(listener, timeout(TIMEOUT_MS)).transportReady();
|
verify(listener, timeout(TIMEOUT_MS)).transportReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class TestHeaderClientStreamTracer extends TestClientStreamTracer {
|
||||||
|
Attributes transportAttrs;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamCreated(Attributes transportAttrs, Metadata metadata) {
|
||||||
|
this.transportAttrs = transportAttrs;
|
||||||
|
metadata.put(tracerHeaderKey, tracerKeyValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class MockServerListener implements ServerListener {
|
private static class MockServerListener implements ServerListener {
|
||||||
public final BlockingQueue<MockServerTransportListener> listeners
|
public final BlockingQueue<MockServerTransportListener> listeners
|
||||||
= new LinkedBlockingQueue<>();
|
= new LinkedBlockingQueue<>();
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import io.grpc.CallCredentials.MetadataApplier;
|
||||||
import io.grpc.CallCredentials.RequestInfo;
|
import io.grpc.CallCredentials.RequestInfo;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.IntegerMarshaller;
|
import io.grpc.IntegerMarshaller;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.MethodDescriptor;
|
import io.grpc.MethodDescriptor;
|
||||||
|
|
@ -48,6 +49,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
import org.mockito.junit.MockitoJUnit;
|
import org.mockito.junit.MockitoJUnit;
|
||||||
|
|
@ -103,6 +105,9 @@ public class CallCredentials2ApplyingTest {
|
||||||
private static final Metadata.Key<String> CREDS_KEY =
|
private static final Metadata.Key<String> CREDS_KEY =
|
||||||
Metadata.Key.of("test-creds", Metadata.ASCII_STRING_MARSHALLER);
|
Metadata.Key.of("test-creds", Metadata.ASCII_STRING_MARSHALLER);
|
||||||
private static final String CREDS_VALUE = "some credentials";
|
private static final String CREDS_VALUE = "some credentials";
|
||||||
|
private static final ClientStreamTracer[] tracers = new ClientStreamTracer[] {
|
||||||
|
new ClientStreamTracer() {}
|
||||||
|
};
|
||||||
|
|
||||||
private final Metadata origHeaders = new Metadata();
|
private final Metadata origHeaders = new Metadata();
|
||||||
private ForwardingConnectionClientTransport transport;
|
private ForwardingConnectionClientTransport transport;
|
||||||
|
|
@ -118,7 +123,9 @@ public class CallCredentials2ApplyingTest {
|
||||||
origHeaders.put(ORIG_HEADER_KEY, ORIG_HEADER_VALUE);
|
origHeaders.put(ORIG_HEADER_KEY, ORIG_HEADER_VALUE);
|
||||||
when(mockTransportFactory.newClientTransport(address, clientTransportOptions, channelLogger))
|
when(mockTransportFactory.newClientTransport(address, clientTransportOptions, channelLogger))
|
||||||
.thenReturn(mockTransport);
|
.thenReturn(mockTransport);
|
||||||
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
|
ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
|
||||||
mockTransportFactory, null, mockExecutor);
|
mockTransportFactory, null, mockExecutor);
|
||||||
|
|
@ -134,7 +141,7 @@ public class CallCredentials2ApplyingTest {
|
||||||
Attributes transportAttrs = Attributes.newBuilder().set(ATTR_KEY, ATTR_VALUE).build();
|
Attributes transportAttrs = Attributes.newBuilder().set(ATTR_KEY, ATTR_VALUE).build();
|
||||||
when(mockTransport.getAttributes()).thenReturn(transportAttrs);
|
when(mockTransport.getAttributes()).thenReturn(transportAttrs);
|
||||||
|
|
||||||
transport.newStream(method, origHeaders, callOptions);
|
transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(
|
verify(mockCreds).applyRequestMetadata(
|
||||||
|
|
@ -155,7 +162,7 @@ public class CallCredentials2ApplyingTest {
|
||||||
.build();
|
.build();
|
||||||
when(mockTransport.getAttributes()).thenReturn(transportAttrs);
|
when(mockTransport.getAttributes()).thenReturn(transportAttrs);
|
||||||
|
|
||||||
transport.newStream(method, origHeaders, callOptions);
|
transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(
|
verify(mockCreds).applyRequestMetadata(
|
||||||
|
|
@ -176,8 +183,10 @@ public class CallCredentials2ApplyingTest {
|
||||||
when(mockTransport.getAttributes()).thenReturn(transportAttrs);
|
when(mockTransport.getAttributes()).thenReturn(transportAttrs);
|
||||||
Executor anotherExecutor = mock(Executor.class);
|
Executor anotherExecutor = mock(Executor.class);
|
||||||
|
|
||||||
transport.newStream(method, origHeaders,
|
transport.newStream(
|
||||||
callOptions.withAuthority("calloptions-authority").withExecutor(anotherExecutor));
|
method, origHeaders,
|
||||||
|
callOptions.withAuthority("calloptions-authority").withExecutor(anotherExecutor),
|
||||||
|
tracers);
|
||||||
|
|
||||||
ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(
|
verify(mockCreds).applyRequestMetadata(
|
||||||
|
|
@ -199,13 +208,15 @@ public class CallCredentials2ApplyingTest {
|
||||||
any(io.grpc.CallCredentials2.MetadataApplier.class));
|
any(io.grpc.CallCredentials2.MetadataApplier.class));
|
||||||
|
|
||||||
FailingClientStream stream =
|
FailingClientStream stream =
|
||||||
(FailingClientStream) transport.newStream(method, origHeaders, callOptions);
|
(FailingClientStream) transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
|
verify(mockTransport, never()).newStream(
|
||||||
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertEquals(Status.Code.UNAUTHENTICATED, stream.getError().getCode());
|
assertEquals(Status.Code.UNAUTHENTICATED, stream.getError().getCode());
|
||||||
assertSame(ex, stream.getError().getCause());
|
assertSame(ex, stream.getError().getCause());
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -226,14 +237,14 @@ public class CallCredentials2ApplyingTest {
|
||||||
any(RequestInfo.class), same(mockExecutor),
|
any(RequestInfo.class), same(mockExecutor),
|
||||||
any(io.grpc.CallCredentials2.MetadataApplier.class));
|
any(io.grpc.CallCredentials2.MetadataApplier.class));
|
||||||
|
|
||||||
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
ClientStream stream = transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
verify(mockTransport).newStream(method, origHeaders, callOptions);
|
verify(mockTransport).newStream(method, origHeaders, callOptions, tracers);
|
||||||
assertSame(mockStream, stream);
|
assertSame(mockStream, stream);
|
||||||
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
||||||
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -254,12 +265,14 @@ public class CallCredentials2ApplyingTest {
|
||||||
any(io.grpc.CallCredentials2.MetadataApplier.class));
|
any(io.grpc.CallCredentials2.MetadataApplier.class));
|
||||||
|
|
||||||
FailingClientStream stream =
|
FailingClientStream stream =
|
||||||
(FailingClientStream) transport.newStream(method, origHeaders, callOptions);
|
(FailingClientStream) transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
|
verify(mockTransport, never()).newStream(
|
||||||
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertSame(error, stream.getError());
|
assertSame(error, stream.getError());
|
||||||
transport.shutdownNow(Status.UNAVAILABLE);
|
transport.shutdownNow(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdownNow(Status.UNAVAILABLE);
|
verify(mockTransport).shutdownNow(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -269,12 +282,15 @@ public class CallCredentials2ApplyingTest {
|
||||||
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
||||||
|
|
||||||
// Will call applyRequestMetadata(), which is no-op.
|
// Will call applyRequestMetadata(), which is no-op.
|
||||||
DelayedStream stream = (DelayedStream) transport.newStream(method, origHeaders, callOptions);
|
DelayedStream stream = (DelayedStream) transport.newStream(
|
||||||
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(
|
verify(mockCreds).applyRequestMetadata(
|
||||||
any(RequestInfo.class), same(mockExecutor), applierCaptor.capture());
|
any(RequestInfo.class), same(mockExecutor), applierCaptor.capture());
|
||||||
verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
|
verify(mockTransport, never()).newStream(
|
||||||
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
verify(mockTransport, never()).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport, never()).shutdown(Status.UNAVAILABLE);
|
||||||
|
|
@ -283,11 +299,11 @@ public class CallCredentials2ApplyingTest {
|
||||||
headers.put(CREDS_KEY, CREDS_VALUE);
|
headers.put(CREDS_KEY, CREDS_VALUE);
|
||||||
applierCaptor.getValue().apply(headers);
|
applierCaptor.getValue().apply(headers);
|
||||||
|
|
||||||
verify(mockTransport).newStream(method, origHeaders, callOptions);
|
verify(mockTransport).newStream(method, origHeaders, callOptions, tracers);
|
||||||
assertSame(mockStream, stream.getRealStream());
|
assertSame(mockStream, stream.getRealStream());
|
||||||
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
||||||
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -297,7 +313,8 @@ public class CallCredentials2ApplyingTest {
|
||||||
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
||||||
|
|
||||||
// Will call applyRequestMetadata(), which is no-op.
|
// Will call applyRequestMetadata(), which is no-op.
|
||||||
DelayedStream stream = (DelayedStream) transport.newStream(method, origHeaders, callOptions);
|
DelayedStream stream = (DelayedStream) transport.newStream(
|
||||||
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(
|
verify(mockCreds).applyRequestMetadata(
|
||||||
|
|
@ -306,11 +323,13 @@ public class CallCredentials2ApplyingTest {
|
||||||
Status error = Status.FAILED_PRECONDITION.withDescription("channel not secure for creds");
|
Status error = Status.FAILED_PRECONDITION.withDescription("channel not secure for creds");
|
||||||
applierCaptor.getValue().fail(error);
|
applierCaptor.getValue().fail(error);
|
||||||
|
|
||||||
verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
|
verify(mockTransport, never()).newStream(
|
||||||
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
FailingClientStream failingStream = (FailingClientStream) stream.getRealStream();
|
FailingClientStream failingStream = (FailingClientStream) stream.getRealStream();
|
||||||
assertSame(error, failingStream.getError());
|
assertSame(error, failingStream.getError());
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -318,14 +337,14 @@ public class CallCredentials2ApplyingTest {
|
||||||
@Test
|
@Test
|
||||||
public void noCreds() {
|
public void noCreds() {
|
||||||
callOptions = callOptions.withCallCredentials(null);
|
callOptions = callOptions.withCallCredentials(null);
|
||||||
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
ClientStream stream = transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
verify(mockTransport).newStream(method, origHeaders, callOptions);
|
verify(mockTransport).newStream(method, origHeaders, callOptions, tracers);
|
||||||
assertSame(mockStream, stream);
|
assertSame(mockStream, stream);
|
||||||
assertNull(origHeaders.get(CREDS_KEY));
|
assertNull(origHeaders.get(CREDS_KEY));
|
||||||
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import io.grpc.CallCredentials;
|
||||||
import io.grpc.CallCredentials.RequestInfo;
|
import io.grpc.CallCredentials.RequestInfo;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.IntegerMarshaller;
|
import io.grpc.IntegerMarshaller;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.MethodDescriptor;
|
import io.grpc.MethodDescriptor;
|
||||||
|
|
@ -49,6 +50,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
import org.mockito.junit.MockitoJUnit;
|
import org.mockito.junit.MockitoJUnit;
|
||||||
|
|
@ -86,6 +88,9 @@ public class CallCredentialsApplyingTest {
|
||||||
@Mock
|
@Mock
|
||||||
private ChannelLogger channelLogger;
|
private ChannelLogger channelLogger;
|
||||||
|
|
||||||
|
private static final ClientStreamTracer[] tracers = new ClientStreamTracer[] {
|
||||||
|
new ClientStreamTracer() {}
|
||||||
|
};
|
||||||
private static final String AUTHORITY = "testauthority";
|
private static final String AUTHORITY = "testauthority";
|
||||||
private static final String USER_AGENT = "testuseragent";
|
private static final String USER_AGENT = "testuseragent";
|
||||||
private static final Attributes.Key<String> ATTR_KEY = Attributes.Key.create("somekey");
|
private static final Attributes.Key<String> ATTR_KEY = Attributes.Key.create("somekey");
|
||||||
|
|
@ -117,7 +122,9 @@ public class CallCredentialsApplyingTest {
|
||||||
origHeaders.put(ORIG_HEADER_KEY, ORIG_HEADER_VALUE);
|
origHeaders.put(ORIG_HEADER_KEY, ORIG_HEADER_VALUE);
|
||||||
when(mockTransportFactory.newClientTransport(address, clientTransportOptions, channelLogger))
|
when(mockTransportFactory.newClientTransport(address, clientTransportOptions, channelLogger))
|
||||||
.thenReturn(mockTransport);
|
.thenReturn(mockTransport);
|
||||||
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
|
ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
|
||||||
mockTransportFactory, null, mockExecutor);
|
mockTransportFactory, null, mockExecutor);
|
||||||
|
|
@ -133,7 +140,7 @@ public class CallCredentialsApplyingTest {
|
||||||
Attributes transportAttrs = Attributes.newBuilder().set(ATTR_KEY, ATTR_VALUE).build();
|
Attributes transportAttrs = Attributes.newBuilder().set(ATTR_KEY, ATTR_VALUE).build();
|
||||||
when(mockTransport.getAttributes()).thenReturn(transportAttrs);
|
when(mockTransport.getAttributes()).thenReturn(transportAttrs);
|
||||||
|
|
||||||
transport.newStream(method, origHeaders, callOptions);
|
transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(infoCaptor.capture(), same(mockExecutor),
|
verify(mockCreds).applyRequestMetadata(infoCaptor.capture(), same(mockExecutor),
|
||||||
|
|
@ -154,8 +161,10 @@ public class CallCredentialsApplyingTest {
|
||||||
when(mockTransport.getAttributes()).thenReturn(transportAttrs);
|
when(mockTransport.getAttributes()).thenReturn(transportAttrs);
|
||||||
Executor anotherExecutor = mock(Executor.class);
|
Executor anotherExecutor = mock(Executor.class);
|
||||||
|
|
||||||
transport.newStream(method, origHeaders,
|
transport.newStream(
|
||||||
callOptions.withAuthority("calloptions-authority").withExecutor(anotherExecutor));
|
method, origHeaders,
|
||||||
|
callOptions.withAuthority("calloptions-authority").withExecutor(anotherExecutor),
|
||||||
|
tracers);
|
||||||
|
|
||||||
ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(infoCaptor.capture(),
|
verify(mockCreds).applyRequestMetadata(infoCaptor.capture(),
|
||||||
|
|
@ -175,15 +184,17 @@ public class CallCredentialsApplyingTest {
|
||||||
any(RequestInfo.class), same(mockExecutor),
|
any(RequestInfo.class), same(mockExecutor),
|
||||||
any(CallCredentials.MetadataApplier.class));
|
any(CallCredentials.MetadataApplier.class));
|
||||||
|
|
||||||
FailingClientStream stream =
|
FailingClientStream stream = (FailingClientStream) transport.newStream(
|
||||||
(FailingClientStream) transport.newStream(method, origHeaders, callOptions);
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
|
verify(mockTransport, never()).newStream(
|
||||||
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertEquals(Status.Code.UNAUTHENTICATED, stream.getError().getCode());
|
assertEquals(Status.Code.UNAUTHENTICATED, stream.getError().getCode());
|
||||||
assertSame(ex, stream.getError().getCause());
|
assertSame(ex, stream.getError().getCause());
|
||||||
|
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -193,14 +204,15 @@ public class CallCredentialsApplyingTest {
|
||||||
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
||||||
|
|
||||||
callOptions = callOptions.withCallCredentials(new FakeCallCredentials(CREDS_KEY, CREDS_VALUE));
|
callOptions = callOptions.withCallCredentials(new FakeCallCredentials(CREDS_KEY, CREDS_VALUE));
|
||||||
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
ClientStream stream = transport.newStream(
|
||||||
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
verify(mockTransport).newStream(method, origHeaders, callOptions);
|
verify(mockTransport).newStream(method, origHeaders, callOptions, tracers);
|
||||||
assertSame(mockStream, stream);
|
assertSame(mockStream, stream);
|
||||||
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
||||||
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -220,13 +232,15 @@ public class CallCredentialsApplyingTest {
|
||||||
}).when(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
}).when(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
||||||
same(mockExecutor), any(CallCredentials.MetadataApplier.class));
|
same(mockExecutor), any(CallCredentials.MetadataApplier.class));
|
||||||
|
|
||||||
FailingClientStream stream =
|
FailingClientStream stream = (FailingClientStream) transport.newStream(
|
||||||
(FailingClientStream) transport.newStream(method, origHeaders, callOptions);
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
|
verify(mockTransport, never()).newStream(
|
||||||
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertSame(error, stream.getError());
|
assertSame(error, stream.getError());
|
||||||
transport.shutdownNow(Status.UNAVAILABLE);
|
transport.shutdownNow(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdownNow(Status.UNAVAILABLE);
|
verify(mockTransport).shutdownNow(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -236,23 +250,26 @@ public class CallCredentialsApplyingTest {
|
||||||
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
||||||
|
|
||||||
// Will call applyRequestMetadata(), which is no-op.
|
// Will call applyRequestMetadata(), which is no-op.
|
||||||
DelayedStream stream = (DelayedStream) transport.newStream(method, origHeaders, callOptions);
|
DelayedStream stream = (DelayedStream) transport.newStream(
|
||||||
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
verify(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
||||||
same(mockExecutor), applierCaptor.capture());
|
same(mockExecutor), applierCaptor.capture());
|
||||||
verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
|
verify(mockTransport, never()).newStream(
|
||||||
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
verify(mockTransport, never()).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport, never()).shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
|
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
headers.put(CREDS_KEY, CREDS_VALUE);
|
headers.put(CREDS_KEY, CREDS_VALUE);
|
||||||
applierCaptor.getValue().apply(headers);
|
applierCaptor.getValue().apply(headers);
|
||||||
|
|
||||||
verify(mockTransport).newStream(method, origHeaders, callOptions);
|
verify(mockTransport).newStream(method, origHeaders, callOptions, tracers);
|
||||||
assertSame(mockStream, stream.getRealStream());
|
assertSame(mockStream, stream.getRealStream());
|
||||||
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
||||||
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
||||||
|
|
@ -261,20 +278,20 @@ public class CallCredentialsApplyingTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void delayedShutdown_shutdownShutdownNowThenApply() {
|
public void delayedShutdown_shutdownShutdownNowThenApply() {
|
||||||
transport.newStream(method, origHeaders, callOptions);
|
transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
verify(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
||||||
same(mockExecutor), applierCaptor.capture());
|
same(mockExecutor), applierCaptor.capture());
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
transport.shutdownNow(Status.ABORTED);
|
transport.shutdownNow(Status.ABORTED);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport, never()).shutdown(any(Status.class));
|
verify(mockTransport, never()).shutdown(any(Status.class));
|
||||||
verify(mockTransport, never()).shutdownNow(any(Status.class));
|
verify(mockTransport, never()).shutdownNow(any(Status.class));
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
headers.put(CREDS_KEY, CREDS_VALUE);
|
headers.put(CREDS_KEY, CREDS_VALUE);
|
||||||
applierCaptor.getValue().apply(headers);
|
applierCaptor.getValue().apply(headers);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
verify(mockTransport).shutdownNow(Status.ABORTED);
|
verify(mockTransport).shutdownNow(Status.ABORTED);
|
||||||
|
|
@ -282,12 +299,12 @@ public class CallCredentialsApplyingTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void delayedShutdown_shutdownThenApplyThenShutdownNow() {
|
public void delayedShutdown_shutdownThenApplyThenShutdownNow() {
|
||||||
transport.newStream(method, origHeaders, callOptions);
|
transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
verify(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
||||||
same(mockExecutor), applierCaptor.capture());
|
same(mockExecutor), applierCaptor.capture());
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport, never()).shutdown(any(Status.class));
|
verify(mockTransport, never()).shutdown(any(Status.class));
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
|
|
@ -308,25 +325,25 @@ public class CallCredentialsApplyingTest {
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
headers.put(CREDS_KEY, CREDS_VALUE);
|
headers.put(CREDS_KEY, CREDS_VALUE);
|
||||||
|
|
||||||
transport.newStream(method, origHeaders, callOptions);
|
transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
transport.newStream(method, origHeaders, callOptions);
|
transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
transport.newStream(method, origHeaders, callOptions);
|
transport.newStream(method, origHeaders, callOptions, tracers);
|
||||||
ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds, times(3)).applyRequestMetadata(any(RequestInfo.class),
|
verify(mockCreds, times(3)).applyRequestMetadata(any(RequestInfo.class),
|
||||||
same(mockExecutor), applierCaptor.capture());
|
same(mockExecutor), applierCaptor.capture());
|
||||||
applierCaptor.getAllValues().get(1).apply(headers);
|
applierCaptor.getAllValues().get(1).apply(headers);
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport, never()).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport, never()).shutdown(Status.UNAVAILABLE);
|
||||||
|
|
||||||
applierCaptor.getAllValues().get(0).apply(headers);
|
applierCaptor.getAllValues().get(0).apply(headers);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport, never()).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport, never()).shutdown(Status.UNAVAILABLE);
|
||||||
|
|
||||||
applierCaptor.getAllValues().get(2).apply(headers);
|
applierCaptor.getAllValues().get(2).apply(headers);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +353,8 @@ public class CallCredentialsApplyingTest {
|
||||||
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
|
||||||
|
|
||||||
// Will call applyRequestMetadata(), which is no-op.
|
// Will call applyRequestMetadata(), which is no-op.
|
||||||
DelayedStream stream = (DelayedStream) transport.newStream(method, origHeaders, callOptions);
|
DelayedStream stream = (DelayedStream) transport.newStream(
|
||||||
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<CallCredentials.MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
verify(mockCreds).applyRequestMetadata(any(RequestInfo.class),
|
||||||
|
|
@ -345,11 +363,13 @@ public class CallCredentialsApplyingTest {
|
||||||
Status error = Status.FAILED_PRECONDITION.withDescription("channel not secure for creds");
|
Status error = Status.FAILED_PRECONDITION.withDescription("channel not secure for creds");
|
||||||
applierCaptor.getValue().fail(error);
|
applierCaptor.getValue().fail(error);
|
||||||
|
|
||||||
verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
|
verify(mockTransport, never()).newStream(
|
||||||
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
FailingClientStream failingStream = (FailingClientStream) stream.getRealStream();
|
FailingClientStream failingStream = (FailingClientStream) stream.getRealStream();
|
||||||
assertSame(error, failingStream.getError());
|
assertSame(error, failingStream.getError());
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -357,14 +377,15 @@ public class CallCredentialsApplyingTest {
|
||||||
@Test
|
@Test
|
||||||
public void noCreds() {
|
public void noCreds() {
|
||||||
callOptions = callOptions.withCallCredentials(null);
|
callOptions = callOptions.withCallCredentials(null);
|
||||||
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
ClientStream stream = transport.newStream(
|
||||||
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
verify(mockTransport).newStream(method, origHeaders, callOptions);
|
verify(mockTransport).newStream(method, origHeaders, callOptions, tracers);
|
||||||
assertSame(mockStream, stream);
|
assertSame(mockStream, stream);
|
||||||
assertNull(origHeaders.get(CREDS_KEY));
|
assertNull(origHeaders.get(CREDS_KEY));
|
||||||
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
|
||||||
transport.shutdown(Status.UNAVAILABLE);
|
transport.shutdown(Status.UNAVAILABLE);
|
||||||
assertTrue(transport.newStream(method, origHeaders, callOptions)
|
assertTrue(transport.newStream(method, origHeaders, callOptions, tracers)
|
||||||
instanceof FailingClientStream);
|
instanceof FailingClientStream);
|
||||||
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
verify(mockTransport).shutdown(Status.UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
@ -373,7 +394,8 @@ public class CallCredentialsApplyingTest {
|
||||||
public void justCallOptionCreds() {
|
public void justCallOptionCreds() {
|
||||||
callOptions = callOptions.withCallCredentials(new FakeCallCredentials(CREDS_KEY, CREDS_VALUE));
|
callOptions = callOptions.withCallCredentials(new FakeCallCredentials(CREDS_KEY, CREDS_VALUE));
|
||||||
|
|
||||||
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
ClientStream stream = transport.newStream(
|
||||||
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
assertSame(mockStream, stream);
|
assertSame(mockStream, stream);
|
||||||
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
||||||
|
|
@ -388,7 +410,8 @@ public class CallCredentialsApplyingTest {
|
||||||
transportFactory.newClientTransport(address, clientTransportOptions, channelLogger);
|
transportFactory.newClientTransport(address, clientTransportOptions, channelLogger);
|
||||||
callOptions = callOptions.withCallCredentials(null);
|
callOptions = callOptions.withCallCredentials(null);
|
||||||
|
|
||||||
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
ClientStream stream = transport.newStream(
|
||||||
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
assertSame(mockStream, stream);
|
assertSame(mockStream, stream);
|
||||||
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
||||||
|
|
@ -406,7 +429,8 @@ public class CallCredentialsApplyingTest {
|
||||||
String creds2Value = "some more credentials";
|
String creds2Value = "some more credentials";
|
||||||
callOptions = callOptions.withCallCredentials(new FakeCallCredentials(creds2Key, creds2Value));
|
callOptions = callOptions.withCallCredentials(new FakeCallCredentials(creds2Key, creds2Value));
|
||||||
|
|
||||||
ClientStream stream = transport.newStream(method, origHeaders, callOptions);
|
ClientStream stream = transport.newStream(
|
||||||
|
method, origHeaders, callOptions, tracers);
|
||||||
|
|
||||||
assertSame(mockStream, stream);
|
assertSame(mockStream, stream);
|
||||||
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import static org.mockito.Mockito.timeout;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyNoInteractions;
|
import static org.mockito.Mockito.verifyNoInteractions;
|
||||||
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
@ -47,6 +48,7 @@ import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ClientCall;
|
import io.grpc.ClientCall;
|
||||||
import io.grpc.ClientStreamTracer;
|
import io.grpc.ClientStreamTracer;
|
||||||
|
import io.grpc.ClientStreamTracer.StreamInfo;
|
||||||
import io.grpc.Codec;
|
import io.grpc.Codec;
|
||||||
import io.grpc.Context;
|
import io.grpc.Context;
|
||||||
import io.grpc.Deadline;
|
import io.grpc.Deadline;
|
||||||
|
|
@ -143,6 +145,8 @@ public class ClientCallImplTest {
|
||||||
any(Metadata.class),
|
any(Metadata.class),
|
||||||
any(Context.class)))
|
any(Context.class)))
|
||||||
.thenReturn(stream);
|
.thenReturn(stream);
|
||||||
|
when(streamTracerFactory.newClientStreamTracer(any(StreamInfo.class), any(Metadata.class)))
|
||||||
|
.thenReturn(new ClientStreamTracer() {});
|
||||||
doAnswer(new Answer<Void>() {
|
doAnswer(new Answer<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void answer(InvocationOnMock in) {
|
public Void answer(InvocationOnMock in) {
|
||||||
|
|
@ -156,7 +160,7 @@ public class ClientCallImplTest {
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
verifyNoInteractions(streamTracerFactory);
|
verifyNoMoreInteractions(streamTracerFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -763,6 +767,7 @@ public class ClientCallImplTest {
|
||||||
channelCallTracer, configSelector)
|
channelCallTracer, configSelector)
|
||||||
.setDecompressorRegistry(decompressorRegistry);
|
.setDecompressorRegistry(decompressorRegistry);
|
||||||
call.start(callListener, new Metadata());
|
call.start(callListener, new Metadata());
|
||||||
|
verify(streamTracerFactory).newClientStreamTracer(any(StreamInfo.class), any(Metadata.class));
|
||||||
verify(clientStreamProvider, never())
|
verify(clientStreamProvider, never())
|
||||||
.newStream(
|
.newStream(
|
||||||
(MethodDescriptor<?, ?>) any(MethodDescriptor.class),
|
(MethodDescriptor<?, ?>) any(MethodDescriptor.class),
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.IntegerMarshaller;
|
import io.grpc.IntegerMarshaller;
|
||||||
import io.grpc.LoadBalancer.PickResult;
|
import io.grpc.LoadBalancer.PickResult;
|
||||||
import io.grpc.LoadBalancer.PickSubchannelArgs;
|
import io.grpc.LoadBalancer.PickSubchannelArgs;
|
||||||
|
|
@ -57,6 +58,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Captor;
|
import org.mockito.Captor;
|
||||||
import org.mockito.InOrder;
|
import org.mockito.InOrder;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
|
@ -89,6 +91,9 @@ public class DelayedClientTransportTest {
|
||||||
= CallOptions.Key.createWithDefault("shard-id", -1);
|
= CallOptions.Key.createWithDefault("shard-id", -1);
|
||||||
private static final Status SHUTDOWN_STATUS =
|
private static final Status SHUTDOWN_STATUS =
|
||||||
Status.UNAVAILABLE.withDescription("shutdown called");
|
Status.UNAVAILABLE.withDescription("shutdown called");
|
||||||
|
private static final ClientStreamTracer[] tracers = new ClientStreamTracer[] {
|
||||||
|
new ClientStreamTracer() {}
|
||||||
|
};
|
||||||
|
|
||||||
private final MethodDescriptor<String, Integer> method =
|
private final MethodDescriptor<String, Integer> method =
|
||||||
MethodDescriptor.<String, Integer>newBuilder()
|
MethodDescriptor.<String, Integer>newBuilder()
|
||||||
|
|
@ -122,9 +127,13 @@ public class DelayedClientTransportTest {
|
||||||
.thenReturn(PickResult.withSubchannel(mockSubchannel));
|
.thenReturn(PickResult.withSubchannel(mockSubchannel));
|
||||||
when(mockSubchannel.getInternalSubchannel()).thenReturn(mockInternalSubchannel);
|
when(mockSubchannel.getInternalSubchannel()).thenReturn(mockInternalSubchannel);
|
||||||
when(mockInternalSubchannel.obtainActiveTransport()).thenReturn(mockRealTransport);
|
when(mockInternalSubchannel.obtainActiveTransport()).thenReturn(mockRealTransport);
|
||||||
when(mockRealTransport.newStream(same(method), same(headers), same(callOptions)))
|
when(mockRealTransport.newStream(
|
||||||
|
same(method), same(headers), same(callOptions),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockRealStream);
|
.thenReturn(mockRealStream);
|
||||||
when(mockRealTransport2.newStream(same(method2), same(headers2), same(callOptions2)))
|
when(mockRealTransport2.newStream(
|
||||||
|
same(method2), same(headers2), same(callOptions2),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockRealStream2);
|
.thenReturn(mockRealStream2);
|
||||||
delayedTransport.start(transportListener);
|
delayedTransport.start(transportListener);
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +144,8 @@ public class DelayedClientTransportTest {
|
||||||
|
|
||||||
@Test public void streamStartThenAssignTransport() {
|
@Test public void streamStartThenAssignTransport() {
|
||||||
assertFalse(delayedTransport.hasPendingStreams());
|
assertFalse(delayedTransport.hasPendingStreams());
|
||||||
ClientStream stream = delayedTransport.newStream(method, headers, callOptions);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, headers, callOptions, tracers);
|
||||||
stream.start(streamListener);
|
stream.start(streamListener);
|
||||||
assertEquals(1, delayedTransport.getPendingStreamsCount());
|
assertEquals(1, delayedTransport.getPendingStreamsCount());
|
||||||
assertTrue(delayedTransport.hasPendingStreams());
|
assertTrue(delayedTransport.hasPendingStreams());
|
||||||
|
|
@ -145,7 +155,9 @@ public class DelayedClientTransportTest {
|
||||||
assertEquals(0, delayedTransport.getPendingStreamsCount());
|
assertEquals(0, delayedTransport.getPendingStreamsCount());
|
||||||
assertFalse(delayedTransport.hasPendingStreams());
|
assertFalse(delayedTransport.hasPendingStreams());
|
||||||
assertEquals(1, fakeExecutor.runDueTasks());
|
assertEquals(1, fakeExecutor.runDueTasks());
|
||||||
verify(mockRealTransport).newStream(same(method), same(headers), same(callOptions));
|
verify(mockRealTransport).newStream(
|
||||||
|
same(method), same(headers), same(callOptions),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
verify(mockRealStream).start(listenerCaptor.capture());
|
verify(mockRealStream).start(listenerCaptor.capture());
|
||||||
verifyNoMoreInteractions(streamListener);
|
verifyNoMoreInteractions(streamListener);
|
||||||
listenerCaptor.getValue().onReady();
|
listenerCaptor.getValue().onReady();
|
||||||
|
|
@ -154,7 +166,7 @@ public class DelayedClientTransportTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void newStreamThenAssignTransportThenShutdown() {
|
@Test public void newStreamThenAssignTransportThenShutdown() {
|
||||||
ClientStream stream = delayedTransport.newStream(method, headers, callOptions);
|
ClientStream stream = delayedTransport.newStream(method, headers, callOptions, tracers);
|
||||||
assertEquals(1, delayedTransport.getPendingStreamsCount());
|
assertEquals(1, delayedTransport.getPendingStreamsCount());
|
||||||
assertTrue(stream instanceof DelayedStream);
|
assertTrue(stream instanceof DelayedStream);
|
||||||
delayedTransport.reprocess(mockPicker);
|
delayedTransport.reprocess(mockPicker);
|
||||||
|
|
@ -163,7 +175,9 @@ public class DelayedClientTransportTest {
|
||||||
verify(transportListener).transportShutdown(same(SHUTDOWN_STATUS));
|
verify(transportListener).transportShutdown(same(SHUTDOWN_STATUS));
|
||||||
verify(transportListener).transportTerminated();
|
verify(transportListener).transportTerminated();
|
||||||
assertEquals(0, fakeExecutor.runDueTasks());
|
assertEquals(0, fakeExecutor.runDueTasks());
|
||||||
verify(mockRealTransport).newStream(same(method), same(headers), same(callOptions));
|
verify(mockRealTransport).newStream(
|
||||||
|
same(method), same(headers), same(callOptions),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
stream.start(streamListener);
|
stream.start(streamListener);
|
||||||
verify(mockRealStream).start(same(streamListener));
|
verify(mockRealStream).start(same(streamListener));
|
||||||
}
|
}
|
||||||
|
|
@ -181,11 +195,13 @@ public class DelayedClientTransportTest {
|
||||||
delayedTransport.shutdown(SHUTDOWN_STATUS);
|
delayedTransport.shutdown(SHUTDOWN_STATUS);
|
||||||
verify(transportListener).transportShutdown(same(SHUTDOWN_STATUS));
|
verify(transportListener).transportShutdown(same(SHUTDOWN_STATUS));
|
||||||
verify(transportListener).transportTerminated();
|
verify(transportListener).transportTerminated();
|
||||||
ClientStream stream = delayedTransport.newStream(method, headers, callOptions);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, headers, callOptions, tracers);
|
||||||
assertEquals(0, delayedTransport.getPendingStreamsCount());
|
assertEquals(0, delayedTransport.getPendingStreamsCount());
|
||||||
assertTrue(stream instanceof FailingClientStream);
|
assertTrue(stream instanceof FailingClientStream);
|
||||||
verify(mockRealTransport, never()).newStream(
|
verify(mockRealTransport, never()).newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void assignTransportThenShutdownNowThenNewStream() {
|
@Test public void assignTransportThenShutdownNowThenNewStream() {
|
||||||
|
|
@ -193,15 +209,18 @@ public class DelayedClientTransportTest {
|
||||||
delayedTransport.shutdownNow(Status.UNAVAILABLE);
|
delayedTransport.shutdownNow(Status.UNAVAILABLE);
|
||||||
verify(transportListener).transportShutdown(any(Status.class));
|
verify(transportListener).transportShutdown(any(Status.class));
|
||||||
verify(transportListener).transportTerminated();
|
verify(transportListener).transportTerminated();
|
||||||
ClientStream stream = delayedTransport.newStream(method, headers, callOptions);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, headers, callOptions, tracers);
|
||||||
assertEquals(0, delayedTransport.getPendingStreamsCount());
|
assertEquals(0, delayedTransport.getPendingStreamsCount());
|
||||||
assertTrue(stream instanceof FailingClientStream);
|
assertTrue(stream instanceof FailingClientStream);
|
||||||
verify(mockRealTransport, never()).newStream(
|
verify(mockRealTransport, never()).newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void startThenCancelStreamWithoutSetTransport() {
|
@Test public void startThenCancelStreamWithoutSetTransport() {
|
||||||
ClientStream stream = delayedTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(streamListener);
|
stream.start(streamListener);
|
||||||
assertEquals(1, delayedTransport.getPendingStreamsCount());
|
assertEquals(1, delayedTransport.getPendingStreamsCount());
|
||||||
stream.cancel(Status.CANCELLED);
|
stream.cancel(Status.CANCELLED);
|
||||||
|
|
@ -213,7 +232,8 @@ public class DelayedClientTransportTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void newStreamThenShutdownTransportThenAssignTransport() {
|
@Test public void newStreamThenShutdownTransportThenAssignTransport() {
|
||||||
ClientStream stream = delayedTransport.newStream(method, headers, callOptions);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, headers, callOptions, tracers);
|
||||||
stream.start(streamListener);
|
stream.start(streamListener);
|
||||||
delayedTransport.shutdown(SHUTDOWN_STATUS);
|
delayedTransport.shutdown(SHUTDOWN_STATUS);
|
||||||
|
|
||||||
|
|
@ -225,7 +245,8 @@ public class DelayedClientTransportTest {
|
||||||
// ... and will proceed if a real transport is available
|
// ... and will proceed if a real transport is available
|
||||||
delayedTransport.reprocess(mockPicker);
|
delayedTransport.reprocess(mockPicker);
|
||||||
fakeExecutor.runDueTasks();
|
fakeExecutor.runDueTasks();
|
||||||
verify(mockRealTransport).newStream(method, headers, callOptions);
|
verify(mockRealTransport).newStream(
|
||||||
|
method, headers, callOptions, tracers);
|
||||||
verify(mockRealStream).start(any(ClientStreamListener.class));
|
verify(mockRealStream).start(any(ClientStreamListener.class));
|
||||||
|
|
||||||
// Since no more streams are pending, delayed transport is now terminated
|
// Since no more streams are pending, delayed transport is now terminated
|
||||||
|
|
@ -233,7 +254,8 @@ public class DelayedClientTransportTest {
|
||||||
verify(transportListener).transportTerminated();
|
verify(transportListener).transportTerminated();
|
||||||
|
|
||||||
// Further newStream() will return a failing stream
|
// Further newStream() will return a failing stream
|
||||||
stream = delayedTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
stream = delayedTransport.newStream(
|
||||||
|
method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
verify(streamListener, never()).closed(
|
verify(streamListener, never()).closed(
|
||||||
any(Status.class), any(RpcProgress.class), any(Metadata.class));
|
any(Status.class), any(RpcProgress.class), any(Metadata.class));
|
||||||
stream.start(streamListener);
|
stream.start(streamListener);
|
||||||
|
|
@ -247,7 +269,8 @@ public class DelayedClientTransportTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void newStreamThenShutdownTransportThenCancelStream() {
|
@Test public void newStreamThenShutdownTransportThenCancelStream() {
|
||||||
ClientStream stream = delayedTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
delayedTransport.shutdown(SHUTDOWN_STATUS);
|
delayedTransport.shutdown(SHUTDOWN_STATUS);
|
||||||
verify(transportListener).transportShutdown(same(SHUTDOWN_STATUS));
|
verify(transportListener).transportShutdown(same(SHUTDOWN_STATUS));
|
||||||
verify(transportListener, times(0)).transportTerminated();
|
verify(transportListener, times(0)).transportTerminated();
|
||||||
|
|
@ -264,7 +287,8 @@ public class DelayedClientTransportTest {
|
||||||
delayedTransport.shutdown(SHUTDOWN_STATUS);
|
delayedTransport.shutdown(SHUTDOWN_STATUS);
|
||||||
verify(transportListener).transportShutdown(same(SHUTDOWN_STATUS));
|
verify(transportListener).transportShutdown(same(SHUTDOWN_STATUS));
|
||||||
verify(transportListener).transportTerminated();
|
verify(transportListener).transportTerminated();
|
||||||
ClientStream stream = delayedTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(streamListener);
|
stream.start(streamListener);
|
||||||
verify(streamListener).closed(
|
verify(streamListener).closed(
|
||||||
statusCaptor.capture(), any(RpcProgress.class), any(Metadata.class));
|
statusCaptor.capture(), any(RpcProgress.class), any(Metadata.class));
|
||||||
|
|
@ -272,7 +296,8 @@ public class DelayedClientTransportTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void startStreamThenShutdownNow() {
|
@Test public void startStreamThenShutdownNow() {
|
||||||
ClientStream stream = delayedTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(streamListener);
|
stream.start(streamListener);
|
||||||
delayedTransport.shutdownNow(Status.UNAVAILABLE);
|
delayedTransport.shutdownNow(Status.UNAVAILABLE);
|
||||||
verify(transportListener).transportShutdown(any(Status.class));
|
verify(transportListener).transportShutdown(any(Status.class));
|
||||||
|
|
@ -286,7 +311,8 @@ public class DelayedClientTransportTest {
|
||||||
delayedTransport.shutdownNow(Status.UNAVAILABLE);
|
delayedTransport.shutdownNow(Status.UNAVAILABLE);
|
||||||
verify(transportListener).transportShutdown(any(Status.class));
|
verify(transportListener).transportShutdown(any(Status.class));
|
||||||
verify(transportListener).transportTerminated();
|
verify(transportListener).transportTerminated();
|
||||||
ClientStream stream = delayedTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(streamListener);
|
stream.start(streamListener);
|
||||||
verify(streamListener).closed(
|
verify(streamListener).closed(
|
||||||
statusCaptor.capture(), any(RpcProgress.class), any(Metadata.class));
|
statusCaptor.capture(), any(RpcProgress.class), any(Metadata.class));
|
||||||
|
|
@ -301,55 +327,59 @@ public class DelayedClientTransportTest {
|
||||||
AbstractSubchannel subchannel1 = mock(AbstractSubchannel.class);
|
AbstractSubchannel subchannel1 = mock(AbstractSubchannel.class);
|
||||||
AbstractSubchannel subchannel2 = mock(AbstractSubchannel.class);
|
AbstractSubchannel subchannel2 = mock(AbstractSubchannel.class);
|
||||||
AbstractSubchannel subchannel3 = mock(AbstractSubchannel.class);
|
AbstractSubchannel subchannel3 = mock(AbstractSubchannel.class);
|
||||||
when(mockRealTransport.newStream(any(MethodDescriptor.class), any(Metadata.class),
|
when(mockRealTransport.newStream(
|
||||||
any(CallOptions.class))).thenReturn(mockRealStream);
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
when(mockRealTransport2.newStream(any(MethodDescriptor.class), any(Metadata.class),
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
any(CallOptions.class))).thenReturn(mockRealStream2);
|
.thenReturn(mockRealStream);
|
||||||
|
when(mockRealTransport2.newStream(
|
||||||
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
|
.thenReturn(mockRealStream2);
|
||||||
when(subchannel1.getInternalSubchannel()).thenReturn(newTransportProvider(mockRealTransport));
|
when(subchannel1.getInternalSubchannel()).thenReturn(newTransportProvider(mockRealTransport));
|
||||||
when(subchannel2.getInternalSubchannel()).thenReturn(newTransportProvider(mockRealTransport2));
|
when(subchannel2.getInternalSubchannel()).thenReturn(newTransportProvider(mockRealTransport2));
|
||||||
when(subchannel3.getInternalSubchannel()).thenReturn(newTransportProvider(null));
|
when(subchannel3.getInternalSubchannel()).thenReturn(newTransportProvider(null));
|
||||||
|
|
||||||
// Fail-fast streams
|
// Fail-fast streams
|
||||||
DelayedStream ff1 = (DelayedStream) delayedTransport.newStream(
|
DelayedStream ff1 = (DelayedStream) delayedTransport.newStream(
|
||||||
method, headers, failFastCallOptions);
|
method, headers, failFastCallOptions, tracers);
|
||||||
ff1.start(mock(ClientStreamListener.class));
|
ff1.start(mock(ClientStreamListener.class));
|
||||||
ff1.halfClose();
|
ff1.halfClose();
|
||||||
PickSubchannelArgsImpl ff1args = new PickSubchannelArgsImpl(method, headers,
|
PickSubchannelArgsImpl ff1args = new PickSubchannelArgsImpl(method, headers,
|
||||||
failFastCallOptions);
|
failFastCallOptions);
|
||||||
verify(transportListener).transportInUse(true);
|
verify(transportListener).transportInUse(true);
|
||||||
DelayedStream ff2 = (DelayedStream) delayedTransport.newStream(
|
DelayedStream ff2 = (DelayedStream) delayedTransport.newStream(
|
||||||
method2, headers2, failFastCallOptions);
|
method2, headers2, failFastCallOptions, tracers);
|
||||||
PickSubchannelArgsImpl ff2args = new PickSubchannelArgsImpl(method2, headers2,
|
PickSubchannelArgsImpl ff2args = new PickSubchannelArgsImpl(method2, headers2,
|
||||||
failFastCallOptions);
|
failFastCallOptions);
|
||||||
DelayedStream ff3 = (DelayedStream) delayedTransport.newStream(
|
DelayedStream ff3 = (DelayedStream) delayedTransport.newStream(
|
||||||
method, headers, failFastCallOptions);
|
method, headers, failFastCallOptions, tracers);
|
||||||
PickSubchannelArgsImpl ff3args = new PickSubchannelArgsImpl(method, headers,
|
PickSubchannelArgsImpl ff3args = new PickSubchannelArgsImpl(method, headers,
|
||||||
failFastCallOptions);
|
failFastCallOptions);
|
||||||
DelayedStream ff4 = (DelayedStream) delayedTransport.newStream(
|
DelayedStream ff4 = (DelayedStream) delayedTransport.newStream(
|
||||||
method2, headers2, failFastCallOptions);
|
method2, headers2, failFastCallOptions, tracers);
|
||||||
PickSubchannelArgsImpl ff4args = new PickSubchannelArgsImpl(method2, headers2,
|
PickSubchannelArgsImpl ff4args = new PickSubchannelArgsImpl(method2, headers2,
|
||||||
failFastCallOptions);
|
failFastCallOptions);
|
||||||
|
|
||||||
// Wait-for-ready streams
|
// Wait-for-ready streams
|
||||||
FakeClock wfr3Executor = new FakeClock();
|
FakeClock wfr3Executor = new FakeClock();
|
||||||
DelayedStream wfr1 = (DelayedStream) delayedTransport.newStream(
|
DelayedStream wfr1 = (DelayedStream) delayedTransport.newStream(
|
||||||
method, headers, waitForReadyCallOptions);
|
method, headers, waitForReadyCallOptions, tracers);
|
||||||
PickSubchannelArgsImpl wfr1args = new PickSubchannelArgsImpl(method, headers,
|
PickSubchannelArgsImpl wfr1args = new PickSubchannelArgsImpl(method, headers,
|
||||||
waitForReadyCallOptions);
|
waitForReadyCallOptions);
|
||||||
DelayedStream wfr2 = (DelayedStream) delayedTransport.newStream(
|
DelayedStream wfr2 = (DelayedStream) delayedTransport.newStream(
|
||||||
method2, headers2, waitForReadyCallOptions);
|
method2, headers2, waitForReadyCallOptions, tracers);
|
||||||
PickSubchannelArgsImpl wfr2args = new PickSubchannelArgsImpl(method2, headers2,
|
PickSubchannelArgsImpl wfr2args = new PickSubchannelArgsImpl(method2, headers2,
|
||||||
waitForReadyCallOptions);
|
waitForReadyCallOptions);
|
||||||
CallOptions wfr3callOptions = waitForReadyCallOptions.withExecutor(
|
CallOptions wfr3callOptions = waitForReadyCallOptions.withExecutor(
|
||||||
wfr3Executor.getScheduledExecutorService());
|
wfr3Executor.getScheduledExecutorService());
|
||||||
DelayedStream wfr3 = (DelayedStream) delayedTransport.newStream(
|
DelayedStream wfr3 = (DelayedStream) delayedTransport.newStream(
|
||||||
method, headers, wfr3callOptions);
|
method, headers, wfr3callOptions, tracers);
|
||||||
wfr3.start(mock(ClientStreamListener.class));
|
wfr3.start(mock(ClientStreamListener.class));
|
||||||
wfr3.halfClose();
|
wfr3.halfClose();
|
||||||
PickSubchannelArgsImpl wfr3args = new PickSubchannelArgsImpl(method, headers,
|
PickSubchannelArgsImpl wfr3args = new PickSubchannelArgsImpl(method, headers,
|
||||||
wfr3callOptions);
|
wfr3callOptions);
|
||||||
DelayedStream wfr4 = (DelayedStream) delayedTransport.newStream(
|
DelayedStream wfr4 = (DelayedStream) delayedTransport.newStream(
|
||||||
method2, headers2, waitForReadyCallOptions);
|
method2, headers2, waitForReadyCallOptions, tracers);
|
||||||
PickSubchannelArgsImpl wfr4args = new PickSubchannelArgsImpl(method2, headers2,
|
PickSubchannelArgsImpl wfr4args = new PickSubchannelArgsImpl(method2, headers2,
|
||||||
waitForReadyCallOptions);
|
waitForReadyCallOptions);
|
||||||
|
|
||||||
|
|
@ -386,8 +416,10 @@ public class DelayedClientTransportTest {
|
||||||
// streams are now owned by a real transport (which should prevent the Channel from
|
// streams are now owned by a real transport (which should prevent the Channel from
|
||||||
// terminating).
|
// terminating).
|
||||||
// ff1 and wfr1 went through
|
// ff1 and wfr1 went through
|
||||||
verify(mockRealTransport).newStream(method, headers, failFastCallOptions);
|
verify(mockRealTransport).newStream(
|
||||||
verify(mockRealTransport2).newStream(method, headers, waitForReadyCallOptions);
|
method, headers, failFastCallOptions, tracers);
|
||||||
|
verify(mockRealTransport2).newStream(
|
||||||
|
method, headers, waitForReadyCallOptions, tracers);
|
||||||
assertSame(mockRealStream, ff1.getRealStream());
|
assertSame(mockRealStream, ff1.getRealStream());
|
||||||
assertSame(mockRealStream2, wfr1.getRealStream());
|
assertSame(mockRealStream2, wfr1.getRealStream());
|
||||||
verify(mockRealStream).start(any(ClientStreamListener.class));
|
verify(mockRealStream).start(any(ClientStreamListener.class));
|
||||||
|
|
@ -443,7 +475,7 @@ public class DelayedClientTransportTest {
|
||||||
|
|
||||||
// New streams will use the last picker
|
// New streams will use the last picker
|
||||||
DelayedStream wfr5 = (DelayedStream) delayedTransport.newStream(
|
DelayedStream wfr5 = (DelayedStream) delayedTransport.newStream(
|
||||||
method, headers, waitForReadyCallOptions);
|
method, headers, waitForReadyCallOptions, tracers);
|
||||||
assertNull(wfr5.getRealStream());
|
assertNull(wfr5.getRealStream());
|
||||||
inOrder.verify(picker).pickSubchannel(
|
inOrder.verify(picker).pickSubchannel(
|
||||||
new PickSubchannelArgsImpl(method, headers, waitForReadyCallOptions));
|
new PickSubchannelArgsImpl(method, headers, waitForReadyCallOptions));
|
||||||
|
|
@ -474,14 +506,17 @@ public class DelayedClientTransportTest {
|
||||||
when(subchannel.getInternalSubchannel()).thenReturn(mockInternalSubchannel);
|
when(subchannel.getInternalSubchannel()).thenReturn(mockInternalSubchannel);
|
||||||
when(picker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(
|
when(picker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(
|
||||||
PickResult.withSubchannel(subchannel));
|
PickResult.withSubchannel(subchannel));
|
||||||
when(mockRealTransport.newStream(any(MethodDescriptor.class), any(Metadata.class),
|
when(mockRealTransport.newStream(
|
||||||
any(CallOptions.class))).thenReturn(mockRealStream);
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
|
.thenReturn(mockRealStream);
|
||||||
delayedTransport.reprocess(picker);
|
delayedTransport.reprocess(picker);
|
||||||
verifyNoMoreInteractions(picker);
|
verifyNoMoreInteractions(picker);
|
||||||
verifyNoMoreInteractions(transportListener);
|
verifyNoMoreInteractions(transportListener);
|
||||||
|
|
||||||
// Though picker was not originally used, it will be saved and serve future streams.
|
// Though picker was not originally used, it will be saved and serve future streams.
|
||||||
ClientStream stream = delayedTransport.newStream(method, headers, CallOptions.DEFAULT);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, headers, CallOptions.DEFAULT, tracers);
|
||||||
verify(picker).pickSubchannel(new PickSubchannelArgsImpl(method, headers, CallOptions.DEFAULT));
|
verify(picker).pickSubchannel(new PickSubchannelArgsImpl(method, headers, CallOptions.DEFAULT));
|
||||||
verify(mockInternalSubchannel).obtainActiveTransport();
|
verify(mockInternalSubchannel).obtainActiveTransport();
|
||||||
assertSame(mockRealStream, stream);
|
assertSame(mockRealStream, stream);
|
||||||
|
|
@ -519,7 +554,7 @@ public class DelayedClientTransportTest {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Will call pickSubchannel and wait on barrier
|
// Will call pickSubchannel and wait on barrier
|
||||||
delayedTransport.newStream(method, headers, callOptions);
|
delayedTransport.newStream(method, headers, callOptions, tracers);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
sideThread.start();
|
sideThread.start();
|
||||||
|
|
@ -552,7 +587,7 @@ public class DelayedClientTransportTest {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Will call pickSubchannel and wait on barrier
|
// Will call pickSubchannel and wait on barrier
|
||||||
delayedTransport.newStream(method, headers2, callOptions);
|
delayedTransport.newStream(method, headers2, callOptions, tracers);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
sideThread2.start();
|
sideThread2.start();
|
||||||
|
|
@ -600,7 +635,8 @@ public class DelayedClientTransportTest {
|
||||||
// Because there is no pending stream yet, it will do nothing but save the picker.
|
// Because there is no pending stream yet, it will do nothing but save the picker.
|
||||||
delayedTransport.reprocess(picker);
|
delayedTransport.reprocess(picker);
|
||||||
|
|
||||||
ClientStream stream = delayedTransport.newStream(method, headers, callOptions);
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, headers, callOptions, tracers);
|
||||||
stream.start(streamListener);
|
stream.start(streamListener);
|
||||||
assertTrue(delayedTransport.hasPendingStreams());
|
assertTrue(delayedTransport.hasPendingStreams());
|
||||||
verify(transportListener).transportInUse(true);
|
verify(transportListener).transportInUse(true);
|
||||||
|
|
@ -609,7 +645,7 @@ public class DelayedClientTransportTest {
|
||||||
@Test
|
@Test
|
||||||
public void pendingStream_appendTimeoutInsight_waitForReady() {
|
public void pendingStream_appendTimeoutInsight_waitForReady() {
|
||||||
ClientStream stream = delayedTransport.newStream(
|
ClientStream stream = delayedTransport.newStream(
|
||||||
method, headers, callOptions.withWaitForReady());
|
method, headers, callOptions.withWaitForReady(), tracers);
|
||||||
stream.start(streamListener);
|
stream.start(streamListener);
|
||||||
InsightBuilder insight = new InsightBuilder();
|
InsightBuilder insight = new InsightBuilder();
|
||||||
stream.appendTimeoutInsight(insight);
|
stream.appendTimeoutInsight(insight);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.Status;
|
import io.grpc.Status;
|
||||||
import io.grpc.internal.ClientStreamListener.RpcProgress;
|
import io.grpc.internal.ClientStreamListener.RpcProgress;
|
||||||
|
|
@ -33,13 +34,16 @@ import org.junit.runners.JUnit4;
|
||||||
*/
|
*/
|
||||||
@RunWith(JUnit4.class)
|
@RunWith(JUnit4.class)
|
||||||
public class FailingClientStreamTest {
|
public class FailingClientStreamTest {
|
||||||
|
private static final ClientStreamTracer[] tracers = new ClientStreamTracer[] {
|
||||||
|
new ClientStreamTracer() {}
|
||||||
|
};
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void processedRpcProgressPopulatedToListener() {
|
public void processedRpcProgressPopulatedToListener() {
|
||||||
ClientStreamListener listener = mock(ClientStreamListener.class);
|
ClientStreamListener listener = mock(ClientStreamListener.class);
|
||||||
Status status = Status.UNAVAILABLE;
|
Status status = Status.UNAVAILABLE;
|
||||||
|
|
||||||
ClientStream stream = new FailingClientStream(status);
|
ClientStream stream = new FailingClientStream(status, RpcProgress.PROCESSED, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
verify(listener).closed(eq(status), eq(RpcProgress.PROCESSED), any(Metadata.class));
|
verify(listener).closed(eq(status), eq(RpcProgress.PROCESSED), any(Metadata.class));
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +53,7 @@ public class FailingClientStreamTest {
|
||||||
ClientStreamListener listener = mock(ClientStreamListener.class);
|
ClientStreamListener listener = mock(ClientStreamListener.class);
|
||||||
Status status = Status.UNAVAILABLE;
|
Status status = Status.UNAVAILABLE;
|
||||||
|
|
||||||
ClientStream stream = new FailingClientStream(status, RpcProgress.DROPPED);
|
ClientStream stream = new FailingClientStream(status, RpcProgress.DROPPED, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
verify(listener).closed(eq(status), eq(RpcProgress.DROPPED), any(Metadata.class));
|
verify(listener).closed(eq(status), eq(RpcProgress.DROPPED), any(Metadata.class));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.Status;
|
import io.grpc.Status;
|
||||||
import io.grpc.internal.ClientStreamListener.RpcProgress;
|
import io.grpc.internal.ClientStreamListener.RpcProgress;
|
||||||
|
|
@ -41,8 +42,9 @@ public class FailingClientTransportTest {
|
||||||
Status error = Status.UNAVAILABLE;
|
Status error = Status.UNAVAILABLE;
|
||||||
RpcProgress rpcProgress = RpcProgress.DROPPED;
|
RpcProgress rpcProgress = RpcProgress.DROPPED;
|
||||||
FailingClientTransport transport = new FailingClientTransport(error, rpcProgress);
|
FailingClientTransport transport = new FailingClientTransport(error, rpcProgress);
|
||||||
ClientStream stream = transport
|
ClientStream stream = transport.newStream(
|
||||||
.newStream(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT);
|
TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT,
|
||||||
|
new ClientStreamTracer[] { new ClientStreamTracer() {} });
|
||||||
ClientStreamListener listener = mock(ClientStreamListener.class);
|
ClientStreamListener listener = mock(ClientStreamListener.class);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 The gRPC Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.grpc.internal;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
|
import io.grpc.ForwardingTestUtil;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Collections;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
|
/** Unit tests for {@link ForwardingClientStreamTracer}. */
|
||||||
|
@RunWith(JUnit4.class)
|
||||||
|
public class ForwardingClientStreamTracerTest {
|
||||||
|
private final ClientStreamTracer mockDelegate = mock(ClientStreamTracer.class);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void allMethodsForwarded() throws Exception {
|
||||||
|
ForwardingTestUtil.testMethodsForwarded(
|
||||||
|
ClientStreamTracer.class,
|
||||||
|
mockDelegate,
|
||||||
|
new ForwardingClientStreamTracerTest.TestClientStreamTracer(),
|
||||||
|
Collections.<Method>emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class TestClientStreamTracer extends ForwardingClientStreamTracer {
|
||||||
|
@Override
|
||||||
|
protected ClientStreamTracer delegate() {
|
||||||
|
return mockDelegate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package io.grpc.internal;
|
package io.grpc.internal;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
@ -27,13 +28,17 @@ import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
|
import io.grpc.ClientStreamTracer.StreamInfo;
|
||||||
import io.grpc.LoadBalancer.PickResult;
|
import io.grpc.LoadBalancer.PickResult;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.Status;
|
import io.grpc.Status;
|
||||||
import io.grpc.internal.ClientStreamListener.RpcProgress;
|
import io.grpc.internal.ClientStreamListener.RpcProgress;
|
||||||
import io.grpc.internal.GrpcUtil.Http2Error;
|
import io.grpc.internal.GrpcUtil.Http2Error;
|
||||||
import io.grpc.testing.TestMethodDescriptors;
|
import io.grpc.testing.TestMethodDescriptors;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
@ -44,6 +49,10 @@ import org.junit.runners.JUnit4;
|
||||||
@RunWith(JUnit4.class)
|
@RunWith(JUnit4.class)
|
||||||
public class GrpcUtilTest {
|
public class GrpcUtilTest {
|
||||||
|
|
||||||
|
private static final ClientStreamTracer[] tracers = new ClientStreamTracer[] {
|
||||||
|
new ClientStreamTracer() {}
|
||||||
|
};
|
||||||
|
|
||||||
@SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467
|
@SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467
|
||||||
@Rule public final ExpectedException thrown = ExpectedException.none();
|
@Rule public final ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
|
@ -244,8 +253,9 @@ public class GrpcUtilTest {
|
||||||
|
|
||||||
assertNotNull(transport);
|
assertNotNull(transport);
|
||||||
|
|
||||||
ClientStream stream = transport
|
ClientStream stream = transport.newStream(
|
||||||
.newStream(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT);
|
TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT,
|
||||||
|
tracers);
|
||||||
ClientStreamListener listener = mock(ClientStreamListener.class);
|
ClientStreamListener listener = mock(ClientStreamListener.class);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
|
|
||||||
|
|
@ -260,8 +270,9 @@ public class GrpcUtilTest {
|
||||||
|
|
||||||
assertNotNull(transport);
|
assertNotNull(transport);
|
||||||
|
|
||||||
ClientStream stream = transport
|
ClientStream stream = transport.newStream(
|
||||||
.newStream(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT);
|
TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT,
|
||||||
|
tracers);
|
||||||
ClientStreamListener listener = mock(ClientStreamListener.class);
|
ClientStreamListener listener = mock(ClientStreamListener.class);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
|
|
||||||
|
|
@ -276,11 +287,39 @@ public class GrpcUtilTest {
|
||||||
|
|
||||||
assertNotNull(transport);
|
assertNotNull(transport);
|
||||||
|
|
||||||
ClientStream stream = transport
|
ClientStream stream = transport.newStream(
|
||||||
.newStream(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT);
|
TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT,
|
||||||
|
tracers);
|
||||||
ClientStreamListener listener = mock(ClientStreamListener.class);
|
ClientStreamListener listener = mock(ClientStreamListener.class);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
|
|
||||||
verify(listener).closed(eq(status), eq(RpcProgress.DROPPED), any(Metadata.class));
|
verify(listener).closed(eq(status), eq(RpcProgress.DROPPED), any(Metadata.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clientStreamTracerFactoryBackwardCompatibility() {
|
||||||
|
final AtomicReference<Attributes> transportAttrsRef = new AtomicReference<>();
|
||||||
|
final ClientStreamTracer mockTracer = mock(ClientStreamTracer.class);
|
||||||
|
final Metadata.Key<String> key = Metadata.Key.of("fake-key", Metadata.ASCII_STRING_MARSHALLER);
|
||||||
|
ClientStreamTracer.Factory oldFactoryImpl = new ClientStreamTracer.Factory() {
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
|
||||||
|
transportAttrsRef.set(info.getTransportAttrs());
|
||||||
|
headers.put(key, "fake-value");
|
||||||
|
return mockTracer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
StreamInfo info =
|
||||||
|
StreamInfo.newBuilder().setCallOptions(CallOptions.DEFAULT.withWaitForReady()).build();
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
Attributes transAttrs =
|
||||||
|
Attributes.newBuilder().set(Attributes.Key.<String>create("foo"), "bar").build();
|
||||||
|
ClientStreamTracer tracer = GrpcUtil.newClientStreamTracer(oldFactoryImpl, info, metadata);
|
||||||
|
tracer.streamCreated(transAttrs, metadata);
|
||||||
|
|
||||||
|
assertThat(transportAttrsRef.get()).isEqualTo(transAttrs);
|
||||||
|
assertThat(metadata.get(key)).isEqualTo("fake-value");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ import io.grpc.ClientCall;
|
||||||
import io.grpc.ClientInterceptor;
|
import io.grpc.ClientInterceptor;
|
||||||
import io.grpc.ClientInterceptors;
|
import io.grpc.ClientInterceptors;
|
||||||
import io.grpc.ClientStreamTracer;
|
import io.grpc.ClientStreamTracer;
|
||||||
|
import io.grpc.ClientStreamTracer.StreamInfo;
|
||||||
import io.grpc.CompositeChannelCredentials;
|
import io.grpc.CompositeChannelCredentials;
|
||||||
import io.grpc.ConnectivityState;
|
import io.grpc.ConnectivityState;
|
||||||
import io.grpc.ConnectivityStateInfo;
|
import io.grpc.ConnectivityStateInfo;
|
||||||
|
|
@ -151,6 +152,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Captor;
|
import org.mockito.Captor;
|
||||||
import org.mockito.InOrder;
|
import org.mockito.InOrder;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
|
@ -225,6 +227,8 @@ public class ManagedChannelImplTest {
|
||||||
private ArgumentCaptor<Status> statusCaptor;
|
private ArgumentCaptor<Status> statusCaptor;
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<CallOptions> callOptionsCaptor;
|
private ArgumentCaptor<CallOptions> callOptionsCaptor;
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<ClientStreamTracer[]> tracersCaptor;
|
||||||
@Mock
|
@Mock
|
||||||
private LoadBalancer mockLoadBalancer;
|
private LoadBalancer mockLoadBalancer;
|
||||||
@Mock
|
@Mock
|
||||||
|
|
@ -525,7 +529,9 @@ public class ManagedChannelImplTest {
|
||||||
MockClientTransportInfo transportInfo = transports.poll();
|
MockClientTransportInfo transportInfo = transports.poll();
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
||||||
when(mockTransport.newStream(same(method), same(headers), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), same(headers), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
transportListener.transportReady();
|
transportListener.transportReady();
|
||||||
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class)))
|
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class)))
|
||||||
|
|
@ -534,7 +540,9 @@ public class ManagedChannelImplTest {
|
||||||
executor.runDueTasks();
|
executor.runDueTasks();
|
||||||
|
|
||||||
ArgumentCaptor<CallOptions> callOptionsCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<CallOptions> callOptionsCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockTransport).newStream(same(method), same(headers), callOptionsCaptor.capture());
|
verify(mockTransport).newStream(
|
||||||
|
same(method), same(headers), callOptionsCaptor.capture(),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertThat(callOptionsCaptor.getValue().isWaitForReady()).isTrue();
|
assertThat(callOptionsCaptor.getValue().isWaitForReady()).isTrue();
|
||||||
verify(mockStream).start(streamListenerCaptor.capture());
|
verify(mockStream).start(streamListenerCaptor.capture());
|
||||||
|
|
||||||
|
|
@ -600,7 +608,9 @@ public class ManagedChannelImplTest {
|
||||||
MockClientTransportInfo transportInfo = transports.poll();
|
MockClientTransportInfo transportInfo = transports.poll();
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
||||||
when(mockTransport.newStream(same(method), same(headers), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), same(headers), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
transportListener.transportReady();
|
transportListener.transportReady();
|
||||||
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class)))
|
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class)))
|
||||||
|
|
@ -609,7 +619,9 @@ public class ManagedChannelImplTest {
|
||||||
executor.runDueTasks();
|
executor.runDueTasks();
|
||||||
|
|
||||||
ArgumentCaptor<CallOptions> callOptionsCaptor = ArgumentCaptor.forClass(null);
|
ArgumentCaptor<CallOptions> callOptionsCaptor = ArgumentCaptor.forClass(null);
|
||||||
verify(mockTransport).newStream(same(method), same(headers), callOptionsCaptor.capture());
|
verify(mockTransport).newStream(
|
||||||
|
same(method), same(headers), callOptionsCaptor.capture(),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertThat(callOptionsCaptor.getValue().getOption(callOptionsKey)).isEqualTo("fooValue");
|
assertThat(callOptionsCaptor.getValue().getOption(callOptionsKey)).isEqualTo("fooValue");
|
||||||
verify(mockStream).start(streamListenerCaptor.capture());
|
verify(mockStream).start(streamListenerCaptor.capture());
|
||||||
|
|
||||||
|
|
@ -800,9 +812,13 @@ public class ManagedChannelImplTest {
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
verify(mockTransport).start(any(ManagedClientTransport.Listener.class));
|
verify(mockTransport).start(any(ManagedClientTransport.Listener.class));
|
||||||
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
||||||
when(mockTransport.newStream(same(method), same(headers), same(CallOptions.DEFAULT)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), same(headers), same(CallOptions.DEFAULT),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
when(mockTransport.newStream(same(method), same(headers2), same(CallOptions.DEFAULT)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), same(headers2), same(CallOptions.DEFAULT),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream2);
|
.thenReturn(mockStream2);
|
||||||
transportListener.transportReady();
|
transportListener.transportReady();
|
||||||
when(mockPicker.pickSubchannel(
|
when(mockPicker.pickSubchannel(
|
||||||
|
|
@ -820,14 +836,19 @@ public class ManagedChannelImplTest {
|
||||||
any(SocketAddress.class), any(ClientTransportOptions.class), any(ChannelLogger.class));
|
any(SocketAddress.class), any(ClientTransportOptions.class), any(ChannelLogger.class));
|
||||||
call.start(mockCallListener, headers);
|
call.start(mockCallListener, headers);
|
||||||
|
|
||||||
verify(mockTransport, never())
|
verify(mockTransport, never()).newStream(
|
||||||
.newStream(same(method), same(headers), same(CallOptions.DEFAULT));
|
same(method), same(headers), same(CallOptions.DEFAULT),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
|
||||||
// Second RPC, will be assigned to the real transport
|
// Second RPC, will be assigned to the real transport
|
||||||
ClientCall<String, Integer> call2 = channel.newCall(method, CallOptions.DEFAULT);
|
ClientCall<String, Integer> call2 = channel.newCall(method, CallOptions.DEFAULT);
|
||||||
call2.start(mockCallListener2, headers2);
|
call2.start(mockCallListener2, headers2);
|
||||||
verify(mockTransport).newStream(same(method), same(headers2), same(CallOptions.DEFAULT));
|
verify(mockTransport).newStream(
|
||||||
verify(mockTransport).newStream(same(method), same(headers2), same(CallOptions.DEFAULT));
|
same(method), same(headers2), same(CallOptions.DEFAULT),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
verify(mockTransport).newStream(
|
||||||
|
same(method), same(headers2), same(CallOptions.DEFAULT),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
verify(mockStream2).start(any(ClientStreamListener.class));
|
verify(mockStream2).start(any(ClientStreamListener.class));
|
||||||
|
|
||||||
// Shutdown
|
// Shutdown
|
||||||
|
|
@ -872,7 +893,9 @@ public class ManagedChannelImplTest {
|
||||||
.thenReturn(PickResult.withSubchannel(subchannel));
|
.thenReturn(PickResult.withSubchannel(subchannel));
|
||||||
updateBalancingStateSafely(helper, READY, picker2);
|
updateBalancingStateSafely(helper, READY, picker2);
|
||||||
executor.runDueTasks();
|
executor.runDueTasks();
|
||||||
verify(mockTransport).newStream(same(method), same(headers), same(CallOptions.DEFAULT));
|
verify(mockTransport).newStream(
|
||||||
|
same(method), same(headers), same(CallOptions.DEFAULT),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
verify(mockStream).start(any(ClientStreamListener.class));
|
verify(mockStream).start(any(ClientStreamListener.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1021,7 +1044,9 @@ public class ManagedChannelImplTest {
|
||||||
MockClientTransportInfo transportInfo = transports.poll();
|
MockClientTransportInfo transportInfo = transports.poll();
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
||||||
when(mockTransport.newStream(same(method), same(headers), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), same(headers), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
transportListener.transportReady();
|
transportListener.transportReady();
|
||||||
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class)))
|
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class)))
|
||||||
|
|
@ -1031,7 +1056,8 @@ public class ManagedChannelImplTest {
|
||||||
|
|
||||||
// Real streams are started in the call executor if they were previously buffered.
|
// Real streams are started in the call executor if they were previously buffered.
|
||||||
assertEquals(1, callExecutor.runDueTasks());
|
assertEquals(1, callExecutor.runDueTasks());
|
||||||
verify(mockTransport).newStream(same(method), same(headers), same(options));
|
verify(mockTransport).newStream(
|
||||||
|
same(method), same(headers), same(options), ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
verify(mockStream).start(streamListenerCaptor.capture());
|
verify(mockStream).start(streamListenerCaptor.capture());
|
||||||
|
|
||||||
// Call listener callbacks are also run in the call executor
|
// Call listener callbacks are also run in the call executor
|
||||||
|
|
@ -1298,7 +1324,8 @@ public class ManagedChannelImplTest {
|
||||||
same(goodAddress), any(ClientTransportOptions.class), any(ChannelLogger.class));
|
same(goodAddress), any(ClientTransportOptions.class), any(ChannelLogger.class));
|
||||||
MockClientTransportInfo goodTransportInfo = transports.poll();
|
MockClientTransportInfo goodTransportInfo = transports.poll();
|
||||||
when(goodTransportInfo.transport.newStream(
|
when(goodTransportInfo.transport.newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class)))
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mock(ClientStream.class));
|
.thenReturn(mock(ClientStream.class));
|
||||||
|
|
||||||
goodTransportInfo.listener.transportReady();
|
goodTransportInfo.listener.transportReady();
|
||||||
|
|
@ -1310,11 +1337,13 @@ public class ManagedChannelImplTest {
|
||||||
// Delayed transport uses the app executor to create real streams.
|
// Delayed transport uses the app executor to create real streams.
|
||||||
executor.runDueTasks();
|
executor.runDueTasks();
|
||||||
|
|
||||||
verify(goodTransportInfo.transport).newStream(same(method), same(headers),
|
verify(goodTransportInfo.transport).newStream(
|
||||||
same(CallOptions.DEFAULT));
|
same(method), same(headers), same(CallOptions.DEFAULT),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
// The bad transport was never used.
|
// The bad transport was never used.
|
||||||
verify(badTransportInfo.transport, times(0)).newStream(any(MethodDescriptor.class),
|
verify(badTransportInfo.transport, times(0)).newStream(
|
||||||
any(Metadata.class), any(CallOptions.class));
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -1464,10 +1493,12 @@ public class ManagedChannelImplTest {
|
||||||
// ... while the wait-for-ready call stays
|
// ... while the wait-for-ready call stays
|
||||||
verifyNoMoreInteractions(mockCallListener);
|
verifyNoMoreInteractions(mockCallListener);
|
||||||
// No real stream was ever created
|
// No real stream was ever created
|
||||||
verify(transportInfo1.transport, times(0))
|
verify(transportInfo1.transport, times(0)).newStream(
|
||||||
.newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
verify(transportInfo2.transport, times(0))
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
.newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
|
verify(transportInfo2.transport, times(0)).newStream(
|
||||||
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -1763,8 +1794,9 @@ public class ManagedChannelImplTest {
|
||||||
assertEquals(0, balancerRpcExecutor.numPendingTasks());
|
assertEquals(0, balancerRpcExecutor.numPendingTasks());
|
||||||
transportInfo.listener.transportReady();
|
transportInfo.listener.transportReady();
|
||||||
assertEquals(1, balancerRpcExecutor.runDueTasks());
|
assertEquals(1, balancerRpcExecutor.runDueTasks());
|
||||||
verify(transportInfo.transport).newStream(same(method), same(headers),
|
verify(transportInfo.transport).newStream(
|
||||||
same(CallOptions.DEFAULT));
|
same(method), same(headers), same(CallOptions.DEFAULT),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
|
||||||
// The transport goes away
|
// The transport goes away
|
||||||
transportInfo.listener.transportShutdown(Status.UNAVAILABLE);
|
transportInfo.listener.transportShutdown(Status.UNAVAILABLE);
|
||||||
|
|
@ -1870,7 +1902,9 @@ public class ManagedChannelImplTest {
|
||||||
ClientCall<String, Integer> call = channel.newCall(method, callOptions);
|
ClientCall<String, Integer> call = channel.newCall(method, callOptions);
|
||||||
call.start(mockCallListener, headers);
|
call.start(mockCallListener, headers);
|
||||||
|
|
||||||
verify(transportInfo.transport).newStream(same(method), same(headers), same(callOptions));
|
verify(transportInfo.transport).newStream(
|
||||||
|
same(method), same(headers), same(callOptions),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertThat(headers.getAll(metadataKey))
|
assertThat(headers.getAll(metadataKey))
|
||||||
.containsExactly(channelCredValue, callCredValue).inOrder();
|
.containsExactly(channelCredValue, callCredValue).inOrder();
|
||||||
|
|
||||||
|
|
@ -1887,7 +1921,9 @@ public class ManagedChannelImplTest {
|
||||||
transportInfo.listener.transportReady();
|
transportInfo.listener.transportReady();
|
||||||
balancerRpcExecutor.runDueTasks();
|
balancerRpcExecutor.runDueTasks();
|
||||||
|
|
||||||
verify(transportInfo.transport).newStream(same(method), same(headers), same(callOptions));
|
verify(transportInfo.transport).newStream(
|
||||||
|
same(method), same(headers), same(callOptions),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertThat(headers.getAll(metadataKey)).containsExactly(callCredValue);
|
assertThat(headers.getAll(metadataKey)).containsExactly(callCredValue);
|
||||||
oob.shutdownNow();
|
oob.shutdownNow();
|
||||||
|
|
||||||
|
|
@ -1919,7 +1955,9 @@ public class ManagedChannelImplTest {
|
||||||
call.start(mockCallListener2, headers);
|
call.start(mockCallListener2, headers);
|
||||||
|
|
||||||
// CallOptions may contain StreamTracerFactory for census that is added by default.
|
// CallOptions may contain StreamTracerFactory for census that is added by default.
|
||||||
verify(transportInfo.transport).newStream(same(method), same(headers), any(CallOptions.class));
|
verify(transportInfo.transport).newStream(
|
||||||
|
same(method), same(headers), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertThat(headers.getAll(metadataKey)).containsExactly(callCredValue);
|
assertThat(headers.getAll(metadataKey)).containsExactly(callCredValue);
|
||||||
oob.shutdownNow();
|
oob.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|
@ -1962,7 +2000,9 @@ public class ManagedChannelImplTest {
|
||||||
ClientCall<String, Integer> call = channel.newCall(method, callOptions);
|
ClientCall<String, Integer> call = channel.newCall(method, callOptions);
|
||||||
call.start(mockCallListener, headers);
|
call.start(mockCallListener, headers);
|
||||||
|
|
||||||
verify(transportInfo.transport).newStream(same(method), same(headers), same(callOptions));
|
verify(transportInfo.transport).newStream(
|
||||||
|
same(method), same(headers), same(callOptions),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertThat(headers.getAll(metadataKey))
|
assertThat(headers.getAll(metadataKey))
|
||||||
.containsExactly(channelCredValue, callCredValue).inOrder();
|
.containsExactly(channelCredValue, callCredValue).inOrder();
|
||||||
|
|
||||||
|
|
@ -1998,7 +2038,9 @@ public class ManagedChannelImplTest {
|
||||||
call.start(mockCallListener2, headers);
|
call.start(mockCallListener2, headers);
|
||||||
|
|
||||||
// CallOptions may contain StreamTracerFactory for census that is added by default.
|
// CallOptions may contain StreamTracerFactory for census that is added by default.
|
||||||
verify(transportInfo.transport).newStream(same(method), same(headers), any(CallOptions.class));
|
verify(transportInfo.transport).newStream(
|
||||||
|
same(method), same(headers), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertThat(headers.getAll(metadataKey))
|
assertThat(headers.getAll(metadataKey))
|
||||||
.containsExactly(oobChannelCredValue, callCredValue).inOrder();
|
.containsExactly(oobChannelCredValue, callCredValue).inOrder();
|
||||||
oob.shutdownNow();
|
oob.shutdownNow();
|
||||||
|
|
@ -2097,7 +2139,9 @@ public class ManagedChannelImplTest {
|
||||||
|
|
||||||
ClientCall<String, Integer> call = sChannel.newCall(method, callOptions);
|
ClientCall<String, Integer> call = sChannel.newCall(method, callOptions);
|
||||||
call.start(mockCallListener, headers);
|
call.start(mockCallListener, headers);
|
||||||
verify(mockTransport).newStream(same(method), same(headers), callOptionsCaptor.capture());
|
verify(mockTransport).newStream(
|
||||||
|
same(method), same(headers), callOptionsCaptor.capture(),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
|
||||||
CallOptions capturedCallOption = callOptionsCaptor.getValue();
|
CallOptions capturedCallOption = callOptionsCaptor.getValue();
|
||||||
assertThat(capturedCallOption.getDeadline()).isSameInstanceAs(callOptions.getDeadline());
|
assertThat(capturedCallOption.getDeadline()).isSameInstanceAs(callOptions.getDeadline());
|
||||||
|
|
@ -2125,7 +2169,8 @@ public class ManagedChannelImplTest {
|
||||||
ClientCall<String, Integer> call = sChannel.newCall(method, CallOptions.DEFAULT);
|
ClientCall<String, Integer> call = sChannel.newCall(method, CallOptions.DEFAULT);
|
||||||
call.start(mockCallListener, headers);
|
call.start(mockCallListener, headers);
|
||||||
verify(mockTransport, never()).newStream(
|
verify(mockTransport, never()).newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
|
||||||
verifyNoInteractions(mockCallListener);
|
verifyNoInteractions(mockCallListener);
|
||||||
assertEquals(1, balancerRpcExecutor.runDueTasks());
|
assertEquals(1, balancerRpcExecutor.runDueTasks());
|
||||||
|
|
@ -2157,7 +2202,8 @@ public class ManagedChannelImplTest {
|
||||||
sChannel.newCall(method, CallOptions.DEFAULT.withWaitForReady());
|
sChannel.newCall(method, CallOptions.DEFAULT.withWaitForReady());
|
||||||
call.start(mockCallListener, headers);
|
call.start(mockCallListener, headers);
|
||||||
verify(mockTransport, never()).newStream(
|
verify(mockTransport, never()).newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
|
||||||
verifyNoInteractions(mockCallListener);
|
verifyNoInteractions(mockCallListener);
|
||||||
assertEquals(1, balancerRpcExecutor.runDueTasks());
|
assertEquals(1, balancerRpcExecutor.runDueTasks());
|
||||||
|
|
@ -2332,7 +2378,8 @@ public class ManagedChannelImplTest {
|
||||||
return mock(ClientStream.class);
|
return mock(ClientStream.class);
|
||||||
}
|
}
|
||||||
}).when(transport).newStream(
|
}).when(transport).newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
|
||||||
verify(creds, never()).applyRequestMetadata(
|
verify(creds, never()).applyRequestMetadata(
|
||||||
any(RequestInfo.class), any(Executor.class), any(CallCredentials.MetadataApplier.class));
|
any(RequestInfo.class), any(Executor.class), any(CallCredentials.MetadataApplier.class));
|
||||||
|
|
@ -2351,11 +2398,14 @@ public class ManagedChannelImplTest {
|
||||||
assertEquals(AUTHORITY, infoCaptor.getValue().getAuthority());
|
assertEquals(AUTHORITY, infoCaptor.getValue().getAuthority());
|
||||||
assertEquals(SecurityLevel.NONE, infoCaptor.getValue().getSecurityLevel());
|
assertEquals(SecurityLevel.NONE, infoCaptor.getValue().getSecurityLevel());
|
||||||
verify(transport, never()).newStream(
|
verify(transport, never()).newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
|
||||||
// newStream() is called after apply() is called
|
// newStream() is called after apply() is called
|
||||||
applierCaptor.getValue().apply(new Metadata());
|
applierCaptor.getValue().apply(new Metadata());
|
||||||
verify(transport).newStream(same(method), any(Metadata.class), same(callOptions));
|
verify(transport).newStream(
|
||||||
|
same(method), any(Metadata.class), same(callOptions),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertEquals("testValue", testKey.get(newStreamContexts.poll()));
|
assertEquals("testValue", testKey.get(newStreamContexts.poll()));
|
||||||
// The context should not live beyond the scope of newStream() and applyRequestMetadata()
|
// The context should not live beyond the scope of newStream() and applyRequestMetadata()
|
||||||
assertNull(testKey.get());
|
assertNull(testKey.get());
|
||||||
|
|
@ -2374,11 +2424,14 @@ public class ManagedChannelImplTest {
|
||||||
assertEquals(SecurityLevel.NONE, infoCaptor.getValue().getSecurityLevel());
|
assertEquals(SecurityLevel.NONE, infoCaptor.getValue().getSecurityLevel());
|
||||||
// This is from the first call
|
// This is from the first call
|
||||||
verify(transport).newStream(
|
verify(transport).newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
|
|
||||||
// Still, newStream() is called after apply() is called
|
// Still, newStream() is called after apply() is called
|
||||||
applierCaptor.getValue().apply(new Metadata());
|
applierCaptor.getValue().apply(new Metadata());
|
||||||
verify(transport, times(2)).newStream(same(method), any(Metadata.class), same(callOptions));
|
verify(transport, times(2)).newStream(
|
||||||
|
same(method), any(Metadata.class), same(callOptions),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
assertEquals("testValue", testKey.get(newStreamContexts.poll()));
|
assertEquals("testValue", testKey.get(newStreamContexts.poll()));
|
||||||
|
|
||||||
assertNull(testKey.get());
|
assertNull(testKey.get());
|
||||||
|
|
@ -2387,8 +2440,20 @@ public class ManagedChannelImplTest {
|
||||||
@Test
|
@Test
|
||||||
public void pickerReturnsStreamTracer_noDelay() {
|
public void pickerReturnsStreamTracer_noDelay() {
|
||||||
ClientStream mockStream = mock(ClientStream.class);
|
ClientStream mockStream = mock(ClientStream.class);
|
||||||
ClientStreamTracer.Factory factory1 = mock(ClientStreamTracer.Factory.class);
|
final ClientStreamTracer tracer1 = new ClientStreamTracer() {};
|
||||||
ClientStreamTracer.Factory factory2 = mock(ClientStreamTracer.Factory.class);
|
final ClientStreamTracer tracer2 = new ClientStreamTracer() {};
|
||||||
|
ClientStreamTracer.Factory factory1 = new ClientStreamTracer.InternalLimitedInfoFactory() {
|
||||||
|
@Override
|
||||||
|
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
|
||||||
|
return tracer1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ClientStreamTracer.Factory factory2 = new ClientStreamTracer.InternalLimitedInfoFactory() {
|
||||||
|
@Override
|
||||||
|
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
|
||||||
|
return tracer2;
|
||||||
|
}
|
||||||
|
};
|
||||||
createChannel();
|
createChannel();
|
||||||
Subchannel subchannel =
|
Subchannel subchannel =
|
||||||
createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
|
createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
|
||||||
|
|
@ -2397,7 +2462,8 @@ public class ManagedChannelImplTest {
|
||||||
transportInfo.listener.transportReady();
|
transportInfo.listener.transportReady();
|
||||||
ClientTransport mockTransport = transportInfo.transport;
|
ClientTransport mockTransport = transportInfo.transport;
|
||||||
when(mockTransport.newStream(
|
when(mockTransport.newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class)))
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
|
|
||||||
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(
|
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(
|
||||||
|
|
@ -2409,20 +2475,29 @@ public class ManagedChannelImplTest {
|
||||||
call.start(mockCallListener, new Metadata());
|
call.start(mockCallListener, new Metadata());
|
||||||
|
|
||||||
verify(mockPicker).pickSubchannel(any(PickSubchannelArgs.class));
|
verify(mockPicker).pickSubchannel(any(PickSubchannelArgs.class));
|
||||||
verify(mockTransport).newStream(same(method), any(Metadata.class), callOptionsCaptor.capture());
|
verify(mockTransport).newStream(
|
||||||
assertEquals(
|
same(method), any(Metadata.class), callOptionsCaptor.capture(),
|
||||||
Arrays.asList(factory1, factory2),
|
tracersCaptor.capture());
|
||||||
callOptionsCaptor.getValue().getStreamTracerFactories());
|
assertThat(tracersCaptor.getValue()).isEqualTo(new ClientStreamTracer[] {tracer1, tracer2});
|
||||||
// The factories are safely not stubbed because we do not expect any usage of them.
|
|
||||||
verifyNoInteractions(factory1);
|
|
||||||
verifyNoInteractions(factory2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pickerReturnsStreamTracer_delayed() {
|
public void pickerReturnsStreamTracer_delayed() {
|
||||||
ClientStream mockStream = mock(ClientStream.class);
|
ClientStream mockStream = mock(ClientStream.class);
|
||||||
ClientStreamTracer.Factory factory1 = mock(ClientStreamTracer.Factory.class);
|
final ClientStreamTracer tracer1 = new ClientStreamTracer() {};
|
||||||
ClientStreamTracer.Factory factory2 = mock(ClientStreamTracer.Factory.class);
|
final ClientStreamTracer tracer2 = new ClientStreamTracer() {};
|
||||||
|
ClientStreamTracer.Factory factory1 = new ClientStreamTracer.InternalLimitedInfoFactory() {
|
||||||
|
@Override
|
||||||
|
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
|
||||||
|
return tracer1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ClientStreamTracer.Factory factory2 = new ClientStreamTracer.InternalLimitedInfoFactory() {
|
||||||
|
@Override
|
||||||
|
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
|
||||||
|
return tracer2;
|
||||||
|
}
|
||||||
|
};
|
||||||
createChannel();
|
createChannel();
|
||||||
|
|
||||||
CallOptions callOptions = CallOptions.DEFAULT.withStreamTracerFactory(factory1);
|
CallOptions callOptions = CallOptions.DEFAULT.withStreamTracerFactory(factory1);
|
||||||
|
|
@ -2436,7 +2511,8 @@ public class ManagedChannelImplTest {
|
||||||
transportInfo.listener.transportReady();
|
transportInfo.listener.transportReady();
|
||||||
ClientTransport mockTransport = transportInfo.transport;
|
ClientTransport mockTransport = transportInfo.transport;
|
||||||
when(mockTransport.newStream(
|
when(mockTransport.newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class)))
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(
|
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(
|
||||||
PickResult.withSubchannel(subchannel, factory2));
|
PickResult.withSubchannel(subchannel, factory2));
|
||||||
|
|
@ -2445,13 +2521,10 @@ public class ManagedChannelImplTest {
|
||||||
assertEquals(1, executor.runDueTasks());
|
assertEquals(1, executor.runDueTasks());
|
||||||
|
|
||||||
verify(mockPicker).pickSubchannel(any(PickSubchannelArgs.class));
|
verify(mockPicker).pickSubchannel(any(PickSubchannelArgs.class));
|
||||||
verify(mockTransport).newStream(same(method), any(Metadata.class), callOptionsCaptor.capture());
|
verify(mockTransport).newStream(
|
||||||
assertEquals(
|
same(method), any(Metadata.class), callOptionsCaptor.capture(),
|
||||||
Arrays.asList(factory1, factory2),
|
tracersCaptor.capture());
|
||||||
callOptionsCaptor.getValue().getStreamTracerFactories());
|
assertThat(tracersCaptor.getValue()).isEqualTo(new ClientStreamTracer[] {tracer1, tracer2});
|
||||||
// The factories are safely not stubbed because we do not expect any usage of them.
|
|
||||||
verifyNoInteractions(factory1);
|
|
||||||
verifyNoInteractions(factory2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -2818,7 +2891,9 @@ public class ManagedChannelImplTest {
|
||||||
MockClientTransportInfo transportInfo = transports.poll();
|
MockClientTransportInfo transportInfo = transports.poll();
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
||||||
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
transportListener.transportReady();
|
transportListener.transportReady();
|
||||||
|
|
||||||
|
|
@ -2829,7 +2904,9 @@ public class ManagedChannelImplTest {
|
||||||
executor.runDueTasks();
|
executor.runDueTasks();
|
||||||
|
|
||||||
// Verify the buffered call was drained
|
// Verify the buffered call was drained
|
||||||
verify(mockTransport).newStream(same(method), any(Metadata.class), any(CallOptions.class));
|
verify(mockTransport).newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
verify(mockStream).start(any(ClientStreamListener.class));
|
verify(mockStream).start(any(ClientStreamListener.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2888,7 +2965,9 @@ public class ManagedChannelImplTest {
|
||||||
MockClientTransportInfo transportInfo = transports.poll();
|
MockClientTransportInfo transportInfo = transports.poll();
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
||||||
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
transportListener.transportReady();
|
transportListener.transportReady();
|
||||||
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class)))
|
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class)))
|
||||||
|
|
@ -2898,7 +2977,9 @@ public class ManagedChannelImplTest {
|
||||||
|
|
||||||
// Verify the original call was drained
|
// Verify the original call was drained
|
||||||
executor.runDueTasks();
|
executor.runDueTasks();
|
||||||
verify(mockTransport).newStream(same(method), any(Metadata.class), any(CallOptions.class));
|
verify(mockTransport).newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
verify(mockStream).start(any(ClientStreamListener.class));
|
verify(mockStream).start(any(ClientStreamListener.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2920,7 +3001,9 @@ public class ManagedChannelImplTest {
|
||||||
MockClientTransportInfo transportInfo = transports.poll();
|
MockClientTransportInfo transportInfo = transports.poll();
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
||||||
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
transportListener.transportReady();
|
transportListener.transportReady();
|
||||||
|
|
||||||
|
|
@ -2929,8 +3012,9 @@ public class ManagedChannelImplTest {
|
||||||
updateBalancingStateSafely(helper, READY, mockPicker);
|
updateBalancingStateSafely(helper, READY, mockPicker);
|
||||||
|
|
||||||
executor.runDueTasks();
|
executor.runDueTasks();
|
||||||
verify(mockTransport, never())
|
verify(mockTransport, never()).newStream(
|
||||||
.newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
verify(mockStream, never()).start(any(ClientStreamListener.class));
|
verify(mockStream, never()).start(any(ClientStreamListener.class));
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2939,7 +3023,9 @@ public class ManagedChannelImplTest {
|
||||||
updateBalancingStateSafely(helper, READY, mockPicker);
|
updateBalancingStateSafely(helper, READY, mockPicker);
|
||||||
|
|
||||||
executor.runDueTasks();
|
executor.runDueTasks();
|
||||||
verify(mockTransport).newStream(same(method), any(Metadata.class), any(CallOptions.class));
|
verify(mockTransport).newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
verify(mockStream).start(any(ClientStreamListener.class));
|
verify(mockStream).start(any(ClientStreamListener.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2958,7 +3044,9 @@ public class ManagedChannelImplTest {
|
||||||
MockClientTransportInfo transportInfo = transports.poll();
|
MockClientTransportInfo transportInfo = transports.poll();
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
||||||
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
transportListener.transportReady();
|
transportListener.transportReady();
|
||||||
|
|
||||||
|
|
@ -2973,7 +3061,9 @@ public class ManagedChannelImplTest {
|
||||||
updateBalancingStateSafely(helper, READY, mockPicker);
|
updateBalancingStateSafely(helper, READY, mockPicker);
|
||||||
|
|
||||||
executor.runDueTasks();
|
executor.runDueTasks();
|
||||||
verify(mockTransport).newStream(same(method), any(Metadata.class), any(CallOptions.class));
|
verify(mockTransport).newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any());
|
||||||
verify(mockStream).start(any(ClientStreamListener.class));
|
verify(mockStream).start(any(ClientStreamListener.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3405,7 +3495,8 @@ public class ManagedChannelImplTest {
|
||||||
transportInfo.listener.transportReady();
|
transportInfo.listener.transportReady();
|
||||||
ClientTransport mockTransport = transportInfo.transport;
|
ClientTransport mockTransport = transportInfo.transport;
|
||||||
when(mockTransport.newStream(
|
when(mockTransport.newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class)))
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(
|
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(
|
||||||
PickResult.withSubchannel(subchannel, factory));
|
PickResult.withSubchannel(subchannel, factory));
|
||||||
|
|
@ -3478,7 +3569,9 @@ public class ManagedChannelImplTest {
|
||||||
MockClientTransportInfo transportInfo = transports.poll();
|
MockClientTransportInfo transportInfo = transports.poll();
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
ManagedClientTransport.Listener transportListener = transportInfo.listener;
|
||||||
when(mockTransport.newStream(same(method), same(headers), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), same(headers), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream);
|
.thenReturn(mockStream);
|
||||||
|
|
||||||
// subchannel stat bumped when call gets assigned to it
|
// subchannel stat bumped when call gets assigned to it
|
||||||
|
|
@ -3650,7 +3743,9 @@ public class ManagedChannelImplTest {
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
ClientStream mockStream = mock(ClientStream.class);
|
ClientStream mockStream = mock(ClientStream.class);
|
||||||
ClientStream mockStream2 = mock(ClientStream.class);
|
ClientStream mockStream2 = mock(ClientStream.class);
|
||||||
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream).thenReturn(mockStream2);
|
.thenReturn(mockStream).thenReturn(mockStream2);
|
||||||
transportInfo.listener.transportReady();
|
transportInfo.listener.transportReady();
|
||||||
updateBalancingStateSafely(helper, READY, mockPicker);
|
updateBalancingStateSafely(helper, READY, mockPicker);
|
||||||
|
|
@ -3754,7 +3849,9 @@ public class ManagedChannelImplTest {
|
||||||
ConnectionClientTransport mockTransport = transportInfo.transport;
|
ConnectionClientTransport mockTransport = transportInfo.transport;
|
||||||
ClientStream mockStream = mock(ClientStream.class);
|
ClientStream mockStream = mock(ClientStream.class);
|
||||||
ClientStream mockStream2 = mock(ClientStream.class);
|
ClientStream mockStream2 = mock(ClientStream.class);
|
||||||
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
|
when(mockTransport.newStream(
|
||||||
|
same(method), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mockStream).thenReturn(mockStream2);
|
.thenReturn(mockStream).thenReturn(mockStream2);
|
||||||
transportInfo.listener.transportReady();
|
transportInfo.listener.transportReady();
|
||||||
updateBalancingStateSafely(helper, READY, mockPicker);
|
updateBalancingStateSafely(helper, READY, mockPicker);
|
||||||
|
|
|
||||||
|
|
@ -163,9 +163,10 @@ public class RetriableStreamTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ClientStream newSubstream(ClientStreamTracer.Factory tracerFactory, Metadata metadata) {
|
ClientStream newSubstream(
|
||||||
|
Metadata metadata, ClientStreamTracer.Factory tracerFactory, boolean isTransparentRetry) {
|
||||||
bufferSizeTracer =
|
bufferSizeTracer =
|
||||||
tracerFactory.newClientStreamTracer(STREAM_INFO, new Metadata());
|
tracerFactory.newClientStreamTracer(STREAM_INFO, metadata);
|
||||||
int actualPreviousRpcAttemptsInHeader = metadata.get(GRPC_PREVIOUS_RPC_ATTEMPTS) == null
|
int actualPreviousRpcAttemptsInHeader = metadata.get(GRPC_PREVIOUS_RPC_ATTEMPTS) == null
|
||||||
? 0 : Integer.valueOf(metadata.get(GRPC_PREVIOUS_RPC_ATTEMPTS));
|
? 0 : Integer.valueOf(metadata.get(GRPC_PREVIOUS_RPC_ATTEMPTS));
|
||||||
return retriableStreamRecorder.newSubstream(actualPreviousRpcAttemptsInHeader);
|
return retriableStreamRecorder.newSubstream(actualPreviousRpcAttemptsInHeader);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.InternalLogId;
|
import io.grpc.InternalLogId;
|
||||||
import io.grpc.LoadBalancer.PickResult;
|
import io.grpc.LoadBalancer.PickResult;
|
||||||
import io.grpc.LoadBalancer.PickSubchannelArgs;
|
import io.grpc.LoadBalancer.PickSubchannelArgs;
|
||||||
|
|
@ -35,6 +36,7 @@ import java.net.SocketAddress;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
|
@ -118,7 +120,8 @@ public final class TestUtils {
|
||||||
when(mockTransport.getLogId())
|
when(mockTransport.getLogId())
|
||||||
.thenReturn(InternalLogId.allocate("mocktransport", /*details=*/ null));
|
.thenReturn(InternalLogId.allocate("mocktransport", /*details=*/ null));
|
||||||
when(mockTransport.newStream(
|
when(mockTransport.newStream(
|
||||||
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class)))
|
any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class),
|
||||||
|
ArgumentMatchers.<ClientStreamTracer[]>any()))
|
||||||
.thenReturn(mock(ClientStream.class));
|
.thenReturn(mock(ClientStream.class));
|
||||||
// Save the listener
|
// Save the listener
|
||||||
doAnswer(new Answer<Runnable>() {
|
doAnswer(new Answer<Runnable>() {
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ public class ForwardingClientStreamTracerTest {
|
||||||
Collections.<Method>emptyList());
|
Collections.<Method>emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private final class TestClientStreamTracer extends ForwardingClientStreamTracer {
|
private final class TestClientStreamTracer extends ForwardingClientStreamTracer {
|
||||||
@Override
|
@Override
|
||||||
protected ClientStreamTracer delegate() {
|
protected ClientStreamTracer delegate() {
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.InternalChannelz.SocketStats;
|
import io.grpc.InternalChannelz.SocketStats;
|
||||||
import io.grpc.InternalLogId;
|
import io.grpc.InternalLogId;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
|
@ -118,7 +119,7 @@ class CronetClientTransport implements ConnectionClientTransport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CronetClientStream newStream(final MethodDescriptor<?, ?> method, final Metadata headers,
|
public CronetClientStream newStream(final MethodDescriptor<?, ?> method, final Metadata headers,
|
||||||
final CallOptions callOptions) {
|
final CallOptions callOptions, ClientStreamTracer[] tracers) {
|
||||||
Preconditions.checkNotNull(method, "method");
|
Preconditions.checkNotNull(method, "method");
|
||||||
Preconditions.checkNotNull(headers, "headers");
|
Preconditions.checkNotNull(headers, "headers");
|
||||||
|
|
||||||
|
|
@ -126,7 +127,7 @@ class CronetClientTransport implements ConnectionClientTransport {
|
||||||
final String url = "https://" + authority + defaultPath;
|
final String url = "https://" + authority + defaultPath;
|
||||||
|
|
||||||
final StatsTraceContext statsTraceCtx =
|
final StatsTraceContext statsTraceCtx =
|
||||||
StatsTraceContext.newClientContext(callOptions, attrs, headers);
|
StatsTraceContext.newClientContext(tracers, attrs, headers);
|
||||||
class StartCallback implements Runnable {
|
class StartCallback implements Runnable {
|
||||||
final CronetClientStream clientStream = new CronetClientStream(
|
final CronetClientStream clientStream = new CronetClientStream(
|
||||||
url, userAgent, executor, headers, CronetClientTransport.this, this, lock, maxMessageSize,
|
url, userAgent, executor, headers, CronetClientTransport.this, this, lock, maxMessageSize,
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import static org.mockito.Mockito.mock;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.MethodDescriptor;
|
import io.grpc.MethodDescriptor;
|
||||||
import io.grpc.cronet.CronetChannelBuilder.CronetTransportFactory;
|
import io.grpc.cronet.CronetChannelBuilder.CronetTransportFactory;
|
||||||
|
|
@ -50,6 +51,8 @@ public final class CronetChannelBuilderTest {
|
||||||
@Mock private ExperimentalCronetEngine mockEngine;
|
@Mock private ExperimentalCronetEngine mockEngine;
|
||||||
@Mock private ChannelLogger channelLogger;
|
@Mock private ChannelLogger channelLogger;
|
||||||
|
|
||||||
|
private final ClientStreamTracer[] tracers =
|
||||||
|
new ClientStreamTracer[]{ new ClientStreamTracer() {} };
|
||||||
private MethodDescriptor<?, ?> method = TestMethodDescriptors.voidMethod();
|
private MethodDescriptor<?, ?> method = TestMethodDescriptors.voidMethod();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
@ -69,7 +72,8 @@ public final class CronetChannelBuilderTest {
|
||||||
new InetSocketAddress("localhost", 443),
|
new InetSocketAddress("localhost", 443),
|
||||||
new ClientTransportOptions(),
|
new ClientTransportOptions(),
|
||||||
channelLogger);
|
channelLogger);
|
||||||
CronetClientStream stream = transport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
CronetClientStream stream = transport.newStream(
|
||||||
|
method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
|
|
||||||
assertTrue(stream.idempotent);
|
assertTrue(stream.idempotent);
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +89,8 @@ public final class CronetChannelBuilderTest {
|
||||||
new InetSocketAddress("localhost", 443),
|
new InetSocketAddress("localhost", 443),
|
||||||
new ClientTransportOptions(),
|
new ClientTransportOptions(),
|
||||||
channelLogger);
|
channelLogger);
|
||||||
CronetClientStream stream = transport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
CronetClientStream stream = transport.newStream(
|
||||||
|
method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
|
|
||||||
assertFalse(stream.idempotent);
|
assertFalse(stream.idempotent);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.MethodDescriptor;
|
import io.grpc.MethodDescriptor;
|
||||||
import io.grpc.SecurityLevel;
|
import io.grpc.SecurityLevel;
|
||||||
|
|
@ -60,6 +61,8 @@ public final class CronetClientTransportTest {
|
||||||
private static final Attributes EAG_ATTRS =
|
private static final Attributes EAG_ATTRS =
|
||||||
Attributes.newBuilder().set(EAG_ATTR_KEY, "value").build();
|
Attributes.newBuilder().set(EAG_ATTR_KEY, "value").build();
|
||||||
|
|
||||||
|
private final ClientStreamTracer[] tracers =
|
||||||
|
new ClientStreamTracer[]{ new ClientStreamTracer() {} };
|
||||||
private CronetClientTransport transport;
|
private CronetClientTransport transport;
|
||||||
@Mock private StreamBuilderFactory streamFactory;
|
@Mock private StreamBuilderFactory streamFactory;
|
||||||
@Mock private Executor executor;
|
@Mock private Executor executor;
|
||||||
|
|
@ -101,9 +104,9 @@ public final class CronetClientTransportTest {
|
||||||
@Test
|
@Test
|
||||||
public void shutdownTransport() throws Exception {
|
public void shutdownTransport() throws Exception {
|
||||||
CronetClientStream stream1 =
|
CronetClientStream stream1 =
|
||||||
transport.newStream(descriptor, new Metadata(), CallOptions.DEFAULT);
|
transport.newStream(descriptor, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
CronetClientStream stream2 =
|
CronetClientStream stream2 =
|
||||||
transport.newStream(descriptor, new Metadata(), CallOptions.DEFAULT);
|
transport.newStream(descriptor, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
|
|
||||||
// Create a transport and start two streams on it.
|
// Create a transport and start two streams on it.
|
||||||
ArgumentCaptor<BidirectionalStream.Callback> callbackCaptor =
|
ArgumentCaptor<BidirectionalStream.Callback> callbackCaptor =
|
||||||
|
|
@ -137,7 +140,7 @@ public final class CronetClientTransportTest {
|
||||||
@Test
|
@Test
|
||||||
public void startStreamAfterShutdown() throws Exception {
|
public void startStreamAfterShutdown() throws Exception {
|
||||||
CronetClientStream stream =
|
CronetClientStream stream =
|
||||||
transport.newStream(descriptor, new Metadata(), CallOptions.DEFAULT);
|
transport.newStream(descriptor, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
transport.shutdown();
|
transport.shutdown();
|
||||||
BaseClientStreamListener listener = new BaseClientStreamListener();
|
BaseClientStreamListener listener = new BaseClientStreamListener();
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import javax.annotation.concurrent.ThreadSafe;
|
||||||
* span of an LB stream with the remote load-balancer.
|
* span of an LB stream with the remote load-balancer.
|
||||||
*/
|
*/
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
final class GrpclbClientLoadRecorder extends ClientStreamTracer.Factory {
|
final class GrpclbClientLoadRecorder extends ClientStreamTracer.InternalLimitedInfoFactory {
|
||||||
|
|
||||||
private static final AtomicLongFieldUpdater<GrpclbClientLoadRecorder> callsStartedUpdater =
|
private static final AtomicLongFieldUpdater<GrpclbClientLoadRecorder> callsStartedUpdater =
|
||||||
AtomicLongFieldUpdater.newUpdater(GrpclbClientLoadRecorder.class, "callsStarted");
|
AtomicLongFieldUpdater.newUpdater(GrpclbClientLoadRecorder.class, "callsStarted");
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import com.google.common.base.Objects;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.ClientStreamTracer;
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
import io.grpc.internal.ForwardingClientStreamTracer;
|
||||||
import io.grpc.internal.GrpcAttributes;
|
import io.grpc.internal.GrpcAttributes;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
|
@ -29,7 +30,7 @@ import javax.annotation.Nullable;
|
||||||
* Wraps a {@link ClientStreamTracer.Factory}, retrieves tokens from transport attributes and
|
* Wraps a {@link ClientStreamTracer.Factory}, retrieves tokens from transport attributes and
|
||||||
* attaches them to headers. This is only used in the PICK_FIRST mode.
|
* attaches them to headers. This is only used in the PICK_FIRST mode.
|
||||||
*/
|
*/
|
||||||
final class TokenAttachingTracerFactory extends ClientStreamTracer.Factory {
|
final class TokenAttachingTracerFactory extends ClientStreamTracer.InternalLimitedInfoFactory {
|
||||||
private static final ClientStreamTracer NOOP_TRACER = new ClientStreamTracer() {};
|
private static final ClientStreamTracer NOOP_TRACER = new ClientStreamTracer() {};
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
@ -42,7 +43,18 @@ final class TokenAttachingTracerFactory extends ClientStreamTracer.Factory {
|
||||||
@Override
|
@Override
|
||||||
public ClientStreamTracer newClientStreamTracer(
|
public ClientStreamTracer newClientStreamTracer(
|
||||||
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
||||||
Attributes transportAttrs = checkNotNull(info.getTransportAttrs(), "transportAttrs");
|
if (delegate == null) {
|
||||||
|
return NOOP_TRACER;
|
||||||
|
}
|
||||||
|
final ClientStreamTracer clientStreamTracer = delegate.newClientStreamTracer(info, headers);
|
||||||
|
class TokenPropagationTracer extends ForwardingClientStreamTracer {
|
||||||
|
@Override
|
||||||
|
protected ClientStreamTracer delegate() {
|
||||||
|
return clientStreamTracer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamCreated(Attributes transportAttrs, Metadata headers) {
|
||||||
Attributes eagAttrs =
|
Attributes eagAttrs =
|
||||||
checkNotNull(transportAttrs.get(GrpcAttributes.ATTR_CLIENT_EAG_ATTRS), "eagAttrs");
|
checkNotNull(transportAttrs.get(GrpcAttributes.ATTR_CLIENT_EAG_ATTRS), "eagAttrs");
|
||||||
String token = eagAttrs.get(GrpclbConstants.TOKEN_ATTRIBUTE_KEY);
|
String token = eagAttrs.get(GrpclbConstants.TOKEN_ATTRIBUTE_KEY);
|
||||||
|
|
@ -50,13 +62,13 @@ final class TokenAttachingTracerFactory extends ClientStreamTracer.Factory {
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
headers.put(GrpclbConstants.TOKEN_METADATA_KEY, token);
|
headers.put(GrpclbConstants.TOKEN_METADATA_KEY, token);
|
||||||
}
|
}
|
||||||
if (delegate != null) {
|
delegate().streamCreated(transportAttrs, headers);
|
||||||
return delegate.newClientStreamTracer(info, headers);
|
|
||||||
} else {
|
|
||||||
return NOOP_TRACER;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new TokenPropagationTracer();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(delegate);
|
return Objects.hashCode(delegate);
|
||||||
|
|
|
||||||
|
|
@ -481,6 +481,7 @@ public class GrpclbLoadBalancerTest {
|
||||||
|
|
||||||
ClientStreamTracer tracer1 =
|
ClientStreamTracer tracer1 =
|
||||||
pick1.getStreamTracerFactory().newClientStreamTracer(STREAM_INFO, new Metadata());
|
pick1.getStreamTracerFactory().newClientStreamTracer(STREAM_INFO, new Metadata());
|
||||||
|
tracer1.streamCreated(Attributes.EMPTY, new Metadata());
|
||||||
|
|
||||||
PickResult pick2 = picker.pickSubchannel(args);
|
PickResult pick2 = picker.pickSubchannel(args);
|
||||||
assertNull(pick2.getSubchannel());
|
assertNull(pick2.getSubchannel());
|
||||||
|
|
@ -504,6 +505,7 @@ public class GrpclbLoadBalancerTest {
|
||||||
assertSame(getLoadRecorder(), pick3.getStreamTracerFactory());
|
assertSame(getLoadRecorder(), pick3.getStreamTracerFactory());
|
||||||
ClientStreamTracer tracer3 =
|
ClientStreamTracer tracer3 =
|
||||||
pick3.getStreamTracerFactory().newClientStreamTracer(STREAM_INFO, new Metadata());
|
pick3.getStreamTracerFactory().newClientStreamTracer(STREAM_INFO, new Metadata());
|
||||||
|
tracer3.streamCreated(Attributes.EMPTY, new Metadata());
|
||||||
|
|
||||||
// pick3 has sent out headers
|
// pick3 has sent out headers
|
||||||
tracer3.outboundHeaders();
|
tracer3.outboundHeaders();
|
||||||
|
|
@ -541,6 +543,7 @@ public class GrpclbLoadBalancerTest {
|
||||||
assertSame(getLoadRecorder(), pick5.getStreamTracerFactory());
|
assertSame(getLoadRecorder(), pick5.getStreamTracerFactory());
|
||||||
ClientStreamTracer tracer5 =
|
ClientStreamTracer tracer5 =
|
||||||
pick5.getStreamTracerFactory().newClientStreamTracer(STREAM_INFO, new Metadata());
|
pick5.getStreamTracerFactory().newClientStreamTracer(STREAM_INFO, new Metadata());
|
||||||
|
tracer5.streamCreated(Attributes.EMPTY, new Metadata());
|
||||||
|
|
||||||
// pick3 ended without receiving response headers
|
// pick3 ended without receiving response headers
|
||||||
tracer3.streamClosed(Status.DEADLINE_EXCEEDED);
|
tracer3.streamClosed(Status.DEADLINE_EXCEEDED);
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,23 @@ import org.junit.runners.JUnit4;
|
||||||
/** Unit tests for {@link TokenAttachingTracerFactory}. */
|
/** Unit tests for {@link TokenAttachingTracerFactory}. */
|
||||||
@RunWith(JUnit4.class)
|
@RunWith(JUnit4.class)
|
||||||
public class TokenAttachingTracerFactoryTest {
|
public class TokenAttachingTracerFactoryTest {
|
||||||
private static final ClientStreamTracer fakeTracer = new ClientStreamTracer() {};
|
private static final class FakeClientStreamTracer extends ClientStreamTracer {
|
||||||
|
Attributes transportAttrs;
|
||||||
|
Metadata headers;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamCreated(Attributes transportAttrs, Metadata headers) {
|
||||||
|
this.transportAttrs = transportAttrs;
|
||||||
|
this.headers = headers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final FakeClientStreamTracer fakeTracer = new FakeClientStreamTracer();
|
||||||
|
|
||||||
private final ClientStreamTracer.Factory delegate = mock(
|
private final ClientStreamTracer.Factory delegate = mock(
|
||||||
ClientStreamTracer.Factory.class,
|
ClientStreamTracer.Factory.class,
|
||||||
delegatesTo(
|
delegatesTo(
|
||||||
new ClientStreamTracer.Factory() {
|
new ClientStreamTracer.InternalLimitedInfoFactory() {
|
||||||
@Override
|
@Override
|
||||||
public ClientStreamTracer newClientStreamTracer(
|
public ClientStreamTracer newClientStreamTracer(
|
||||||
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
||||||
|
|
@ -51,28 +62,25 @@ public class TokenAttachingTracerFactoryTest {
|
||||||
TokenAttachingTracerFactory factory = new TokenAttachingTracerFactory(delegate);
|
TokenAttachingTracerFactory factory = new TokenAttachingTracerFactory(delegate);
|
||||||
Attributes eagAttrs = Attributes.newBuilder()
|
Attributes eagAttrs = Attributes.newBuilder()
|
||||||
.set(GrpclbConstants.TOKEN_ATTRIBUTE_KEY, "token0001").build();
|
.set(GrpclbConstants.TOKEN_ATTRIBUTE_KEY, "token0001").build();
|
||||||
ClientStreamTracer.StreamInfo info = ClientStreamTracer.StreamInfo.newBuilder()
|
ClientStreamTracer.StreamInfo info = ClientStreamTracer.StreamInfo.newBuilder().build();
|
||||||
.setTransportAttrs(
|
|
||||||
Attributes.newBuilder().set(GrpcAttributes.ATTR_CLIENT_EAG_ATTRS, eagAttrs).build())
|
|
||||||
.build();
|
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
// Preexisting token should be replaced
|
// Preexisting token should be replaced
|
||||||
headers.put(GrpclbConstants.TOKEN_METADATA_KEY, "preexisting-token");
|
headers.put(GrpclbConstants.TOKEN_METADATA_KEY, "preexisting-token");
|
||||||
|
|
||||||
ClientStreamTracer tracer = factory.newClientStreamTracer(info, headers);
|
ClientStreamTracer tracer = factory.newClientStreamTracer(info, headers);
|
||||||
verify(delegate).newClientStreamTracer(same(info), same(headers));
|
verify(delegate).newClientStreamTracer(same(info), same(headers));
|
||||||
assertThat(tracer).isSameInstanceAs(fakeTracer);
|
Attributes transportAttrs =
|
||||||
|
Attributes.newBuilder().set(GrpcAttributes.ATTR_CLIENT_EAG_ATTRS, eagAttrs).build();
|
||||||
|
tracer.streamCreated(transportAttrs, headers);
|
||||||
|
assertThat(fakeTracer.transportAttrs).isSameInstanceAs(transportAttrs);
|
||||||
|
assertThat(fakeTracer.headers).isSameInstanceAs(headers);
|
||||||
assertThat(headers.getAll(GrpclbConstants.TOKEN_METADATA_KEY)).containsExactly("token0001");
|
assertThat(headers.getAll(GrpclbConstants.TOKEN_METADATA_KEY)).containsExactly("token0001");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noToken() {
|
public void noToken() {
|
||||||
TokenAttachingTracerFactory factory = new TokenAttachingTracerFactory(delegate);
|
TokenAttachingTracerFactory factory = new TokenAttachingTracerFactory(delegate);
|
||||||
ClientStreamTracer.StreamInfo info = ClientStreamTracer.StreamInfo.newBuilder()
|
ClientStreamTracer.StreamInfo info = ClientStreamTracer.StreamInfo.newBuilder().build();
|
||||||
.setTransportAttrs(
|
|
||||||
Attributes.newBuilder()
|
|
||||||
.set(GrpcAttributes.ATTR_CLIENT_EAG_ATTRS, Attributes.EMPTY).build())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
// Preexisting token should be removed
|
// Preexisting token should be removed
|
||||||
|
|
@ -80,22 +88,25 @@ public class TokenAttachingTracerFactoryTest {
|
||||||
|
|
||||||
ClientStreamTracer tracer = factory.newClientStreamTracer(info, headers);
|
ClientStreamTracer tracer = factory.newClientStreamTracer(info, headers);
|
||||||
verify(delegate).newClientStreamTracer(same(info), same(headers));
|
verify(delegate).newClientStreamTracer(same(info), same(headers));
|
||||||
assertThat(tracer).isSameInstanceAs(fakeTracer);
|
Attributes transportAttrs =
|
||||||
|
Attributes.newBuilder().set(GrpcAttributes.ATTR_CLIENT_EAG_ATTRS, Attributes.EMPTY).build();
|
||||||
|
tracer.streamCreated(transportAttrs, headers);
|
||||||
|
assertThat(fakeTracer.transportAttrs).isSameInstanceAs(transportAttrs);
|
||||||
|
assertThat(fakeTracer.headers).isSameInstanceAs(headers);
|
||||||
assertThat(headers.get(GrpclbConstants.TOKEN_METADATA_KEY)).isNull();
|
assertThat(headers.get(GrpclbConstants.TOKEN_METADATA_KEY)).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nullDelegate() {
|
public void nullDelegate() {
|
||||||
TokenAttachingTracerFactory factory = new TokenAttachingTracerFactory(null);
|
TokenAttachingTracerFactory factory = new TokenAttachingTracerFactory(null);
|
||||||
ClientStreamTracer.StreamInfo info = ClientStreamTracer.StreamInfo.newBuilder()
|
ClientStreamTracer.StreamInfo info = ClientStreamTracer.StreamInfo.newBuilder().build();
|
||||||
.setTransportAttrs(
|
|
||||||
Attributes.newBuilder()
|
|
||||||
.set(GrpcAttributes.ATTR_CLIENT_EAG_ATTRS, Attributes.EMPTY).build())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Metadata headers = new Metadata();
|
Metadata headers = new Metadata();
|
||||||
|
|
||||||
ClientStreamTracer tracer = factory.newClientStreamTracer(info, headers);
|
ClientStreamTracer tracer = factory.newClientStreamTracer(info, headers);
|
||||||
|
tracer.streamCreated(
|
||||||
|
Attributes.newBuilder().set(GrpcAttributes.ATTR_CLIENT_EAG_ATTRS, Attributes.EMPTY).build(),
|
||||||
|
headers);
|
||||||
assertThat(tracer).isNotNull();
|
assertThat(tracer).isNotNull();
|
||||||
assertThat(headers.get(GrpclbConstants.TOKEN_METADATA_KEY)).isNull();
|
assertThat(headers.get(GrpclbConstants.TOKEN_METADATA_KEY)).isNull();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ public abstract class AbstractInteropTest {
|
||||||
new LinkedBlockingQueue<>();
|
new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
private final ClientStreamTracer.Factory clientStreamTracerFactory =
|
private final ClientStreamTracer.Factory clientStreamTracerFactory =
|
||||||
new ClientStreamTracer.Factory() {
|
new ClientStreamTracer.InternalLimitedInfoFactory() {
|
||||||
@Override
|
@Override
|
||||||
public ClientStreamTracer newClientStreamTracer(
|
public ClientStreamTracer newClientStreamTracer(
|
||||||
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
ClientStreamTracer.StreamInfo info, Metadata headers) {
|
||||||
|
|
@ -375,7 +375,8 @@ public abstract class AbstractInteropTest {
|
||||||
.getClientInterceptor(
|
.getClientInterceptor(
|
||||||
tagger, tagContextBinarySerializer, clientStatsRecorder,
|
tagger, tagContextBinarySerializer, clientStatsRecorder,
|
||||||
GrpcUtil.STOPWATCH_SUPPLIER,
|
GrpcUtil.STOPWATCH_SUPPLIER,
|
||||||
true, true, true, false /* real-time metrics */);
|
true, true, true,
|
||||||
|
/* recordRealTimeMetrics= */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final ServerStreamTracer.Factory createCustomCensusTracerFactory() {
|
protected final ServerStreamTracer.Factory createCustomCensusTracerFactory() {
|
||||||
|
|
@ -1179,6 +1180,7 @@ public abstract class AbstractInteropTest {
|
||||||
public void deadlineExceededServerStreaming() throws Exception {
|
public void deadlineExceededServerStreaming() throws Exception {
|
||||||
// warm up the channel and JVM
|
// warm up the channel and JVM
|
||||||
blockingStub.emptyCall(Empty.getDefaultInstance());
|
blockingStub.emptyCall(Empty.getDefaultInstance());
|
||||||
|
assertStatsTrace("grpc.testing.TestService/EmptyCall", Status.Code.OK);
|
||||||
ResponseParameters.Builder responseParameters = ResponseParameters.newBuilder()
|
ResponseParameters.Builder responseParameters = ResponseParameters.newBuilder()
|
||||||
.setSize(1)
|
.setSize(1)
|
||||||
.setIntervalUs(10000);
|
.setIntervalUs(10000);
|
||||||
|
|
@ -1195,7 +1197,6 @@ public abstract class AbstractInteropTest {
|
||||||
recorder.awaitCompletion();
|
recorder.awaitCompletion();
|
||||||
assertEquals(Status.DEADLINE_EXCEEDED.getCode(),
|
assertEquals(Status.DEADLINE_EXCEEDED.getCode(),
|
||||||
Status.fromThrowable(recorder.getError()).getCode());
|
Status.fromThrowable(recorder.getError()).getCode());
|
||||||
assertStatsTrace("grpc.testing.TestService/EmptyCall", Status.Code.OK);
|
|
||||||
if (metricsExpected()) {
|
if (metricsExpected()) {
|
||||||
// Stream may not have been created when deadline is exceeded, thus we don't check tracer
|
// Stream may not have been created when deadline is exceeded, thus we don't check tracer
|
||||||
// stats.
|
// stats.
|
||||||
|
|
@ -1239,6 +1240,12 @@ public abstract class AbstractInteropTest {
|
||||||
|
|
||||||
// warm up the channel
|
// warm up the channel
|
||||||
blockingStub.emptyCall(Empty.getDefaultInstance());
|
blockingStub.emptyCall(Empty.getDefaultInstance());
|
||||||
|
if (metricsExpected()) {
|
||||||
|
// clientStartRecord
|
||||||
|
clientStatsRecorder.pollRecord(5, TimeUnit.SECONDS);
|
||||||
|
// clientEndRecord
|
||||||
|
clientStatsRecorder.pollRecord(5, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
blockingStub
|
blockingStub
|
||||||
.withDeadlineAfter(-10, TimeUnit.SECONDS)
|
.withDeadlineAfter(-10, TimeUnit.SECONDS)
|
||||||
|
|
@ -1249,7 +1256,6 @@ public abstract class AbstractInteropTest {
|
||||||
assertThat(ex.getStatus().getDescription())
|
assertThat(ex.getStatus().getDescription())
|
||||||
.startsWith("ClientCall started after deadline exceeded");
|
.startsWith("ClientCall started after deadline exceeded");
|
||||||
}
|
}
|
||||||
assertStatsTrace("grpc.testing.TestService/EmptyCall", Status.Code.OK);
|
|
||||||
if (metricsExpected()) {
|
if (metricsExpected()) {
|
||||||
MetricsRecord clientStartRecord = clientStatsRecorder.pollRecord(5, TimeUnit.SECONDS);
|
MetricsRecord clientStartRecord = clientStatsRecorder.pollRecord(5, TimeUnit.SECONDS);
|
||||||
checkStartTags(clientStartRecord, "grpc.testing.TestService/EmptyCall", true);
|
checkStartTags(clientStartRecord, "grpc.testing.TestService/EmptyCall", true);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import com.google.common.util.concurrent.SettableFuture;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.InternalChannelz.SocketStats;
|
import io.grpc.InternalChannelz.SocketStats;
|
||||||
import io.grpc.InternalLogId;
|
import io.grpc.InternalLogId;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
|
@ -167,14 +168,15 @@ class NettyClientTransport implements ConnectionClientTransport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientStream newStream(
|
public ClientStream newStream(
|
||||||
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions) {
|
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
||||||
|
ClientStreamTracer[] tracers) {
|
||||||
Preconditions.checkNotNull(method, "method");
|
Preconditions.checkNotNull(method, "method");
|
||||||
Preconditions.checkNotNull(headers, "headers");
|
Preconditions.checkNotNull(headers, "headers");
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
return new FailingClientStream(statusExplainingWhyTheChannelIsNull);
|
return new FailingClientStream(statusExplainingWhyTheChannelIsNull, tracers);
|
||||||
}
|
}
|
||||||
StatsTraceContext statsTraceCtx =
|
StatsTraceContext statsTraceCtx =
|
||||||
StatsTraceContext.newClientContext(callOptions, getAttributes(), headers);
|
StatsTraceContext.newClientContext(tracers, getAttributes(), headers);
|
||||||
return new NettyClientStream(
|
return new NettyClientStream(
|
||||||
new NettyClientStream.TransportState(
|
new NettyClientStream.TransportState(
|
||||||
handler,
|
handler,
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ import com.google.common.util.concurrent.SettableFuture;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ChannelLogger;
|
import io.grpc.ChannelLogger;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Grpc;
|
import io.grpc.Grpc;
|
||||||
import io.grpc.InternalChannelz;
|
import io.grpc.InternalChannelz;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
|
@ -828,7 +829,9 @@ public class NettyClientTransportTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rpc(NettyClientTransport transport, Metadata headers) {
|
Rpc(NettyClientTransport transport, Metadata headers) {
|
||||||
stream = transport.newStream(METHOD, headers, CallOptions.DEFAULT);
|
stream = transport.newStream(
|
||||||
|
METHOD, headers, CallOptions.DEFAULT,
|
||||||
|
new ClientStreamTracer[]{ new ClientStreamTracer() {} });
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
stream.writeMessage(new ByteArrayInputStream(MESSAGE.getBytes(UTF_8)));
|
stream.writeMessage(new ByteArrayInputStream(MESSAGE.getBytes(UTF_8)));
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import com.squareup.okhttp.Request;
|
||||||
import com.squareup.okhttp.internal.http.StatusLine;
|
import com.squareup.okhttp.internal.http.StatusLine;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.Grpc;
|
import io.grpc.Grpc;
|
||||||
import io.grpc.HttpConnectProxiedSocketAddress;
|
import io.grpc.HttpConnectProxiedSocketAddress;
|
||||||
import io.grpc.InternalChannelz;
|
import io.grpc.InternalChannelz;
|
||||||
|
|
@ -387,12 +388,13 @@ class OkHttpClientTransport implements ConnectionClientTransport, TransportExcep
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OkHttpClientStream newStream(final MethodDescriptor<?, ?> method,
|
public OkHttpClientStream newStream(
|
||||||
final Metadata headers, CallOptions callOptions) {
|
MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions,
|
||||||
|
ClientStreamTracer[] tracers) {
|
||||||
Preconditions.checkNotNull(method, "method");
|
Preconditions.checkNotNull(method, "method");
|
||||||
Preconditions.checkNotNull(headers, "headers");
|
Preconditions.checkNotNull(headers, "headers");
|
||||||
StatsTraceContext statsTraceCtx =
|
StatsTraceContext statsTraceContext =
|
||||||
StatsTraceContext.newClientContext(callOptions, attributes, headers);
|
StatsTraceContext.newClientContext(tracers, getAttributes(), headers);
|
||||||
// FIXME: it is likely wrong to pass the transportTracer here as it'll exit the lock's scope
|
// FIXME: it is likely wrong to pass the transportTracer here as it'll exit the lock's scope
|
||||||
synchronized (lock) { // to make @GuardedBy linter happy
|
synchronized (lock) { // to make @GuardedBy linter happy
|
||||||
return new OkHttpClientStream(
|
return new OkHttpClientStream(
|
||||||
|
|
@ -406,7 +408,7 @@ class OkHttpClientTransport implements ConnectionClientTransport, TransportExcep
|
||||||
initialWindowSize,
|
initialWindowSize,
|
||||||
defaultAuthority,
|
defaultAuthority,
|
||||||
userAgent,
|
userAgent,
|
||||||
statsTraceCtx,
|
statsTraceContext,
|
||||||
transportTracer,
|
transportTracer,
|
||||||
callOptions,
|
callOptions,
|
||||||
useGetForSafeMethods);
|
useGetForSafeMethods);
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
import io.grpc.Attributes;
|
import io.grpc.Attributes;
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
|
import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.HttpConnectProxiedSocketAddress;
|
import io.grpc.HttpConnectProxiedSocketAddress;
|
||||||
import io.grpc.InternalChannelz.SocketStats;
|
import io.grpc.InternalChannelz.SocketStats;
|
||||||
import io.grpc.InternalChannelz.TransportStats;
|
import io.grpc.InternalChannelz.TransportStats;
|
||||||
|
|
@ -146,6 +147,9 @@ public class OkHttpClientTransportTest {
|
||||||
private static final int DEFAULT_MAX_INBOUND_METADATA_SIZE = Integer.MAX_VALUE;
|
private static final int DEFAULT_MAX_INBOUND_METADATA_SIZE = Integer.MAX_VALUE;
|
||||||
private static final Attributes EAG_ATTRS = Attributes.EMPTY;
|
private static final Attributes EAG_ATTRS = Attributes.EMPTY;
|
||||||
private static final Logger logger = Logger.getLogger(OkHttpClientTransport.class.getName());
|
private static final Logger logger = Logger.getLogger(OkHttpClientTransport.class.getName());
|
||||||
|
private static final ClientStreamTracer[] tracers = new ClientStreamTracer[] {
|
||||||
|
new ClientStreamTracer() {}
|
||||||
|
};
|
||||||
|
|
||||||
@Rule public final Timeout globalTimeout = Timeout.seconds(10);
|
@Rule public final Timeout globalTimeout = Timeout.seconds(10);
|
||||||
|
|
||||||
|
|
@ -299,7 +303,7 @@ public class OkHttpClientTransportTest {
|
||||||
|
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
|
|
||||||
|
|
@ -387,7 +391,7 @@ public class OkHttpClientTransportTest {
|
||||||
|
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
assertContainStream(3);
|
assertContainStream(3);
|
||||||
|
|
@ -443,11 +447,11 @@ public class OkHttpClientTransportTest {
|
||||||
MockStreamListener listener1 = new MockStreamListener();
|
MockStreamListener listener1 = new MockStreamListener();
|
||||||
MockStreamListener listener2 = new MockStreamListener();
|
MockStreamListener listener2 = new MockStreamListener();
|
||||||
OkHttpClientStream stream1 =
|
OkHttpClientStream stream1 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream1.start(listener1);
|
stream1.start(listener1);
|
||||||
stream1.request(1);
|
stream1.request(1);
|
||||||
OkHttpClientStream stream2 =
|
OkHttpClientStream stream2 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream2.start(listener2);
|
stream2.start(listener2);
|
||||||
stream2.request(1);
|
stream2.request(1);
|
||||||
assertEquals(2, activeStreamCount());
|
assertEquals(2, activeStreamCount());
|
||||||
|
|
@ -477,7 +481,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
assertEquals(1, activeStreamCount());
|
assertEquals(1, activeStreamCount());
|
||||||
|
|
@ -498,7 +502,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
frameReader.nextFrameAtEndOfStream();
|
frameReader.nextFrameAtEndOfStream();
|
||||||
|
|
@ -516,7 +520,7 @@ public class OkHttpClientTransportTest {
|
||||||
final String message = "Hello Client";
|
final String message = "Hello Client";
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(numMessages);
|
stream.request(numMessages);
|
||||||
assertContainStream(3);
|
assertContainStream(3);
|
||||||
|
|
@ -566,7 +570,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
assertContainStream(3);
|
assertContainStream(3);
|
||||||
|
|
@ -590,7 +594,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
assertContainStream(3);
|
assertContainStream(3);
|
||||||
|
|
@ -610,7 +614,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
assertContainStream(3);
|
assertContainStream(3);
|
||||||
frameHandler().headers(true, true, 3, 0, grpcResponseTrailers(), HeadersMode.HTTP_20_HEADERS);
|
frameHandler().headers(true, true, 3, 0, grpcResponseTrailers(), HeadersMode.HTTP_20_HEADERS);
|
||||||
|
|
@ -624,7 +628,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
assertContainStream(3);
|
assertContainStream(3);
|
||||||
frameHandler().rstStream(3, ErrorCode.PROTOCOL_ERROR);
|
frameHandler().rstStream(3, ErrorCode.PROTOCOL_ERROR);
|
||||||
|
|
@ -641,7 +645,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
assertContainStream(3);
|
assertContainStream(3);
|
||||||
frameHandler().headers(false, false, 3, 0, grpcResponseHeaders(), HeadersMode.HTTP_20_HEADERS);
|
frameHandler().headers(false, false, 3, 0, grpcResponseHeaders(), HeadersMode.HTTP_20_HEADERS);
|
||||||
|
|
@ -661,7 +665,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
getStream(3).cancel(Status.CANCELLED);
|
getStream(3).cancel(Status.CANCELLED);
|
||||||
verify(frameWriter, timeout(TIME_OUT_MS)).rstStream(eq(3), eq(ErrorCode.CANCEL));
|
verify(frameWriter, timeout(TIME_OUT_MS)).rstStream(eq(3), eq(ErrorCode.CANCEL));
|
||||||
|
|
@ -676,7 +680,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
Header userAgentHeader = new Header(GrpcUtil.USER_AGENT_KEY.name(),
|
Header userAgentHeader = new Header(GrpcUtil.USER_AGENT_KEY.name(),
|
||||||
GrpcUtil.getGrpcUserAgent("okhttp", null));
|
GrpcUtil.getGrpcUserAgent("okhttp", null));
|
||||||
|
|
@ -695,7 +699,7 @@ public class OkHttpClientTransportTest {
|
||||||
startTransport(3, null, true, DEFAULT_MAX_MESSAGE_SIZE, INITIAL_WINDOW_SIZE, "fakeUserAgent");
|
startTransport(3, null, true, DEFAULT_MAX_MESSAGE_SIZE, INITIAL_WINDOW_SIZE, "fakeUserAgent");
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
List<Header> expectedHeaders = Arrays.asList(HTTP_SCHEME_HEADER, METHOD_HEADER,
|
List<Header> expectedHeaders = Arrays.asList(HTTP_SCHEME_HEADER, METHOD_HEADER,
|
||||||
new Header(Header.TARGET_AUTHORITY, "notarealauthority:80"),
|
new Header(Header.TARGET_AUTHORITY, "notarealauthority:80"),
|
||||||
|
|
@ -714,7 +718,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
getStream(3).cancel(Status.DEADLINE_EXCEEDED);
|
getStream(3).cancel(Status.DEADLINE_EXCEEDED);
|
||||||
verify(frameWriter, timeout(TIME_OUT_MS)).rstStream(eq(3), eq(ErrorCode.CANCEL));
|
verify(frameWriter, timeout(TIME_OUT_MS)).rstStream(eq(3), eq(ErrorCode.CANCEL));
|
||||||
|
|
@ -728,7 +732,7 @@ public class OkHttpClientTransportTest {
|
||||||
final String message = "Hello Server";
|
final String message = "Hello Server";
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
InputStream input = new ByteArrayInputStream(message.getBytes(UTF_8));
|
InputStream input = new ByteArrayInputStream(message.getBytes(UTF_8));
|
||||||
assertEquals(12, input.available());
|
assertEquals(12, input.available());
|
||||||
|
|
@ -772,12 +776,12 @@ public class OkHttpClientTransportTest {
|
||||||
MockStreamListener listener1 = new MockStreamListener();
|
MockStreamListener listener1 = new MockStreamListener();
|
||||||
MockStreamListener listener2 = new MockStreamListener();
|
MockStreamListener listener2 = new MockStreamListener();
|
||||||
OkHttpClientStream stream1 =
|
OkHttpClientStream stream1 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream1.start(listener1);
|
stream1.start(listener1);
|
||||||
stream1.request(2);
|
stream1.request(2);
|
||||||
|
|
||||||
OkHttpClientStream stream2 =
|
OkHttpClientStream stream2 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream2.start(listener2);
|
stream2.start(listener2);
|
||||||
stream2.request(2);
|
stream2.request(2);
|
||||||
assertEquals(2, activeStreamCount());
|
assertEquals(2, activeStreamCount());
|
||||||
|
|
@ -838,7 +842,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
int messageLength = INITIAL_WINDOW_SIZE / 2 + 1;
|
int messageLength = INITIAL_WINDOW_SIZE / 2 + 1;
|
||||||
byte[] fakeMessage = new byte[messageLength];
|
byte[] fakeMessage = new byte[messageLength];
|
||||||
|
|
@ -874,7 +878,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
|
|
||||||
// Outbound window always starts at 65535 until changed by Settings.INITIAL_WINDOW_SIZE
|
// Outbound window always starts at 65535 until changed by Settings.INITIAL_WINDOW_SIZE
|
||||||
|
|
@ -920,7 +924,7 @@ public class OkHttpClientTransportTest {
|
||||||
|
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
|
|
||||||
int messageLength = 75;
|
int messageLength = 75;
|
||||||
|
|
@ -963,7 +967,7 @@ public class OkHttpClientTransportTest {
|
||||||
|
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
|
|
||||||
int messageLength = 100000;
|
int messageLength = 100000;
|
||||||
|
|
@ -999,7 +1003,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
int messageLength = 20;
|
int messageLength = 20;
|
||||||
setInitialWindowSize(HEADER_LENGTH + 10);
|
setInitialWindowSize(HEADER_LENGTH + 10);
|
||||||
|
|
@ -1045,7 +1049,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
int messageLength = 20;
|
int messageLength = 20;
|
||||||
setInitialWindowSize(HEADER_LENGTH + 10);
|
setInitialWindowSize(HEADER_LENGTH + 10);
|
||||||
|
|
@ -1080,10 +1084,10 @@ public class OkHttpClientTransportTest {
|
||||||
MockStreamListener listener1 = new MockStreamListener();
|
MockStreamListener listener1 = new MockStreamListener();
|
||||||
MockStreamListener listener2 = new MockStreamListener();
|
MockStreamListener listener2 = new MockStreamListener();
|
||||||
OkHttpClientStream stream1 =
|
OkHttpClientStream stream1 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream1.start(listener1);
|
stream1.start(listener1);
|
||||||
OkHttpClientStream stream2 =
|
OkHttpClientStream stream2 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream2.start(listener2);
|
stream2.start(listener2);
|
||||||
assertEquals(2, activeStreamCount());
|
assertEquals(2, activeStreamCount());
|
||||||
clientTransport.shutdown(SHUTDOWN_REASON);
|
clientTransport.shutdown(SHUTDOWN_REASON);
|
||||||
|
|
@ -1110,11 +1114,11 @@ public class OkHttpClientTransportTest {
|
||||||
MockStreamListener listener1 = new MockStreamListener();
|
MockStreamListener listener1 = new MockStreamListener();
|
||||||
MockStreamListener listener2 = new MockStreamListener();
|
MockStreamListener listener2 = new MockStreamListener();
|
||||||
OkHttpClientStream stream1 =
|
OkHttpClientStream stream1 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream1.start(listener1);
|
stream1.start(listener1);
|
||||||
stream1.request(1);
|
stream1.request(1);
|
||||||
OkHttpClientStream stream2 =
|
OkHttpClientStream stream2 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream2.start(listener2);
|
stream2.start(listener2);
|
||||||
stream2.request(1);
|
stream2.request(1);
|
||||||
assertEquals(2, activeStreamCount());
|
assertEquals(2, activeStreamCount());
|
||||||
|
|
@ -1168,7 +1172,7 @@ public class OkHttpClientTransportTest {
|
||||||
|
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
|
|
||||||
|
|
@ -1204,11 +1208,11 @@ public class OkHttpClientTransportTest {
|
||||||
final MockStreamListener listener1 = new MockStreamListener();
|
final MockStreamListener listener1 = new MockStreamListener();
|
||||||
final MockStreamListener listener2 = new MockStreamListener();
|
final MockStreamListener listener2 = new MockStreamListener();
|
||||||
OkHttpClientStream stream1 =
|
OkHttpClientStream stream1 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream1.start(listener1);
|
stream1.start(listener1);
|
||||||
// The second stream should be pending.
|
// The second stream should be pending.
|
||||||
OkHttpClientStream stream2 =
|
OkHttpClientStream stream2 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream2.start(listener2);
|
stream2.start(listener2);
|
||||||
String sentMessage = "hello";
|
String sentMessage = "hello";
|
||||||
InputStream input = new ByteArrayInputStream(sentMessage.getBytes(UTF_8));
|
InputStream input = new ByteArrayInputStream(sentMessage.getBytes(UTF_8));
|
||||||
|
|
@ -1241,7 +1245,7 @@ public class OkHttpClientTransportTest {
|
||||||
setMaxConcurrentStreams(0);
|
setMaxConcurrentStreams(0);
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
waitForStreamPending(1);
|
waitForStreamPending(1);
|
||||||
stream.cancel(Status.CANCELLED);
|
stream.cancel(Status.CANCELLED);
|
||||||
|
|
@ -1260,11 +1264,11 @@ public class OkHttpClientTransportTest {
|
||||||
final MockStreamListener listener1 = new MockStreamListener();
|
final MockStreamListener listener1 = new MockStreamListener();
|
||||||
final MockStreamListener listener2 = new MockStreamListener();
|
final MockStreamListener listener2 = new MockStreamListener();
|
||||||
OkHttpClientStream stream1 =
|
OkHttpClientStream stream1 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream1.start(listener1);
|
stream1.start(listener1);
|
||||||
// The second stream should be pending.
|
// The second stream should be pending.
|
||||||
OkHttpClientStream stream2 =
|
OkHttpClientStream stream2 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream2.start(listener2);
|
stream2.start(listener2);
|
||||||
|
|
||||||
waitForStreamPending(1);
|
waitForStreamPending(1);
|
||||||
|
|
@ -1290,7 +1294,7 @@ public class OkHttpClientTransportTest {
|
||||||
final MockStreamListener listener = new MockStreamListener();
|
final MockStreamListener listener = new MockStreamListener();
|
||||||
// The second stream should be pending.
|
// The second stream should be pending.
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
waitForStreamPending(1);
|
waitForStreamPending(1);
|
||||||
|
|
||||||
|
|
@ -1314,15 +1318,15 @@ public class OkHttpClientTransportTest {
|
||||||
final MockStreamListener listener3 = new MockStreamListener();
|
final MockStreamListener listener3 = new MockStreamListener();
|
||||||
|
|
||||||
OkHttpClientStream stream1 =
|
OkHttpClientStream stream1 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream1.start(listener1);
|
stream1.start(listener1);
|
||||||
|
|
||||||
// The second and third stream should be pending.
|
// The second and third stream should be pending.
|
||||||
OkHttpClientStream stream2 =
|
OkHttpClientStream stream2 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream2.start(listener2);
|
stream2.start(listener2);
|
||||||
OkHttpClientStream stream3 =
|
OkHttpClientStream stream3 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream3.start(listener3);
|
stream3.start(listener3);
|
||||||
|
|
||||||
waitForStreamPending(2);
|
waitForStreamPending(2);
|
||||||
|
|
@ -1346,7 +1350,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
|
|
||||||
|
|
@ -1398,7 +1402,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
verify(frameWriter, timeout(TIME_OUT_MS)).synStream(
|
verify(frameWriter, timeout(TIME_OUT_MS)).synStream(
|
||||||
eq(false), eq(false), eq(3), eq(0), ArgumentMatchers.<Header>anyList());
|
eq(false), eq(false), eq(3), eq(0), ArgumentMatchers.<Header>anyList());
|
||||||
|
|
@ -1415,7 +1419,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
Buffer buffer = createMessageFrame(new byte[1]);
|
Buffer buffer = createMessageFrame(new byte[1]);
|
||||||
|
|
@ -1437,7 +1441,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
Buffer buffer = createMessageFrame(new byte[1]);
|
Buffer buffer = createMessageFrame(new byte[1]);
|
||||||
|
|
@ -1459,7 +1463,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.request(1);
|
stream.request(1);
|
||||||
Buffer buffer = createMessageFrame(new byte[1000]);
|
Buffer buffer = createMessageFrame(new byte[1000]);
|
||||||
|
|
@ -1480,7 +1484,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.cancel(Status.CANCELLED);
|
stream.cancel(Status.CANCELLED);
|
||||||
|
|
||||||
|
|
@ -1507,7 +1511,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
stream.cancel(Status.CANCELLED);
|
stream.cancel(Status.CANCELLED);
|
||||||
// This should be ignored.
|
// This should be ignored.
|
||||||
|
|
@ -1527,7 +1531,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransport();
|
initTransport();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
assertTrue(stream.isReady());
|
assertTrue(stream.isReady());
|
||||||
assertTrue(listener.isOnReadyCalled());
|
assertTrue(listener.isOnReadyCalled());
|
||||||
|
|
@ -1545,7 +1549,7 @@ public class OkHttpClientTransportTest {
|
||||||
setInitialWindowSize(0);
|
setInitialWindowSize(0);
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
assertTrue(stream.isReady());
|
assertTrue(stream.isReady());
|
||||||
// Be notified at the beginning.
|
// Be notified at the beginning.
|
||||||
|
|
@ -1695,7 +1699,7 @@ public class OkHttpClientTransportTest {
|
||||||
final String message = "Hello Server";
|
final String message = "Hello Server";
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
InputStream input = new ByteArrayInputStream(message.getBytes(UTF_8));
|
InputStream input = new ByteArrayInputStream(message.getBytes(UTF_8));
|
||||||
stream.writeMessage(input);
|
stream.writeMessage(input);
|
||||||
|
|
@ -1720,7 +1724,7 @@ public class OkHttpClientTransportTest {
|
||||||
final String message = "Hello Server";
|
final String message = "Hello Server";
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
InputStream input = new ByteArrayInputStream(message.getBytes(UTF_8));
|
InputStream input = new ByteArrayInputStream(message.getBytes(UTF_8));
|
||||||
stream.writeMessage(input);
|
stream.writeMessage(input);
|
||||||
|
|
@ -1738,7 +1742,7 @@ public class OkHttpClientTransportTest {
|
||||||
initTransportAndDelayConnected();
|
initTransportAndDelayConnected();
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
clientTransport.shutdown(SHUTDOWN_REASON);
|
clientTransport.shutdown(SHUTDOWN_REASON);
|
||||||
allowTransportConnected();
|
allowTransportConnected();
|
||||||
|
|
@ -1810,7 +1814,8 @@ public class OkHttpClientTransportTest {
|
||||||
assertTrue(status.getCause().toString(), status.getCause() instanceof IOException);
|
assertTrue(status.getCause().toString(), status.getCause() instanceof IOException);
|
||||||
|
|
||||||
MockStreamListener streamListener = new MockStreamListener();
|
MockStreamListener streamListener = new MockStreamListener();
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT).start(streamListener);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers)
|
||||||
|
.start(streamListener);
|
||||||
streamListener.waitUntilStreamClosed();
|
streamListener.waitUntilStreamClosed();
|
||||||
assertEquals(Status.UNAVAILABLE.getCode(), streamListener.status.getCode());
|
assertEquals(Status.UNAVAILABLE.getCode(), streamListener.status.getCode());
|
||||||
}
|
}
|
||||||
|
|
@ -2054,13 +2059,13 @@ public class OkHttpClientTransportTest {
|
||||||
MockStreamListener listener2 = new MockStreamListener();
|
MockStreamListener listener2 = new MockStreamListener();
|
||||||
MockStreamListener listener3 = new MockStreamListener();
|
MockStreamListener listener3 = new MockStreamListener();
|
||||||
OkHttpClientStream stream1 =
|
OkHttpClientStream stream1 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream1.start(listener1);
|
stream1.start(listener1);
|
||||||
OkHttpClientStream stream2 =
|
OkHttpClientStream stream2 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream2.start(listener2);
|
stream2.start(listener2);
|
||||||
OkHttpClientStream stream3 =
|
OkHttpClientStream stream3 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream3.start(listener3);
|
stream3.start(listener3);
|
||||||
waitForStreamPending(1);
|
waitForStreamPending(1);
|
||||||
|
|
||||||
|
|
@ -2094,13 +2099,13 @@ public class OkHttpClientTransportTest {
|
||||||
MockStreamListener listener2 = new MockStreamListener();
|
MockStreamListener listener2 = new MockStreamListener();
|
||||||
MockStreamListener listener3 = new MockStreamListener();
|
MockStreamListener listener3 = new MockStreamListener();
|
||||||
OkHttpClientStream stream1 =
|
OkHttpClientStream stream1 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream1.start(listener1);
|
stream1.start(listener1);
|
||||||
OkHttpClientStream stream2 =
|
OkHttpClientStream stream2 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream2.start(listener2);
|
stream2.start(listener2);
|
||||||
OkHttpClientStream stream3 =
|
OkHttpClientStream stream3 =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream3.start(listener3);
|
stream3.start(listener3);
|
||||||
|
|
||||||
assertEquals(3, activeStreamCount());
|
assertEquals(3, activeStreamCount());
|
||||||
|
|
@ -2158,7 +2163,7 @@ public class OkHttpClientTransportTest {
|
||||||
private void assertNewStreamFail() throws Exception {
|
private void assertNewStreamFail() throws Exception {
|
||||||
MockStreamListener listener = new MockStreamListener();
|
MockStreamListener listener = new MockStreamListener();
|
||||||
OkHttpClientStream stream =
|
OkHttpClientStream stream =
|
||||||
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT);
|
clientTransport.newStream(method, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||||
stream.start(listener);
|
stream.start(listener);
|
||||||
listener.waitUntilStreamClosed();
|
listener.waitUntilStreamClosed();
|
||||||
assertFalse(listener.status.isOk());
|
assertFalse(listener.status.isOk());
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,8 @@ import io.grpc.InternalLogId;
|
||||||
import io.grpc.LoadBalancer;
|
import io.grpc.LoadBalancer;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
import io.grpc.Status;
|
import io.grpc.Status;
|
||||||
|
import io.grpc.internal.ForwardingClientStreamTracer;
|
||||||
import io.grpc.internal.ObjectPool;
|
import io.grpc.internal.ObjectPool;
|
||||||
import io.grpc.util.ForwardingClientStreamTracer;
|
|
||||||
import io.grpc.util.ForwardingLoadBalancerHelper;
|
import io.grpc.util.ForwardingLoadBalancerHelper;
|
||||||
import io.grpc.util.ForwardingSubchannel;
|
import io.grpc.util.ForwardingSubchannel;
|
||||||
import io.grpc.xds.ClusterImplLoadBalancerProvider.ClusterImplConfig;
|
import io.grpc.xds.ClusterImplLoadBalancerProvider.ClusterImplConfig;
|
||||||
|
|
@ -329,7 +329,8 @@ final class ClusterImplLoadBalancer extends LoadBalancer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class CountingStreamTracerFactory extends ClientStreamTracer.Factory {
|
private static final class CountingStreamTracerFactory extends
|
||||||
|
ClientStreamTracer.InternalLimitedInfoFactory {
|
||||||
private ClusterLocalityStats stats;
|
private ClusterLocalityStats stats;
|
||||||
private final AtomicLong inFlights;
|
private final AtomicLong inFlights;
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ import io.grpc.ClientStreamTracer;
|
||||||
import io.grpc.ClientStreamTracer.StreamInfo;
|
import io.grpc.ClientStreamTracer.StreamInfo;
|
||||||
import io.grpc.LoadBalancer;
|
import io.grpc.LoadBalancer;
|
||||||
import io.grpc.Metadata;
|
import io.grpc.Metadata;
|
||||||
|
import io.grpc.internal.ForwardingClientStreamTracer;
|
||||||
import io.grpc.protobuf.ProtoUtils;
|
import io.grpc.protobuf.ProtoUtils;
|
||||||
import io.grpc.util.ForwardingClientStreamTracer;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ import java.util.List;
|
||||||
abstract class OrcaPerRequestUtil {
|
abstract class OrcaPerRequestUtil {
|
||||||
private static final ClientStreamTracer NOOP_CLIENT_STREAM_TRACER = new ClientStreamTracer() {};
|
private static final ClientStreamTracer NOOP_CLIENT_STREAM_TRACER = new ClientStreamTracer() {};
|
||||||
private static final ClientStreamTracer.Factory NOOP_CLIENT_STREAM_TRACER_FACTORY =
|
private static final ClientStreamTracer.Factory NOOP_CLIENT_STREAM_TRACER_FACTORY =
|
||||||
new ClientStreamTracer.Factory() {
|
new ClientStreamTracer.InternalLimitedInfoFactory() {
|
||||||
@Override
|
@Override
|
||||||
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
|
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
|
||||||
return NOOP_CLIENT_STREAM_TRACER;
|
return NOOP_CLIENT_STREAM_TRACER;
|
||||||
|
|
@ -189,7 +189,8 @@ abstract class OrcaPerRequestUtil {
|
||||||
* per-request ORCA reports and push to registered listeners for calls they trace.
|
* per-request ORCA reports and push to registered listeners for calls they trace.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final class OrcaReportingTracerFactory extends ClientStreamTracer.Factory {
|
static final class OrcaReportingTracerFactory extends
|
||||||
|
ClientStreamTracer.InternalLimitedInfoFactory {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final Metadata.Key<OrcaLoadReport> ORCA_ENDPOINT_LOAD_METRICS_KEY =
|
static final Metadata.Key<OrcaLoadReport> ORCA_ENDPOINT_LOAD_METRICS_KEY =
|
||||||
|
|
|
||||||
|
|
@ -341,8 +341,8 @@ public class ClusterImplLoadBalancerTest {
|
||||||
PickResult result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
|
PickResult result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
|
||||||
assertThat(result.getStatus().isOk()).isTrue();
|
assertThat(result.getStatus().isOk()).isTrue();
|
||||||
ClientStreamTracer.Factory streamTracerFactory = result.getStreamTracerFactory();
|
ClientStreamTracer.Factory streamTracerFactory = result.getStreamTracerFactory();
|
||||||
streamTracerFactory.newClientStreamTracer(ClientStreamTracer.StreamInfo.newBuilder().build(),
|
streamTracerFactory.newClientStreamTracer(
|
||||||
new Metadata());
|
ClientStreamTracer.StreamInfo.newBuilder().build(), new Metadata());
|
||||||
}
|
}
|
||||||
ClusterStats clusterStats =
|
ClusterStats clusterStats =
|
||||||
Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
|
Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
|
||||||
|
|
@ -429,8 +429,8 @@ public class ClusterImplLoadBalancerTest {
|
||||||
PickResult result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
|
PickResult result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
|
||||||
assertThat(result.getStatus().isOk()).isTrue();
|
assertThat(result.getStatus().isOk()).isTrue();
|
||||||
ClientStreamTracer.Factory streamTracerFactory = result.getStreamTracerFactory();
|
ClientStreamTracer.Factory streamTracerFactory = result.getStreamTracerFactory();
|
||||||
streamTracerFactory.newClientStreamTracer(ClientStreamTracer.StreamInfo.newBuilder().build(),
|
streamTracerFactory.newClientStreamTracer(
|
||||||
new Metadata());
|
ClientStreamTracer.StreamInfo.newBuilder().build(), new Metadata());
|
||||||
}
|
}
|
||||||
ClusterStats clusterStats =
|
ClusterStats clusterStats =
|
||||||
Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
|
Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue