package org.infinispan.client.hotrod;
import static org.testng.Assert.assertNotEquals;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.fail;
import java.util.Collections;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.client.hotrod.test.InternalRemoteCacheManager;
import org.infinispan.client.hotrod.test.SingleHotRodServerTest;
import org.testng.annotations.Test;
/**
* @author Mircea.Markus@jboss.com
* @since 4.1
*/
@Test(groups = "functional", testName = "client.hotrod.RemoteAsyncAPITest")
public class RemoteAsyncAPITest extends SingleHotRodServerTest {
@Override
protected RemoteCacheManager getRemoteCacheManager() {
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.forceReturnValues(isForceReturnValuesViaConfiguration());
builder.addServer().host("127.0.0.1").port(hotrodServer.getPort());
return new InternalRemoteCacheManager(builder.build());
}
protected boolean isForceReturnValuesViaConfiguration() {
return true;
}
protected RemoteCache<String, String> remote() {
return remoteCacheManager.getCache();
}
public void testPutAsync() throws Exception {
// put
Future<String> f = remote().putAsync("k", "v");
testFuture(f, null);
testK("v");
f = remote().putAsync("k", "v2");
testFuture(f, "v");
testK("v2");
}
public void testPutAsyncWithListener() throws Exception {
CompletableFuture<String> f = remote().putAsync("k", "v");
testFutureWithListener(f, null);
testK("v");
f = remote().putAsync("k", "v2");
testFutureWithListener(f, "v");
testK("v2");
}
public void testPutAllAsync() throws Exception {
Future<Void> f = remote().putAllAsync(Collections.singletonMap("k", "v3"));
testFuture(f, null);
testK("v3");
}
public void testPutAllAsyncWithListener() throws Exception {
CompletableFuture<Void> f = remote().putAllAsync(Collections.singletonMap("k", "v3"));
testFutureWithListener(f, null);
testK("v3");
}
public void testPutIfAbsentAsync() throws Exception {
remote().put("k", "v3");
testK("v3");
Future<String> f = remote().putIfAbsentAsync("k", "v4");
testFuture(f, "v3");
assertEquals("v3", remote().remove("k"));
f = remote().putIfAbsentAsync("k", "v5");
testFuture(f, null);
testK("v5");
}
public void testPutIfAbsentAsyncWithListener() throws Exception {
remote().put("k", "v3");
testK("v3");
CompletableFuture<String> f = remote().putIfAbsentAsync("k", "v4");
testFutureWithListener(f, "v3");
assertEquals("v3", remote().remove("k"));
f = remote().putIfAbsentAsync("k", "v5");
testFutureWithListener(f, null);
testK("v5");
}
public void testRemoveAsync() throws Exception {
remote().put("k", "v3");
testK("v3");
Future<String> f = remote().removeAsync("k");
testFuture(f, "v3");
testK(null);
}
public void testRemoveAsyncWithListener() throws Exception {
remote().put("k", "v3");
testK("v3");
CompletableFuture<String> f = remote().removeAsync("k");
testFutureWithListener(f, "v3");
testK(null);
}
public void testGetAsync() throws Exception {
remote().put("k", "v");
testK("v");
Future<String> f = remote().getAsync("k");
testFuture(f, "v");
testK("v");
}
public void testGetAsyncWithListener() throws Exception {
remote().put("k", "v");
testK("v");
CompletableFuture<String> f = remote().getAsync("k");
testFutureWithListener(f, "v");
}
public void testRemoveWithVersionAsync() throws Exception {
remote().put("k", "v4");
VersionedValue value = remote().getVersioned("k");
Future<Boolean> f = remote().removeWithVersionAsync("k", value.getVersion() + 1);
testFuture(f, false);
testK("v4");
f = remote().removeWithVersionAsync("k", value.getVersion());
testFuture(f, true);
testK(null);
}
public void testRemoveWithVersionAsyncWithListener() throws Exception {
remote().put("k", "v4");
VersionedValue value = remote().getVersioned("k");
CompletableFuture<Boolean> f = remote().removeWithVersionAsync("k", value.getVersion() + 1);
testFutureWithListener(f, false);
testK("v4");
f = remote().removeWithVersionAsync("k", value.getVersion());
testFutureWithListener(f, true);
testK(null);
}
public void testReplaceAsync() throws Exception {
testK(null);
Future<String> f = remote().replaceAsync("k", "v5");
testFuture(f, null);
testK(null);
remote().put("k", "v");
testK("v");
f = remote().replaceAsync("k", "v5");
testFuture(f, "v");
testK("v5");
}
public void testReplaceAsyncWithListener() throws Exception {
testK(null);
CompletableFuture<String> f = remote().replaceAsync("k", "v5");
testFutureWithListener(f, null);
testK(null);
remote().put("k", "v");
testK("v");
f = remote().replaceAsync("k", "v5");
testFutureWithListener(f, "v");
testK("v5");
}
public void testReplaceWithVersionAsync() throws Exception {
remote().put("k", "v");
VersionedValue versioned1 = remote().getVersioned("k");
Future<Boolean> f = remote().replaceWithVersionAsync("k", "v2", versioned1.getVersion());
testFuture(f, true);
VersionedValue versioned2 = remote().getVersioned("k");
assertNotEquals(versioned1.getVersion(), versioned2.getVersion());
assertEquals(versioned2.getValue(), "v2");
f = remote().replaceWithVersionAsync("k", "v3", versioned1.getVersion());
testFuture(f, false);
testK("v2");
}
public void testReplaceWithVersionAsyncWithListener() throws Exception {
remote().put("k", "v");
VersionedValue versioned1 = remote().getVersioned("k");
CompletableFuture<Boolean> f = remote().replaceWithVersionAsync("k", "v2", versioned1.getVersion());
testFutureWithListener(f, true);
VersionedValue versioned2 = remote().getVersioned("k");
assertNotEquals(versioned1.getVersion(), versioned2.getVersion());
assertEquals(versioned2.getValue(), "v2");
f = remote().replaceWithVersionAsync("k", "v3", versioned1.getVersion());
testFutureWithListener(f, false);
testK("v2");
}
private <T> void testK(T expected) {
assertEquals(expected, remote().get("k"));
}
private <T> void testFuture(Future<T> f, T expected) throws ExecutionException, InterruptedException {
assertNotNull(f);
assertFalse(f.isCancelled());
T value = f.get();
assertEquals("Obtained " + value, expected, value);
assertTrue(f.isDone());
}
private <T> void testFutureWithListener(CompletableFuture<T> f, T expected) throws InterruptedException {
assertNotNull(f);
AtomicReference<Throwable> ex = new AtomicReference<Throwable>();
CountDownLatch latch = new CountDownLatch(1);
f.whenComplete((v, t) -> {
if (t != null) {
ex.set(t);
}
assertEquals("Obtained " + v, expected, v);
latch.countDown();
});
if (!latch.await(5, TimeUnit.SECONDS)) {
fail("Not finished within 5 seconds");
}
if (ex.get() != null) {
throw new AssertionError(ex.get());
}
}
}