Java tutorial
/** * Copyright (c) 2015 CodisLabs. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.codis.nedis; import static io.codis.nedis.TestUtils.cleanRedis; import static io.codis.nedis.TestUtils.probeFreePort; import static io.codis.nedis.TestUtils.waitUntilRedisUp; import static io.codis.nedis.protocol.RedisCommand.GET; import static io.codis.nedis.util.NedisUtils.bytesToString; import static io.codis.nedis.util.NedisUtils.toBytes; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import io.codis.nedis.NedisClient; import io.codis.nedis.NedisClientPool; import io.codis.nedis.NedisClientPoolBuilder; import io.codis.nedis.exception.RedisResponseException; import io.codis.nedis.exception.TxnAbortException; import io.codis.nedis.exception.TxnDiscardException; import io.codis.nedis.util.NedisUtils; import io.netty.handler.timeout.ReadTimeoutException; import io.netty.util.concurrent.Future; import java.io.IOException; import java.net.InetSocketAddress; import java.util.List; import java.util.concurrent.ExecutionException; import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; /** * @author Apache9 */ public class TestNedis { private static int PORT; private static RedisServer REDIS; private NedisClientPool pool; @BeforeClass public static void setUp() throws IOException, InterruptedException { PORT = probeFreePort(); REDIS = new RedisServer(PORT); REDIS.start(); waitUntilRedisUp(PORT); } @AfterClass public static void tearDownAfterClass() throws InterruptedException { REDIS.stop(); } @After public void tearDown() throws InterruptedException, IOException { if (pool != null) { pool.close(); } cleanRedis(PORT); } @Test public void test() throws InterruptedException, ExecutionException { pool = NedisClientPoolBuilder.create().remoteAddress(new InetSocketAddress("127.0.0.1", PORT)) .clientName("test").build(); NedisClient client = NedisUtils.newPooledClient(pool); System.out.println(client.toString()); Future<String> pingFuture = client.ping(); for (int i = 0; i < 1000; i++) { Future<Boolean> setFuture = client.set(toBytes("foo"), toBytes("bar" + i)); assertTrue(setFuture.sync().getNow()); assertEquals("bar" + i, bytesToString(client.get(toBytes("foo")).sync().getNow())); } assertEquals("PONG", pingFuture.sync().getNow()); assertEquals(null, client.get(toBytes("bar")).sync().getNow()); NedisClient pipelineClient = pool.acquire().sync().getNow(); Future<Long> incrFuture = pipelineClient.incr(toBytes("num")); Future<Long> incrByFuture = pipelineClient.incrby(toBytes("num"), 2L); Future<Long> decrFuture = pipelineClient.decr(toBytes("num")); Future<Long> decrByFuture = pipelineClient.decrby(toBytes("num"), 2L); assertEquals(1L, incrFuture.sync().getNow().longValue()); assertEquals(3L, incrByFuture.sync().getNow().longValue()); assertEquals(2L, decrFuture.sync().getNow().longValue()); assertEquals(0L, decrByFuture.sync().getNow().longValue()); pipelineClient.release(); client.mset(toBytes("a1"), toBytes("b1"), toBytes("a2"), toBytes("b2")).sync(); List<byte[]> resp = client.mget(toBytes("a1"), toBytes("a2"), toBytes("a3")).sync().getNow(); assertEquals(3, resp.size()); assertEquals("b1", bytesToString(resp.get(0))); assertEquals("b2", bytesToString(resp.get(1))); assertEquals(null, resp.get(2)); assertEquals(pool.numConns(), pool.numPooledConns()); int numConns = pool.numConns(); Throwable error = client.execCmd(GET.raw).await().cause(); error.printStackTrace(); assertTrue(error instanceof RedisResponseException); // this error does not cause a connection closing. assertEquals(numConns, pool.numConns()); assertEquals(numConns, pool.numPooledConns()); client.close().sync(); assertEquals(0, pool.numPooledConns()); assertEquals(0, pool.numConns()); } @Test public void testTimeout() throws InterruptedException { pool = NedisClientPoolBuilder.create().remoteAddress(new InetSocketAddress("127.0.0.1", PORT)).database(1) .build(); NedisClient client = pool.acquire().sync().getNow(); Thread.sleep(1000); assertEquals(1, pool.numPooledConns()); assertEquals(1, pool.numConns()); assertEquals(0L, client.setTimeout(100).sync().getNow().longValue()); Future<?> future = client.blpop(1, toBytes("foo")).await(); assertFalse(future.isSuccess()); assertTrue(future.cause() instanceof ReadTimeoutException); Thread.sleep(1000); assertEquals(0, pool.numPooledConns()); assertEquals(0, pool.numConns()); } @Test public void testBlockingCommands() throws InterruptedException { pool = NedisClientPoolBuilder.create().remoteAddress(new InetSocketAddress("127.0.0.1", PORT)) .timeoutMs(100).exclusive(true).build(); NedisClient client = NedisUtils.newPooledClient(pool); Future<List<byte[]>> brpopFuture = client.brpop(100, toBytes("foo")); Thread.sleep(1000); assertFalse(brpopFuture.isDone()); client.lpush(toBytes("foo"), toBytes("bar")); List<byte[]> brpopResp = brpopFuture.sync().getNow(); assertEquals(2, brpopResp.size()); assertEquals("foo", bytesToString(brpopResp.get(0))); assertEquals("bar", bytesToString(brpopResp.get(1))); Future<List<byte[]>> blpopFuture = client.blpop(100, toBytes("a1")); Future<byte[]> brpoplpushFuture = client.brpoplpush(toBytes("a2"), toBytes("a1"), 100); Thread.sleep(1000); assertFalse(blpopFuture.isDone()); assertFalse(brpoplpushFuture.isDone()); client.lpush(toBytes("a2"), toBytes("b")); List<byte[]> blpopResp = blpopFuture.sync().getNow(); assertEquals(2, blpopResp.size()); assertEquals("a1", bytesToString(blpopResp.get(0))); assertEquals("b", bytesToString(blpopResp.get(1))); assertTrue(brpoplpushFuture.isDone()); assertEquals("b", bytesToString(brpoplpushFuture.getNow())); } private void testTxn(NedisClient txnClient, NedisClient chkClient) throws InterruptedException { Future<Void> multiFuture = txnClient.multi(); Future<Boolean> setFuture1 = txnClient.set(toBytes("k1"), toBytes("v1")); Future<Boolean> setFuture2 = txnClient.set(toBytes("k2"), toBytes("v2")); Thread.sleep(1000); assertFalse(setFuture1.isDone()); assertFalse(setFuture2.isDone()); assertFalse(chkClient.exists(toBytes("k1")).sync().getNow().booleanValue()); assertFalse(chkClient.exists(toBytes("k2")).sync().getNow().booleanValue()); List<Object> execResult = txnClient.exec().sync().getNow(); assertTrue(multiFuture.isDone()); assertTrue(setFuture1.getNow().booleanValue()); assertTrue(setFuture2.getNow().booleanValue()); assertEquals(2, execResult.size()); assertEquals("OK", execResult.get(0).toString()); assertEquals("OK", execResult.get(1).toString()); multiFuture = txnClient.multi(); setFuture1 = txnClient.set(toBytes("k1"), toBytes("v3")); setFuture2 = txnClient.set(toBytes("k2"), toBytes("v4")); Thread.sleep(1000); assertFalse(setFuture1.isDone()); assertFalse(setFuture2.isDone()); assertEquals("v1", bytesToString(chkClient.get(toBytes("k1")).sync().getNow())); assertEquals("v2", bytesToString(chkClient.get(toBytes("k2")).sync().getNow())); txnClient.discard().sync(); assertTrue(multiFuture.isDone()); assertTrue(setFuture1.isDone()); assertTrue(setFuture2.isDone()); assertThat(setFuture1.cause(), is(instanceOf(TxnDiscardException.class))); assertThat(setFuture2.cause(), is(instanceOf(TxnDiscardException.class))); assertEquals("v1", bytesToString(chkClient.get(toBytes("k1")).sync().getNow())); assertEquals("v2", bytesToString(chkClient.get(toBytes("k2")).sync().getNow())); Future<Void> watchFuture = txnClient.watch(toBytes("k1")); multiFuture = txnClient.multi(); setFuture1 = txnClient.set(toBytes("k1"), toBytes("v3")); execResult = txnClient.exec().sync().getNow(); assertTrue(watchFuture.isDone()); assertTrue(multiFuture.isDone()); assertTrue(setFuture1.getNow().booleanValue()); assertEquals(1, execResult.size()); assertEquals("OK", execResult.get(0).toString()); assertEquals("v3", bytesToString(chkClient.get(toBytes("k1")).sync().getNow())); txnClient.watch(toBytes("k1")).sync(); multiFuture = txnClient.multi(); setFuture1 = txnClient.set(toBytes("k1"), toBytes("v4")); assertTrue(chkClient.set(toBytes("k1"), toBytes("v1")).sync().getNow().booleanValue()); execResult = txnClient.exec().sync().getNow(); assertTrue(watchFuture.isDone()); assertTrue(multiFuture.isDone()); assertTrue(setFuture1.isDone()); assertThat(setFuture1.cause(), is(instanceOf(TxnAbortException.class))); assertNull(execResult); assertEquals("v1", bytesToString(chkClient.get(toBytes("k1")).sync().getNow())); } @Test public void testTxn() throws InterruptedException { pool = NedisClientPoolBuilder.create().remoteAddress(new InetSocketAddress("127.0.0.1", PORT)) .exclusive(true).build(); NedisClient client = pool.acquire().sync().getNow(); NedisClient client2 = pool.acquire().sync().getNow(); try { testTxn(client, client2); } finally { client.release(); client2.release(); } } @Test public void testInfiniteWaitWhenClosing() throws InterruptedException { pool = NedisClientPoolBuilder.create().remoteAddress(new InetSocketAddress("127.0.0.1", PORT)).build(); pool.close().sync(); } }