@Test
  public void submitRunnableToAllMembers_withMultiExecutionCallback() throws Exception {
    IExecutorService service = client.getExecutorService(randomString());

    final CountDownLatch responseLatch = new CountDownLatch(CLUSTER_SIZE);
    final CountDownLatch completeLatch = new CountDownLatch(1);
    String mapName = randomString();
    Runnable runnable = new MapPutRunnable(mapName);

    service.submitToAllMembers(
        runnable,
        new MultiExecutionCallback() {
          public void onResponse(Member member, Object value) {
            responseLatch.countDown();
          }

          public void onComplete(Map<Member, Object> values) {
            completeLatch.countDown();
          }
        });
    IMap map = client.getMap(mapName);

    assertOpenEventually("responseLatch", responseLatch);
    assertOpenEventually("completeLatch", completeLatch);
    assertEquals(CLUSTER_SIZE, map.size());
  }
  @Test
  public void submitCallableWithNullResultToAllMembers_withMultiExecutionCallback()
      throws Exception {
    IExecutorService service = client.getExecutorService(randomString());

    final CountDownLatch responseLatch = new CountDownLatch(CLUSTER_SIZE);
    final CountDownLatch completeLatch = new CountDownLatch(CLUSTER_SIZE);
    Callable callable = new NullCallable();

    service.submitToAllMembers(
        callable,
        new MultiExecutionCallback() {
          public void onResponse(Member member, Object value) {
            if (value == null) {
              responseLatch.countDown();
            }
          }

          public void onComplete(Map<Member, Object> values) {
            for (Member member : values.keySet()) {
              Object value = values.get(member);
              if (value == null) {
                completeLatch.countDown();
              }
            }
          }
        });

    assertOpenEventually("responseLatch", responseLatch);
    assertOpenEventually("completeLatch", completeLatch);
  }
  @Test
  public void submitCallableToMembers_withExecutionCallback() {
    IExecutorService service = client.getExecutorService(randomString());

    final CountDownLatch responseLatch = new CountDownLatch(CLUSTER_SIZE);
    final CountDownLatch completeLatch = new CountDownLatch(1);
    final String msg = randomString();
    Callable callable = new AppendCallable(msg);
    MemberSelector selector = new SelectAllMembers();

    service.submitToMembers(
        callable,
        selector,
        new MultiExecutionCallback() {
          public void onResponse(Member member, Object value) {
            if (value.equals(msg + AppendCallable.APPENDAGE)) {
              responseLatch.countDown();
            }
          }

          public void onComplete(Map<Member, Object> values) {
            completeLatch.countDown();
          }
        });

    assertOpenEventually("responseLatch", responseLatch);
    assertOpenEventually("completeLatch", completeLatch);
  }
  @Test
  public void submitCallableToMember_withMultiExecutionCallback() throws Exception {
    IExecutorService service = client.getExecutorService(randomString());

    final CountDownLatch responseLatch = new CountDownLatch(CLUSTER_SIZE);
    final CountDownLatch completeLatch = new CountDownLatch(CLUSTER_SIZE);
    final String msg = randomString();
    Callable<String> callable = new AppendCallable(msg);
    Collection<Member> collection = server.getCluster().getMembers();

    service.submitToMembers(
        callable,
        collection,
        new MultiExecutionCallback() {
          public void onResponse(Member member, Object value) {
            if (value.equals(msg + AppendCallable.APPENDAGE)) {
              responseLatch.countDown();
            }
          }

          public void onComplete(Map<Member, Object> values) {
            for (Member member : values.keySet()) {
              Object value = values.get(member);
              if (value.equals(msg + AppendCallable.APPENDAGE)) {
                completeLatch.countDown();
              }
            }
          }
        });

    assertOpenEventually("responseLatch", responseLatch);
    assertOpenEventually("completeLatch", completeLatch);
  }
  @Test
  public void submitCallablePartitionAware_WithExecutionCallback() throws Exception {
    IExecutorService service = client.getExecutorService(randomString());

    String mapName = randomString();
    IMap map = client.getMap(mapName);
    String key = HazelcastTestSupport.generateKeyOwnedBy(server);
    Member member = server.getCluster().getLocalMember();

    Callable<String> runnable = new MapPutPartitionAwareCallable<String, String>(mapName, key);

    final AtomicReference<String> result = new AtomicReference<String>();
    final CountDownLatch responseLatch = new CountDownLatch(1);

    service.submit(
        runnable,
        new ExecutionCallback<String>() {
          public void onResponse(String response) {
            result.set(response);
            responseLatch.countDown();
          }

          public void onFailure(Throwable t) {}
        });

    assertOpenEventually("responseLatch", responseLatch);
    assertEquals(member.getUuid(), result.get());
    assertTrue(map.containsKey(member.getUuid()));
  }
  @Test
  public void submitRunnablePartitionAware_withExecutionCallback() throws Exception {
    IExecutorService service = client.getExecutorService(randomString());

    String mapName = randomString();
    String key = HazelcastTestSupport.generateKeyOwnedBy(server);
    Member member = server.getCluster().getLocalMember();
    Runnable runnable = new MapPutPartitionAwareRunnable<String>(mapName, key);
    final CountDownLatch responseLatch = new CountDownLatch(1);

    service.submit(
        runnable,
        new ExecutionCallback() {
          @Override
          public void onResponse(Object response) {
            responseLatch.countDown();
          }

          @Override
          public void onFailure(Throwable t) {}
        });
    IMap map = client.getMap(mapName);

    assertOpenEventually("responseLatch", responseLatch);
    assertTrue(map.containsKey(member.getUuid()));
  }
  @Test
  public void submitCallable_withExecutionCallback() {
    IExecutorService service = client.getExecutorService(randomString());

    final CountDownLatch responseLatch = new CountDownLatch(1);
    String msg = randomString();
    Callable runnable = new AppendCallable(msg);
    MemberSelector selector = new SelectAllMembers();
    final AtomicReference<Object> result = new AtomicReference<Object>();

    service.submit(
        runnable,
        selector,
        new ExecutionCallback() {
          public void onResponse(Object response) {
            result.set(response);
            responseLatch.countDown();
          }

          public void onFailure(Throwable t) {}
        });

    assertOpenEventually("responseLatch", responseLatch);
    assertEquals(msg + AppendCallable.APPENDAGE, result.get());
  }
  @Test
  public void testSubmitCallableToMember_withExecutionCallback() throws Exception {
    IExecutorService service = client.getExecutorService(randomString());

    Callable getUuidCallable = new GetMemberUuidTask();
    Member member = server.getCluster().getLocalMember();
    final CountDownLatch responseLatch = new CountDownLatch(1);
    final AtomicReference<Object> result = new AtomicReference<Object>();

    service.submitToMember(
        getUuidCallable,
        member,
        new ExecutionCallback() {
          @Override
          public void onResponse(Object response) {
            result.set(response);
            responseLatch.countDown();
          }

          @Override
          public void onFailure(Throwable t) {}
        });

    assertOpenEventually("responseLatch", responseLatch);
    assertEquals(member.getUuid(), result.get());
  }
  @Test
  public void testSubmitRunnable_withExecutionCallback() throws Exception {
    IExecutorService service = client.getExecutorService(randomString());

    String mapName = randomString();
    Runnable runnable = new MapPutRunnable(mapName);
    final CountDownLatch responseLatch = new CountDownLatch(1);

    service.submit(
        runnable,
        new ExecutionCallback() {
          public void onResponse(Object response) {
            responseLatch.countDown();
          }

          public void onFailure(Throwable t) {}
        });
    IMap map = client.getMap(mapName);

    assertOpenEventually("responseLatch", responseLatch);
    assertEquals(1, map.size());
  }
  @Test
  public void testSubmitCallable_withExecutionCallback() throws Exception {
    IExecutorService service = client.getExecutorService(randomString());

    String msg = randomString();
    Callable<String> callable = new AppendCallable(msg);
    final AtomicReference<String> result = new AtomicReference<String>();
    final CountDownLatch responseLatch = new CountDownLatch(1);

    service.submit(
        callable,
        new ExecutionCallback<String>() {
          public void onResponse(String response) {
            result.set(response);
            responseLatch.countDown();
          }

          public void onFailure(Throwable t) {}
        });

    assertOpenEventually("responseLatch", responseLatch);
    assertEquals(msg + AppendCallable.APPENDAGE, result.get());
  }
  @Test
  public void submitRunnableToMember_withExecutionCallback() {
    IExecutorService service = client.getExecutorService(randomString());

    String mapName = randomString();
    Runnable runnable = new MapPutRunnable(mapName);
    Member member = server.getCluster().getLocalMember();
    final CountDownLatch responseLatch = new CountDownLatch(1);

    service.submitToMember(
        runnable,
        member,
        new ExecutionCallback() {
          public void onResponse(Object response) {
            responseLatch.countDown();
          }

          public void onFailure(Throwable t) {}
        });
    Map map = client.getMap(mapName);

    assertOpenEventually("responseLatch", responseLatch);
    assertEquals(1, map.size());
  }
 public static void assertOpenEventually(CountDownLatch latch, long timeoutSeconds) {
   assertOpenEventually(null, latch, timeoutSeconds);
 }
 public static void assertOpenEventually(String message, CountDownLatch latch) {
   assertOpenEventually(message, latch, ASSERT_TRUE_EVENTUALLY_TIMEOUT);
 }
 public static void assertOpenEventually(CountDownLatch latch) {
   assertOpenEventually(latch, ASSERT_TRUE_EVENTUALLY_TIMEOUT);
 }