Skip to content

Commit 4c7e405

Browse files
christophstroblThomas Darimont
authored andcommitted
DATAREDIS-344 - Assert RedisCache works with Spring 4.1.
Added `putIfAbsent` to `RedisCache` to satisfy compatibility with newly introduced method. Original pull request: spring-projects#102.
1 parent f94df9f commit 4c7e405

File tree

2 files changed

+76
-4
lines changed

2 files changed

+76
-4
lines changed

src/main/java/org/springframework/data/redis/cache/RedisCache.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,38 @@ public Object doInRedis(RedisConnection connection) throws DataAccessException {
137137
}, true);
138138
}
139139

140+
public ValueWrapper putIfAbsent(Object key, final Object value) {
141+
142+
final byte[] keyBytes = computeKey(key);
143+
final byte[] valueBytes = convertToBytesIfNecessary(template.getValueSerializer(), value);
144+
145+
return toWrapper(template.execute(new RedisCallback<Object>() {
146+
public Object doInRedis(RedisConnection connection) throws DataAccessException {
147+
148+
waitForLock(connection);
149+
150+
Object resultValue = value;
151+
boolean valueWasSet = connection.setNX(keyBytes, valueBytes);
152+
if (valueWasSet) {
153+
connection.zAdd(setName, 0, keyBytes);
154+
if (expiration > 0) {
155+
connection.expire(keyBytes, expiration);
156+
// update the expiration of the set of keys as well
157+
connection.expire(setName, expiration);
158+
}
159+
} else {
160+
resultValue = deserializeIfNecessary(template.getValueSerializer(), connection.get(keyBytes));
161+
}
162+
163+
return resultValue;
164+
}
165+
}, true));
166+
}
167+
168+
private ValueWrapper toWrapper(Object value) {
169+
return (value != null ? new SimpleValueWrapper(value) : null);
170+
}
171+
140172
public void evict(Object key) {
141173
final byte[] k = computeKey(key);
142174

@@ -227,4 +259,14 @@ private byte[] convertToBytesIfNecessary(RedisSerializer<Object> serializer, Obj
227259

228260
return serializer.serialize(value);
229261
}
262+
263+
private Object deserializeIfNecessary(RedisSerializer<byte[]> serializer, byte[] value) {
264+
265+
if (serializer != null) {
266+
return serializer.deserialize(value);
267+
}
268+
269+
return value;
270+
}
271+
230272
}

src/test/java/org/springframework/data/redis/cache/RedisCacheTest.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@
1616

1717
package org.springframework.data.redis.cache;
1818

19-
import static org.hamcrest.core.IsInstanceOf.*;
20-
import static org.hamcrest.core.IsNull.*;
19+
import static org.hamcrest.core.IsEqual.equalTo;
20+
import static org.hamcrest.core.IsInstanceOf.instanceOf;
21+
import static org.hamcrest.core.IsNot.not;
22+
import static org.hamcrest.core.IsNull.nullValue;
23+
import static org.hamcrest.core.IsSame.sameInstance;
2124
import static org.junit.Assert.assertFalse;
2225
import static org.junit.Assert.assertNotNull;
2326
import static org.junit.Assert.assertNull;
2427
import static org.junit.Assert.assertThat;
2528
import static org.junit.Assert.assertTrue;
26-
import static org.junit.Assume.*;
29+
import static org.junit.Assume.assumeThat;
2730
import static org.springframework.data.redis.matcher.RedisTestMatchers.isEqual;
2831

2932
import java.util.Collection;
@@ -71,7 +74,7 @@ public static Collection<Object[]> testParams() {
7174
}
7275

7376
@SuppressWarnings("unchecked")
74-
protected Cache createCache(RedisTemplate nativeCache) {
77+
protected RedisCache createCache(RedisTemplate nativeCache) {
7578
return new RedisCache(CACHE_NAME, CACHE_NAME.concat(":").getBytes(), nativeCache, TimeUnit.MINUTES.toSeconds(10));
7679
}
7780

@@ -246,4 +249,31 @@ public void testCacheGetShouldReturnNullIfNoCachedValueFound() {
246249
Object invalidKey = template.getKeySerializer() == null ? "spring-data-redis".getBytes() : "spring-data-redis";
247250
assertThat(redisCache.get(invalidKey, value.getClass()), nullValue());
248251
}
252+
253+
/**
254+
* @see DATAREDIS-344
255+
*/
256+
@Test
257+
public void putIfAbsentShouldSetValueOnlyIfNotPresent() {
258+
259+
assumeThat(cache, instanceOf(RedisCache.class));
260+
261+
RedisCache redisCache = (RedisCache)cache;
262+
263+
Object key = getKey();
264+
template.delete(key);
265+
266+
Object value = getValue();
267+
ValueWrapper wrapper = redisCache.putIfAbsent(key, value);
268+
269+
assertThat(wrapper.get(), sameInstance(value));
270+
271+
ValueWrapper wrapper2 = redisCache.putIfAbsent(key, value);
272+
273+
if (!(value instanceof Number)) {
274+
assertThat(wrapper2.get(), not(sameInstance(value)));
275+
}
276+
277+
assertThat(wrapper2.get(), equalTo(value));
278+
}
249279
}

0 commit comments

Comments
 (0)