core: Inline AbstractServerImplBuilder

This commit is contained in:
Sergii Tkachenko 2020-09-18 16:31:08 -04:00 committed by GitHub
parent bf7a42dbd1
commit b571f23ad2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 320 additions and 498 deletions

View File

@ -1,330 +0,0 @@
/*
* Copyright 2014 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 com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.util.concurrent.MoreExecutors;
import io.grpc.BinaryLog;
import io.grpc.BindableService;
import io.grpc.CompressorRegistry;
import io.grpc.Context;
import io.grpc.Deadline;
import io.grpc.DecompressorRegistry;
import io.grpc.HandlerRegistry;
import io.grpc.InternalChannelz;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.ServerInterceptor;
import io.grpc.ServerMethodDefinition;
import io.grpc.ServerServiceDefinition;
import io.grpc.ServerStreamTracer;
import io.grpc.ServerTransportFilter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
/**
* The base class for server builders.
*
* @param <T> The concrete type for this builder.
*/
public abstract class AbstractServerImplBuilder<T extends AbstractServerImplBuilder<T>>
extends ServerBuilder<T> {
private static final Logger log = Logger.getLogger(AbstractServerImplBuilder.class.getName());
public static ServerBuilder<?> forPort(int port) {
throw new UnsupportedOperationException("Subclass failed to hide static factory");
}
// defaults
private static final ObjectPool<? extends Executor> DEFAULT_EXECUTOR_POOL =
SharedResourcePool.forResource(GrpcUtil.SHARED_CHANNEL_EXECUTOR);
private static final HandlerRegistry DEFAULT_FALLBACK_REGISTRY = new DefaultFallbackRegistry();
private static final DecompressorRegistry DEFAULT_DECOMPRESSOR_REGISTRY =
DecompressorRegistry.getDefaultInstance();
private static final CompressorRegistry DEFAULT_COMPRESSOR_REGISTRY =
CompressorRegistry.getDefaultInstance();
private static final long DEFAULT_HANDSHAKE_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(120);
// mutable state
final InternalHandlerRegistry.Builder registryBuilder =
new InternalHandlerRegistry.Builder();
final List<ServerTransportFilter> transportFilters = new ArrayList<>();
final List<ServerInterceptor> interceptors = new ArrayList<>();
private final List<ServerStreamTracer.Factory> streamTracerFactories = new ArrayList<>();
HandlerRegistry fallbackRegistry = DEFAULT_FALLBACK_REGISTRY;
ObjectPool<? extends Executor> executorPool = DEFAULT_EXECUTOR_POOL;
DecompressorRegistry decompressorRegistry = DEFAULT_DECOMPRESSOR_REGISTRY;
CompressorRegistry compressorRegistry = DEFAULT_COMPRESSOR_REGISTRY;
long handshakeTimeoutMillis = DEFAULT_HANDSHAKE_TIMEOUT_MILLIS;
Deadline.Ticker ticker = Deadline.getSystemTicker();
private boolean statsEnabled = true;
private boolean recordStartedRpcs = true;
private boolean recordFinishedRpcs = true;
private boolean recordRealTimeMetrics = false;
private boolean tracingEnabled = true;
@Nullable BinaryLog binlog;
TransportTracer.Factory transportTracerFactory = TransportTracer.getDefaultFactory();
InternalChannelz channelz = InternalChannelz.instance();
CallTracer.Factory callTracerFactory = CallTracer.getDefaultFactory();
@Override
public final T directExecutor() {
return executor(MoreExecutors.directExecutor());
}
@Override
public final T executor(@Nullable Executor executor) {
this.executorPool = executor != null ? new FixedObjectPool<>(executor) : DEFAULT_EXECUTOR_POOL;
return thisT();
}
@Override
public final T addService(ServerServiceDefinition service) {
registryBuilder.addService(checkNotNull(service, "service"));
return thisT();
}
@Override
public final T addService(BindableService bindableService) {
return addService(checkNotNull(bindableService, "bindableService").bindService());
}
@Override
public final T addTransportFilter(ServerTransportFilter filter) {
transportFilters.add(checkNotNull(filter, "filter"));
return thisT();
}
@Override
public final T intercept(ServerInterceptor interceptor) {
interceptors.add(checkNotNull(interceptor, "interceptor"));
return thisT();
}
@Override
public final T addStreamTracerFactory(ServerStreamTracer.Factory factory) {
streamTracerFactories.add(checkNotNull(factory, "factory"));
return thisT();
}
@Override
public final T fallbackHandlerRegistry(@Nullable HandlerRegistry registry) {
this.fallbackRegistry = registry != null ? registry : DEFAULT_FALLBACK_REGISTRY;
return thisT();
}
@Override
public final T decompressorRegistry(@Nullable DecompressorRegistry registry) {
this.decompressorRegistry = registry != null ? registry : DEFAULT_DECOMPRESSOR_REGISTRY;
return thisT();
}
@Override
public final T compressorRegistry(@Nullable CompressorRegistry registry) {
this.compressorRegistry = registry != null ? registry : DEFAULT_COMPRESSOR_REGISTRY;
return thisT();
}
@Override
public final T handshakeTimeout(long timeout, TimeUnit unit) {
checkArgument(timeout > 0, "handshake timeout is %s, but must be positive", timeout);
this.handshakeTimeoutMillis = checkNotNull(unit, "unit").toMillis(timeout);
return thisT();
}
@Override
public final T setBinaryLog(@Nullable BinaryLog binaryLog) {
this.binlog = binaryLog;
return thisT();
}
@VisibleForTesting
public final T setTransportTracerFactory(TransportTracer.Factory transportTracerFactory) {
this.transportTracerFactory = transportTracerFactory;
return thisT();
}
/**
* Disable or enable stats features. Enabled by default.
*/
protected void setStatsEnabled(boolean value) {
this.statsEnabled = value;
}
/**
* Disable or enable stats recording for RPC upstarts. Effective only if {@link
* #setStatsEnabled} is set to true. Enabled by default.
*/
protected void setStatsRecordStartedRpcs(boolean value) {
recordStartedRpcs = value;
}
/**
* Disable or enable stats recording for RPC completions. Effective only if {@link
* #setStatsEnabled} is set to true. Enabled by default.
*/
protected void setStatsRecordFinishedRpcs(boolean value) {
recordFinishedRpcs = value;
}
/**
* Disable or enable real-time metrics recording. Effective only if {@link #setStatsEnabled} is
* set to true. Disabled by default.
*/
protected void setStatsRecordRealTimeMetrics(boolean value) {
recordRealTimeMetrics = value;
}
/**
* Disable or enable tracing features. Enabled by default.
*/
protected void setTracingEnabled(boolean value) {
tracingEnabled = value;
}
/**
* Sets a custom deadline ticker. This should only be called from InProcessServerBuilder.
*/
protected void setDeadlineTicker(Deadline.Ticker ticker) {
this.ticker = checkNotNull(ticker, "ticker");
}
@Override
public final Server build() {
return new ServerImpl(this, buildTransportServers(getTracerFactories()), Context.ROOT);
}
@VisibleForTesting
final List<? extends ServerStreamTracer.Factory> getTracerFactories() {
ArrayList<ServerStreamTracer.Factory> tracerFactories = new ArrayList<>();
if (statsEnabled) {
ServerStreamTracer.Factory censusStatsTracerFactory = null;
try {
Class<?> censusStatsAccessor =
Class.forName("io.grpc.census.InternalCensusStatsAccessor");
Method getServerStreamTracerFactoryMethod =
censusStatsAccessor.getDeclaredMethod(
"getServerStreamTracerFactory",
boolean.class,
boolean.class,
boolean.class);
censusStatsTracerFactory =
(ServerStreamTracer.Factory) getServerStreamTracerFactoryMethod
.invoke(
null,
recordStartedRpcs,
recordFinishedRpcs,
recordRealTimeMetrics);
} catch (ClassNotFoundException e) {
// Replace these separate catch statements with multicatch when Android min-API >= 19
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (NoSuchMethodException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (IllegalAccessException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (InvocationTargetException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
}
if (censusStatsTracerFactory != null) {
tracerFactories.add(censusStatsTracerFactory);
}
}
if (tracingEnabled) {
ServerStreamTracer.Factory tracingStreamTracerFactory = null;
try {
Class<?> censusTracingAccessor =
Class.forName("io.grpc.census.InternalCensusTracingAccessor");
Method getServerStreamTracerFactoryMethod =
censusTracingAccessor.getDeclaredMethod("getServerStreamTracerFactory");
tracingStreamTracerFactory =
(ServerStreamTracer.Factory) getServerStreamTracerFactoryMethod.invoke(null);
} catch (ClassNotFoundException e) {
// Replace these separate catch statements with multicatch when Android min-API >= 19
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (NoSuchMethodException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (IllegalAccessException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (InvocationTargetException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
}
if (tracingStreamTracerFactory != null) {
tracerFactories.add(tracingStreamTracerFactory);
}
}
tracerFactories.addAll(streamTracerFactories);
tracerFactories.trimToSize();
return Collections.unmodifiableList(tracerFactories);
}
protected InternalChannelz getChannelz() {
return channelz;
}
protected final TransportTracer.Factory getTransportTracerFactory() {
return transportTracerFactory;
}
/**
* Children of AbstractServerBuilder should override this method to provide transport specific
* information for the server. This method is mean for Transport implementors and should not be
* used by normal users.
*
* @param streamTracerFactories an immutable list of stream tracer factories
*/
protected abstract List<? extends io.grpc.internal.InternalServer> buildTransportServers(
List<? extends ServerStreamTracer.Factory> streamTracerFactories);
private T thisT() {
@SuppressWarnings("unchecked")
T thisT = (T) this;
return thisT;
}
private static final class DefaultFallbackRegistry extends HandlerRegistry {
@Override
public List<ServerServiceDefinition> getServices() {
return Collections.emptyList();
}
@Nullable
@Override
public ServerMethodDefinition<?, ?> lookupMethod(
String methodName, @Nullable String authority) {
return null;
}
}
/**
* Returns the internal ExecutorPool for offloading tasks.
*/
protected ObjectPool<? extends Executor> getExecutorPool() {
return this.executorPool;
}
}

View File

@ -135,7 +135,7 @@ public final class ServerImpl extends io.grpc.Server implements InternalInstrume
* @param rootContext context that callbacks for new RPCs should be derived from
*/
ServerImpl(
AbstractServerImplBuilder<?> builder,
ServerImplBuilder builder,
List<? extends InternalServer> transportServers,
Context rootContext) {
this.executorPool = Preconditions.checkNotNull(builder.executorPool, "executorPool");

View File

@ -16,20 +16,81 @@
package io.grpc.internal;
import com.google.common.base.Preconditions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.util.concurrent.MoreExecutors;
import io.grpc.BinaryLog;
import io.grpc.BindableService;
import io.grpc.CompressorRegistry;
import io.grpc.Context;
import io.grpc.Deadline;
import io.grpc.DecompressorRegistry;
import io.grpc.HandlerRegistry;
import io.grpc.InternalChannelz;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.ServerInterceptor;
import io.grpc.ServerMethodDefinition;
import io.grpc.ServerServiceDefinition;
import io.grpc.ServerStreamTracer;
import io.grpc.ServerTransportFilter;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
/**
* Default builder for {@link io.grpc.Server} instances, for usage in Transport implementations.
*/
public final class ServerImplBuilder extends AbstractServerImplBuilder<ServerImplBuilder> {
public final class ServerImplBuilder extends ServerBuilder<ServerImplBuilder> {
private static final Logger log = Logger.getLogger(ServerImplBuilder.class.getName());
public static ServerBuilder<?> forPort(int port) {
throw new UnsupportedOperationException(
"ClientTransportServersBuilder is required, use a constructor");
}
// defaults
private static final ObjectPool<? extends Executor> DEFAULT_EXECUTOR_POOL =
SharedResourcePool.forResource(GrpcUtil.SHARED_CHANNEL_EXECUTOR);
private static final HandlerRegistry DEFAULT_FALLBACK_REGISTRY = new DefaultFallbackRegistry();
private static final DecompressorRegistry DEFAULT_DECOMPRESSOR_REGISTRY =
DecompressorRegistry.getDefaultInstance();
private static final CompressorRegistry DEFAULT_COMPRESSOR_REGISTRY =
CompressorRegistry.getDefaultInstance();
private static final long DEFAULT_HANDSHAKE_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(120);
// mutable state
final InternalHandlerRegistry.Builder registryBuilder =
new InternalHandlerRegistry.Builder();
final List<ServerTransportFilter> transportFilters = new ArrayList<>();
final List<ServerInterceptor> interceptors = new ArrayList<>();
private final List<ServerStreamTracer.Factory> streamTracerFactories = new ArrayList<>();
private final ClientTransportServersBuilder clientTransportServersBuilder;
HandlerRegistry fallbackRegistry = DEFAULT_FALLBACK_REGISTRY;
ObjectPool<? extends Executor> executorPool = DEFAULT_EXECUTOR_POOL;
DecompressorRegistry decompressorRegistry = DEFAULT_DECOMPRESSOR_REGISTRY;
CompressorRegistry compressorRegistry = DEFAULT_COMPRESSOR_REGISTRY;
long handshakeTimeoutMillis = DEFAULT_HANDSHAKE_TIMEOUT_MILLIS;
Deadline.Ticker ticker = Deadline.getSystemTicker();
private boolean statsEnabled = true;
private boolean recordStartedRpcs = true;
private boolean recordFinishedRpcs = true;
private boolean recordRealTimeMetrics = false;
private boolean tracingEnabled = true;
@Nullable BinaryLog binlog;
InternalChannelz channelz = InternalChannelz.instance();
CallTracer.Factory callTracerFactory = CallTracer.getDefaultFactory();
/**
* An interface to provide to provide transport specific information for the server. This method
@ -44,62 +105,223 @@ public final class ServerImplBuilder extends AbstractServerImplBuilder<ServerImp
* Creates a new server builder with given transport servers provider.
*/
public ServerImplBuilder(ClientTransportServersBuilder clientTransportServersBuilder) {
this.clientTransportServersBuilder = Preconditions
.checkNotNull(clientTransportServersBuilder, "clientTransportServersBuilder");
this.clientTransportServersBuilder = checkNotNull(clientTransportServersBuilder,
"clientTransportServersBuilder");
}
@Override
protected List<? extends InternalServer> buildTransportServers(
List<? extends ServerStreamTracer.Factory> streamTracerFactories) {
return clientTransportServersBuilder.buildClientTransportServers(streamTracerFactories);
public ServerImplBuilder directExecutor() {
return executor(MoreExecutors.directExecutor());
}
@Override
public void setDeadlineTicker(Deadline.Ticker ticker) {
super.setDeadlineTicker(ticker);
public ServerImplBuilder executor(@Nullable Executor executor) {
this.executorPool = executor != null ? new FixedObjectPool<>(executor) : DEFAULT_EXECUTOR_POOL;
return this;
}
@Override
public void setTracingEnabled(boolean value) {
super.setTracingEnabled(value);
public ServerImplBuilder addService(ServerServiceDefinition service) {
registryBuilder.addService(checkNotNull(service, "service"));
return this;
}
@Override
public ServerImplBuilder addService(BindableService bindableService) {
return addService(checkNotNull(bindableService, "bindableService").bindService());
}
@Override
public ServerImplBuilder addTransportFilter(ServerTransportFilter filter) {
transportFilters.add(checkNotNull(filter, "filter"));
return this;
}
@Override
public ServerImplBuilder intercept(ServerInterceptor interceptor) {
interceptors.add(checkNotNull(interceptor, "interceptor"));
return this;
}
@Override
public ServerImplBuilder addStreamTracerFactory(ServerStreamTracer.Factory factory) {
streamTracerFactories.add(checkNotNull(factory, "factory"));
return this;
}
@Override
public ServerImplBuilder fallbackHandlerRegistry(@Nullable HandlerRegistry registry) {
this.fallbackRegistry = registry != null ? registry : DEFAULT_FALLBACK_REGISTRY;
return this;
}
@Override
public ServerImplBuilder decompressorRegistry(@Nullable DecompressorRegistry registry) {
this.decompressorRegistry = registry != null ? registry : DEFAULT_DECOMPRESSOR_REGISTRY;
return this;
}
@Override
public ServerImplBuilder compressorRegistry(@Nullable CompressorRegistry registry) {
this.compressorRegistry = registry != null ? registry : DEFAULT_COMPRESSOR_REGISTRY;
return this;
}
@Override
public ServerImplBuilder handshakeTimeout(long timeout, TimeUnit unit) {
checkArgument(timeout > 0, "handshake timeout is %s, but must be positive", timeout);
this.handshakeTimeoutMillis = checkNotNull(unit, "unit").toMillis(timeout);
return this;
}
@Override
public ServerImplBuilder setBinaryLog(@Nullable BinaryLog binaryLog) {
this.binlog = binaryLog;
return this;
}
/**
* Disable or enable stats features. Enabled by default.
*/
public void setStatsEnabled(boolean value) {
super.setStatsEnabled(value);
this.statsEnabled = value;
}
@Override
/**
* Disable or enable stats recording for RPC upstarts. Effective only if {@link
* #setStatsEnabled} is set to true. Enabled by default.
*/
public void setStatsRecordStartedRpcs(boolean value) {
super.setStatsRecordStartedRpcs(value);
recordStartedRpcs = value;
}
@Override
/**
* Disable or enable stats recording for RPC completions. Effective only if {@link
* #setStatsEnabled} is set to true. Enabled by default.
*/
public void setStatsRecordFinishedRpcs(boolean value) {
super.setStatsRecordFinishedRpcs(value);
recordFinishedRpcs = value;
}
@Override
/**
* Disable or enable real-time metrics recording. Effective only if {@link #setStatsEnabled} is
* set to true. Disabled by default.
*/
public void setStatsRecordRealTimeMetrics(boolean value) {
super.setStatsRecordRealTimeMetrics(value);
recordRealTimeMetrics = value;
}
/**
* Disable or enable tracing features. Enabled by default.
*/
public void setTracingEnabled(boolean value) {
tracingEnabled = value;
}
/**
* Sets a custom deadline ticker. This should only be called from InProcessServerBuilder.
*/
public void setDeadlineTicker(Deadline.Ticker ticker) {
this.ticker = checkNotNull(ticker, "ticker");
}
@Override
public Server build() {
return new ServerImpl(this,
clientTransportServersBuilder.buildClientTransportServers(getTracerFactories()),
Context.ROOT);
}
@VisibleForTesting
List<? extends ServerStreamTracer.Factory> getTracerFactories() {
ArrayList<ServerStreamTracer.Factory> tracerFactories = new ArrayList<>();
if (statsEnabled) {
ServerStreamTracer.Factory censusStatsTracerFactory = null;
try {
Class<?> censusStatsAccessor =
Class.forName("io.grpc.census.InternalCensusStatsAccessor");
Method getServerStreamTracerFactoryMethod =
censusStatsAccessor.getDeclaredMethod(
"getServerStreamTracerFactory",
boolean.class,
boolean.class,
boolean.class);
censusStatsTracerFactory =
(ServerStreamTracer.Factory) getServerStreamTracerFactoryMethod
.invoke(
null,
recordStartedRpcs,
recordFinishedRpcs,
recordRealTimeMetrics);
} catch (ClassNotFoundException e) {
// Replace these separate catch statements with multicatch when Android min-API >= 19
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (NoSuchMethodException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (IllegalAccessException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (InvocationTargetException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
}
if (censusStatsTracerFactory != null) {
tracerFactories.add(censusStatsTracerFactory);
}
}
if (tracingEnabled) {
ServerStreamTracer.Factory tracingStreamTracerFactory = null;
try {
Class<?> censusTracingAccessor =
Class.forName("io.grpc.census.InternalCensusTracingAccessor");
Method getServerStreamTracerFactoryMethod =
censusTracingAccessor.getDeclaredMethod("getServerStreamTracerFactory");
tracingStreamTracerFactory =
(ServerStreamTracer.Factory) getServerStreamTracerFactoryMethod.invoke(null);
} catch (ClassNotFoundException e) {
// Replace these separate catch statements with multicatch when Android min-API >= 19
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (NoSuchMethodException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (IllegalAccessException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
} catch (InvocationTargetException e) {
log.log(Level.FINE, "Unable to apply census stats", e);
}
if (tracingStreamTracerFactory != null) {
tracerFactories.add(tracingStreamTracerFactory);
}
}
tracerFactories.addAll(streamTracerFactories);
tracerFactories.trimToSize();
return Collections.unmodifiableList(tracerFactories);
}
public InternalChannelz getChannelz() {
return super.getChannelz();
return channelz;
}
@Override
private static final class DefaultFallbackRegistry extends HandlerRegistry {
@Override
public List<ServerServiceDefinition> getServices() {
return Collections.emptyList();
}
@Nullable
@Override
public ServerMethodDefinition<?, ?> lookupMethod(
String methodName, @Nullable String authority) {
return null;
}
}
/**
* Returns the internal ExecutorPool for offloading tasks.
*/
public ObjectPool<? extends Executor> getExecutorPool() {
return super.getExecutorPool();
return this.executorPool;
}
@Override
public ServerImplBuilder useTransportSecurity(File certChain, File privateKey) {
throw new UnsupportedOperationException("TLS not supported in ServerImplBuilder");
}
public static ServerBuilder<?> forPort(int port) {
throw new UnsupportedOperationException("ClientTransportServersBuilder is required");
}
}

View File

@ -1,107 +0,0 @@
/*
* Copyright 2017 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 com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import io.grpc.Metadata;
import io.grpc.ServerStreamTracer;
import java.io.File;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link AbstractServerImplBuilder}. */
@RunWith(JUnit4.class)
public class AbstractServerImplBuilderTest {
private static final ServerStreamTracer.Factory DUMMY_USER_TRACER =
new ServerStreamTracer.Factory() {
@Override
public ServerStreamTracer newServerStreamTracer(String fullMethodName, Metadata headers) {
throw new UnsupportedOperationException();
}
};
private Builder builder = new Builder();
@Test
public void getTracerFactories_default() {
builder.addStreamTracerFactory(DUMMY_USER_TRACER);
List<? extends ServerStreamTracer.Factory> factories = builder.getTracerFactories();
assertEquals(3, factories.size());
assertThat(factories.get(0).getClass().getName())
.isEqualTo("io.grpc.census.CensusStatsModule$ServerTracerFactory");
assertThat(factories.get(1).getClass().getName())
.isEqualTo("io.grpc.census.CensusTracingModule$ServerTracerFactory");
assertThat(factories.get(2)).isSameInstanceAs(DUMMY_USER_TRACER);
}
@Test
public void getTracerFactories_disableStats() {
builder.addStreamTracerFactory(DUMMY_USER_TRACER);
builder.setStatsEnabled(false);
List<? extends ServerStreamTracer.Factory> factories = builder.getTracerFactories();
assertEquals(2, factories.size());
assertThat(factories.get(0).getClass().getName())
.isEqualTo("io.grpc.census.CensusTracingModule$ServerTracerFactory");
assertThat(factories.get(1)).isSameInstanceAs(DUMMY_USER_TRACER);
}
@Test
public void getTracerFactories_disableTracing() {
builder.addStreamTracerFactory(DUMMY_USER_TRACER);
builder.setTracingEnabled(false);
List<? extends ServerStreamTracer.Factory> factories = builder.getTracerFactories();
assertEquals(2, factories.size());
assertThat(factories.get(0).getClass().getName())
.isEqualTo("io.grpc.census.CensusStatsModule$ServerTracerFactory");
assertThat(factories.get(1)).isSameInstanceAs(DUMMY_USER_TRACER);
}
@Test
public void getTracerFactories_disableBoth() {
builder.addStreamTracerFactory(DUMMY_USER_TRACER);
builder.setTracingEnabled(false);
builder.setStatsEnabled(false);
List<? extends ServerStreamTracer.Factory> factories = builder.getTracerFactories();
assertThat(factories).containsExactly(DUMMY_USER_TRACER);
}
static class Builder extends AbstractServerImplBuilder<Builder> {
@Override
protected List<io.grpc.internal.InternalServer> buildTransportServers(
List<? extends ServerStreamTracer.Factory> streamTracerFactories) {
throw new UnsupportedOperationException();
}
@Override
public Builder useTransportSecurity(File certChain, File privateKey) {
throw new UnsupportedOperationException();
}
}
}

View File

@ -16,49 +16,89 @@
package io.grpc.internal;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import io.grpc.Metadata;
import io.grpc.ServerStreamTracer;
import io.grpc.internal.ServerImplBuilder.ClientTransportServersBuilder;
import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
/** Unit tests for {@link ServerImplBuilder}. */
@RunWith(JUnit4.class)
public class ServerImplBuilderTest {
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
private static final ServerStreamTracer.Factory DUMMY_USER_TRACER =
new ServerStreamTracer.Factory() {
@Override
public ServerStreamTracer newServerStreamTracer(String fullMethodName, Metadata headers) {
throw new UnsupportedOperationException();
}
};
@Mock private ClientTransportServersBuilder mockClientTransportServersBuilder;
@Mock private List<? extends ServerStreamTracer.Factory> mockServerStreamTracerFactories;
@Mock private List<? extends InternalServer> mockInternalServers;
private ServerImplBuilder builder;
@Before
public void setUp() throws Exception {
builder = new ServerImplBuilder(mockClientTransportServersBuilder);
builder = new ServerImplBuilder(
new ClientTransportServersBuilder() {
@Override
public List<? extends InternalServer> buildClientTransportServers(
List<? extends ServerStreamTracer.Factory> streamTracerFactories) {
throw new UnsupportedOperationException();
}
});
}
@Test
public void buildTransportServers() {
doReturn(mockInternalServers).when(mockClientTransportServersBuilder)
.buildClientTransportServers(ArgumentMatchers.<ServerStreamTracer.Factory>anyList());
public void getTracerFactories_default() {
builder.addStreamTracerFactory(DUMMY_USER_TRACER);
List<? extends InternalServer> servers = builder
.buildTransportServers(mockServerStreamTracerFactories);
assertEquals(mockInternalServers, servers);
assertNotNull(servers);
verify(mockClientTransportServersBuilder)
.buildClientTransportServers(mockServerStreamTracerFactories);
List<? extends ServerStreamTracer.Factory> factories = builder.getTracerFactories();
assertEquals(3, factories.size());
assertThat(factories.get(0).getClass().getName())
.isEqualTo("io.grpc.census.CensusStatsModule$ServerTracerFactory");
assertThat(factories.get(1).getClass().getName())
.isEqualTo("io.grpc.census.CensusTracingModule$ServerTracerFactory");
assertThat(factories.get(2)).isSameInstanceAs(DUMMY_USER_TRACER);
}
@Test
public void getTracerFactories_disableStats() {
builder.addStreamTracerFactory(DUMMY_USER_TRACER);
builder.setStatsEnabled(false);
List<? extends ServerStreamTracer.Factory> factories = builder.getTracerFactories();
assertEquals(2, factories.size());
assertThat(factories.get(0).getClass().getName())
.isEqualTo("io.grpc.census.CensusTracingModule$ServerTracerFactory");
assertThat(factories.get(1)).isSameInstanceAs(DUMMY_USER_TRACER);
}
@Test
public void getTracerFactories_disableTracing() {
builder.addStreamTracerFactory(DUMMY_USER_TRACER);
builder.setTracingEnabled(false);
List<? extends ServerStreamTracer.Factory> factories = builder.getTracerFactories();
assertEquals(2, factories.size());
assertThat(factories.get(0).getClass().getName())
.isEqualTo("io.grpc.census.CensusStatsModule$ServerTracerFactory");
assertThat(factories.get(1)).isSameInstanceAs(DUMMY_USER_TRACER);
}
@Test
public void getTracerFactories_disableBoth() {
builder.addStreamTracerFactory(DUMMY_USER_TRACER);
builder.setTracingEnabled(false);
builder.setStatsEnabled(false);
List<? extends ServerStreamTracer.Factory> factories = builder.getTracerFactories();
assertThat(factories).containsExactly(DUMMY_USER_TRACER);
}
}

View File

@ -76,12 +76,12 @@ import io.grpc.ServiceDescriptor;
import io.grpc.Status;
import io.grpc.StringMarshaller;
import io.grpc.internal.ServerImpl.JumpToApplicationThreadServerStreamListener;
import io.grpc.internal.ServerImplBuilder.ClientTransportServersBuilder;
import io.grpc.internal.testing.SingleMessageProducer;
import io.grpc.internal.testing.TestServerStreamTracer;
import io.grpc.util.MutableHandlerRegistry;
import io.perfmark.PerfMark;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
@ -164,7 +164,7 @@ public class ServerImplTest {
};
@Mock
private ObjectPool<Executor> executorPool;
private Builder builder = new Builder();
private ServerImplBuilder builder;
private MutableHandlerRegistry mutableFallbackRegistry = new MutableHandlerRegistry();
private HandlerRegistry fallbackRegistry = mock(
HandlerRegistry.class,
@ -201,6 +201,14 @@ public class ServerImplTest {
@Before
public void startUp() throws IOException {
MockitoAnnotations.initMocks(this);
builder = new ServerImplBuilder(
new ClientTransportServersBuilder() {
@Override
public List<? extends InternalServer> buildClientTransportServers(
List<? extends ServerStreamTracer.Factory> streamTracerFactories) {
throw new UnsupportedOperationException();
}
});
builder.channelz = channelz;
builder.ticker = timer.getDeadlineTicker();
streamTracerFactories = Arrays.asList(streamTracerFactory);
@ -1507,17 +1515,6 @@ public class ServerImplTest {
}
}
private static class Builder extends AbstractServerImplBuilder<Builder> {
@Override protected List<InternalServer> buildTransportServers(
List<? extends ServerStreamTracer.Factory> streamTracerFactories) {
throw new UnsupportedOperationException();
}
@Override public Builder useTransportSecurity(File f1, File f2) {
throw new UnsupportedOperationException();
}
}
/** Allows more precise catch blocks than plain Error to avoid catching AssertionError. */
private static final class TestError extends Error {}
}