Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api,core: change ManagedChannel and Server Builders to use GlobalInterceptors #9312

Merged
merged 2 commits into from Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/src/main/java/io/grpc/GlobalInterceptors.java
Expand Up @@ -33,6 +33,10 @@ final class GlobalInterceptors {
// Prevent instantiation
private GlobalInterceptors() {}

static boolean isIsGlobalInterceptorsTracersSet() {
return isGlobalInterceptorsTracersSet;
}

/**
* Sets the list of global interceptors and global server stream tracers.
*
Expand Down
4 changes: 4 additions & 0 deletions api/src/main/java/io/grpc/InternalGlobalInterceptors.java
Expand Up @@ -42,5 +42,9 @@ public static List<ServerStreamTracer.Factory> getServerStreamTracerFactories()
return GlobalInterceptors.getServerStreamTracerFactories();
}

public static boolean isGlobalInterceptorsTracersSet() {
return GlobalInterceptors.isIsGlobalInterceptorsTracersSet();
}

private InternalGlobalInterceptors() {}
}
14 changes: 10 additions & 4 deletions core/src/main/java/io/grpc/internal/ManagedChannelImplBuilder.java
Expand Up @@ -31,6 +31,7 @@
import io.grpc.DecompressorRegistry;
import io.grpc.EquivalentAddressGroup;
import io.grpc.InternalChannelz;
import io.grpc.InternalGlobalInterceptors;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.NameResolver;
Expand Down Expand Up @@ -636,9 +637,14 @@ public ManagedChannel build() {
// TODO(zdapeng): FIX IT
@VisibleForTesting
List<ClientInterceptor> getEffectiveInterceptors() {
List<ClientInterceptor> effectiveInterceptors =
new ArrayList<>(this.interceptors);
if (statsEnabled) {
List<ClientInterceptor> effectiveInterceptors = new ArrayList<>(this.interceptors);
boolean isGlobalInterceptorsSet = InternalGlobalInterceptors.isGlobalInterceptorsTracersSet();
List<ClientInterceptor> globalClientInterceptors =
sanjaypujare marked this conversation as resolved.
Show resolved Hide resolved
InternalGlobalInterceptors.getClientInterceptors();
if (isGlobalInterceptorsSet) {
effectiveInterceptors.addAll(globalClientInterceptors);
}
if (!isGlobalInterceptorsSet && statsEnabled) {
ClientInterceptor statsInterceptor = null;
try {
Class<?> censusStatsAccessor =
Expand Down Expand Up @@ -674,7 +680,7 @@ List<ClientInterceptor> getEffectiveInterceptors() {
effectiveInterceptors.add(0, statsInterceptor);
}
}
if (tracingEnabled) {
if (!isGlobalInterceptorsSet && tracingEnabled) {
ClientInterceptor tracingInterceptor = null;
try {
Class<?> censusTracingAccessor =
Expand Down
15 changes: 13 additions & 2 deletions core/src/main/java/io/grpc/internal/ServerImplBuilder.java
Expand Up @@ -30,6 +30,7 @@
import io.grpc.DecompressorRegistry;
import io.grpc.HandlerRegistry;
import io.grpc.InternalChannelz;
import io.grpc.InternalGlobalInterceptors;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.ServerCallExecutorSupplier;
Expand Down Expand Up @@ -246,7 +247,17 @@ public Server build() {
@VisibleForTesting
List<? extends ServerStreamTracer.Factory> getTracerFactories() {
ArrayList<ServerStreamTracer.Factory> tracerFactories = new ArrayList<>();
if (statsEnabled) {
boolean isGlobalInterceptorsTracersSet
= InternalGlobalInterceptors.isGlobalInterceptorsTracersSet();
List<ServerInterceptor> globalServerInterceptors
= InternalGlobalInterceptors.getServerInterceptors();
List<ServerStreamTracer.Factory> globalServerStreamTracerFactories
= InternalGlobalInterceptors.getServerStreamTracerFactories();
if (isGlobalInterceptorsTracersSet) {
tracerFactories.addAll(globalServerStreamTracerFactories);
interceptors.addAll(globalServerInterceptors);
}
if (!isGlobalInterceptorsTracersSet && statsEnabled) {
ServerStreamTracer.Factory censusStatsTracerFactory = null;
try {
Class<?> censusStatsAccessor =
Expand Down Expand Up @@ -278,7 +289,7 @@ List<? extends ServerStreamTracer.Factory> getTracerFactories() {
tracerFactories.add(censusStatsTracerFactory);
}
}
if (tracingEnabled) {
if (!isGlobalInterceptorsTracersSet && tracingEnabled) {
ServerStreamTracer.Factory tracingStreamTracerFactory = null;
try {
Class<?> censusTracingAccessor =
Expand Down
Expand Up @@ -35,9 +35,11 @@
import io.grpc.ClientInterceptor;
import io.grpc.CompressorRegistry;
import io.grpc.DecompressorRegistry;
import io.grpc.InternalGlobalInterceptors;
import io.grpc.ManagedChannel;
import io.grpc.MethodDescriptor;
import io.grpc.NameResolver;
import io.grpc.StaticTestingClassLoader;
import io.grpc.internal.ManagedChannelImplBuilder.ChannelBuilderDefaultPortProvider;
import io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder;
import io.grpc.internal.ManagedChannelImplBuilder.FixedPortProvider;
Expand All @@ -47,12 +49,14 @@
import java.net.SocketAddress;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
Expand All @@ -78,6 +82,14 @@ public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
return next.newCall(method, callOptions);
}
};
private static final ClientInterceptor DUMMY_USER_INTERCEPTOR1 =
new ClientInterceptor() {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
return next.newCall(method, callOptions);
}
};

@Rule public final MockitoRule mocks = MockitoJUnit.rule();
@SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467
Expand All @@ -90,7 +102,12 @@ public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
private ManagedChannelImplBuilder builder;
private ManagedChannelImplBuilder directAddressBuilder;
private final FakeClock clock = new FakeClock();

private final StaticTestingClassLoader classLoader =
new StaticTestingClassLoader(
getClass().getClassLoader(),
Pattern.compile(
"io\\.grpc\\.InternalGlobalInterceptors|io\\.grpc\\.GlobalInterceptors|"
+ "io\\.grpc\\.internal\\.[^.]+"));

@Before
public void setUp() throws Exception {
Expand Down Expand Up @@ -447,6 +464,86 @@ public void getEffectiveInterceptors_disableBoth() {
assertThat(effectiveInterceptors).containsExactly(DUMMY_USER_INTERCEPTOR);
}

@Test
public void getEffectiveInterceptors_callsGetGlobalInterceptors() throws Exception {
Class<?> runnable = classLoader.loadClass(StaticTestingClassLoaderCallsGet.class.getName());
((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
}

// UsedReflectively
public static final class StaticTestingClassLoaderCallsGet implements Runnable {

@Override
public void run() {
ManagedChannelImplBuilder builder =
new ManagedChannelImplBuilder(
DUMMY_TARGET,
new UnsupportedClientTransportFactoryBuilder(),
new FixedPortProvider(DUMMY_PORT));
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
assertThat(effectiveInterceptors).hasSize(2);
try {
InternalGlobalInterceptors.setInterceptorsTracers(
Arrays.asList(DUMMY_USER_INTERCEPTOR),
Collections.emptyList(),
Collections.emptyList());
fail("exception expected");
} catch (IllegalStateException e) {
assertThat(e).hasMessageThat().contains("Set cannot be called after any get call");
}
}
}

@Test
public void getEffectiveInterceptors_callsSetGlobalInterceptors() throws Exception {
Class<?> runnable = classLoader.loadClass(StaticTestingClassLoaderCallsSet.class.getName());
((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
}

// UsedReflectively
public static final class StaticTestingClassLoaderCallsSet implements Runnable {

@Override
public void run() {
InternalGlobalInterceptors.setInterceptorsTracers(
Arrays.asList(DUMMY_USER_INTERCEPTOR, DUMMY_USER_INTERCEPTOR1),
Collections.emptyList(),
Collections.emptyList());
ManagedChannelImplBuilder builder =
new ManagedChannelImplBuilder(
DUMMY_TARGET,
new UnsupportedClientTransportFactoryBuilder(),
new FixedPortProvider(DUMMY_PORT));
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
assertThat(effectiveInterceptors)
.containsExactly(DUMMY_USER_INTERCEPTOR, DUMMY_USER_INTERCEPTOR1);
}
}

@Test
public void getEffectiveInterceptors_setEmptyGlobalInterceptors() throws Exception {
Class<?> runnable =
classLoader.loadClass(StaticTestingClassLoaderCallsSetEmpty.class.getName());
((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
}

// UsedReflectively
public static final class StaticTestingClassLoaderCallsSetEmpty implements Runnable {

@Override
public void run() {
InternalGlobalInterceptors.setInterceptorsTracers(
Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
ManagedChannelImplBuilder builder =
new ManagedChannelImplBuilder(
DUMMY_TARGET,
new UnsupportedClientTransportFactoryBuilder(),
new FixedPortProvider(DUMMY_PORT));
List<ClientInterceptor> effectiveInterceptors = builder.getEffectiveInterceptors();
assertThat(effectiveInterceptors).isEmpty();
}
}

@Test
public void idleTimeout() {
assertEquals(ManagedChannelImplBuilder.IDLE_MODE_DEFAULT_TIMEOUT_MILLIS,
Expand Down
97 changes: 97 additions & 0 deletions core/src/test/java/io/grpc/internal/ServerImplBuilderTest.java
Expand Up @@ -18,11 +18,20 @@

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import io.grpc.InternalGlobalInterceptors;
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.ServerStreamTracer;
import io.grpc.StaticTestingClassLoader;
import io.grpc.internal.ServerImplBuilder.ClientTransportServersBuilder;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand All @@ -38,6 +47,21 @@ public ServerStreamTracer newServerStreamTracer(String fullMethodName, Metadata
throw new UnsupportedOperationException();
}
};
private static final ServerInterceptor DUMMY_TEST_INTERCEPTOR =
new ServerInterceptor() {

@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
throw new UnsupportedOperationException();
}
};
private final StaticTestingClassLoader classLoader =
new StaticTestingClassLoader(
getClass().getClassLoader(),
Pattern.compile(
"io\\.grpc\\.InternalGlobalInterceptors|io\\.grpc\\.GlobalInterceptors|"
+ "io\\.grpc\\.internal\\.[^.]+"));

private ServerImplBuilder builder;

Expand Down Expand Up @@ -101,4 +125,77 @@ public void getTracerFactories_disableBoth() {
List<? extends ServerStreamTracer.Factory> factories = builder.getTracerFactories();
assertThat(factories).containsExactly(DUMMY_USER_TRACER);
}

@Test
public void getTracerFactories_callsGet() throws Exception {
Class<?> runnable = classLoader.loadClass(StaticTestingClassLoaderCallsGet.class.getName());
((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
}

public static final class StaticTestingClassLoaderCallsGet implements Runnable {
@Override
public void run() {
ServerImplBuilder builder =
new ServerImplBuilder(
streamTracerFactories -> {
throw new UnsupportedOperationException();
});
assertThat(builder.getTracerFactories()).hasSize(2);
assertThat(builder.interceptors).hasSize(0);
try {
InternalGlobalInterceptors.setInterceptorsTracers(
Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
fail("exception expected");
} catch (IllegalStateException e) {
assertThat(e).hasMessageThat().contains("Set cannot be called after any get call");
}
}
}

@Test
public void getTracerFactories_callsSet() throws Exception {
Class<?> runnable = classLoader.loadClass(StaticTestingClassLoaderCallsSet.class.getName());
((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
}

public static final class StaticTestingClassLoaderCallsSet implements Runnable {
@Override
public void run() {
InternalGlobalInterceptors.setInterceptorsTracers(
Collections.emptyList(),
Arrays.asList(DUMMY_TEST_INTERCEPTOR),
Arrays.asList(DUMMY_USER_TRACER));
ServerImplBuilder builder =
new ServerImplBuilder(
streamTracerFactories -> {
throw new UnsupportedOperationException();
});
assertThat(builder.getTracerFactories()).containsExactly(DUMMY_USER_TRACER);
assertThat(builder.interceptors).containsExactly(DUMMY_TEST_INTERCEPTOR);
}
}

@Test
public void getEffectiveInterceptors_setEmpty() throws Exception {
Class<?> runnable =
classLoader.loadClass(StaticTestingClassLoaderCallsSetEmpty.class.getName());
((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
}

// UsedReflectively
public static final class StaticTestingClassLoaderCallsSetEmpty implements Runnable {

@Override
public void run() {
InternalGlobalInterceptors.setInterceptorsTracers(
Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
ServerImplBuilder builder =
new ServerImplBuilder(
streamTracerFactories -> {
throw new UnsupportedOperationException();
});
assertThat(builder.getTracerFactories()).isEmpty();
assertThat(builder.interceptors).isEmpty();
}
}
}