Package reactor.net

Source Code of reactor.net.AbstractNetClientServerTest

package reactor.net;

import com.gs.collections.api.RichIterable;
import com.gs.collections.impl.list.mutable.FastList;
import org.junit.After;
import org.junit.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.Environment;
import reactor.function.Predicate;
import reactor.io.Buffer;
import reactor.io.encoding.Codec;
import reactor.io.encoding.StandardCodecs;
import reactor.net.tcp.TcpClient;
import reactor.net.tcp.TcpServer;
import reactor.net.tcp.spec.TcpClientSpec;
import reactor.net.tcp.spec.TcpServerSpec;
import reactor.net.tcp.support.SocketUtils;
import reactor.support.NamedDaemonThreadFactory;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
* @author Jon Brisbin
*/
public class AbstractNetClientServerTest {

  public static final String LOCALHOST = "127.0.0.1";

  private static final Random random = new Random(System.nanoTime());
  private static final String CHARS  = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789";

  protected final Logger log = LoggerFactory.getLogger(getClass());

  private final int senderThreads = Environment.PROCESSORS;
  protected Data            data;
  private   ExecutorService serverPool;
  private   ExecutorService clientPool;
  private   Environment     env1;
  private   Environment     env2;
  private   int             port;

  protected static Data generateData() {
    char[] name = new char[16];
    for (int i = 0; i < name.length; i++) {
      name[i] = CHARS.charAt(random.nextInt(CHARS.length()));
    }
    return new Data(random.nextInt(), random.nextLong(), new String(name));
  }

  protected static <IN, OUT> NetChannel<IN, OUT> assertClientStarted(NetClient<IN, OUT> client)
      throws InterruptedException {
    NetChannel<IN, OUT> ch = client.open().await(1, TimeUnit.SECONDS);
    assertNotNull(client.getClass().getSimpleName() + " was started", ch);
    return ch;
  }

  protected static <IN, OUT> void assertClientStopped(NetClient<IN, OUT> client)
      throws InterruptedException {
    assertTrue(client.getClass().getSimpleName() + " was stopped", client.close().await(1, TimeUnit.SECONDS));
  }


  protected static <IN, OUT> void assertServerStarted(NetServer<IN, OUT> server) throws InterruptedException {
    assertTrue(server.getClass().getSimpleName() + " was started", server.start().await(1, TimeUnit.SECONDS));
  }

  protected static <IN, OUT> void assertServerStopped(NetServer<IN, OUT> server) throws InterruptedException {
    assertTrue(server.getClass().getSimpleName() + " was started", server.shutdown().await(1, TimeUnit.SECONDS));
  }

  @Before
  public void setup() {
    clientPool = Executors.newCachedThreadPool(new NamedDaemonThreadFactory(getClass().getSimpleName() + "-server"));
    serverPool = Executors.newCachedThreadPool(new NamedDaemonThreadFactory(getClass().getSimpleName() + "-client"));

    env1 = new Environment();
    env2 = new Environment();

    port = SocketUtils.findAvailableTcpPort();

    data = generateData();
  }

  @After
  public void cleanup() throws InterruptedException {
    //env1.shutdown();
    //env2.shutdown();

    clientPool.shutdownNow();
    clientPool.awaitTermination(5, TimeUnit.SECONDS);

    serverPool.shutdownNow();
    serverPool.awaitTermination(5, TimeUnit.SECONDS);
  }

  protected int getPort() {
    return port;
  }

  protected <T> TcpServerSpec<T, T> createTcpServer(Class<? extends TcpServer> type,
                                                    Class<? extends T> dataType) {
    return createTcpServer(type, dataType, dataType);
  }

  protected <IN, OUT> TcpServerSpec<IN, OUT> createTcpServer(Class<? extends TcpServer> type,
                                                             Class<? extends IN> inType,
                                                             Class<? extends OUT> outType) {
    return new TcpServerSpec<IN, OUT>(type).env(env1).dispatcher("sync").listen(LOCALHOST, port);
  }

  protected <T> TcpClientSpec<T, T> createTcpClient(Class<? extends TcpClient> type,
                                                    Class<? extends T> dataType) {
    return createTcpClient(type, dataType, dataType);
  }

  protected <IN, OUT> TcpClientSpec<IN, OUT> createTcpClient(Class<? extends TcpClient> type,
                                                             Class<? extends IN> inType,
                                                             Class<? extends OUT> outType) {
    return new TcpClientSpec<IN, OUT>(type).env(env2).dispatcher("sync").connect(LOCALHOST, port);
  }

  protected <T> void assertTcpClientServerExchangedData(Class<? extends TcpServer> serverType,
                                                        Class<? extends TcpClient> clientType,
                                                        Buffer data) throws InterruptedException {
    assertTcpClientServerExchangedData(
        serverType,
        clientType,
        StandardCodecs.PASS_THROUGH_CODEC,
        data,
        (Buffer b) -> {
          byte[] b1 = data.flip().asBytes();
          byte[] b2 = b.asBytes();
          return Arrays.equals(b1, b2);
        }
    );
  }

  @SuppressWarnings("unchecked")
  protected <T> void assertTcpClientServerExchangedData(Class<? extends TcpServer> serverType,
                                                        Class<? extends TcpClient> clientType,
                                                        Codec<Buffer, T, T> codec,
                                                        T data,
                                                        Predicate<T> replyPredicate)
      throws InterruptedException {
    if (null == codec) {
      codec = (Codec<Buffer, T, T>) StandardCodecs.PASS_THROUGH_CODEC;
    }
    TcpServer<T, T> server = new TcpServerSpec<T, T>(serverType)
        .env(env1)
        .listen(LOCALHOST, getPort())
        .codec(codec)
        .consume(ch -> ch.consume(ch::send))
        .get();

    assertServerStarted(server);

    TcpClient<T, T> client = new TcpClientSpec<T, T>(clientType)
        .env(env2)
        .connect(LOCALHOST, getPort())
        .codec(codec)
        .get();

    NetChannel<T, T> ch = assertClientStarted(client);

    T reply = ch.sendAndReceive(data).await(1, TimeUnit.SECONDS);
    assertTrue("reply was correct", replyPredicate.test(reply));

//    assertServerStopped(server);
//    assertClientStopped(client);
  }

  protected Environment getServerEnvironment() {
    return env1;
  }

  protected Environment getClientEnvironment() {
    return env2;
  }

  protected Future<?> submitServer(Runnable r) {
    return serverPool.submit(r);
  }

  protected RichIterable<Future<?>> submitClients(Runnable r) {
    FastList<Future<?>> futures = FastList.newList();
    for (int i = 0; i < senderThreads; i++) {
      futures.add(clientPool.submit(r));
    }
    return futures.toImmutable();
  }

  protected static class Data {
    private int    count;
    private long   length;
    private String name;

    public Data() {
    }

    public Data(int count, long length, String name) {
      this.count = count;
      this.length = length;
      this.name = name;
    }

    public int getCount() {
      return count;
    }

    public long getLength() {
      return length;
    }

    public String getName() {
      return name;
    }

    @Override
    public String toString() {
      return "Data{" +
          "count=" + count +
          ", length=" + length +
          ", name='" + name + '\'' +
          '}';
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof Data)) return false;

      Data data = (Data) o;

      if (count != data.count) return false;
      if (length != data.length) return false;
      if (!name.equals(data.name)) return false;

      return true;
    }

    @Override
    public int hashCode() {
      int result = count;
      result = 31 * result + (int) (length ^ (length >>> 32));
      result = 31 * result + name.hashCode();
      return result;
    }
  }

}
TOP

Related Classes of reactor.net.AbstractNetClientServerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.