public void testConstructor() throws Exception {

    final Acceptor acceptor = new Acceptor("localhost", 0, 1);

    final FanOutServerSender serverSender =
        new FanOutServerSender(acceptor, ConnectionType.AGENT, 3);

    serverSender.shutdown();
    acceptor.shutdown();
  }
  public void testSend() throws Exception {

    final Acceptor acceptor = new Acceptor("localhost", 0, 1);

    final FanOutServerSender serverSender =
        new FanOutServerSender(acceptor, ConnectionType.AGENT, 3);

    final Socket[] socket = new Socket[5];

    for (int i = 0; i < socket.length; ++i) {
      socket[i] =
          new Connector(
                  InetAddress.getByName(null).getHostName(),
                  acceptor.getPort(),
                  ConnectionType.AGENT)
              .connect();
    }

    // Sleep until we've accepted all connections. Give up after a few
    // seconds.
    final ResourcePool socketSet = acceptor.getSocketSet(ConnectionType.AGENT);

    for (int i = 0; socketSet.countActive() != 5 && i < 10; ++i) {
      Thread.sleep(i * i * 10);
    }

    final SimpleMessage message1 = new SimpleMessage();
    final SimpleMessage message2 = new SimpleMessage();

    serverSender.send(message1);
    serverSender.send(message2);

    for (int i = 0; i < socket.length; ++i) {
      final InputStream socketInput = socket[i].getInputStream();

      final Message m1 = readMessage(socketInput);
      final Message m2 = readMessage(socketInput);

      assertEquals(message1, m1);
      assertEquals(message2, m2);

      assertEquals(0, socketInput.available());

      socket[i].close();
    }

    serverSender.shutdown();
    acceptor.shutdown();
  }
  public void testShutdown() throws Exception {

    final Acceptor acceptor = new Acceptor("localhost", 0, 1);

    final FanOutServerSender serverSender =
        new FanOutServerSender(acceptor, ConnectionType.AGENT, 3);

    assertEquals(1, acceptor.getThreadGroup().activeCount());

    final Socket socket =
        new Connector(
                InetAddress.getByName(null).getHostName(), acceptor.getPort(), ConnectionType.AGENT)
            .connect();

    // Sleep until we've accepted the connection. Give up after a few
    // seconds.
    final ResourcePool socketSet = acceptor.getSocketSet(ConnectionType.AGENT);

    for (int i = 0; socketSet.countActive() != 1 && i < 10; ++i) {
      Thread.sleep(i * i * 10);
    }

    final Message message = new SimpleMessage();
    serverSender.send(message);

    final InputStream socketStream = socket.getInputStream();

    final Object o1 = readMessage(socketStream);
    assertNotNull(o1);

    serverSender.shutdown();

    try {
      serverSender.send(message);
      fail("Expected CommunicationException");
    } catch (CommunicationException e) {
    }

    try {
      final Object o2 = readMessage(socketStream);

      assertTrue(o2 instanceof CloseCommunicationMessage);
    } catch (StreamCorruptedException e) {
      // Occasionally this occurs because the connection is shutdown.
      // Whatever.
    }

    acceptor.shutdown();
  }
  /**
   * Registers a new {@link Acceptor} from which the <code>ServerReceiver</code> should process
   * messages. Actively polls connections of the given types for messages, deserialises them, and
   * queues them for retrieval using {@link #waitForMessage()}.
   *
   * <p>A single <code>ServerReceiver</code> can listen to messages from multiple {@link Acceptor}s.
   * You can register the same {@link Acceptor} with multiple <code>ServerReceiver</code>s, but then
   * there is no way of controlling which receiver will receive messages from a given {@link
   * Acceptor}.
   *
   * @param acceptor Acceptor.
   * @param connectionTypes Type of connections to listen for.
   * @param numberOfThreads How many threads to dedicate to processing the Acceptor. The threads
   *     this method spawns just read, deserialise, and queue. Set <code>numberOfThreads</code> to
   *     the number of concurrent streams you expect to be able to read.
   * @param idleThreadPollDelay Time in milliseconds that an idle thread should sleep if there are
   *     no sockets to process.
   * @exception CommunicationException If this <code>ServerReceiver</code> has been shutdown.
   */
  public void receiveFrom(
      Acceptor acceptor,
      ConnectionType[] connectionTypes,
      int numberOfThreads,
      final int idleThreadPollDelay)
      throws CommunicationException {

    if (connectionTypes.length == 0) {
      // Nothing to do.
      return;
    }

    final ResourcePool[] acceptedSocketSets = new ResourcePool[connectionTypes.length];

    for (int i = 0; i < connectionTypes.length; ++i) {
      acceptedSocketSets[i] = acceptor.getSocketSet(connectionTypes[i]);
    }

    final ThreadPool.InterruptibleRunnableFactory runnableFactory =
        new ThreadPool.InterruptibleRunnableFactory() {
          public InterruptibleRunnable create() {
            return new ServerReceiverRunnable(
                new CombinedResourcePool(acceptedSocketSets), idleThreadPollDelay);
          }
        };

    final ThreadPool threadPool =
        new ThreadPool(
            "ServerReceiver (" + acceptor.getPort() + ", " + Arrays.asList(connectionTypes) + ")",
            numberOfThreads,
            runnableFactory);

    synchronized (this) {
      try {
        m_messageQueue.checkIfShutdown();
      } catch (ShutdownException e) {
        throw new CommunicationException("Shut down", e);
      }

      m_threadPools.add(threadPool);
    }

    threadPool.start();
  }
  public void testSendAddressedMessage() throws Exception {

    final Acceptor acceptor = new Acceptor("localhost", 0, 1);

    final FanOutServerSender serverSender =
        new FanOutServerSender(acceptor, ConnectionType.AGENT, 3);

    final Socket[] socket = new Socket[5];

    for (int i = 0; i < socket.length; ++i) {
      socket[i] =
          new Connector(
                  InetAddress.getByName(null).getHostName(),
                  acceptor.getPort(),
                  ConnectionType.AGENT)
              .connect(new StubAddress(new Integer(i)));
    }

    // Sleep until we've accepted all connections. Give up after a few
    // seconds.
    final ResourcePool socketSet = acceptor.getSocketSet(ConnectionType.AGENT);

    for (int i = 0; socketSet.countActive() != 5 && i < 10; ++i) {
      Thread.sleep(i * i * 10);
    }

    final SimpleMessage message1 = new SimpleMessage();
    final SimpleMessage message2 = new SimpleMessage();

    serverSender.send(new StubAddress(new Integer(1)), message1);
    serverSender.send(new StubAddress(new Integer(2)), message2);

    for (int i = 0; i < socket.length; ++i) {
      final InputStream socketInput = socket[i].getInputStream();

      if (i == 1) {
        final Message m = readMessage(socketInput);
        assertEquals(message1, m);
      } else if (i == 2) {
        final Message m = readMessage(socketInput);
        assertEquals(message2, m);
      }

      assertEquals(0, socketInput.available());

      socket[i].close();
    }

    serverSender.shutdown();

    try {
      serverSender.send(
          new Address() {
            public boolean includes(Address address) {
              return false;
            }
          },
          message1);
      fail("Expected CommunicationException");
    } catch (CommunicationException e) {
    }

    acceptor.shutdown();
  }