/*
 * JBoss, Home of Professional Open Source
 * Copyright 2006, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.test.remoting.transport.multiplex;

import java.lang.reflect.Field;
import java.net.InetSocketAddress;

import javax.management.MBeanServer;

import org.jboss.logging.Logger;
import org.jboss.remoting.Client;
import org.jboss.remoting.InvocationRequest;
import org.jboss.remoting.InvokerLocator;
import org.jboss.remoting.ServerInvocationHandler;
import org.jboss.remoting.ServerInvoker;
import org.jboss.remoting.callback.Callback;
import org.jboss.remoting.callback.HandleCallbackException;
import org.jboss.remoting.callback.InvokerCallbackHandler;
import org.jboss.remoting.transport.Connector;
import org.jboss.remoting.transport.PortUtil;
import org.jboss.remoting.transport.multiplex.MultiplexClientInvoker;
import org.jboss.remoting.transport.multiplex.MultiplexServerInvoker;
import org.jboss.remoting.transport.multiplex.MultiplexServerInvoker.SocketGroupInfo;
import org.jboss.test.remoting.transport.multiplex.utility.SuccessCountingTestCase;

public class MultiplexInvokerAnonymousPortTestCase extends SuccessCountingTestCase
{
   private static final Logger log = Logger.getLogger(MultiplexInvokerAnonymousPortTestCase.class);
   static int connectPort;
   static String serverLocatorURI;
   static InvokerLocator serverLocator;;
   static Connector connector;

   
   public void setUp() throws Exception
   {
      super.setUp();
      
      if (connector == null)
      {
         try
         {
            connectPort = PortUtil.findFreePort("localhost");
            log.info("binding server to port: " + connectPort);
            serverLocatorURI  = "multiplex://localhost:" + connectPort;
            serverLocator = new InvokerLocator(serverLocatorURI);
            connector = new Connector(serverLocator.getLocatorURI());
            connector.create();
            connector.addInvocationHandler("test", new InvocationHandler());
            connector.start();
         }
         catch (Exception e)
         {
            log.error(e);
            e.printStackTrace();
         }
      }
      else
      {
         Thread.sleep(500);
      }
   }

   
   /**
    *  Client starts first              - rule 2 - positive port
    *  callback Connector starts second - rule 1 - no port
    *
    */
   public void testClient2PositiveServer1None()
   {
      log.info("ENTERING " + getName());
      
      try
      {
         // Create Client.
         int freePort = PortUtil.findFreePort("localhost");
         log.info("free port: " + freePort);
         String params = "/?clientMultiplexId=id&multiplexBindHost=localhost&multiplexBindPort=" + freePort;
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         Client client = new Client(clientLocator);
         client.connect();

         // Start callback Connector.
         String callbackURI = "multiplex://localhost/?serverMultiplexId=id";
         log.info("callback locator: " + callbackURI);
         Connector callbackConnector = new Connector(callbackURI);
         callbackConnector.start();
         
         // Verify callback MultiplexServerInvoker has right port.
         MultiplexServerInvoker invoker = (MultiplexServerInvoker) callbackConnector.getServerInvoker();
         int serverInvokerPort = invoker.getServerSocket().getLocalPort();
         log.info("MultiplexServerInvoker's port: " + serverInvokerPort);
         assertTrue(serverInvokerPort == freePort);
         
         // Verify callback Connector's InvokerLocator was correctly reset.
         int callbackConnectorPort = callbackConnector.getLocator().getPort();
         log.info("callback Connector's port: " + callbackConnectorPort);
         assertTrue(callbackConnectorPort == freePort);
         
         // Verify server can find callback Connector.
         CallbackHandler callbackHandler = new CallbackHandler();
         client.addListener(callbackHandler, callbackConnector.getLocator());
         assertTrue(callbackHandler.allOk());

         callbackConnector.stop();
         client.disconnect();
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
   
   
   /**
    *  Client starts first              - rule 2 - positive port
    *  callback Connector starts second - rule 1 - port == 0
    *
    */
   public void testClient2PositiveServer1Zero()
   {
      log.info("ENTERING " + getName());
      
      try
      {
         // Create Client.
         int freePort = PortUtil.findFreePort("localhost");
         log.info("free port: " + freePort);
         String params = "/?clientMultiplexId=id&multiplexBindHost=localhost&multiplexBindPort=" + freePort;
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         Client client = new Client(clientLocator);
         client.connect();

         // Start callback Connector.
         String callbackURI = "multiplex://localhost:0/?serverMultiplexId=id";
         Connector callbackConnector = new Connector(callbackURI);
         log.info("callback locator: " + callbackURI);
         callbackConnector.start();
         
         // Verify callback MultiplexServerInvoker has right port.
         MultiplexServerInvoker invoker = (MultiplexServerInvoker) callbackConnector.getServerInvoker();
         int serverInvokerPort = invoker.getServerSocket().getLocalPort();
         log.info("MultiplexServerInvoker's port: " + serverInvokerPort);
         assertTrue(serverInvokerPort == freePort);
         
         // Verify callback Connector's InvokerLocator was correctly reset.
         int callbackConnectorPort = callbackConnector.getLocator().getPort();
         log.info("callback Connector's port: " + callbackConnectorPort);
         assertTrue(callbackConnectorPort == freePort);
         
         // Verify server can find callback Connector.
         CallbackHandler callbackHandler = new CallbackHandler();
         client.addListener(callbackHandler, callbackConnector.getLocator());
         assertTrue(callbackHandler.allOk());

         callbackConnector.stop();
         client.disconnect();
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
   
     
   /**
    *  Client starts first              - rule 2 - port == 0
    *  callback Connector starts second - rule 1 - no port
    *
    */
   public void testClient2ZeroServer1None()
   {
      log.info("ENTERING " + getName());
      
      try
      {
         // Create Client.
         String params = "/?clientMultiplexId=id&multiplexBindHost=localhost&multiplexBindPort=0";
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         Client client = new Client(clientLocator);
         client.connect();
         
         // Start callback Connector.
         String callbackURI = "multiplex://localhost/?serverMultiplexId=id";
         Connector callbackConnector = new Connector(callbackURI);
         log.info("callback locator: " + callbackURI);
         callbackConnector.start();
         
         // Verify callback MultiplexServerInvoker has right port.
         Field field = MultiplexClientInvoker.class.getDeclaredField("bindSocketAddress");
         field.setAccessible(true);
         int clientBindPort = ((InetSocketAddress)field.get(client.getInvoker())).getPort();
         log.info("client bind port: " + clientBindPort);
         MultiplexServerInvoker invoker = (MultiplexServerInvoker) callbackConnector.getServerInvoker();
         int serverInvokerPort = invoker.getServerSocket().getLocalPort();
         log.info("MultiplexServerInvoker's port: " + serverInvokerPort);
         assertTrue(serverInvokerPort == clientBindPort);
         
         // Verify callback Connector's InvokerLocator was correctly reset.
         int callbackConnectorPort = callbackConnector.getLocator().getPort();
         log.info("callback Connector's port: " + callbackConnectorPort);
         assertTrue(callbackConnectorPort == clientBindPort);
         
         // Verify server can find callback Connector.
         CallbackHandler callbackHandler = new CallbackHandler();
         client.addListener(callbackHandler, callbackConnector.getLocator());
         assertTrue(callbackHandler.allOk());

         callbackConnector.stop();
         client.disconnect();
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
   
   
   /**
    *  Client starts first              - rule 2 - port == 0
    *  callback Connector starts second - rule 1 - port == 0
    *
    */
   public void testClient2ZeroServer1Zero()
   {
      log.info("ENTERING " + getName());
      
      try
      {
         // Create Client.
         String params = "/?clientMultiplexId=id&multiplexBindHost=localhost&multiplexBindPort=0";
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         Client client = new Client(clientLocator);
         client.connect();
         
         // Start callback Connector.
         String callbackURI = "multiplex://localhost:0/?serverMultiplexId=id";
         Connector callbackConnector = new Connector(callbackURI);
         log.info("callback locator: " + callbackURI);
         callbackConnector.start();
         
         // Verify callback MultiplexServerInvoker has right port.
         Field field = MultiplexClientInvoker.class.getDeclaredField("bindSocketAddress");
         field.setAccessible(true);
         int clientBindPort = ((InetSocketAddress)field.get(client.getInvoker())).getPort();
         log.info("client bind port: " + clientBindPort);
         MultiplexServerInvoker invoker = (MultiplexServerInvoker) callbackConnector.getServerInvoker();
         int serverInvokerPort = invoker.getServerSocket().getLocalPort();
         log.info("MultiplexServerInvoker's port: " + serverInvokerPort);
         assertTrue(serverInvokerPort == clientBindPort);
         
         // Verify callback Connector's InvokerLocator was correctly reset.
         int callbackConnectorPort = callbackConnector.getLocator().getPort();
         log.info("callback Connector's port: " + callbackConnectorPort);
         assertTrue(callbackConnectorPort == clientBindPort);
         
         // Verify server can find callback Connector.
         CallbackHandler callbackHandler = new CallbackHandler();
         client.addListener(callbackHandler, callbackConnector.getLocator());
         assertTrue(callbackHandler.allOk());

         callbackConnector.stop();
         client.disconnect();
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
   
   
   /**
    *  Client starts first              - rule 2 - no port
    *  callback Connector starts second - rule 1 - no port
    *
    */
   public void testClient2NoneServer1None()
   {
      log.info("ENTERING " + getName());
      
      try
      {
         // Create Client.
         String params = "/?clientMultiplexId=id&multiplexBindHost=localhost";
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         Client client = new Client(clientLocator);
         client.connect();
         
         // Start callback Connector.
         String callbackURI = "multiplex://localhost/?serverMultiplexId=id";
         Connector callbackConnector = new Connector(callbackURI);
         log.info("callback locator: " + callbackURI);
         callbackConnector.start();
         
         // Verify callback MultiplexServerInvoker has right port.
         Field field = MultiplexClientInvoker.class.getDeclaredField("bindSocketAddress");
         field.setAccessible(true);
         int clientBindPort = ((InetSocketAddress)field.get(client.getInvoker())).getPort();
         log.info("client bind port: " + clientBindPort);
         MultiplexServerInvoker invoker = (MultiplexServerInvoker) callbackConnector.getServerInvoker();
         int serverInvokerPort = invoker.getServerSocket().getLocalPort();
         log.info("MultiplexServerInvoker's port: " + serverInvokerPort);
         assertTrue(serverInvokerPort == clientBindPort);
         
         // Verify callback Connector's InvokerLocator was correctly reset.
         int callbackConnectorPort = callbackConnector.getLocator().getPort();
         log.info("callback Connector's port: " + callbackConnectorPort);
         assertTrue(callbackConnectorPort == clientBindPort);
         
         // Verify server can find callback Connector.
         CallbackHandler callbackHandler = new CallbackHandler();
         client.addListener(callbackHandler, callbackConnector.getLocator());
         assertTrue(callbackHandler.allOk());

         callbackConnector.stop();
         client.disconnect();
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
   
   
   /**
    *  Client starts first              - rule 2 - no port
    *  callback Connector starts second - rule 1 - port == 0
    *
    */
   public void testClient2NoneServer1Zero()
   {
      log.info("ENTERING " + getName());
      
      try
      {
         // Create Client.
         String params = "/?clientMultiplexId=id&multiplexBindHost=localhost";
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         Client client = new Client(clientLocator);
         client.connect();
         
         // Start callback Connector.
         String callbackURI = "multiplex://localhost:0/?serverMultiplexId=id";
         Connector callbackConnector = new Connector(callbackURI);
         log.info("callback locator: " + callbackURI);
         callbackConnector.start();
         
         // Verify callback MultiplexServerInvoker has right port.
         Field field = MultiplexClientInvoker.class.getDeclaredField("bindSocketAddress");
         field.setAccessible(true);
         int clientBindPort = ((InetSocketAddress)field.get(client.getInvoker())).getPort();
         log.info("client bind port: " + clientBindPort);
         MultiplexServerInvoker invoker = (MultiplexServerInvoker) callbackConnector.getServerInvoker();
         int serverInvokerPort = invoker.getServerSocket().getLocalPort();
         log.info("MultiplexServerInvoker's port: " + serverInvokerPort);
         assertTrue(serverInvokerPort == clientBindPort);
         
         // Verify callback Connector's InvokerLocator was correctly reset.
         int callbackConnectorPort = callbackConnector.getLocator().getPort();
         log.info("callback Connector's port: " + callbackConnectorPort);
         assertTrue(callbackConnectorPort == clientBindPort);
         
         // Verify server can find callback Connector.
         CallbackHandler callbackHandler = new CallbackHandler();
         client.addListener(callbackHandler, callbackConnector.getLocator());
         assertTrue(callbackHandler.allOk());

         callbackConnector.stop();
         client.disconnect();
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
   
   
   /**
    *  callback Connector starts first   - rule 2 - no port
    *  Client starts second              - rule 1
    *
    */
   public void testServer2NoneClient1()
   {
      log.info("ENTERING " + getName());
      
      try
      {  
         // Start callback Connector.
         String callbackURI = "multiplex://localhost/?serverMultiplexId=id";
         callbackURI += "&multiplexConnectHost=localhost&multiplexConnectPort="+connectPort;
         Connector callbackConnector = new Connector(callbackURI);
         log.info("callback locator: " + callbackURI);
         callbackConnector.start();
         
         // Verify callback MultiplexServerInvoker has started.
         assertTrue(callbackConnector.getServerInvoker().isStarted());
         
         // Create Client.
         String params = "/?clientMultiplexId=id";
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         Client client = new Client(clientLocator);
         client.connect();
         
         // Verify callback MultiplexServerInvoker and MultiplexClientInvoker have same port.
         Field field = MultiplexClientInvoker.class.getDeclaredField("bindSocketAddress");
         field.setAccessible(true);
         int clientBindPort = ((InetSocketAddress)field.get(client.getInvoker())).getPort();
         log.info("client bind port: " + clientBindPort);
         MultiplexServerInvoker invoker = (MultiplexServerInvoker) callbackConnector.getServerInvoker();
         int serverInvokerPort = invoker.getServerSocket().getLocalPort();
         log.info("MultiplexServerInvoker's port: " + serverInvokerPort);
         assertTrue(serverInvokerPort == clientBindPort);
         
         // Verify callback Connector's InvokerLocator was correctly reset.
         int callbackConnectorPort = callbackConnector.getLocator().getPort();
         log.info("callback Connector's port: " + callbackConnectorPort);
         assertTrue(callbackConnectorPort == serverInvokerPort);
         
         // Verify server can find callback Connector.
         CallbackHandler callbackHandler = new CallbackHandler();
         client.addListener(callbackHandler, callbackConnector.getLocator());
         assertTrue(callbackHandler.allOk());

         callbackConnector.stop();
         client.disconnect();
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
   
   
   /**
    *  callback Connector starts first   - rule 2 - port == 0
    *  Client starts second              - rule 1
    */
   public void testServer2ZeroClient1()
   {
      log.info("ENTERING " + getName());
      
      try
      {  
         // Start callback Connector.
         String callbackURI = "multiplex://localhost:0/?serverMultiplexId=id";
         callbackURI += "&multiplexConnectHost=localhost&multiplexConnectPort="+connectPort;
         Connector callbackConnector = new Connector(callbackURI);
         log.info("callback locator: " + callbackURI);
         callbackConnector.start();

         // Verify callback MultiplexServerInvoker has started.
         assertTrue(callbackConnector.getServerInvoker().isStarted());
         
         // Create Client.
         String params = "/?clientMultiplexId=id";
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         Client client = new Client(clientLocator);
         client.connect();
         
         // Verify callback MultiplexServerInvoker and MultiplexClientInvoker have same port.
         Field field = MultiplexClientInvoker.class.getDeclaredField("bindSocketAddress");
         field.setAccessible(true);
         int clientBindPort = ((InetSocketAddress)field.get(client.getInvoker())).getPort();
         log.info("client bind port: " + clientBindPort);
         MultiplexServerInvoker invoker = (MultiplexServerInvoker) callbackConnector.getServerInvoker();
         int serverInvokerPort = invoker.getServerSocket().getLocalPort();
         log.info("MultiplexServerInvoker's port: " + serverInvokerPort);
         assertTrue(serverInvokerPort == clientBindPort);
         
         // Verify callback Connector's InvokerLocator was correctly reset.
         int callbackConnectorPort = callbackConnector.getLocator().getPort();
         log.info("callback Connector's port: " + callbackConnectorPort);
         assertTrue(callbackConnectorPort == serverInvokerPort);
         
         // Verify server can find callback Connector.
         CallbackHandler callbackHandler = new CallbackHandler();
         client.addListener(callbackHandler, callbackConnector.getLocator());
         assertTrue(callbackHandler.allOk());

         callbackConnector.stop();
         client.disconnect();
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
 
    
   /**
    *  callback Connector starts first   - rule 3 - no port
    *  Client starts second              - rule 1
    *
    */
   public void testServer3NoneClient1None()
   {
      log.info("ENTERING " + getName());
      
      try
      {  
         // Start callback Connector.
         String callbackURI = "multiplex://localhost/?serverMultiplexId=id";
         Connector callbackConnector = new Connector(callbackURI);
         log.info("callback locator: " + callbackURI);
         callbackConnector.start();
         
         // Verify that MultiplexServerInvoker has a positive bind port.
         MultiplexServerInvoker invoker = (MultiplexServerInvoker) callbackConnector.getServerInvoker();
         Field field = MultiplexServerInvoker.class.getDeclaredField("socketGroupInfo");
         field.setAccessible(true);
         SocketGroupInfo socketGroupInfo = (SocketGroupInfo) field.get(invoker);
         assertTrue(socketGroupInfo.getBindPort() > 0);
         
         // Verify callback MultiplexServerInvoker has not started (rule 3).
         assertFalse(callbackConnector.getServerInvoker().isStarted());
         
         // Create Client.
         String params = "/?clientMultiplexId=id";
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         Client client = new Client(clientLocator);
         client.connect();

         // Verify callback MultiplexServerInvoker has started.
         assertTrue(callbackConnector.getServerInvoker().isStarted());
         
         // Verify callback MultiplexServerInvoker and MultiplexClientInvoker have same port.
         field = MultiplexClientInvoker.class.getDeclaredField("bindSocketAddress");
         field.setAccessible(true);
         int clientBindPort = ((InetSocketAddress)field.get(client.getInvoker())).getPort();
         log.info("client bind port: " + clientBindPort);
         int serverInvokerPort = invoker.getServerSocket().getLocalPort();
         log.info("MultiplexServerInvoker's port: " + serverInvokerPort);
         assertTrue(serverInvokerPort == clientBindPort);
         
         // Verify callback Connector's InvokerLocator was correctly reset.
         int callbackConnectorPort = callbackConnector.getLocator().getPort();
         log.info("callback Connector's port: " + callbackConnectorPort);
         assertTrue(callbackConnectorPort == serverInvokerPort);
         
         // Verify server can find callback Connector.
         CallbackHandler callbackHandler = new CallbackHandler();
         client.addListener(callbackHandler, callbackConnector.getLocator());
         assertTrue(callbackHandler.allOk());

         callbackConnector.stop();
         client.disconnect();
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
   
   
   /**
    *  callback Connector starts first   - rule 3 - port == 0
    *  Client starts second              - rule 1
    */
   public void testServer3ZeroClient1()
   {
      log.info("ENTERING " + getName());
      
      try
      {  
         // Start callback Connector.
         String callbackURI = "multiplex://localhost:0/?serverMultiplexId=id";
         Connector callbackConnector = new Connector(callbackURI);
         log.info("callback locator: " + callbackURI);
         callbackConnector.start();
         
         // Verify that MultiplexServerInvoker has a positive bind port.
         MultiplexServerInvoker invoker = (MultiplexServerInvoker) callbackConnector.getServerInvoker();
         Field field = MultiplexServerInvoker.class.getDeclaredField("socketGroupInfo");
         field.setAccessible(true);
         SocketGroupInfo socketGroupInfo = (SocketGroupInfo) field.get(invoker);
         assertTrue(socketGroupInfo.getBindPort() > 0);
         
         // Verify callback MultiplexServerInvoker has not started.
         assertFalse(callbackConnector.getServerInvoker().isStarted());
         
         // Create Client.
         String params = "/?clientMultiplexId=id";
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         Client client = new Client(clientLocator);
         client.connect();

         // Verify callback MultiplexServerInvoker has started.
         assertTrue(callbackConnector.getServerInvoker().isStarted());
         
         // Verify callback MultiplexServerInvoker and MultiplexClientInvoker have same port.
         field = MultiplexClientInvoker.class.getDeclaredField("bindSocketAddress");
         field.setAccessible(true);
         int clientBindPort = ((InetSocketAddress)field.get(client.getInvoker())).getPort();
         log.info("client bind port: " + clientBindPort);
         int serverInvokerPort = invoker.getServerSocket().getLocalPort();
         log.info("MultiplexServerInvoker's port: " + serverInvokerPort);
         assertTrue(serverInvokerPort == clientBindPort);
         
         // Verify callback Connector's InvokerLocator was correctly reset.
         int callbackConnectorPort = callbackConnector.getLocator().getPort();
         log.info("callback Connector's port: " + callbackConnectorPort);
         assertTrue(callbackConnectorPort == serverInvokerPort);
         
         // Verify server can find callback Connector.
         CallbackHandler callbackHandler = new CallbackHandler();
         client.addListener(callbackHandler, callbackConnector.getLocator());
         assertTrue(callbackHandler.allOk());

         callbackConnector.stop();
         client.disconnect();
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
   
   
   /**
    *  Client starts first - rule 2 - no port - no multiplex id
    *  This test is disabled because we downgraded the condition from an error
    *  with exception to a warning.
    */
   public void xtestClient2Orphan()
   {
      log.info("ENTERING " + getName());
      
      try
      {
         // Create Client.
         String params = "/?multiplexBindHost=localhost";
         String locatorURI =  serverLocatorURI + params;
         InvokerLocator clientLocator = new InvokerLocator(locatorURI);
         log.info("client locator: " + clientLocator);
         
         try
         {
            Client client = new Client(clientLocator);
            client.disconnect();
            fail();
         }
         catch (Exception e)
         {
            if (e.getCause() == null)
               fail();
            
            if (!("Can never be found by any MultiplexServerInvoker: " +
                 "bind port == 0 and socketGroupId == null").equals(e.getCause().getMessage()))
               fail();
         }
 
         log.info(getName() + " PASSES");
         OKCounter++;
      }
      catch (Throwable t)
      {
         log.error(getName() + " FAILS");
         log.error(t);
         t.printStackTrace();
         fail();
      }
   }
   
   
   public static class InvocationHandler implements ServerInvocationHandler
   {
      public Object invoke(InvocationRequest invocation) throws Throwable
      {
         return invocation.getParameter();
      }

      public void addListener(InvokerCallbackHandler callbackHandler)
      {
         try
         {
            Callback callback = new Callback(new Integer(17));
            callbackHandler.handleCallback(callback);
            log.info("sent callback");
         }
         catch(Exception e)
         {
            e.printStackTrace();
         }
      }

      public void removeListener(InvokerCallbackHandler callbackHandler)
      {
      }

      public void setMBeanServer(MBeanServer server)
      {
      }

      public void setInvoker(ServerInvoker invoker)
      {
      }
   }
   
   
   public static class CallbackHandler implements InvokerCallbackHandler
   {
      boolean ok;
      
      public void handleCallback(Callback callback) throws HandleCallbackException
      {
         Object o = callback.getCallbackObject();
         log.info("Received push callback: " + o);
         if (new Integer(17).equals(o))
            ok = true;
      }
      
      public boolean allOk()
      {
         return ok;
      }
   }
}
