/** Basic load balance testing. A random distribution is used amongst nodes for client now. */
  private void loadbalance(EJBDirectory directory, String deployment1, String deployment2)
      throws Exception {
    this.start(CONTAINER_1);
    this.deploy(CONTAINER_1, deployment1);
    this.start(CONTAINER_2);
    this.deploy(CONTAINER_2, deployment2);

    final ContextSelector<EJBClientContext> previousSelector =
        EJBClientContextSelector.setup(CLIENT_PROPERTIES);

    int numberOfServers = 2;
    int numberOfCalls = 40;
    // there will be at least 20% of calls processed by all servers
    double serversProccessedAtLeast = 0.2;

    try {
      StatelessRemoteHome home =
          directory.lookupHome(StatelessBean.class, StatelessRemoteHome.class);
      StatelessRemote bean = home.create();

      String node = bean.getNodeName();
      log.info("Node called : " + node);

      validateBalancing(bean, numberOfCalls, numberOfServers, serversProccessedAtLeast);

      Properties contextChangeProperties = new Properties();
      contextChangeProperties.put(REMOTE_PORT_PROPERTY_NAME, PORT_2.toString());
      contextChangeProperties.put(REMOTE_HOST_PROPERTY_NAME, HOST_2.toString());
      EJBClientContextSelector.setup(CLIENT_PROPERTIES, contextChangeProperties);

      bean = home.create();
      node = bean.getNodeName();
      log.info("Node called : " + node);

      validateBalancing(bean, numberOfCalls, numberOfServers, serversProccessedAtLeast);
    } finally {
      // reset the selector
      if (previousSelector != null) {
        EJBClientContext.setSelector(previousSelector);
      }
      // undeploy&shutdown the containers
      undeployAll();
      shutdownAll();
    }
  }
  @Test
  public void testFailoverOnUndeploy() throws Exception {
    // Container is unmanaged, so start it ourselves
    this.start(0);
    this.deploy(0);

    final ContextSelector<EJBClientContext> selector =
        EJBClientContextSelector.setup(CLIENT_PROPERTIES);

    try {
      ViewChangeListener listener =
          context.lookupStateless(ViewChangeListenerBean.class, ViewChangeListener.class);

      this.establishView(listener, NODES[0]);

      Stateless bean = context.lookupStateless(StatelessBean.class, Stateless.class);

      assertEquals(NODES[0], bean.getNodeName());

      this.start(1);
      this.deploy(1);

      this.establishView(listener, NODES);

      List<String> results = new ArrayList<String>(10);
      for (int i = 0; i < 10; ++i) {
        results.add(bean.getNodeName());
      }

      for (int i = 0; i < NODES.length; ++i) {
        int frequency = Collections.frequency(results, NODES[i]);
        Assert.assertTrue(String.valueOf(frequency), frequency > 0);
      }

      this.undeploy(0);

      this.establishView(listener, NODES[1]);

      assertEquals(NODES[1], bean.getNodeName());
    } finally {
      // reset the selector
      if (selector != null) {
        EJBClientContext.setSelector(selector);
      }
      // shutdown the containers
      for (int i = 0; i < NODES.length; ++i) {
        this.undeploy(i);
        this.stop(i);
      }
    }
  }
  @Test
  public void test() throws Exception {

    String cluster = "server";
    String nodeNameFormat = "%s/%s";
    String nodeName1 = String.format(nodeNameFormat, NODE_1, cluster);
    String nodeName2 = String.format(nodeNameFormat, NODE_2, cluster);

    ContextSelector<EJBClientContext> selector = EJBClientContextSelector.setup(CLIENT_PROPERTIES);

    try {
      ServiceProviderRetriever bean =
          context.lookupStateless(
              ServiceProviderRetrieverBean.class, ServiceProviderRetriever.class);
      Collection<String> names = bean.getProviders();
      assertEquals(2, names.size());
      assertTrue(names.toString(), names.contains(nodeName1));
      assertTrue(names.toString(), names.contains(nodeName2));

      undeploy(DEPLOYMENT_1);

      names = bean.getProviders();
      assertEquals(1, names.size());
      assertTrue(names.contains(nodeName2));

      deploy(DEPLOYMENT_1);

      names = bean.getProviders();
      assertEquals(2, names.size());
      assertTrue(names.contains(nodeName1));
      assertTrue(names.contains(nodeName2));

      stop(CONTAINER_2);

      names = bean.getProviders();
      assertEquals(1, names.size());
      assertTrue(names.contains(nodeName1));

      start(CONTAINER_2);

      names = bean.getProviders();
      assertEquals(2, names.size());
      assertTrue(names.contains(nodeName1));
      assertTrue(names.contains(nodeName2));
    } finally {
      // reset the selector
      if (selector != null) {
        EJBClientContext.setSelector(selector);
      }
    }
  }
  private void doFailover(
      boolean isStop, EJBDirectory directory, String deployment1, String deployment2)
      throws Exception {
    this.start(CONTAINER_1);
    this.deploy(CONTAINER_1, deployment1);

    final ContextSelector<EJBClientContext> selector =
        EJBClientContextSelector.setup(CLIENT_PROPERTIES);

    try {
      StatelessRemoteHome home =
          directory.lookupHome(StatelessBean.class, StatelessRemoteHome.class);
      StatelessRemote bean = home.create();

      assertEquals(
          "The only " + NODES[0] + " is active. Bean had to be invoked on it but it wasn't.",
          NODES[0],
          bean.getNodeName());

      this.start(CONTAINER_2);
      this.deploy(CONTAINER_2, deployment2);

      if (isStop) {
        this.stop(CONTAINER_1);
      } else {
        this.undeploy(CONTAINER_1, deployment1);
      }

      assertEquals(
          "Only " + NODES[1] + " is active. The bean had to be invoked on it but it wasn't.",
          NODES[1],
          bean.getNodeName());
    } finally {
      // reset the selector
      if (selector != null) {
        EJBClientContext.setSelector(selector);
      }
      // need to have the container started to undeploy deployment afterwards
      this.start(CONTAINER_1);
      // shutdown the containers
      undeployAll();
      shutdownAll();
    }
  }
  /** Basic load balance testing. A random distribution is used amongst nodes for client now. */
  @Test
  public void testLoadbalance() throws Exception {
    this.start(0);
    this.deploy(0);
    this.start(1);
    this.deploy(1);

    final ContextSelector<EJBClientContext> previousSelector =
        EJBClientContextSelector.setup(CLIENT_PROPERTIES);

    int numberOfServers = 2;
    int numberOfCalls = 50;
    // there will be at least 20% of calls processed by all servers
    double serversProccessedAtLeast = 0.2;

    try {
      ViewChangeListener listener =
          context.lookupStateless(ViewChangeListenerBean.class, ViewChangeListener.class);

      this.establishView(listener, NODES);

      Stateless bean = context.lookupStateless(StatelessBean.class, Stateless.class);

      String node = bean.getNodeName();
      log.info("Node called : " + node);

      validateBalancing(bean, numberOfCalls, numberOfServers, serversProccessedAtLeast);

      Properties contextChangeProperties = new Properties();
      contextChangeProperties.put(REMOTE_PORT_PROPERTY_NAME, PORT_2.toString());
      contextChangeProperties.put(REMOTE_HOST_PROPERTY_NAME, HOST_2.toString());
      EJBClientContextSelector.setup(CLIENT_PROPERTIES, contextChangeProperties);

      bean = context.lookupStateless(StatelessBean.class, Stateless.class);
      node = bean.getNodeName();
      log.info("Node called : " + node);

      validateBalancing(bean, numberOfCalls, numberOfServers, serversProccessedAtLeast);

      this.stop(0);

      this.establishView(listener, NODES[1]);

      node = bean.getNodeName();
      log.info("Node called : " + node);

      this.start(0);

      this.establishView(listener, NODES);

      node = bean.getNodeName();
      log.info("Node called : " + node);

      validateBalancing(bean, numberOfCalls, numberOfServers, serversProccessedAtLeast);
    } finally {
      // reset the selector
      if (previousSelector != null) {
        EJBClientContext.setSelector(previousSelector);
      }
      // shutdown the containers
      for (int i = 0; i < NODES.length; ++i) {
        this.undeploy(i);
        this.stop(i);
      }
    }
  }