// Path: contrib/grpc-contrib/src/main/java/com/salesforce/grpc/contrib/Servers.java
// public final class Servers {
// 
//     /**
//      * Attempt to {@link Server#shutdown()} the {@link Server} gracefully. If the max wait time is exceeded, give up and
//      * perform a hard {@link Server#shutdownNow()}.
//      *
//      * @param server the server to be shutdown
//      * @param maxWaitTimeInMillis the max amount of time to wait for graceful shutdown to occur
//      * @return the given server
//      * @throws InterruptedException if waiting for termination is interrupted
//      */
//     public static Server shutdownGracefully(Server server, long maxWaitTimeInMillis) throws InterruptedException {
//         return shutdownGracefully(server, maxWaitTimeInMillis, TimeUnit.MILLISECONDS);
//     }
// 
//     /**
//      * Attempt to {@link Server#shutdown()} the {@link Server} gracefully. If the max wait time is exceeded, give up and
//      * perform a hard {@link Server#shutdownNow()}.
//      *
//      * @param server the server to be shutdown
//      * @param timeout the max amount of time to wait for graceful shutdown to occur
//      * @param unit the time unit denominating the shutdown timeout
//      * @return the given server
//      * @throws InterruptedException if waiting for termination is interrupted
//      */
//     public static Server shutdownGracefully(Server server, long timeout, TimeUnit unit) throws InterruptedException {
//         Preconditions.checkNotNull(server, "server");
//         Preconditions.checkArgument(timeout > 0, "timeout must be greater than 0");
//         Preconditions.checkNotNull(unit, "unit");
// 
//         server.shutdown();
// 
//         try {
//             server.awaitTermination(timeout, unit);
//         } finally {
//             server.shutdownNow();
//         }
// 
//         return server;
//     }
// 
//     /**
//      * Attempt to {@link Server#shutdown()} the {@link Server} gracefully when the JVM terminates. If the max wait time
//      * is exceeded, give up and perform a hard {@link Server#shutdownNow()}.
//      *
//      * @param server the server to be shutdown
//      * @param maxWaitTimeInMillis the max amount of time to wait for graceful shutdown to occur
//      * @return the given server
//      */
//     public static Server shutdownWithJvm(Server server, long maxWaitTimeInMillis) {
//         Runtime.getRuntime().addShutdownHook(new Thread(() -> {
//             try {
//                 shutdownGracefully(server, maxWaitTimeInMillis);
//             } catch (InterruptedException ex) {
//                 // do nothing
//             }
//         }));
// 
//         return server;
//     }
// 
//     private Servers() { }
// }


import com.salesforce.grpc.contrib.Servers;
import io.grpc.ManagedChannel;
import io.grpc.Server;
import io.grpc.netty.NettyChannelBuilder;
import io.grpc.netty.NettyServerBuilder;
import io.grpc.util.MutableHandlerRegistry;
import org.junit.rules.ExternalResource;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
    @Override
    protected void before() throws Throwable {
        serviceRegistry = new MutableHandlerRegistry();

        NettyServerBuilder serverBuilder = NettyServerBuilder
                .forPort(0)
                .fallbackHandlerRegistry(serviceRegistry);

        if (useDirectExecutor) {
            serverBuilder.directExecutor();
        }

        configureServerBuilder.accept(serverBuilder);
        server = serverBuilder.build().start();
        port = server.getPort();

        NettyChannelBuilder channelBuilder = NettyChannelBuilder.forAddress("localhost", port).usePlaintext(true);
        configureChannelBuilder.accept(channelBuilder);
        channel = channelBuilder.build();
    }

    /**
     * After the test has completed, clean up the channel and server.
     */
    @Override
    protected void after() {
        serviceRegistry = null;

        channel.shutdown();
        channel = null;
// Path: contrib/grpc-contrib/src/main/java/com/salesforce/grpc/contrib/Servers.java
// public final class Servers {
// 
//     /**
//      * Attempt to {@link Server#shutdown()} the {@link Server} gracefully. If the max wait time is exceeded, give up and
//      * perform a hard {@link Server#shutdownNow()}.
//      *
//      * @param server the server to be shutdown
//      * @param maxWaitTimeInMillis the max amount of time to wait for graceful shutdown to occur
//      * @return the given server
//      * @throws InterruptedException if waiting for termination is interrupted
//      */
//     public static Server shutdownGracefully(Server server, long maxWaitTimeInMillis) throws InterruptedException {
//         return shutdownGracefully(server, maxWaitTimeInMillis, TimeUnit.MILLISECONDS);
//     }
// 
//     /**
//      * Attempt to {@link Server#shutdown()} the {@link Server} gracefully. If the max wait time is exceeded, give up and
//      * perform a hard {@link Server#shutdownNow()}.
//      *
//      * @param server the server to be shutdown
//      * @param timeout the max amount of time to wait for graceful shutdown to occur
//      * @param unit the time unit denominating the shutdown timeout
//      * @return the given server
//      * @throws InterruptedException if waiting for termination is interrupted
//      */
//     public static Server shutdownGracefully(Server server, long timeout, TimeUnit unit) throws InterruptedException {
//         Preconditions.checkNotNull(server, "server");
//         Preconditions.checkArgument(timeout > 0, "timeout must be greater than 0");
//         Preconditions.checkNotNull(unit, "unit");
// 
//         server.shutdown();
// 
//         try {
//             server.awaitTermination(timeout, unit);
//         } finally {
//             server.shutdownNow();
//         }
// 
//         return server;
//     }
// 
//     /**
//      * Attempt to {@link Server#shutdown()} the {@link Server} gracefully when the JVM terminates. If the max wait time
//      * is exceeded, give up and perform a hard {@link Server#shutdownNow()}.
//      *
//      * @param server the server to be shutdown
//      * @param maxWaitTimeInMillis the max amount of time to wait for graceful shutdown to occur
//      * @return the given server
//      */
//     public static Server shutdownWithJvm(Server server, long maxWaitTimeInMillis) {
//         Runtime.getRuntime().addShutdownHook(new Thread(() -> {
//             try {
//                 shutdownGracefully(server, maxWaitTimeInMillis);
//             } catch (InterruptedException ex) {
//                 // do nothing
//             }
//         }));
// 
//         return server;
//     }
// 
//     private Servers() { }
// }


// Path: contrib/grpc-testing-contrib/src/main/java/com/salesforce/grpc/testing/contrib/NettyGrpcServerRule.java
import com.salesforce.grpc.contrib.Servers;
import io.grpc.ManagedChannel;
import io.grpc.Server;
import io.grpc.netty.NettyChannelBuilder;
import io.grpc.netty.NettyServerBuilder;
import io.grpc.util.MutableHandlerRegistry;
import org.junit.rules.ExternalResource;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

    @Override
    protected void before() throws Throwable {
        serviceRegistry = new MutableHandlerRegistry();

        NettyServerBuilder serverBuilder = NettyServerBuilder
                .forPort(0)
                .fallbackHandlerRegistry(serviceRegistry);

        if (useDirectExecutor) {
            serverBuilder.directExecutor();
        }

        configureServerBuilder.accept(serverBuilder);
        server = serverBuilder.build().start();
        port = server.getPort();

        NettyChannelBuilder channelBuilder = NettyChannelBuilder.forAddress("localhost", port).usePlaintext(true);
        configureChannelBuilder.accept(channelBuilder);
        channel = channelBuilder.build();
    }

    /**
     * After the test has completed, clean up the channel and server.
     */
    @Override
    protected void after() {
        serviceRegistry = null;

        channel.shutdown();
        channel = null;
        port = 0;