Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: d3c555cc28bf2c7085e5d4b17afc0e2b63524e4f (plain) (tree)
1
2
3
4
5
6
7
8
9
  
                                                                           






                                                                        
                                                         






















                                                                 
                                                    















                                                                   












































































































































































                                                                                                                
                                     















































                                                                                                  
                                     











































































                                                                                                  
                                     

























































                                                                        
                                     

























































                                                                        
                                     




































                                                                         
                                     























































































































                                                                            
/*
 * Copyright (c) 2008-2012, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 *    Teerawat Chaiyakijpichet (No Magic Asia Ltd.) - SSL
 */
package org.eclipse.net4j.tests;

import org.eclipse.net4j.Net4jUtil;
import org.eclipse.net4j.buffer.IBufferPool;
import org.eclipse.net4j.channel.IChannel;
import org.eclipse.net4j.connector.ConnectorException;
import org.eclipse.net4j.connector.IConnector;
import org.eclipse.net4j.internal.tcp.TCPAcceptor;
import org.eclipse.net4j.internal.tcp.TCPAcceptorFactory;
import org.eclipse.net4j.internal.tcp.TCPClientConnector;
import org.eclipse.net4j.internal.tcp.TCPConnector;
import org.eclipse.net4j.internal.tcp.TCPConnectorFactory;
import org.eclipse.net4j.internal.tcp.TCPSelector;
import org.eclipse.net4j.internal.tcp.ssl.SSLAcceptor;
import org.eclipse.net4j.internal.tcp.ssl.SSLAcceptorFactory;
import org.eclipse.net4j.internal.tcp.ssl.SSLClientConnector;
import org.eclipse.net4j.internal.tcp.ssl.SSLConnectorFactory;
import org.eclipse.net4j.tcp.ITCPSelector;
import org.eclipse.net4j.tcp.TCPUtil;
import org.eclipse.net4j.tests.bundle.OM;
import org.eclipse.net4j.util.collection.RoundRobinBlockingQueue;
import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
import org.eclipse.net4j.util.concurrent.ThreadPool;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.security.ChallengeNegotiator;
import org.eclipse.net4j.util.security.NegotiationException;
import org.eclipse.net4j.util.security.PasswordCredentials;
import org.eclipse.net4j.util.security.PasswordCredentialsProvider;
import org.eclipse.net4j.util.security.Randomizer;
import org.eclipse.net4j.util.security.ResponseNegotiator;
import org.eclipse.net4j.util.security.UserManager;

import org.eclipse.spi.net4j.Channel;
import org.eclipse.spi.net4j.InternalChannel;

import java.nio.channels.ServerSocketChannel;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;

/**
 * @author Eike Stepper
 * @author Teerawat Chaiyakijpichet (No Magic Asia Ltd.)
 */
public class TCPConnectorTest extends AbstractTransportTest
{
  private static final int TIMEOUT = 10000;

  private static final int PORT = 2040;

  private static final String USER_ID = "stepper"; //$NON-NLS-1$

  private static final String INVALID_USER_ID = "invalid"; //$NON-NLS-1$

  private static final char[] PASSWORD = "eike2008".toCharArray(); //$NON-NLS-1$

  private static final char[] INVALID_PASSWORD = "invalid".toCharArray(); //$NON-NLS-1$

  private static final PasswordCredentials CREDENTIALS = new PasswordCredentials(USER_ID, PASSWORD);

  private ExecutorService threadPool;

  private IBufferPool bufferPool;

  private TCPSelector selector;

  private TCPAcceptor acceptor;

  private TCPConnector connector;

  private Randomizer randomizer;

  private UserManager userManager;

  private ChallengeNegotiator challengeNegotiator;

  private PasswordCredentialsProvider credentialsProvider;

  private ResponseNegotiator responseNegotiator;

  @Override
  protected void doTearDown() throws Exception
  {
    cleanup();
    super.doTearDown();
  }

  private void cleanup() throws Exception
  {
    sleep(100);

    if (connector != null)
    {
      connector.close();
      connector = null;
    }

    if (responseNegotiator != null)
    {
      LifecycleUtil.deactivate(responseNegotiator);
      responseNegotiator = null;
    }

    if (credentialsProvider != null)
    {
      LifecycleUtil.deactivate(credentialsProvider);
      credentialsProvider = null;
    }

    if (acceptor != null)
    {
      acceptor.close();
      acceptor = null;
    }

    if (challengeNegotiator != null)
    {
      LifecycleUtil.deactivate(challengeNegotiator);
      challengeNegotiator = null;
    }

    if (userManager != null)
    {
      LifecycleUtil.deactivate(userManager);
      userManager = null;
    }

    if (randomizer != null)
    {
      LifecycleUtil.deactivate(randomizer);
      randomizer = null;
    }

    if (selector != null)
    {
      LifecycleUtil.deactivate(selector);
      selector = null;
    }

    if (bufferPool != null)
    {
      LifecycleUtil.deactivate(bufferPool);
      bufferPool = null;
    }

    if (threadPool != null)
    {
      LifecycleUtil.deactivate(threadPool);
      threadPool = null;
    }
  }

  private void provideTransport()
  {
    selector = new TCPSelector();

    if (useSSLTransport())
    {
      acceptor = new SSLAcceptor();
      container.putElement(SSLAcceptorFactory.PRODUCT_GROUP, SSLAcceptorFactory.TYPE, null, acceptor);

      // cannot use same container with the acceptor.
      connector = new SSLClientConnector();
      separateContainer.putElement(SSLConnectorFactory.PRODUCT_GROUP, SSLConnectorFactory.TYPE, null, acceptor);
    }
    else
    {
      acceptor = new TCPAcceptor();
      container.putElement(TCPAcceptorFactory.PRODUCT_GROUP, TCPUtil.FACTORY_TYPE, null, acceptor);

      connector = new TCPClientConnector();
      container.putElement(TCPConnectorFactory.PRODUCT_GROUP, TCPConnectorFactory.TYPE, null, acceptor);
    }
  }

  private void provideTransport(final long increaseDelayAcceptor)
  {
    selector = new TCPSelector();

    if (useSSLTransport())
    {
      acceptor = new SSLAcceptor()
      {
        @Override
        public void handleAccept(ITCPSelector selector, ServerSocketChannel serverSocketChannel)
        {
          ConcurrencyUtil.sleep(increaseDelayAcceptor);
          super.handleAccept(selector, serverSocketChannel);
        }
      };

      connector = new SSLClientConnector();
    }
    else
    {
      acceptor = new TCPAcceptor()
      {
        @Override
        public void handleAccept(ITCPSelector selector, ServerSocketChannel serverSocketChannel)
        {
          ConcurrencyUtil.sleep(increaseDelayAcceptor);
          super.handleAccept(selector, serverSocketChannel);
        }
      };

      connector = new TCPClientConnector();
    }
  }

  public void testDeferredActivation() throws Exception
  {
    final long DELAY = 500L;
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    provideTransport(DELAY);

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);
    connector.activate();
    // Can fail due to timing variations: assertEquals(false, connector.isActive());

    connector.waitForConnection(DEFAULT_TIMEOUT);
    assertEquals(true, connector.isActive());
  }

  public void testDeferredActivation10() throws Exception
  {
    for (int i = 0; i < 10; i++)
    {
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println("#####################################################"); //$NON-NLS-1$
      IOUtil.OUT().println(" RUN = " + i); //$NON-NLS-1$
      IOUtil.OUT().println("#####################################################"); //$NON-NLS-1$
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      testDeferredActivation();
      cleanup();
    }
  }

  public void testNegotiationSuccess() throws Exception
  {
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    randomizer = new Randomizer();
    randomizer.activate();

    userManager = new UserManager();
    userManager.activate();
    userManager.addUser(USER_ID, PASSWORD);

    challengeNegotiator = new ChallengeNegotiator();
    challengeNegotiator.setRandomizer(randomizer);
    challengeNegotiator.setUserManager(userManager);
    challengeNegotiator.activate();

    provideTransport();

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.getConfig().setNegotiator(challengeNegotiator);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    credentialsProvider = new PasswordCredentialsProvider(CREDENTIALS);
    LifecycleUtil.activate(credentialsProvider);

    responseNegotiator = new ResponseNegotiator();
    responseNegotiator.setCredentialsProvider(credentialsProvider);
    responseNegotiator.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.getConfig().setNegotiator(responseNegotiator);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);
    connector.activate();

    connector.waitForConnection(DEFAULT_TIMEOUT);

    InternalChannel clientChannel = connector.openChannel();
    assertEquals(USER_ID, clientChannel.getUserID());

    IConnector serverConnector = acceptor.getElements()[0];
    IChannel serverChannel = serverConnector.getElements()[0];
    assertEquals(USER_ID, serverChannel.getUserID());

    System.out.println(serverChannel);
  }

  public void testNegotiationSuccess10() throws Exception
  {
    for (int i = 0; i < 10; i++)
    {
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println("#####################################################"); //$NON-NLS-1$
      IOUtil.OUT().println("                          RUN = " + i); //$NON-NLS-1$
      IOUtil.OUT().println("#####################################################"); //$NON-NLS-1$
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      testNegotiationSuccess();
      cleanup();
    }
  }

  public void testInvalidUser() throws Exception
  {
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    randomizer = new Randomizer();
    randomizer.activate();

    userManager = new UserManager();
    userManager.activate();
    userManager.addUser(INVALID_USER_ID, PASSWORD);

    challengeNegotiator = new ChallengeNegotiator();
    challengeNegotiator.setRandomizer(randomizer);
    challengeNegotiator.setUserManager(userManager);
    challengeNegotiator.activate();

    provideTransport();

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.getConfig().setNegotiator(challengeNegotiator);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    credentialsProvider = new PasswordCredentialsProvider(CREDENTIALS);
    LifecycleUtil.activate(credentialsProvider);

    responseNegotiator = new ResponseNegotiator();
    responseNegotiator.setCredentialsProvider(credentialsProvider);
    responseNegotiator.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.getConfig().setNegotiator(responseNegotiator);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);

    try
    {
      connector.connectAsync();
      connector.waitForConnection(DEFAULT_TIMEOUT_EXPECTED);
      fail("ConnectorException expected"); //$NON-NLS-1$
    }
    catch (ConnectorException ex)
    {
      OM.LOG.info("Expected ConnectorException:", ex); //$NON-NLS-1$
      assertEquals(true, ex.getCause() instanceof NegotiationException);
    }
  }

  public void testInvalidPassword() throws Exception
  {
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    randomizer = new Randomizer();
    randomizer.activate();

    userManager = new UserManager();
    userManager.activate();
    userManager.addUser(USER_ID, INVALID_PASSWORD);

    challengeNegotiator = new ChallengeNegotiator();
    challengeNegotiator.setRandomizer(randomizer);
    challengeNegotiator.setUserManager(userManager);
    challengeNegotiator.activate();

    provideTransport();

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.getConfig().setNegotiator(challengeNegotiator);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    credentialsProvider = new PasswordCredentialsProvider(CREDENTIALS);
    LifecycleUtil.activate(credentialsProvider);

    responseNegotiator = new ResponseNegotiator();
    responseNegotiator.setCredentialsProvider(credentialsProvider);
    responseNegotiator.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.getConfig().setNegotiator(responseNegotiator);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);

    try
    {
      connector.connectAsync();
      connector.waitForConnection(DEFAULT_TIMEOUT_EXPECTED);
      fail("ConnectorException expected"); //$NON-NLS-1$
    }
    catch (ConnectorException ex)
    {
      OM.LOG.info("Expected ConnectorException:", ex); //$NON-NLS-1$
      assertEquals(true, ex.getCause() instanceof NegotiationException);
    }
  }

  public void testNoNegotiator() throws Exception
  {
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    provideTransport();

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);
    connector.setUserID("SHOULD_FAIL_LATER"); //$NON-NLS-1$

    try
    {
      connector.connect();
      fail("ConnectorException expected"); //$NON-NLS-1$
    }
    catch (ConnectorException ex)
    {
      OM.LOG.info("Expected ConnectorException:", ex); //$NON-NLS-1$
      assertEquals(true, ex.getCause() instanceof IllegalStateException);
    }
  }

  public void testNegotiatorTooLate() throws Exception
  {
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    provideTransport();

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);
    connector.connect();

    credentialsProvider = new PasswordCredentialsProvider(CREDENTIALS);
    LifecycleUtil.activate(credentialsProvider);

    responseNegotiator = new ResponseNegotiator();
    responseNegotiator.setCredentialsProvider(credentialsProvider);
    responseNegotiator.activate();

    try
    {
      connector.getConfig().setNegotiator(responseNegotiator);
      fail("IllegalStateException expected"); //$NON-NLS-1$
    }
    catch (IllegalStateException ex)
    {
      OM.LOG.info("Expected IllegalStateException:", ex); //$NON-NLS-1$
    }
  }

  public void testRoundRobinBlockingQueue() throws Exception
  {
    BlockingQueue<IChannel> queue = new RoundRobinBlockingQueue<IChannel>();

    Channel[] channels = new Channel[3];

    for (int i = 0; i < channels.length; i++)
    {
      Channel c = new Channel();
      c.setID((short)i);
      channels[i] = c;
    }

    assertEquals(true, queue.isEmpty());
    assertNull(queue.peek());
    assertNull(queue.poll());

    // Order will be 0000...1111...2222...
    for (int i = 0; i < channels.length; i++)
    {
      for (int j = 0; j < 10; j++)
      {
        queue.put(channels[i]);
      }
    }

    for (int i = 0; i < 30; i++)
    {
      IChannel peek1 = queue.peek();
      IChannel peek2 = queue.peek();
      assertSame(peek1, peek2);

      IChannel poll = queue.poll();
      // The order should be 012012012012...
      assertEquals(i % 3, poll.getID());
      assertSame(peek1, poll);
    }

    assertEquals(true, queue.isEmpty());
    assertNull(queue.peek());
    assertNull(queue.poll());
  }

  /**
   * @author Teerawat Chaiyakijpichet (No Magic Asia Ltd.)
   */
  public static final class TCP extends TCPConnectorTest
  {
    @Override
    protected boolean useJVMTransport()
    {
      return false;
    }

    @Override
    protected boolean useSSLTransport()
    {
      return false;
    }
  }

  /**
   * @author Teerawat Chaiyakijpichet (No Magic Asia Ltd.)
   */
  public static final class SSL extends TCPConnectorTest
  {
    @Override
    protected boolean useJVMTransport()
    {
      return false;
    }

    @Override
    protected boolean useSSLTransport()
    {
      return true;
    }
  }
}

Back to the top