diff --git a/redisson/src/main/java/org/redisson/RedissonMap.java b/redisson/src/main/java/org/redisson/RedissonMap.java index ee74b50e6..736e40f23 100644 --- a/redisson/src/main/java/org/redisson/RedissonMap.java +++ b/redisson/src/main/java/org/redisson/RedissonMap.java @@ -15,7 +15,6 @@ */ package org.redisson; -import java.io.IOException; import java.math.BigDecimal; import java.net.InetSocketAddress; import java.util.AbstractCollection; @@ -86,6 +85,10 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture valueSizeAsync(K key) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + return commandExecutor.readAsync(getName(), codec, RedisCommands.HSTRLEN, getName(key), key); } @@ -101,6 +104,10 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture containsKeyAsync(Object key) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + return commandExecutor.readAsync(getName(key), codec, RedisCommands.HEXISTS, getName(key), key); } @@ -111,6 +118,10 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture containsValueAsync(Object value) { + if (value == null) { + throw new NullPointerException("map value can't be null"); + } + return commandExecutor.evalReadAsync(getName(), codec, new RedisCommand("EVAL", new BooleanReplayConvertor(), 4), "local s = redis.call('hvals', KEYS[1]);" + "for i = 1, #s, 1 do " @@ -232,6 +243,13 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture putIfAbsentAsync(K key, V value) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + if (value == null) { + throw new NullPointerException("map value can't be null"); + } + return commandExecutor.evalWriteAsync(getName(key), codec, EVAL_PUT, "if redis.call('hsetnx', KEYS[1], ARGV[1], ARGV[2]) == 1 then " + "return nil " @@ -248,6 +266,13 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture fastPutIfAbsentAsync(K key, V value) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + if (value == null) { + throw new NullPointerException("map value can't be null"); + } + return commandExecutor.writeAsync(getName(key), codec, RedisCommands.HSETNX, getName(key), key, value); } @@ -258,6 +283,13 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture removeAsync(Object key, Object value) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + if (value == null) { + throw new NullPointerException("map value can't be null"); + } + return commandExecutor.evalWriteAsync(getName(key), codec, EVAL_REMOVE_VALUE, "if redis.call('hget', KEYS[1], ARGV[1]) == ARGV[2] then " + "return redis.call('hdel', KEYS[1], ARGV[1]) " @@ -274,6 +306,17 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture replaceAsync(K key, V oldValue, V newValue) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + if (oldValue == null) { + throw new NullPointerException("map oldValue can't be null"); + } + if (newValue == null) { + throw new NullPointerException("map newValue can't be null"); + } + + return commandExecutor.evalWriteAsync(getName(key), codec, EVAL_REPLACE_VALUE, "if redis.call('hget', KEYS[1], ARGV[1]) == ARGV[2] then " + "redis.call('hset', KEYS[1], ARGV[1], ARGV[3]); " @@ -291,6 +334,13 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture replaceAsync(K key, V value) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + if (value == null) { + throw new NullPointerException("map value can't be null"); + } + return commandExecutor.evalWriteAsync(getName(key), codec, EVAL_REPLACE, "if redis.call('hexists', KEYS[1], ARGV[1]) == 1 then " + "local v = redis.call('hget', KEYS[1], ARGV[1]); " @@ -304,6 +354,10 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture getAsync(K key) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + return commandExecutor.readAsync(getName(key), codec, RedisCommands.HGET, getName(key), key); } @@ -313,6 +367,13 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture putAsync(K key, V value) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + if (value == null) { + throw new NullPointerException("map value can't be null"); + } + return commandExecutor.evalWriteAsync(getName(key), codec, EVAL_PUT, "local v = redis.call('hget', KEYS[1], ARGV[1]); " + "redis.call('hset', KEYS[1], ARGV[1], ARGV[2]); " @@ -323,6 +384,10 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture removeAsync(K key) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + return commandExecutor.evalWriteAsync(getName(key), codec, EVAL_REMOVE, "local v = redis.call('hget', KEYS[1], ARGV[1]); " + "redis.call('hdel', KEYS[1], ARGV[1]); " @@ -332,6 +397,13 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture fastPutAsync(K key, V value) { + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + if (value == null) { + throw new NullPointerException("map value can't be null"); + } + return commandExecutor.writeAsync(getName(key), codec, RedisCommands.HSET, getName(key), key, value); } @@ -370,14 +442,17 @@ public class RedissonMap extends RedissonExpirable implements RMap { @Override public RFuture addAndGetAsync(K key, Number value) { - try { - byte[] keyState = codec.getMapKeyEncoder().encode(key); - return commandExecutor.writeAsync(getName(key), StringCodec.INSTANCE, - new RedisCommand("HINCRBYFLOAT", new NumberConvertor(value.getClass())), - getName(key), keyState, new BigDecimal(value.toString()).toPlainString()); - } catch (IOException e) { - throw new IllegalArgumentException(e); + if (key == null) { + throw new NullPointerException("map key can't be null"); + } + if (value == null) { + throw new NullPointerException("map value can't be null"); } + + byte[] keyState = encodeMapKey(key); + return commandExecutor.writeAsync(getName(key), StringCodec.INSTANCE, + new RedisCommand("HINCRBYFLOAT", new NumberConvertor(value.getClass())), + getName(key), keyState, new BigDecimal(value.toString()).toPlainString()); } @Override diff --git a/redisson/src/test/java/org/redisson/RedissonMapTest.java b/redisson/src/test/java/org/redisson/RedissonMapTest.java index 6db62557f..c332fed08 100644 --- a/redisson/src/test/java/org/redisson/RedissonMapTest.java +++ b/redisson/src/test/java/org/redisson/RedissonMapTest.java @@ -291,21 +291,16 @@ public class RedissonMapTest extends BaseTest { assertThat(counter).isEqualTo(size); } - @Test - public void testNull() { + @Test(expected = NullPointerException.class) + public void testNullValue() { Map map = redisson.getMap("simple12"); map.put(1, null); - map.put(2, null); - map.put(3, "43"); - - assertThat(map.size()).isEqualTo(3); - - String val = map.get(2); - assertThat(val).isNull(); - String val2 = map.get(1); - assertThat(val2).isNull(); - String val3 = map.get(3); - assertThat(val3).isEqualTo("43"); + } + + @Test(expected = NullPointerException.class) + public void testNullKey() { + Map map = redisson.getMap("simple12"); + map.put(null, "1"); } @Test